aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir/src/code_model.rs8
-rw-r--r--crates/hir/src/from_id.rs17
-rw-r--r--crates/hir/src/has_source.rs14
-rw-r--r--crates/hir/src/semantics.rs51
-rw-r--r--crates/hir/src/semantics/source_to_def.rs21
-rw-r--r--crates/hir_def/src/generics.rs49
-rw-r--r--crates/hir_def/src/item_tree/lower.rs5
-rw-r--r--crates/hir_def/src/keys.rs5
-rw-r--r--crates/hir_expand/src/builtin_macro.rs10
-rw-r--r--crates/hir_expand/src/name.rs1
-rw-r--r--crates/proc_macro_srv/Cargo.toml2
-rw-r--r--crates/proc_macro_srv/src/dylib.rs65
12 files changed, 170 insertions, 78 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index fcc42c6bb..42dc35b76 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -1250,6 +1250,14 @@ impl LifetimeParam {
1250 let params = db.generic_params(self.id.parent); 1250 let params = db.generic_params(self.id.parent);
1251 params.lifetimes[self.id.local_id].name.clone() 1251 params.lifetimes[self.id.local_id].name.clone()
1252 } 1252 }
1253
1254 pub fn module(self, db: &dyn HirDatabase) -> Module {
1255 self.id.parent.module(db.upcast()).into()
1256 }
1257
1258 pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
1259 self.id.parent.into()
1260 }
1253} 1261}
1254 1262
1255// FIXME: rename from `ImplDef` to `Impl` 1263// FIXME: rename from `ImplDef` to `Impl`
diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs
index 265ef6d1f..dd3fcfe4a 100644
--- a/crates/hir/src/from_id.rs
+++ b/crates/hir/src/from_id.rs
@@ -41,6 +41,7 @@ from_id![
41 (hir_def::FunctionId, crate::Function), 41 (hir_def::FunctionId, crate::Function),
42 (hir_def::ImplId, crate::ImplDef), 42 (hir_def::ImplId, crate::ImplDef),
43 (hir_def::TypeParamId, crate::TypeParam), 43 (hir_def::TypeParamId, crate::TypeParam),
44 (hir_def::LifetimeParamId, crate::LifetimeParam),
44 (hir_expand::MacroDefId, crate::MacroDef) 45 (hir_expand::MacroDefId, crate::MacroDef)
45]; 46];
46 47
@@ -154,6 +155,22 @@ impl From<GenericDef> for GenericDefId {
154 } 155 }
155} 156}
156 157
158impl From<GenericDefId> for GenericDef {
159 fn from(def: GenericDefId) -> Self {
160 match def {
161 GenericDefId::FunctionId(it) => GenericDef::Function(it.into()),
162 GenericDefId::AdtId(it) => GenericDef::Adt(it.into()),
163 GenericDefId::TraitId(it) => GenericDef::Trait(it.into()),
164 GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()),
165 GenericDefId::ImplId(it) => GenericDef::ImplDef(it.into()),
166 GenericDefId::EnumVariantId(it) => {
167 GenericDef::EnumVariant(EnumVariant { parent: it.parent.into(), id: it.local_id })
168 }
169 GenericDefId::ConstId(it) => GenericDef::Const(it.into()),
170 }
171 }
172}
173
157impl From<Adt> for GenericDefId { 174impl From<Adt> for GenericDefId {
158 fn from(id: Adt) -> Self { 175 fn from(id: Adt) -> Self {
159 match id { 176 match id {
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs
index c77494152..1e64a1614 100644
--- a/crates/hir/src/has_source.rs
+++ b/crates/hir/src/has_source.rs
@@ -10,8 +10,8 @@ use hir_expand::InFile;
10use syntax::ast; 10use syntax::ast;
11 11
12use crate::{ 12use crate::{
13 db::HirDatabase, Const, Enum, EnumVariant, Field, FieldSource, Function, ImplDef, MacroDef, 13 db::HirDatabase, Const, Enum, EnumVariant, Field, FieldSource, Function, ImplDef,
14 Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, 14 LifetimeParam, MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union,
15}; 15};
16 16
17pub trait HasSource { 17pub trait HasSource {
@@ -129,6 +129,14 @@ impl HasSource for TypeParam {
129 type Ast = Either<ast::Trait, ast::TypeParam>; 129 type Ast = Either<ast::Trait, ast::TypeParam>;
130 fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> { 130 fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> {
131 let child_source = self.id.parent.child_source(db.upcast()); 131 let child_source = self.id.parent.child_source(db.upcast());
132 child_source.map(|it| it[self.id.local_id].clone()) 132 child_source.map(|it| it.type_params[self.id.local_id].clone())
133 }
134}
135
136impl HasSource for LifetimeParam {
137 type Ast = ast::LifetimeParam;
138 fn source(self, db: &dyn HirDatabase) -> InFile<Self::Ast> {
139 let child_source = self.id.parent.child_source(db.upcast());
140 child_source.map(|it| it.lifetime_params[self.id.local_id].clone())
133 } 141 }
134} 142}
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 4bd22ed27..e4fc21ced 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -13,7 +13,11 @@ use hir_expand::{hygiene::Hygiene, name::AsName, ExpansionInfo};
13use hir_ty::associated_type_shorthand_candidates; 13use hir_ty::associated_type_shorthand_candidates;
14use itertools::Itertools; 14use itertools::Itertools;
15use rustc_hash::{FxHashMap, FxHashSet}; 15use rustc_hash::{FxHashMap, FxHashSet};
16use syntax::{algo::find_node_at_offset, ast, AstNode, SyntaxNode, SyntaxToken, TextSize}; 16use syntax::{
17 algo::find_node_at_offset,
18 ast::{self, GenericParamsOwner},
19 match_ast, AstNode, SyntaxNode, SyntaxToken, TextSize,
20};
17 21
18use crate::{ 22use crate::{
19 code_model::Access, 23 code_model::Access,
@@ -21,8 +25,9 @@ use crate::{
21 diagnostics::Diagnostic, 25 diagnostics::Diagnostic,
22 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, 26 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
23 source_analyzer::{resolve_hir_path, SourceAnalyzer}, 27 source_analyzer::{resolve_hir_path, SourceAnalyzer},
24 AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, 28 AssocItem, Callable, Crate, Field, Function, HirFileId, ImplDef, InFile, LifetimeParam, Local,
25 Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, VariantDef, 29 MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam,
30 VariantDef,
26}; 31};
27 32
28#[derive(Debug, Clone, PartialEq, Eq)] 33#[derive(Debug, Clone, PartialEq, Eq)]
@@ -173,6 +178,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
173 self.imp.descend_node_at_offset(node, offset).find_map(N::cast) 178 self.imp.descend_node_at_offset(node, offset).find_map(N::cast)
174 } 179 }
175 180
181 // FIXME: Replace the SyntaxToken with a typed ast Node/Token
182 pub fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> {
183 self.imp.resolve_lifetime_param(lifetime_token)
184 }
185
176 pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { 186 pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
177 self.imp.type_of_expr(expr) 187 self.imp.type_of_expr(expr)
178 } 188 }
@@ -392,16 +402,44 @@ impl<'db> SemanticsImpl<'db> {
392 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len()) 402 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len())
393 } 403 }
394 404
405 // FIXME: Replace the SyntaxToken with a typed ast Node/Token
406 fn resolve_lifetime_param(&self, lifetime_token: &SyntaxToken) -> Option<LifetimeParam> {
407 if lifetime_token.kind() != syntax::SyntaxKind::LIFETIME {
408 return None;
409 }
410 let lifetime_text = lifetime_token.text();
411 let lifetime_param = lifetime_token.parent().ancestors().find_map(|syn| {
412 let gpl = match_ast! {
413 match syn {
414 ast::Fn(it) => it.generic_param_list()?,
415 ast::TypeAlias(it) => it.generic_param_list()?,
416 ast::Struct(it) => it.generic_param_list()?,
417 ast::Enum(it) => it.generic_param_list()?,
418 ast::Union(it) => it.generic_param_list()?,
419 ast::Trait(it) => it.generic_param_list()?,
420 ast::Impl(it) => it.generic_param_list()?,
421 ast::WherePred(it) => it.generic_param_list()?,
422 ast::ForType(it) => it.generic_param_list()?,
423 _ => return None,
424 }
425 };
426 gpl.lifetime_params()
427 .find(|tp| tp.lifetime_token().as_ref().map(|lt| lt.text()) == Some(lifetime_text))
428 })?;
429 let src = self.find_file(lifetime_param.syntax().clone()).with_value(lifetime_param);
430 ToDef::to_def(self, src)
431 }
432
395 fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> { 433 fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
396 self.analyze(expr.syntax()).type_of_expr(self.db, &expr) 434 self.analyze(expr.syntax()).type_of_expr(self.db, expr)
397 } 435 }
398 436
399 fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> { 437 fn type_of_pat(&self, pat: &ast::Pat) -> Option<Type> {
400 self.analyze(pat.syntax()).type_of_pat(self.db, &pat) 438 self.analyze(pat.syntax()).type_of_pat(self.db, pat)
401 } 439 }
402 440
403 fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> { 441 fn type_of_self(&self, param: &ast::SelfParam) -> Option<Type> {
404 self.analyze(param.syntax()).type_of_self(self.db, &param) 442 self.analyze(param.syntax()).type_of_self(self.db, param)
405 } 443 }
406 444
407 fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> { 445 fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> {
@@ -684,6 +722,7 @@ to_def_impls![
684 (crate::Field, ast::TupleField, tuple_field_to_def), 722 (crate::Field, ast::TupleField, tuple_field_to_def),
685 (crate::EnumVariant, ast::Variant, enum_variant_to_def), 723 (crate::EnumVariant, ast::Variant, enum_variant_to_def),
686 (crate::TypeParam, ast::TypeParam, type_param_to_def), 724 (crate::TypeParam, ast::TypeParam, type_param_to_def),
725 (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def),
687 (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros 726 (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros
688 (crate::Local, ast::IdentPat, bind_pat_to_def), 727 (crate::Local, ast::IdentPat, bind_pat_to_def),
689]; 728];
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index 66fc11611..badcf0ae8 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -7,7 +7,8 @@ use hir_def::{
7 expr::PatId, 7 expr::PatId,
8 keys::{self, Key}, 8 keys::{self, Key},
9 ConstId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId, GenericDefId, ImplId, 9 ConstId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId, GenericDefId, ImplId,
10 ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, VariantId, 10 LifetimeParamId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
11 VariantId,
11}; 12};
12use hir_expand::{name::AsName, AstId, MacroDefKind}; 13use hir_expand::{name::AsName, AstId, MacroDefKind};
13use rustc_hash::FxHashMap; 14use rustc_hash::FxHashMap;
@@ -128,13 +129,25 @@ impl SourceToDefCtx<'_, '_> {
128 129
129 pub(super) fn type_param_to_def(&mut self, src: InFile<ast::TypeParam>) -> Option<TypeParamId> { 130 pub(super) fn type_param_to_def(&mut self, src: InFile<ast::TypeParam>) -> Option<TypeParamId> {
130 let container: ChildContainer = 131 let container: ChildContainer =
131 self.find_type_param_container(src.as_ref().map(|it| it.syntax()))?.into(); 132 self.find_generic_param_container(src.as_ref().map(|it| it.syntax()))?.into();
132 let db = self.db; 133 let db = self.db;
133 let dyn_map = 134 let dyn_map =
134 &*self.cache.entry(container).or_insert_with(|| container.child_by_source(db)); 135 &*self.cache.entry(container).or_insert_with(|| container.child_by_source(db));
135 dyn_map[keys::TYPE_PARAM].get(&src).copied() 136 dyn_map[keys::TYPE_PARAM].get(&src).copied()
136 } 137 }
137 138
139 pub(super) fn lifetime_param_to_def(
140 &mut self,
141 src: InFile<ast::LifetimeParam>,
142 ) -> Option<LifetimeParamId> {
143 let container: ChildContainer =
144 self.find_generic_param_container(src.as_ref().map(|it| it.syntax()))?.into();
145 let db = self.db;
146 let dyn_map =
147 &*self.cache.entry(container).or_insert_with(|| container.child_by_source(db));
148 dyn_map[keys::LIFETIME_PARAM].get(&src).copied()
149 }
150
138 // FIXME: use DynMap as well? 151 // FIXME: use DynMap as well?
139 pub(super) fn macro_call_to_def(&mut self, src: InFile<ast::MacroCall>) -> Option<MacroDefId> { 152 pub(super) fn macro_call_to_def(&mut self, src: InFile<ast::MacroCall>) -> Option<MacroDefId> {
140 let kind = MacroDefKind::Declarative; 153 let kind = MacroDefKind::Declarative;
@@ -203,7 +216,7 @@ impl SourceToDefCtx<'_, '_> {
203 Some(def.into()) 216 Some(def.into())
204 } 217 }
205 218
206 fn find_type_param_container(&mut self, src: InFile<&SyntaxNode>) -> Option<GenericDefId> { 219 fn find_generic_param_container(&mut self, src: InFile<&SyntaxNode>) -> Option<GenericDefId> {
207 for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) { 220 for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) {
208 let res: GenericDefId = match_ast! { 221 let res: GenericDefId = match_ast! {
209 match (container.value) { 222 match (container.value) {
@@ -247,7 +260,7 @@ pub(crate) enum ChildContainer {
247 VariantId(VariantId), 260 VariantId(VariantId),
248 TypeAliasId(TypeAliasId), 261 TypeAliasId(TypeAliasId),
249 /// XXX: this might be the same def as, for example an `EnumId`. However, 262 /// XXX: this might be the same def as, for example an `EnumId`. However,
250 /// here the children generic parameters, and not, eg enum variants. 263 /// here the children are generic parameters, and not, eg enum variants.
251 GenericDefId(GenericDefId), 264 GenericDefId(GenericDefId),
252} 265}
253impl_from! { 266impl_from! {
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs
index 5189c7e9f..81912a454 100644
--- a/crates/hir_def/src/generics.rs
+++ b/crates/hir_def/src/generics.rs
@@ -19,10 +19,10 @@ use crate::{
19 db::DefDatabase, 19 db::DefDatabase,
20 dyn_map::DynMap, 20 dyn_map::DynMap,
21 keys, 21 keys,
22 src::HasChildSource,
23 src::HasSource, 22 src::HasSource,
24 type_ref::{LifetimeRef, TypeBound, TypeRef}, 23 type_ref::{LifetimeRef, TypeBound, TypeRef},
25 AdtId, GenericDefId, LocalTypeParamId, Lookup, TypeParamId, 24 AdtId, GenericDefId, LifetimeParamId, LocalLifetimeParamId, LocalTypeParamId, Lookup,
25 TypeParamId,
26}; 26};
27 27
28/// Data about a generic parameter (to a function, struct, impl, ...). 28/// Data about a generic parameter (to a function, struct, impl, ...).
@@ -72,7 +72,11 @@ pub enum WherePredicateTypeTarget {
72 // FIXME: ForLifetime(Vec<LifetimeParamId>, TypeRef) 72 // FIXME: ForLifetime(Vec<LifetimeParamId>, TypeRef)
73} 73}
74 74
75type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>; 75#[derive(Default)]
76pub struct SourceMaps {
77 pub type_params: ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>,
78 pub lifetime_params: ArenaMap<LocalLifetimeParamId, ast::LifetimeParam>,
79}
76 80
77impl GenericParams { 81impl GenericParams {
78 pub(crate) fn generic_params_query( 82 pub(crate) fn generic_params_query(
@@ -129,9 +133,9 @@ impl GenericParams {
129 Arc::new(generics) 133 Arc::new(generics)
130 } 134 }
131 135
132 fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) { 136 fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMaps>) {
133 let mut generics = GenericParams::default(); 137 let mut generics = GenericParams::default();
134 let mut sm = ArenaMap::default(); 138 let mut sm = SourceMaps::default();
135 139
136 // FIXME: add `: Sized` bound for everything except for `Self` in traits 140 // FIXME: add `: Sized` bound for everything except for `Self` in traits
137 let file_id = match def { 141 let file_id = match def {
@@ -174,7 +178,7 @@ impl GenericParams {
174 default: None, 178 default: None,
175 provenance: TypeParamProvenance::TraitSelf, 179 provenance: TypeParamProvenance::TraitSelf,
176 }); 180 });
177 sm.insert(self_param_id, Either::Left(src.value.clone())); 181 sm.type_params.insert(self_param_id, Either::Left(src.value.clone()));
178 // add super traits as bounds on Self 182 // add super traits as bounds on Self
179 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar 183 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
180 let self_param = TypeRef::Path(name![Self].into()); 184 let self_param = TypeRef::Path(name![Self].into());
@@ -210,7 +214,7 @@ impl GenericParams {
210 pub(crate) fn fill( 214 pub(crate) fn fill(
211 &mut self, 215 &mut self,
212 lower_ctx: &LowerCtx, 216 lower_ctx: &LowerCtx,
213 sm: &mut SourceMap, 217 sm: &mut SourceMaps,
214 node: &dyn GenericParamsOwner, 218 node: &dyn GenericParamsOwner,
215 ) { 219 ) {
216 if let Some(params) = node.generic_param_list() { 220 if let Some(params) = node.generic_param_list() {
@@ -237,7 +241,7 @@ impl GenericParams {
237 fn fill_params( 241 fn fill_params(
238 &mut self, 242 &mut self,
239 lower_ctx: &LowerCtx, 243 lower_ctx: &LowerCtx,
240 sm: &mut SourceMap, 244 sm: &mut SourceMaps,
241 params: ast::GenericParamList, 245 params: ast::GenericParamList,
242 ) { 246 ) {
243 for type_param in params.type_params() { 247 for type_param in params.type_params() {
@@ -250,7 +254,7 @@ impl GenericParams {
250 provenance: TypeParamProvenance::TypeParamList, 254 provenance: TypeParamProvenance::TypeParamList,
251 }; 255 };
252 let param_id = self.types.alloc(param); 256 let param_id = self.types.alloc(param);
253 sm.insert(param_id, Either::Right(type_param.clone())); 257 sm.type_params.insert(param_id, Either::Right(type_param.clone()));
254 258
255 let type_ref = TypeRef::Path(name.into()); 259 let type_ref = TypeRef::Path(name.into());
256 self.fill_bounds(&lower_ctx, &type_param, Either::Left(type_ref)); 260 self.fill_bounds(&lower_ctx, &type_param, Either::Left(type_ref));
@@ -260,7 +264,8 @@ impl GenericParams {
260 .lifetime_token() 264 .lifetime_token()
261 .map_or_else(Name::missing, |tok| Name::new_lifetime(&tok)); 265 .map_or_else(Name::missing, |tok| Name::new_lifetime(&tok));
262 let param = LifetimeParamData { name: name.clone() }; 266 let param = LifetimeParamData { name: name.clone() };
263 let _param_id = self.lifetimes.alloc(param); 267 let param_id = self.lifetimes.alloc(param);
268 sm.lifetime_params.insert(param_id, lifetime_param.clone());
264 let lifetime_ref = LifetimeRef::new_name(name); 269 let lifetime_ref = LifetimeRef::new_name(name);
265 self.fill_bounds(&lower_ctx, &lifetime_param, Either::Right(lifetime_ref)); 270 self.fill_bounds(&lower_ctx, &lifetime_param, Either::Right(lifetime_ref));
266 } 271 }
@@ -340,27 +345,29 @@ impl GenericParams {
340 }) 345 })
341 } 346 }
342} 347}
343 348impl GenericDefId {
344impl HasChildSource for GenericDefId { 349 // FIXME: Change HasChildSource's ChildId AssocItem to be a generic parameter instead
345 type ChildId = LocalTypeParamId; 350 pub fn child_source(&self, db: &dyn DefDatabase) -> InFile<SourceMaps> {
346 type Value = Either<ast::Trait, ast::TypeParam>; 351 GenericParams::new(db, *self).1
347 fn child_source(&self, db: &dyn DefDatabase) -> InFile<SourceMap> {
348 let (_, sm) = GenericParams::new(db, *self);
349 sm
350 } 352 }
351} 353}
352 354
353impl ChildBySource for GenericDefId { 355impl ChildBySource for GenericDefId {
354 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap { 356 fn child_by_source(&self, db: &dyn DefDatabase) -> DynMap {
355 let mut res = DynMap::default(); 357 let mut res = DynMap::default();
356 let arena_map = self.child_source(db); 358 let (_, sm) = GenericParams::new(db, *self);
357 let arena_map = arena_map.as_ref(); 359
358 for (local_id, src) in arena_map.value.iter() { 360 let sm = sm.as_ref();
361 for (local_id, src) in sm.value.type_params.iter() {
359 let id = TypeParamId { parent: *self, local_id }; 362 let id = TypeParamId { parent: *self, local_id };
360 if let Either::Right(type_param) = src { 363 if let Either::Right(type_param) = src {
361 res[keys::TYPE_PARAM].insert(arena_map.with_value(type_param.clone()), id) 364 res[keys::TYPE_PARAM].insert(sm.with_value(type_param.clone()), id)
362 } 365 }
363 } 366 }
367 for (local_id, src) in sm.value.lifetime_params.iter() {
368 let id = LifetimeParamId { parent: *self, local_id };
369 res[keys::LIFETIME_PARAM].insert(sm.with_value(src.clone()), id);
370 }
364 res 371 res
365 } 372 }
366} 373}
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index f7ce2e26d..2939c6b1e 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -2,7 +2,6 @@
2 2
3use std::{collections::hash_map::Entry, mem, sync::Arc}; 3use std::{collections::hash_map::Entry, mem, sync::Arc};
4 4
5use arena::map::ArenaMap;
6use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, name::known, HirFileId}; 5use hir_expand::{ast_id_map::AstIdMap, hygiene::Hygiene, name::known, HirFileId};
7use smallvec::SmallVec; 6use smallvec::SmallVec;
8use syntax::{ 7use syntax::{
@@ -607,7 +606,7 @@ impl Ctx {
607 owner: GenericsOwner<'_>, 606 owner: GenericsOwner<'_>,
608 node: &impl ast::GenericParamsOwner, 607 node: &impl ast::GenericParamsOwner,
609 ) -> GenericParamsId { 608 ) -> GenericParamsId {
610 let mut sm = &mut ArenaMap::default(); 609 let mut sm = &mut Default::default();
611 let mut generics = GenericParams::default(); 610 let mut generics = GenericParams::default();
612 match owner { 611 match owner {
613 GenericsOwner::Function(func) => { 612 GenericsOwner::Function(func) => {
@@ -630,7 +629,7 @@ impl Ctx {
630 default: None, 629 default: None,
631 provenance: TypeParamProvenance::TraitSelf, 630 provenance: TypeParamProvenance::TraitSelf,
632 }); 631 });
633 sm.insert(self_param_id, Either::Left(trait_def.clone())); 632 sm.type_params.insert(self_param_id, Either::Left(trait_def.clone()));
634 // add super traits as bounds on Self 633 // add super traits as bounds on Self
635 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar 634 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
636 let self_param = TypeRef::Path(name![Self].into()); 635 let self_param = TypeRef::Path(name![Self].into());
diff --git a/crates/hir_def/src/keys.rs b/crates/hir_def/src/keys.rs
index 40a5d92b5..9c585de2c 100644
--- a/crates/hir_def/src/keys.rs
+++ b/crates/hir_def/src/keys.rs
@@ -8,8 +8,8 @@ use syntax::{ast, AstNode, AstPtr};
8 8
9use crate::{ 9use crate::{
10 dyn_map::{DynMap, Policy}, 10 dyn_map::{DynMap, Policy},
11 ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, StaticId, StructId, TraitId, 11 ConstId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId, StaticId,
12 TypeAliasId, TypeParamId, UnionId, 12 StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
13}; 13};
14 14
15pub type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>; 15pub type Key<K, V> = crate::dyn_map::Key<InFile<K>, V, AstPtrPolicy<K, V>>;
@@ -28,6 +28,7 @@ pub const VARIANT: Key<ast::Variant, EnumVariantId> = Key::new();
28pub const TUPLE_FIELD: Key<ast::TupleField, FieldId> = Key::new(); 28pub const TUPLE_FIELD: Key<ast::TupleField, FieldId> = Key::new();
29pub const RECORD_FIELD: Key<ast::RecordField, FieldId> = Key::new(); 29pub const RECORD_FIELD: Key<ast::RecordField, FieldId> = Key::new();
30pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new(); 30pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new();
31pub const LIFETIME_PARAM: Key<ast::LifetimeParam, LifetimeParamId> = Key::new();
31 32
32pub const MACRO: Key<ast::MacroCall, MacroDefId> = Key::new(); 33pub const MACRO: Key<ast::MacroCall, MacroDefId> = Key::new();
33 34
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index 477192a09..8db8c7d0c 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -88,6 +88,7 @@ register_builtin! {
88 (column, Column) => column_expand, 88 (column, Column) => column_expand,
89 (file, File) => file_expand, 89 (file, File) => file_expand,
90 (line, Line) => line_expand, 90 (line, Line) => line_expand,
91 (module_path, ModulePath) => module_path_expand,
91 (assert, Assert) => assert_expand, 92 (assert, Assert) => assert_expand,
92 (stringify, Stringify) => stringify_expand, 93 (stringify, Stringify) => stringify_expand,
93 (format_args, FormatArgs) => format_args_expand, 94 (format_args, FormatArgs) => format_args_expand,
@@ -105,6 +106,15 @@ register_builtin! {
105 (option_env, OptionEnv) => option_env_expand 106 (option_env, OptionEnv) => option_env_expand
106} 107}
107 108
109fn module_path_expand(
110 _db: &dyn AstDatabase,
111 _id: LazyMacroId,
112 _tt: &tt::Subtree,
113) -> ExpandResult<tt::Subtree> {
114 // Just return a dummy result.
115 ExpandResult::ok(quote! { "module::path" })
116}
117
108fn line_expand( 118fn line_expand(
109 _db: &dyn AstDatabase, 119 _db: &dyn AstDatabase,
110 _id: LazyMacroId, 120 _id: LazyMacroId,
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index 583ed6142..6ec5ca0a9 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -188,6 +188,7 @@ pub mod known {
188 column, 188 column,
189 compile_error, 189 compile_error,
190 line, 190 line,
191 module_path,
191 assert, 192 assert,
192 stringify, 193 stringify,
193 concat, 194 concat,
diff --git a/crates/proc_macro_srv/Cargo.toml b/crates/proc_macro_srv/Cargo.toml
index 729372968..1bfa6c3fc 100644
--- a/crates/proc_macro_srv/Cargo.toml
+++ b/crates/proc_macro_srv/Cargo.toml
@@ -10,7 +10,7 @@ edition = "2018"
10doctest = false 10doctest = false
11 11
12[dependencies] 12[dependencies]
13goblin = "0.2.1" 13object = { version = "0.23", default-features = false, features = ["std", "read_core", "elf", "macho", "pe", "unaligned"] }
14libloading = "0.6.0" 14libloading = "0.6.0"
15memmap = "0.7" 15memmap = "0.7"
16 16
diff --git a/crates/proc_macro_srv/src/dylib.rs b/crates/proc_macro_srv/src/dylib.rs
index f8f705da8..2afb973cc 100644
--- a/crates/proc_macro_srv/src/dylib.rs
+++ b/crates/proc_macro_srv/src/dylib.rs
@@ -1,14 +1,17 @@
1//! Handles dynamic library loading for proc macro 1//! Handles dynamic library loading for proc macro
2 2
3use crate::{proc_macro::bridge, rustc_server::TokenStream}; 3use std::{
4use std::fs::File; 4 fs::File,
5use std::path::{Path, PathBuf}; 5 io,
6 path::{Path, PathBuf},
7};
6 8
7use goblin::{mach::Mach, Object};
8use libloading::Library; 9use libloading::Library;
9use memmap::Mmap; 10use memmap::Mmap;
11use object::Object;
10use proc_macro_api::ProcMacroKind; 12use proc_macro_api::ProcMacroKind;
11use std::io; 13
14use crate::{proc_macro::bridge, rustc_server::TokenStream};
12 15
13const NEW_REGISTRAR_SYMBOL: &str = "_rustc_proc_macro_decls_"; 16const NEW_REGISTRAR_SYMBOL: &str = "_rustc_proc_macro_decls_";
14 17
@@ -23,40 +26,26 @@ fn is_derive_registrar_symbol(symbol: &str) -> bool {
23fn find_registrar_symbol(file: &Path) -> io::Result<Option<String>> { 26fn find_registrar_symbol(file: &Path) -> io::Result<Option<String>> {
24 let file = File::open(file)?; 27 let file = File::open(file)?;
25 let buffer = unsafe { Mmap::map(&file)? }; 28 let buffer = unsafe { Mmap::map(&file)? };
26 let object = Object::parse(&buffer).map_err(invalid_data_err)?;
27 29
28 let name = match object { 30 Ok(object::File::parse(&buffer)
29 Object::Elf(elf) => { 31 .map_err(invalid_data_err)?
30 let symbols = elf.dynstrtab.to_vec().map_err(invalid_data_err)?; 32 .exports()
31 symbols.into_iter().find(|s| is_derive_registrar_symbol(s)).map(&str::to_owned) 33 .map_err(invalid_data_err)?
32 } 34 .into_iter()
33 Object::PE(pe) => pe 35 .map(|export| export.name())
34 .exports 36 .filter_map(|sym| String::from_utf8(sym.into()).ok())
35 .iter() 37 .find(|sym| is_derive_registrar_symbol(sym))
36 .flat_map(|s| s.name) 38 .map(|sym| {
37 .find(|s| is_derive_registrar_symbol(s)) 39 // From MacOS docs:
38 .map(&str::to_owned), 40 // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html
39 Object::Mach(Mach::Binary(binary)) => { 41 // Unlike other dyld API's, the symbol name passed to dlsym() must NOT be
40 let exports = binary.exports().map_err(invalid_data_err)?; 42 // prepended with an underscore.
41 exports 43 if cfg!(target_os = "macos") && sym.starts_with('_') {
42 .iter() 44 sym[1..].to_owned()
43 .map(|s| { 45 } else {
44 // In macos doc: 46 sym
45 // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/dlsym.3.html 47 }
46 // Unlike other dyld API's, the symbol name passed to dlsym() must NOT be 48 }))
47 // prepended with an underscore.
48 if s.name.starts_with('_') {
49 &s.name[1..]
50 } else {
51 &s.name
52 }
53 })
54 .find(|s| is_derive_registrar_symbol(s))
55 .map(&str::to_owned)
56 }
57 _ => return Ok(None),
58 };
59 return Ok(name);
60} 49}
61 50
62/// Loads dynamic library in platform dependent manner. 51/// Loads dynamic library in platform dependent manner.