aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/attr.rs6
-rw-r--r--crates/ra_hir_def/src/body.rs2
-rw-r--r--crates/ra_hir_def/src/body/lower.rs4
-rw-r--r--crates/ra_hir_def/src/builtin_type.rs42
-rw-r--r--crates/ra_hir_def/src/data.rs4
-rw-r--r--crates/ra_hir_def/src/generics.rs6
-rw-r--r--crates/ra_hir_def/src/nameres.rs4
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs18
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs24
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs12
-rw-r--r--crates/ra_hir_def/src/path.rs429
-rw-r--r--crates/ra_hir_def/src/path/lower.rs176
-rw-r--r--crates/ra_hir_def/src/path/lower/lower_use.rs (renamed from crates/ra_hir_def/src/path/lower_use.rs)23
-rw-r--r--crates/ra_hir_def/src/resolver.rs62
14 files changed, 447 insertions, 365 deletions
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 5bf82e191..9efa4970c 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -12,7 +12,7 @@ use ra_syntax::{
12use tt::Subtree; 12use tt::Subtree;
13 13
14use crate::{ 14use crate::{
15 db::DefDatabase, path::Path, src::HasChildSource, src::HasSource, AdtId, AttrDefId, Lookup, 15 db::DefDatabase, path::ModPath, src::HasChildSource, src::HasSource, AdtId, AttrDefId, Lookup,
16}; 16};
17 17
18#[derive(Default, Debug, Clone, PartialEq, Eq)] 18#[derive(Default, Debug, Clone, PartialEq, Eq)]
@@ -94,7 +94,7 @@ impl Attrs {
94 94
95#[derive(Debug, Clone, PartialEq, Eq)] 95#[derive(Debug, Clone, PartialEq, Eq)]
96pub struct Attr { 96pub struct Attr {
97 pub(crate) path: Path, 97 pub(crate) path: ModPath,
98 pub(crate) input: Option<AttrInput>, 98 pub(crate) input: Option<AttrInput>,
99} 99}
100 100
@@ -106,7 +106,7 @@ pub enum AttrInput {
106 106
107impl Attr { 107impl Attr {
108 fn from_src(ast: ast::Attr, hygiene: &Hygiene) -> Option<Attr> { 108 fn from_src(ast: ast::Attr, hygiene: &Hygiene) -> Option<Attr> {
109 let path = Path::from_src(ast.path()?, hygiene)?; 109 let path = ModPath::from_src(ast.path()?, hygiene)?;
110 let input = match ast.input() { 110 let input = match ast.input() {
111 None => None, 111 None => None,
112 Some(ast::AttrInput::Literal(lit)) => { 112 Some(ast::AttrInput::Literal(lit)) => {
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index b3bc336cf..7787cb87f 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -83,7 +83,7 @@ impl Expander {
83 83
84 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> { 84 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> {
85 self.crate_def_map 85 self.crate_def_map
86 .resolve_path(db, self.module.local_id, path, BuiltinShadowMode::Other) 86 .resolve_path(db, self.module.local_id, path.mod_path(), BuiltinShadowMode::Other)
87 .0 87 .0
88 .take_macros() 88 .take_macros()
89 } 89 }
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index cc068ff94..61193b4d8 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -2,7 +2,7 @@
2//! representation. 2//! representation.
3 3
4use either::Either; 4use either::Either;
5use hir_expand::name::{self, AsName, Name}; 5use hir_expand::name::{name, AsName, Name};
6use ra_arena::Arena; 6use ra_arena::Arena;
7use ra_syntax::{ 7use ra_syntax::{
8 ast::{ 8 ast::{
@@ -68,7 +68,7 @@ where
68 let ptr = AstPtr::new(&self_param); 68 let ptr = AstPtr::new(&self_param);
69 let param_pat = self.alloc_pat( 69 let param_pat = self.alloc_pat(
70 Pat::Bind { 70 Pat::Bind {
71 name: name::SELF_PARAM, 71 name: name![self],
72 mode: BindingAnnotation::Unannotated, 72 mode: BindingAnnotation::Unannotated,
73 subpat: None, 73 subpat: None,
74 }, 74 },
diff --git a/crates/ra_hir_def/src/builtin_type.rs b/crates/ra_hir_def/src/builtin_type.rs
index 5e8157144..d14901a9b 100644
--- a/crates/ra_hir_def/src/builtin_type.rs
+++ b/crates/ra_hir_def/src/builtin_type.rs
@@ -5,7 +5,7 @@
5 5
6use std::fmt; 6use std::fmt;
7 7
8use hir_expand::name::{self, Name}; 8use hir_expand::name::{name, Name};
9 9
10#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 10#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
11pub enum Signedness { 11pub enum Signedness {
@@ -52,26 +52,26 @@ pub enum BuiltinType {
52impl BuiltinType { 52impl BuiltinType {
53 #[rustfmt::skip] 53 #[rustfmt::skip]
54 pub const ALL: &'static [(Name, BuiltinType)] = &[ 54 pub const ALL: &'static [(Name, BuiltinType)] = &[
55 (name::CHAR, BuiltinType::Char), 55 (name![char], BuiltinType::Char),
56 (name::BOOL, BuiltinType::Bool), 56 (name![bool], BuiltinType::Bool),
57 (name::STR, BuiltinType::Str ), 57 (name![str], BuiltinType::Str),
58 58
59 (name::ISIZE, BuiltinType::Int(BuiltinInt::ISIZE)), 59 (name![isize], BuiltinType::Int(BuiltinInt::ISIZE)),
60 (name::I8, BuiltinType::Int(BuiltinInt::I8)), 60 (name![i8], BuiltinType::Int(BuiltinInt::I8)),
61 (name::I16, BuiltinType::Int(BuiltinInt::I16)), 61 (name![i16], BuiltinType::Int(BuiltinInt::I16)),
62 (name::I32, BuiltinType::Int(BuiltinInt::I32)), 62 (name![i32], BuiltinType::Int(BuiltinInt::I32)),
63 (name::I64, BuiltinType::Int(BuiltinInt::I64)), 63 (name![i64], BuiltinType::Int(BuiltinInt::I64)),
64 (name::I128, BuiltinType::Int(BuiltinInt::I128)), 64 (name![i128], BuiltinType::Int(BuiltinInt::I128)),
65 65
66 (name::USIZE, BuiltinType::Int(BuiltinInt::USIZE)), 66 (name![usize], BuiltinType::Int(BuiltinInt::USIZE)),
67 (name::U8, BuiltinType::Int(BuiltinInt::U8)), 67 (name![u8], BuiltinType::Int(BuiltinInt::U8)),
68 (name::U16, BuiltinType::Int(BuiltinInt::U16)), 68 (name![u16], BuiltinType::Int(BuiltinInt::U16)),
69 (name::U32, BuiltinType::Int(BuiltinInt::U32)), 69 (name![u32], BuiltinType::Int(BuiltinInt::U32)),
70 (name::U64, BuiltinType::Int(BuiltinInt::U64)), 70 (name![u64], BuiltinType::Int(BuiltinInt::U64)),
71 (name::U128, BuiltinType::Int(BuiltinInt::U128)), 71 (name![u128], BuiltinType::Int(BuiltinInt::U128)),
72 72
73 (name::F32, BuiltinType::Float(BuiltinFloat::F32)), 73 (name![f32], BuiltinType::Float(BuiltinFloat::F32)),
74 (name::F64, BuiltinType::Float(BuiltinFloat::F64)), 74 (name![f64], BuiltinType::Float(BuiltinFloat::F64)),
75 ]; 75 ];
76} 76}
77 77
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index b2dac183e..4f4ef57cc 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -3,7 +3,7 @@
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_expand::{ 5use hir_expand::{
6 name::{self, AsName, Name}, 6 name::{name, AsName, Name},
7 AstId, 7 AstId,
8}; 8};
9use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; 9use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
@@ -37,7 +37,7 @@ impl FunctionData {
37 let self_type = if let Some(type_ref) = self_param.ascribed_type() { 37 let self_type = if let Some(type_ref) = self_param.ascribed_type() {
38 TypeRef::from_ast(type_ref) 38 TypeRef::from_ast(type_ref)
39 } else { 39 } else {
40 let self_type = TypeRef::Path(name::SELF_TYPE.into()); 40 let self_type = TypeRef::Path(name![Self].into());
41 match self_param.kind() { 41 match self_param.kind() {
42 ast::SelfParamKind::Owned => self_type, 42 ast::SelfParamKind::Owned => self_type,
43 ast::SelfParamKind::Ref => { 43 ast::SelfParamKind::Ref => {
diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs
index e502dd798..e9c28c730 100644
--- a/crates/ra_hir_def/src/generics.rs
+++ b/crates/ra_hir_def/src/generics.rs
@@ -6,7 +6,7 @@ use std::sync::Arc;
6 6
7use either::Either; 7use either::Either;
8use hir_expand::{ 8use hir_expand::{
9 name::{self, AsName, Name}, 9 name::{name, AsName, Name},
10 InFile, 10 InFile,
11}; 11};
12use ra_arena::{map::ArenaMap, Arena}; 12use ra_arena::{map::ArenaMap, Arena};
@@ -90,11 +90,11 @@ impl GenericParams {
90 90
91 // traits get the Self type as an implicit first type parameter 91 // traits get the Self type as an implicit first type parameter
92 let self_param_id = 92 let self_param_id =
93 generics.types.alloc(TypeParamData { name: name::SELF_TYPE, default: None }); 93 generics.types.alloc(TypeParamData { name: name![Self], default: None });
94 sm.insert(self_param_id, Either::Left(src.value.clone())); 94 sm.insert(self_param_id, Either::Left(src.value.clone()));
95 // add super traits as bounds on Self 95 // add super traits as bounds on Self
96 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar 96 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
97 let self_param = TypeRef::Path(name::SELF_TYPE.into()); 97 let self_param = TypeRef::Path(name![Self].into());
98 generics.fill_bounds(&src.value, self_param); 98 generics.fill_bounds(&src.value, self_param);
99 99
100 generics.fill(&mut sm, &src.value); 100 generics.fill(&mut sm, &src.value);
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index bd237a7b3..9aae7e48e 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -74,7 +74,7 @@ use crate::{
74 builtin_type::BuiltinType, 74 builtin_type::BuiltinType,
75 db::DefDatabase, 75 db::DefDatabase,
76 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, 76 nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
77 path::Path, 77 path::ModPath,
78 per_ns::PerNs, 78 per_ns::PerNs,
79 AstId, FunctionId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId, 79 AstId, FunctionId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId,
80}; 80};
@@ -329,7 +329,7 @@ impl CrateDefMap {
329 &self, 329 &self,
330 db: &impl DefDatabase, 330 db: &impl DefDatabase,
331 original_module: LocalModuleId, 331 original_module: LocalModuleId,
332 path: &Path, 332 path: &ModPath,
333 shadow: BuiltinShadowMode, 333 shadow: BuiltinShadowMode,
334 ) -> (PerNs, Option<usize>) { 334 ) -> (PerNs, Option<usize>) {
335 let res = 335 let res =
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 04aadead1..912a073ea 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -6,7 +6,7 @@
6use hir_expand::{ 6use hir_expand::{
7 builtin_derive::find_builtin_derive, 7 builtin_derive::find_builtin_derive,
8 builtin_macro::find_builtin_macro, 8 builtin_macro::find_builtin_macro,
9 name::{self, AsName, Name}, 9 name::{name, AsName, Name},
10 HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, 10 HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
11}; 11};
12use ra_cfg::CfgOptions; 12use ra_cfg::CfgOptions;
@@ -22,7 +22,7 @@ use crate::{
22 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 22 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
23 raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, Resolution, ResolveMode, 23 raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, Resolution, ResolveMode,
24 }, 24 },
25 path::{Path, PathKind}, 25 path::{ModPath, PathKind},
26 per_ns::PerNs, 26 per_ns::PerNs,
27 AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, 27 AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern,
28 LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, 28 LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc,
@@ -101,7 +101,7 @@ struct ImportDirective {
101struct MacroDirective { 101struct MacroDirective {
102 module_id: LocalModuleId, 102 module_id: LocalModuleId,
103 ast_id: AstId<ast::MacroCall>, 103 ast_id: AstId<ast::MacroCall>,
104 path: Path, 104 path: ModPath,
105 legacy: Option<MacroCallId>, 105 legacy: Option<MacroCallId>,
106} 106}
107 107
@@ -113,7 +113,7 @@ struct DefCollector<'a, DB> {
113 unresolved_imports: Vec<ImportDirective>, 113 unresolved_imports: Vec<ImportDirective>,
114 resolved_imports: Vec<ImportDirective>, 114 resolved_imports: Vec<ImportDirective>,
115 unexpanded_macros: Vec<MacroDirective>, 115 unexpanded_macros: Vec<MacroDirective>,
116 unexpanded_attribute_macros: Vec<(LocalModuleId, AstId<ast::ModuleItem>, Path)>, 116 unexpanded_attribute_macros: Vec<(LocalModuleId, AstId<ast::ModuleItem>, ModPath)>,
117 mod_dirs: FxHashMap<LocalModuleId, ModDir>, 117 mod_dirs: FxHashMap<LocalModuleId, ModDir>,
118 cfg_options: &'a CfgOptions, 118 cfg_options: &'a CfgOptions,
119} 119}
@@ -428,7 +428,7 @@ where
428 } else { 428 } else {
429 match import.path.segments.last() { 429 match import.path.segments.last() {
430 Some(last_segment) => { 430 Some(last_segment) => {
431 let name = import.alias.clone().unwrap_or_else(|| last_segment.name.clone()); 431 let name = import.alias.clone().unwrap_or_else(|| last_segment.clone());
432 log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); 432 log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
433 433
434 // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 434 // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
@@ -565,7 +565,7 @@ where
565 res 565 res
566 } 566 }
567 567
568 fn resolve_attribute_macro(&self, path: &Path) -> Option<MacroDefId> { 568 fn resolve_attribute_macro(&self, path: &ModPath) -> Option<MacroDefId> {
569 // FIXME this is currently super hacky, just enough to support the 569 // FIXME this is currently super hacky, just enough to support the
570 // built-in derives 570 // built-in derives
571 if let Some(name) = path.as_ident() { 571 if let Some(name) = path.as_ident() {
@@ -829,7 +829,7 @@ where
829 tt::TokenTree::Leaf(tt::Leaf::Punct(_)) => continue, // , is ok 829 tt::TokenTree::Leaf(tt::Leaf::Punct(_)) => continue, // , is ok
830 _ => continue, // anything else would be an error (which we currently ignore) 830 _ => continue, // anything else would be an error (which we currently ignore)
831 }; 831 };
832 let path = Path::from_tt_ident(ident); 832 let path = ModPath::from_tt_ident(ident);
833 833
834 let ast_id = AstId::new(self.file_id, def.kind.ast_id()); 834 let ast_id = AstId::new(self.file_id, def.kind.ast_id());
835 self.def_collector.unexpanded_attribute_macros.push((self.module_id, ast_id, path)); 835 self.def_collector.unexpanded_attribute_macros.push((self.module_id, ast_id, path));
@@ -917,8 +917,8 @@ where
917 } 917 }
918} 918}
919 919
920fn is_macro_rules(path: &Path) -> bool { 920fn is_macro_rules(path: &ModPath) -> bool {
921 path.as_ident() == Some(&name::MACRO_RULES) 921 path.as_ident() == Some(&name![macro_rules])
922} 922}
923 923
924#[cfg(test)] 924#[cfg(test)]
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs
index aab4b1dd9..4a249e7e7 100644
--- a/crates/ra_hir_def/src/nameres/path_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/path_resolution.rs
@@ -17,7 +17,7 @@ use test_utils::tested_by;
17use crate::{ 17use crate::{
18 db::DefDatabase, 18 db::DefDatabase,
19 nameres::{BuiltinShadowMode, CrateDefMap}, 19 nameres::{BuiltinShadowMode, CrateDefMap},
20 path::{Path, PathKind}, 20 path::{ModPath, PathKind},
21 per_ns::PerNs, 21 per_ns::PerNs,
22 AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, 22 AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
23}; 23};
@@ -69,7 +69,7 @@ impl CrateDefMap {
69 db: &impl DefDatabase, 69 db: &impl DefDatabase,
70 mode: ResolveMode, 70 mode: ResolveMode,
71 original_module: LocalModuleId, 71 original_module: LocalModuleId,
72 path: &Path, 72 path: &ModPath,
73 shadow: BuiltinShadowMode, 73 shadow: BuiltinShadowMode,
74 ) -> ResolvePathResult { 74 ) -> ResolvePathResult {
75 // if it is not the last segment, we prefer the module to the builtin 75 // if it is not the last segment, we prefer the module to the builtin
@@ -113,7 +113,7 @@ impl CrateDefMap {
113 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), 113 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
114 }; 114 };
115 log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); 115 log::debug!("resolving {:?} in crate root (+ extern prelude)", segment);
116 self.resolve_name_in_crate_root_or_extern_prelude(&segment.name, prefer_module(idx)) 116 self.resolve_name_in_crate_root_or_extern_prelude(&segment, prefer_module(idx))
117 } 117 }
118 PathKind::Plain => { 118 PathKind::Plain => {
119 let (idx, segment) = match segments.next() { 119 let (idx, segment) = match segments.next() {
@@ -121,7 +121,7 @@ impl CrateDefMap {
121 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), 121 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
122 }; 122 };
123 log::debug!("resolving {:?} in module", segment); 123 log::debug!("resolving {:?} in module", segment);
124 self.resolve_name_in_module(db, original_module, &segment.name, prefer_module(idx)) 124 self.resolve_name_in_module(db, original_module, &segment, prefer_module(idx))
125 } 125 }
126 PathKind::Super => { 126 PathKind::Super => {
127 if let Some(p) = self.modules[original_module].parent { 127 if let Some(p) = self.modules[original_module].parent {
@@ -137,7 +137,7 @@ impl CrateDefMap {
137 Some((_, segment)) => segment, 137 Some((_, segment)) => segment,
138 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), 138 None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
139 }; 139 };
140 if let Some(def) = self.extern_prelude.get(&segment.name) { 140 if let Some(def) = self.extern_prelude.get(&segment) {
141 log::debug!("absolute path {:?} resolved to crate {:?}", path, def); 141 log::debug!("absolute path {:?} resolved to crate {:?}", path, def);
142 PerNs::types(*def) 142 PerNs::types(*def)
143 } else { 143 } else {
@@ -168,8 +168,10 @@ impl CrateDefMap {
168 curr_per_ns = match curr { 168 curr_per_ns = match curr {
169 ModuleDefId::ModuleId(module) => { 169 ModuleDefId::ModuleId(module) => {
170 if module.krate != self.krate { 170 if module.krate != self.krate {
171 let path = 171 let path = ModPath {
172 Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; 172 segments: path.segments[i..].to_vec(),
173 kind: PathKind::Self_,
174 };
173 log::debug!("resolving {:?} in other crate", path); 175 log::debug!("resolving {:?} in other crate", path);
174 let defp_map = db.crate_def_map(module.krate); 176 let defp_map = db.crate_def_map(module.krate);
175 let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow); 177 let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow);
@@ -182,10 +184,10 @@ impl CrateDefMap {
182 } 184 }
183 185
184 // Since it is a qualified path here, it should not contains legacy macros 186 // Since it is a qualified path here, it should not contains legacy macros
185 match self[module.local_id].scope.get(&segment.name, prefer_module(i)) { 187 match self[module.local_id].scope.get(&segment, prefer_module(i)) {
186 Some(res) => res.def, 188 Some(res) => res.def,
187 _ => { 189 _ => {
188 log::debug!("path segment {:?} not found", segment.name); 190 log::debug!("path segment {:?} not found", segment);
189 return ResolvePathResult::empty(ReachedFixedPoint::No); 191 return ResolvePathResult::empty(ReachedFixedPoint::No);
190 } 192 }
191 } 193 }
@@ -194,7 +196,7 @@ impl CrateDefMap {
194 // enum variant 196 // enum variant
195 tested_by!(can_import_enum_variant); 197 tested_by!(can_import_enum_variant);
196 let enum_data = db.enum_data(e); 198 let enum_data = db.enum_data(e);
197 match enum_data.variant(&segment.name) { 199 match enum_data.variant(&segment) {
198 Some(local_id) => { 200 Some(local_id) => {
199 let variant = EnumVariantId { parent: e, local_id }; 201 let variant = EnumVariantId { parent: e, local_id };
200 PerNs::both(variant.into(), variant.into()) 202 PerNs::both(variant.into(), variant.into())
@@ -214,7 +216,7 @@ impl CrateDefMap {
214 // (`Struct::method`), or some other kind of associated item 216 // (`Struct::method`), or some other kind of associated item
215 log::debug!( 217 log::debug!(
216 "path segment {:?} resolved to non-module {:?}, but is not last", 218 "path segment {:?} resolved to non-module {:?}, but is not last",
217 segment.name, 219 segment,
218 curr, 220 curr,
219 ); 221 );
220 222
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index a2821e1c3..ecb4d7c03 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -22,7 +22,7 @@ use ra_syntax::{
22use test_utils::tested_by; 22use test_utils::tested_by;
23 23
24use crate::{ 24use crate::{
25 attr::Attrs, db::DefDatabase, path::Path, trace::Trace, FileAstId, HirFileId, InFile, 25 attr::Attrs, db::DefDatabase, path::ModPath, trace::Trace, FileAstId, HirFileId, InFile,
26 LocalImportId, 26 LocalImportId,
27}; 27};
28 28
@@ -154,7 +154,7 @@ pub(super) enum ModuleData {
154 154
155#[derive(Debug, Clone, PartialEq, Eq)] 155#[derive(Debug, Clone, PartialEq, Eq)]
156pub struct ImportData { 156pub struct ImportData {
157 pub(super) path: Path, 157 pub(super) path: ModPath,
158 pub(super) alias: Option<Name>, 158 pub(super) alias: Option<Name>,
159 pub(super) is_glob: bool, 159 pub(super) is_glob: bool,
160 pub(super) is_prelude: bool, 160 pub(super) is_prelude: bool,
@@ -206,7 +206,7 @@ impl_arena_id!(Macro);
206#[derive(Debug, PartialEq, Eq)] 206#[derive(Debug, PartialEq, Eq)]
207pub(super) struct MacroData { 207pub(super) struct MacroData {
208 pub(super) ast_id: FileAstId<ast::MacroCall>, 208 pub(super) ast_id: FileAstId<ast::MacroCall>,
209 pub(super) path: Path, 209 pub(super) path: ModPath,
210 pub(super) name: Option<Name>, 210 pub(super) name: Option<Name>,
211 pub(super) export: bool, 211 pub(super) export: bool,
212 pub(super) builtin: bool, 212 pub(super) builtin: bool,
@@ -327,7 +327,7 @@ impl RawItemsCollector {
327 let attrs = self.parse_attrs(&use_item); 327 let attrs = self.parse_attrs(&use_item);
328 328
329 let mut buf = Vec::new(); 329 let mut buf = Vec::new();
330 Path::expand_use_item( 330 ModPath::expand_use_item(
331 InFile { value: use_item, file_id: self.file_id }, 331 InFile { value: use_item, file_id: self.file_id },
332 &self.hygiene, 332 &self.hygiene,
333 |path, use_tree, is_glob, alias| { 333 |path, use_tree, is_glob, alias| {
@@ -353,7 +353,7 @@ impl RawItemsCollector {
353 extern_crate: ast::ExternCrateItem, 353 extern_crate: ast::ExternCrateItem,
354 ) { 354 ) {
355 if let Some(name_ref) = extern_crate.name_ref() { 355 if let Some(name_ref) = extern_crate.name_ref() {
356 let path = Path::from_name_ref(&name_ref); 356 let path = ModPath::from_name_ref(&name_ref);
357 let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name()); 357 let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name());
358 let attrs = self.parse_attrs(&extern_crate); 358 let attrs = self.parse_attrs(&extern_crate);
359 // FIXME: cfg_attr 359 // FIXME: cfg_attr
@@ -377,7 +377,7 @@ impl RawItemsCollector {
377 377
378 fn add_macro(&mut self, current_module: Option<Module>, m: ast::MacroCall) { 378 fn add_macro(&mut self, current_module: Option<Module>, m: ast::MacroCall) {
379 let attrs = self.parse_attrs(&m); 379 let attrs = self.parse_attrs(&m);
380 let path = match m.path().and_then(|path| Path::from_src(path, &self.hygiene)) { 380 let path = match m.path().and_then(|path| ModPath::from_src(path, &self.hygiene)) {
381 Some(it) => it, 381 Some(it) => it,
382 _ => return, 382 _ => return,
383 }; 383 };
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 50f0cad94..20d6d98ea 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -1,31 +1,78 @@
1//! A desugared representation of paths like `crate::foo` or `<Type as Trait>::bar`. 1//! A desugared representation of paths like `crate::foo` or `<Type as Trait>::bar`.
2mod lower_use; 2mod lower;
3 3
4use std::{iter, sync::Arc}; 4use std::{iter, sync::Arc};
5 5
6use either::Either;
7use hir_expand::{ 6use hir_expand::{
8 hygiene::Hygiene, 7 hygiene::Hygiene,
9 name::{self, AsName, Name}, 8 name::{AsName, Name},
10}; 9};
11use ra_db::CrateId; 10use ra_db::CrateId;
12use ra_syntax::{ 11use ra_syntax::ast;
13 ast::{self, TypeAscriptionOwner},
14 AstNode,
15};
16 12
17use crate::{type_ref::TypeRef, InFile}; 13use crate::{type_ref::TypeRef, InFile};
18 14
19#[derive(Debug, Clone, PartialEq, Eq, Hash)] 15#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20pub struct Path { 16pub struct ModPath {
21 pub kind: PathKind, 17 pub kind: PathKind,
22 pub segments: Vec<PathSegment>, 18 pub segments: Vec<Name>,
19}
20
21impl ModPath {
22 pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> {
23 lower::lower_path(path, hygiene).map(|it| it.mod_path)
24 }
25
26 pub fn from_simple_segments(
27 kind: PathKind,
28 segments: impl IntoIterator<Item = Name>,
29 ) -> ModPath {
30 let segments = segments.into_iter().collect::<Vec<_>>();
31 ModPath { kind, segments }
32 }
33
34 pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> ModPath {
35 name_ref.as_name().into()
36 }
37
38 /// Converts an `tt::Ident` into a single-identifier `Path`.
39 pub(crate) fn from_tt_ident(ident: &tt::Ident) -> ModPath {
40 ident.as_name().into()
41 }
42
43 /// Calls `cb` with all paths, represented by this use item.
44 pub(crate) fn expand_use_item(
45 item_src: InFile<ast::UseItem>,
46 hygiene: &Hygiene,
47 mut cb: impl FnMut(ModPath, &ast::UseTree, /* is_glob */ bool, Option<Name>),
48 ) {
49 if let Some(tree) = item_src.value.use_tree() {
50 lower::lower_use_tree(None, tree, hygiene, &mut cb);
51 }
52 }
53
54 pub fn is_ident(&self) -> bool {
55 self.kind == PathKind::Plain && self.segments.len() == 1
56 }
57
58 pub fn is_self(&self) -> bool {
59 self.kind == PathKind::Self_ && self.segments.is_empty()
60 }
61
62 /// If this path is a single identifier, like `foo`, return its name.
63 pub fn as_ident(&self) -> Option<&Name> {
64 if self.kind != PathKind::Plain || self.segments.len() > 1 {
65 return None;
66 }
67 self.segments.first()
68 }
23} 69}
24 70
25#[derive(Debug, Clone, PartialEq, Eq, Hash)] 71#[derive(Debug, Clone, PartialEq, Eq, Hash)]
26pub struct PathSegment { 72pub struct Path {
27 pub name: Name, 73 mod_path: ModPath,
28 pub args_and_bindings: Option<Arc<GenericArgs>>, 74 /// Invariant: the same len as self.path.segments
75 generic_args: Vec<Option<Arc<GenericArgs>>>,
29} 76}
30 77
31/// Generic arguments to a path segment (e.g. the `i32` in `Option<i32>`). This 78/// Generic arguments to a path segment (e.g. the `i32` in `Option<i32>`). This
@@ -65,300 +112,162 @@ pub enum PathKind {
65} 112}
66 113
67impl Path { 114impl Path {
68 /// Calls `cb` with all paths, represented by this use item.
69 pub(crate) fn expand_use_item(
70 item_src: InFile<ast::UseItem>,
71 hygiene: &Hygiene,
72 mut cb: impl FnMut(Path, &ast::UseTree, bool, Option<Name>),
73 ) {
74 if let Some(tree) = item_src.value.use_tree() {
75 lower_use::lower_use_tree(None, tree, hygiene, &mut cb);
76 }
77 }
78
79 pub(crate) fn from_simple_segments(
80 kind: PathKind,
81 segments: impl IntoIterator<Item = Name>,
82 ) -> Path {
83 Path {
84 kind,
85 segments: segments
86 .into_iter()
87 .map(|name| PathSegment { name, args_and_bindings: None })
88 .collect(),
89 }
90 }
91
92 /// Converts an `ast::Path` to `Path`. Works with use trees. 115 /// Converts an `ast::Path` to `Path`. Works with use trees.
93 /// DEPRECATED: It does not handle `$crate` from macro call. 116 /// DEPRECATED: It does not handle `$crate` from macro call.
94 pub fn from_ast(path: ast::Path) -> Option<Path> { 117 pub fn from_ast(path: ast::Path) -> Option<Path> {
95 Path::from_src(path, &Hygiene::new_unhygienic()) 118 lower::lower_path(path, &Hygiene::new_unhygienic())
96 } 119 }
97 120
98 /// Converts an `ast::Path` to `Path`. Works with use trees. 121 /// Converts an `ast::Path` to `Path`. Works with use trees.
99 /// It correctly handles `$crate` based path from macro call. 122 /// It correctly handles `$crate` based path from macro call.
100 pub fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> { 123 pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option<Path> {
101 let mut kind = PathKind::Plain; 124 lower::lower_path(path, hygiene)
102 let mut segments = Vec::new();
103 loop {
104 let segment = path.segment()?;
105
106 if segment.has_colon_colon() {
107 kind = PathKind::Abs;
108 }
109
110 match segment.kind()? {
111 ast::PathSegmentKind::Name(name_ref) => {
112 // FIXME: this should just return name
113 match hygiene.name_ref_to_name(name_ref) {
114 Either::Left(name) => {
115 let args = segment
116 .type_arg_list()
117 .and_then(GenericArgs::from_ast)
118 .or_else(|| {
119 GenericArgs::from_fn_like_path_ast(
120 segment.param_list(),
121 segment.ret_type(),
122 )
123 })
124 .map(Arc::new);
125 let segment = PathSegment { name, args_and_bindings: args };
126 segments.push(segment);
127 }
128 Either::Right(crate_id) => {
129 kind = PathKind::DollarCrate(crate_id);
130 break;
131 }
132 }
133 }
134 ast::PathSegmentKind::Type { type_ref, trait_ref } => {
135 assert!(path.qualifier().is_none()); // this can only occur at the first segment
136
137 let self_type = TypeRef::from_ast(type_ref?);
138
139 match trait_ref {
140 // <T>::foo
141 None => {
142 kind = PathKind::Type(Box::new(self_type));
143 }
144 // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo
145 Some(trait_ref) => {
146 let path = Path::from_src(trait_ref.path()?, hygiene)?;
147 kind = path.kind;
148 let mut prefix_segments = path.segments;
149 prefix_segments.reverse();
150 segments.extend(prefix_segments);
151 // Insert the type reference (T in the above example) as Self parameter for the trait
152 let mut last_segment = segments.last_mut()?;
153 if last_segment.args_and_bindings.is_none() {
154 last_segment.args_and_bindings =
155 Some(Arc::new(GenericArgs::empty()));
156 };
157 let args = last_segment.args_and_bindings.as_mut().unwrap();
158 let mut args_inner = Arc::make_mut(args);
159 args_inner.has_self_type = true;
160 args_inner.args.insert(0, GenericArg::Type(self_type));
161 }
162 }
163 }
164 ast::PathSegmentKind::CrateKw => {
165 kind = PathKind::Crate;
166 break;
167 }
168 ast::PathSegmentKind::SelfKw => {
169 kind = PathKind::Self_;
170 break;
171 }
172 ast::PathSegmentKind::SuperKw => {
173 kind = PathKind::Super;
174 break;
175 }
176 }
177 path = match qualifier(&path) {
178 Some(it) => it,
179 None => break,
180 };
181 }
182 segments.reverse();
183 return Some(Path { kind, segments });
184
185 fn qualifier(path: &ast::Path) -> Option<ast::Path> {
186 if let Some(q) = path.qualifier() {
187 return Some(q);
188 }
189 // FIXME: this bottom up traversal is not too precise.
190 // Should we handle do a top-down analysis, recording results?
191 let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
192 let use_tree = use_tree_list.parent_use_tree();
193 use_tree.path()
194 }
195 } 125 }
196 126
197 /// Converts an `ast::NameRef` into a single-identifier `Path`. 127 /// Converts an `ast::NameRef` into a single-identifier `Path`.
198 pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path { 128 pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path {
199 name_ref.as_name().into() 129 Path { mod_path: name_ref.as_name().into(), generic_args: vec![None] }
200 }
201
202 /// Converts an `tt::Ident` into a single-identifier `Path`.
203 pub(crate) fn from_tt_ident(ident: &tt::Ident) -> Path {
204 ident.as_name().into()
205 }
206
207 /// `true` is this path is a single identifier, like `foo`
208 pub fn is_ident(&self) -> bool {
209 self.kind == PathKind::Plain && self.segments.len() == 1
210 } 130 }
211 131
212 /// `true` if this path is just a standalone `self` 132 /// `true` if this path is just a standalone `self`
213 pub fn is_self(&self) -> bool { 133 pub fn is_self(&self) -> bool {
214 self.kind == PathKind::Self_ && self.segments.is_empty() 134 self.mod_path.is_self()
215 } 135 }
216 136
217 /// If this path is a single identifier, like `foo`, return its name. 137 pub fn kind(&self) -> &PathKind {
218 pub fn as_ident(&self) -> Option<&Name> { 138 &self.mod_path.kind
219 if self.kind != PathKind::Plain || self.segments.len() > 1 {
220 return None;
221 }
222 self.segments.first().map(|s| &s.name)
223 } 139 }
224 140
225 pub fn expand_macro_expr(&self) -> Option<Name> { 141 pub fn segments(&self) -> PathSegments<'_> {
226 self.as_ident().and_then(|name| Some(name.clone())) 142 PathSegments {
227 } 143 segments: self.mod_path.segments.as_slice(),
228 144 generic_args: self.generic_args.as_slice(),
229 pub fn is_type_relative(&self) -> bool {
230 match self.kind {
231 PathKind::Type(_) => true,
232 _ => false,
233 } 145 }
234 } 146 }
235}
236 147
237impl GenericArgs { 148 pub fn mod_path(&self) -> &ModPath {
238 pub(crate) fn from_ast(node: ast::TypeArgList) -> Option<GenericArgs> { 149 &self.mod_path
239 let mut args = Vec::new();
240 for type_arg in node.type_args() {
241 let type_ref = TypeRef::from_ast_opt(type_arg.type_ref());
242 args.push(GenericArg::Type(type_ref));
243 }
244 // lifetimes ignored for now
245 let mut bindings = Vec::new();
246 for assoc_type_arg in node.assoc_type_args() {
247 if let Some(name_ref) = assoc_type_arg.name_ref() {
248 let name = name_ref.as_name();
249 let type_ref = TypeRef::from_ast_opt(assoc_type_arg.type_ref());
250 bindings.push((name, type_ref));
251 }
252 }
253 if args.is_empty() && bindings.is_empty() {
254 None
255 } else {
256 Some(GenericArgs { args, has_self_type: false, bindings })
257 }
258 } 150 }
259 151
260 /// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) 152 pub fn qualifier(&self) -> Option<Path> {
261 /// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). 153 if self.mod_path.is_ident() {
262 pub(crate) fn from_fn_like_path_ast( 154 return None;
263 params: Option<ast::ParamList>,
264 ret_type: Option<ast::RetType>,
265 ) -> Option<GenericArgs> {
266 let mut args = Vec::new();
267 let mut bindings = Vec::new();
268 if let Some(params) = params {
269 let mut param_types = Vec::new();
270 for param in params.params() {
271 let type_ref = TypeRef::from_ast_opt(param.ascribed_type());
272 param_types.push(type_ref);
273 }
274 let arg = GenericArg::Type(TypeRef::Tuple(param_types));
275 args.push(arg);
276 }
277 if let Some(ret_type) = ret_type {
278 let type_ref = TypeRef::from_ast_opt(ret_type.type_ref());
279 bindings.push((name::OUTPUT_TYPE, type_ref))
280 }
281 if args.is_empty() && bindings.is_empty() {
282 None
283 } else {
284 Some(GenericArgs { args, has_self_type: false, bindings })
285 } 155 }
286 } 156 let res = Path {
287 157 mod_path: ModPath {
288 pub(crate) fn empty() -> GenericArgs { 158 kind: self.mod_path.kind.clone(),
289 GenericArgs { args: Vec::new(), has_self_type: false, bindings: Vec::new() } 159 segments: self.mod_path.segments[..self.mod_path.segments.len() - 1].to_vec(),
160 },
161 generic_args: self.generic_args[..self.generic_args.len() - 1].to_vec(),
162 };
163 Some(res)
290 } 164 }
291} 165}
292 166
293impl From<Name> for Path { 167#[derive(Debug, Clone, PartialEq, Eq, Hash)]
294 fn from(name: Name) -> Path { 168pub struct PathSegment<'a> {
295 Path::from_simple_segments(PathKind::Plain, iter::once(name)) 169 pub name: &'a Name,
296 } 170 pub args_and_bindings: Option<&'a GenericArgs>,
297} 171}
298 172
299pub mod known { 173pub struct PathSegments<'a> {
300 use hir_expand::name; 174 segments: &'a [Name],
301 175 generic_args: &'a [Option<Arc<GenericArgs>>],
302 use super::{Path, PathKind}; 176}
303 177
304 pub fn std_iter_into_iterator() -> Path { 178impl<'a> PathSegments<'a> {
305 Path::from_simple_segments( 179 pub const EMPTY: PathSegments<'static> = PathSegments { segments: &[], generic_args: &[] };
306 PathKind::Abs, 180 pub fn is_empty(&self) -> bool {
307 vec![name::STD, name::ITER, name::INTO_ITERATOR_TYPE], 181 self.len() == 0
308 )
309 } 182 }
310 183 pub fn len(&self) -> usize {
311 pub fn std_ops_try() -> Path { 184 self.segments.len()
312 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::TRY_TYPE])
313 } 185 }
314 186 pub fn first(&self) -> Option<PathSegment<'a>> {
315 pub fn std_ops_range() -> Path { 187 self.get(0)
316 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_TYPE])
317 } 188 }
318 189 pub fn last(&self) -> Option<PathSegment<'a>> {
319 pub fn std_ops_range_from() -> Path { 190 self.get(self.len().checked_sub(1)?)
320 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_FROM_TYPE])
321 } 191 }
322 192 pub fn get(&self, idx: usize) -> Option<PathSegment<'a>> {
323 pub fn std_ops_range_full() -> Path { 193 assert_eq!(self.segments.len(), self.generic_args.len());
324 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_FULL_TYPE]) 194 let res = PathSegment {
195 name: self.segments.get(idx)?,
196 args_and_bindings: self.generic_args.get(idx).unwrap().as_ref().map(|it| &**it),
197 };
198 Some(res)
325 } 199 }
326 200 pub fn skip(&self, len: usize) -> PathSegments<'a> {
327 pub fn std_ops_range_inclusive() -> Path { 201 assert_eq!(self.segments.len(), self.generic_args.len());
328 Path::from_simple_segments( 202 PathSegments { segments: &self.segments[len..], generic_args: &self.generic_args[len..] }
329 PathKind::Abs,
330 vec![name::STD, name::OPS, name::RANGE_INCLUSIVE_TYPE],
331 )
332 } 203 }
333 204 pub fn take(&self, len: usize) -> PathSegments<'a> {
334 pub fn std_ops_range_to() -> Path { 205 assert_eq!(self.segments.len(), self.generic_args.len());
335 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_TO_TYPE]) 206 PathSegments { segments: &self.segments[..len], generic_args: &self.generic_args[..len] }
336 } 207 }
337 208 pub fn iter(&self) -> impl Iterator<Item = PathSegment<'a>> {
338 pub fn std_ops_range_to_inclusive() -> Path { 209 self.segments.iter().zip(self.generic_args.iter()).map(|(name, args)| PathSegment {
339 Path::from_simple_segments( 210 name,
340 PathKind::Abs, 211 args_and_bindings: args.as_ref().map(|it| &**it),
341 vec![name::STD, name::OPS, name::RANGE_TO_INCLUSIVE_TYPE], 212 })
342 )
343 } 213 }
214}
344 215
345 pub fn std_ops_neg() -> Path { 216impl GenericArgs {
346 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::NEG_TYPE]) 217 pub(crate) fn from_ast(node: ast::TypeArgList) -> Option<GenericArgs> {
218 lower::lower_generic_args(node)
347 } 219 }
348 220
349 pub fn std_ops_not() -> Path { 221 pub(crate) fn empty() -> GenericArgs {
350 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::NOT_TYPE]) 222 GenericArgs { args: Vec::new(), has_self_type: false, bindings: Vec::new() }
351 } 223 }
224}
352 225
353 pub fn std_result_result() -> Path { 226impl From<Name> for Path {
354 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::RESULT, name::RESULT_TYPE]) 227 fn from(name: Name) -> Path {
228 Path {
229 mod_path: ModPath::from_simple_segments(PathKind::Plain, iter::once(name)),
230 generic_args: vec![None],
231 }
355 } 232 }
233}
356 234
357 pub fn std_future_future() -> Path { 235impl From<Name> for ModPath {
358 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::FUTURE, name::FUTURE_TYPE]) 236 fn from(name: Name) -> ModPath {
237 ModPath::from_simple_segments(PathKind::Plain, iter::once(name))
359 } 238 }
239}
360 240
361 pub fn std_boxed_box() -> Path { 241pub use hir_expand::name as __name;
362 Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::BOXED, name::BOX_TYPE]) 242
363 } 243#[macro_export]
244macro_rules! __known_path {
245 (std::iter::IntoIterator) => {};
246 (std::result::Result) => {};
247 (std::ops::Range) => {};
248 (std::ops::RangeFrom) => {};
249 (std::ops::RangeFull) => {};
250 (std::ops::RangeTo) => {};
251 (std::ops::RangeToInclusive) => {};
252 (std::ops::RangeInclusive) => {};
253 (std::boxed::Box) => {};
254 (std::future::Future) => {};
255 (std::ops::Try) => {};
256 (std::ops::Neg) => {};
257 (std::ops::Not) => {};
258 ($path:path) => {
259 compile_error!("Please register your known path in the path module")
260 };
364} 261}
262
263#[macro_export]
264macro_rules! __path {
265 ($start:ident $(:: $seg:ident)*) => ({
266 $crate::__known_path!($start $(:: $seg)*);
267 $crate::path::ModPath::from_simple_segments($crate::path::PathKind::Abs, vec![
268 $crate::path::__name![$start], $($crate::path::__name![$seg],)*
269 ])
270 });
271}
272
273pub use crate::__path as path;
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs
new file mode 100644
index 000000000..a2e995198
--- /dev/null
+++ b/crates/ra_hir_def/src/path/lower.rs
@@ -0,0 +1,176 @@
1//! Transforms syntax into `Path` objects, ideally with accounting for hygiene
2
3mod lower_use;
4
5use std::sync::Arc;
6
7use either::Either;
8use hir_expand::{
9 hygiene::Hygiene,
10 name::{name, AsName},
11};
12use ra_syntax::ast::{self, AstNode, TypeAscriptionOwner};
13
14use crate::{
15 path::{GenericArg, GenericArgs, ModPath, Path, PathKind},
16 type_ref::TypeRef,
17};
18
19pub(super) use lower_use::lower_use_tree;
20
21/// Converts an `ast::Path` to `Path`. Works with use trees.
22/// It correctly handles `$crate` based path from macro call.
23pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> {
24 let mut kind = PathKind::Plain;
25 let mut segments = Vec::new();
26 let mut generic_args = Vec::new();
27 loop {
28 let segment = path.segment()?;
29
30 if segment.has_colon_colon() {
31 kind = PathKind::Abs;
32 }
33
34 match segment.kind()? {
35 ast::PathSegmentKind::Name(name_ref) => {
36 // FIXME: this should just return name
37 match hygiene.name_ref_to_name(name_ref) {
38 Either::Left(name) => {
39 let args = segment
40 .type_arg_list()
41 .and_then(lower_generic_args)
42 .or_else(|| {
43 lower_generic_args_from_fn_path(
44 segment.param_list(),
45 segment.ret_type(),
46 )
47 })
48 .map(Arc::new);
49 segments.push(name);
50 generic_args.push(args)
51 }
52 Either::Right(crate_id) => {
53 kind = PathKind::DollarCrate(crate_id);
54 break;
55 }
56 }
57 }
58 ast::PathSegmentKind::Type { type_ref, trait_ref } => {
59 assert!(path.qualifier().is_none()); // this can only occur at the first segment
60
61 let self_type = TypeRef::from_ast(type_ref?);
62
63 match trait_ref {
64 // <T>::foo
65 None => {
66 kind = PathKind::Type(Box::new(self_type));
67 }
68 // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo
69 Some(trait_ref) => {
70 let path = Path::from_src(trait_ref.path()?, hygiene)?;
71 kind = path.mod_path.kind;
72
73 let mut prefix_segments = path.mod_path.segments;
74 prefix_segments.reverse();
75 segments.extend(prefix_segments);
76
77 let mut prefix_args = path.generic_args;
78 prefix_args.reverse();
79 generic_args.extend(prefix_args);
80
81 // Insert the type reference (T in the above example) as Self parameter for the trait
82 let last_segment = generic_args.last_mut()?;
83 if last_segment.is_none() {
84 *last_segment = Some(Arc::new(GenericArgs::empty()));
85 };
86 let args = last_segment.as_mut().unwrap();
87 let mut args_inner = Arc::make_mut(args);
88 args_inner.has_self_type = true;
89 args_inner.args.insert(0, GenericArg::Type(self_type));
90 }
91 }
92 }
93 ast::PathSegmentKind::CrateKw => {
94 kind = PathKind::Crate;
95 break;
96 }
97 ast::PathSegmentKind::SelfKw => {
98 kind = PathKind::Self_;
99 break;
100 }
101 ast::PathSegmentKind::SuperKw => {
102 kind = PathKind::Super;
103 break;
104 }
105 }
106 path = match qualifier(&path) {
107 Some(it) => it,
108 None => break,
109 };
110 }
111 segments.reverse();
112 generic_args.reverse();
113 let mod_path = ModPath { kind, segments };
114 return Some(Path { mod_path, generic_args });
115
116 fn qualifier(path: &ast::Path) -> Option<ast::Path> {
117 if let Some(q) = path.qualifier() {
118 return Some(q);
119 }
120 // FIXME: this bottom up traversal is not too precise.
121 // Should we handle do a top-down analysis, recording results?
122 let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
123 let use_tree = use_tree_list.parent_use_tree();
124 use_tree.path()
125 }
126}
127
128pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option<GenericArgs> {
129 let mut args = Vec::new();
130 for type_arg in node.type_args() {
131 let type_ref = TypeRef::from_ast_opt(type_arg.type_ref());
132 args.push(GenericArg::Type(type_ref));
133 }
134 // lifetimes ignored for now
135 let mut bindings = Vec::new();
136 for assoc_type_arg in node.assoc_type_args() {
137 if let Some(name_ref) = assoc_type_arg.name_ref() {
138 let name = name_ref.as_name();
139 let type_ref = TypeRef::from_ast_opt(assoc_type_arg.type_ref());
140 bindings.push((name, type_ref));
141 }
142 }
143 if args.is_empty() && bindings.is_empty() {
144 None
145 } else {
146 Some(GenericArgs { args, has_self_type: false, bindings })
147 }
148}
149
150/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y)
151/// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`).
152fn lower_generic_args_from_fn_path(
153 params: Option<ast::ParamList>,
154 ret_type: Option<ast::RetType>,
155) -> Option<GenericArgs> {
156 let mut args = Vec::new();
157 let mut bindings = Vec::new();
158 if let Some(params) = params {
159 let mut param_types = Vec::new();
160 for param in params.params() {
161 let type_ref = TypeRef::from_ast_opt(param.ascribed_type());
162 param_types.push(type_ref);
163 }
164 let arg = GenericArg::Type(TypeRef::Tuple(param_types));
165 args.push(arg);
166 }
167 if let Some(ret_type) = ret_type {
168 let type_ref = TypeRef::from_ast_opt(ret_type.type_ref());
169 bindings.push((name![Output], type_ref))
170 }
171 if args.is_empty() && bindings.is_empty() {
172 None
173 } else {
174 Some(GenericArgs { args, has_self_type: false, bindings })
175 }
176}
diff --git a/crates/ra_hir_def/src/path/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs
index e2e1f716d..ea3fdb56c 100644
--- a/crates/ra_hir_def/src/path/lower_use.rs
+++ b/crates/ra_hir_def/src/path/lower/lower_use.rs
@@ -10,13 +10,13 @@ use hir_expand::{
10}; 10};
11use ra_syntax::ast::{self, NameOwner}; 11use ra_syntax::ast::{self, NameOwner};
12 12
13use crate::path::{Path, PathKind, PathSegment}; 13use crate::path::{ModPath, PathKind};
14 14
15pub(crate) fn lower_use_tree( 15pub(crate) fn lower_use_tree(
16 prefix: Option<Path>, 16 prefix: Option<ModPath>,
17 tree: ast::UseTree, 17 tree: ast::UseTree,
18 hygiene: &Hygiene, 18 hygiene: &Hygiene,
19 cb: &mut dyn FnMut(Path, &ast::UseTree, bool, Option<Name>), 19 cb: &mut dyn FnMut(ModPath, &ast::UseTree, bool, Option<Name>),
20) { 20) {
21 if let Some(use_tree_list) = tree.use_tree_list() { 21 if let Some(use_tree_list) = tree.use_tree_list() {
22 let prefix = match tree.path() { 22 let prefix = match tree.path() {
@@ -57,7 +57,7 @@ pub(crate) fn lower_use_tree(
57 } 57 }
58} 58}
59 59
60fn convert_path(prefix: Option<Path>, path: ast::Path, hygiene: &Hygiene) -> Option<Path> { 60fn convert_path(prefix: Option<ModPath>, path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> {
61 let prefix = if let Some(qual) = path.qualifier() { 61 let prefix = if let Some(qual) = path.qualifier() {
62 Some(convert_path(prefix, qual, hygiene)?) 62 Some(convert_path(prefix, qual, hygiene)?)
63 } else { 63 } else {
@@ -70,18 +70,15 @@ fn convert_path(prefix: Option<Path>, path: ast::Path, hygiene: &Hygiene) -> Opt
70 match hygiene.name_ref_to_name(name_ref) { 70 match hygiene.name_ref_to_name(name_ref) {
71 Either::Left(name) => { 71 Either::Left(name) => {
72 // no type args in use 72 // no type args in use
73 let mut res = prefix.unwrap_or_else(|| Path { 73 let mut res = prefix.unwrap_or_else(|| ModPath {
74 kind: PathKind::Plain, 74 kind: PathKind::Plain,
75 segments: Vec::with_capacity(1), 75 segments: Vec::with_capacity(1),
76 }); 76 });
77 res.segments.push(PathSegment { 77 res.segments.push(name);
78 name,
79 args_and_bindings: None, // no type args in use
80 });
81 res 78 res
82 } 79 }
83 Either::Right(crate_id) => { 80 Either::Right(crate_id) => {
84 return Some(Path::from_simple_segments( 81 return Some(ModPath::from_simple_segments(
85 PathKind::DollarCrate(crate_id), 82 PathKind::DollarCrate(crate_id),
86 iter::empty(), 83 iter::empty(),
87 )) 84 ))
@@ -92,19 +89,19 @@ fn convert_path(prefix: Option<Path>, path: ast::Path, hygiene: &Hygiene) -> Opt
92 if prefix.is_some() { 89 if prefix.is_some() {
93 return None; 90 return None;
94 } 91 }
95 Path::from_simple_segments(PathKind::Crate, iter::empty()) 92 ModPath::from_simple_segments(PathKind::Crate, iter::empty())
96 } 93 }
97 ast::PathSegmentKind::SelfKw => { 94 ast::PathSegmentKind::SelfKw => {
98 if prefix.is_some() { 95 if prefix.is_some() {
99 return None; 96 return None;
100 } 97 }
101 Path::from_simple_segments(PathKind::Self_, iter::empty()) 98 ModPath::from_simple_segments(PathKind::Self_, iter::empty())
102 } 99 }
103 ast::PathSegmentKind::SuperKw => { 100 ast::PathSegmentKind::SuperKw => {
104 if prefix.is_some() { 101 if prefix.is_some() {
105 return None; 102 return None;
106 } 103 }
107 Path::from_simple_segments(PathKind::Super, iter::empty()) 104 ModPath::from_simple_segments(PathKind::Super, iter::empty())
108 } 105 }
109 ast::PathSegmentKind::Type { .. } => { 106 ast::PathSegmentKind::Type { .. } => {
110 // not allowed in imports 107 // not allowed in imports
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index 17b2169d2..2694c0438 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -2,7 +2,7 @@
2use std::sync::Arc; 2use std::sync::Arc;
3 3
4use hir_expand::{ 4use hir_expand::{
5 name::{self, Name}, 5 name::{name, Name},
6 MacroDefId, 6 MacroDefId,
7}; 7};
8use ra_db::CrateId; 8use ra_db::CrateId;
@@ -15,7 +15,7 @@ use crate::{
15 expr::{ExprId, PatId}, 15 expr::{ExprId, PatId},
16 generics::GenericParams, 16 generics::GenericParams,
17 nameres::{BuiltinShadowMode, CrateDefMap}, 17 nameres::{BuiltinShadowMode, CrateDefMap},
18 path::{Path, PathKind}, 18 path::{ModPath, PathKind},
19 per_ns::PerNs, 19 per_ns::PerNs,
20 AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, 20 AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId,
21 HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, 21 HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId,
@@ -91,7 +91,7 @@ pub enum ValueNs {
91 91
92impl Resolver { 92impl Resolver {
93 /// Resolve known trait from std, like `std::futures::Future` 93 /// Resolve known trait from std, like `std::futures::Future`
94 pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &Path) -> Option<TraitId> { 94 pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &ModPath) -> Option<TraitId> {
95 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; 95 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
96 match res { 96 match res {
97 ModuleDefId::TraitId(it) => Some(it), 97 ModuleDefId::TraitId(it) => Some(it),
@@ -100,7 +100,7 @@ impl Resolver {
100 } 100 }
101 101
102 /// Resolve known struct from std, like `std::boxed::Box` 102 /// Resolve known struct from std, like `std::boxed::Box`
103 pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &Path) -> Option<StructId> { 103 pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &ModPath) -> Option<StructId> {
104 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; 104 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
105 match res { 105 match res {
106 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), 106 ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it),
@@ -109,7 +109,7 @@ impl Resolver {
109 } 109 }
110 110
111 /// Resolve known enum from std, like `std::result::Result` 111 /// Resolve known enum from std, like `std::result::Result`
112 pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &Path) -> Option<EnumId> { 112 pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &ModPath) -> Option<EnumId> {
113 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; 113 let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?;
114 match res { 114 match res {
115 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), 115 ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it),
@@ -120,33 +120,30 @@ impl Resolver {
120 fn resolve_module_path( 120 fn resolve_module_path(
121 &self, 121 &self,
122 db: &impl DefDatabase, 122 db: &impl DefDatabase,
123 path: &Path, 123 path: &ModPath,
124 shadow: BuiltinShadowMode, 124 shadow: BuiltinShadowMode,
125 ) -> PerNs { 125 ) -> PerNs {
126 let (item_map, module) = match self.module() { 126 let (item_map, module) = match self.module() {
127 Some(it) => it, 127 Some(it) => it,
128 None => return PerNs::none(), 128 None => return PerNs::none(),
129 }; 129 };
130 let (module_res, segment_index) = item_map.resolve_path(db, module, path, shadow); 130 let (module_res, segment_index) = item_map.resolve_path(db, module, &path, shadow);
131 if segment_index.is_some() { 131 if segment_index.is_some() {
132 return PerNs::none(); 132 return PerNs::none();
133 } 133 }
134 module_res 134 module_res
135 } 135 }
136 136
137 pub fn resolve_module_path_in_items(&self, db: &impl DefDatabase, path: &Path) -> PerNs { 137 pub fn resolve_module_path_in_items(&self, db: &impl DefDatabase, path: &ModPath) -> PerNs {
138 self.resolve_module_path(db, path, BuiltinShadowMode::Module) 138 self.resolve_module_path(db, path, BuiltinShadowMode::Module)
139 } 139 }
140 140
141 pub fn resolve_path_in_type_ns( 141 pub fn resolve_path_in_type_ns(
142 &self, 142 &self,
143 db: &impl DefDatabase, 143 db: &impl DefDatabase,
144 path: &Path, 144 path: &ModPath,
145 ) -> Option<(TypeNs, Option<usize>)> { 145 ) -> Option<(TypeNs, Option<usize>)> {
146 if path.is_type_relative() { 146 let first_name = path.segments.first()?;
147 return None;
148 }
149 let first_name = &path.segments.first()?.name;
150 let skip_to_mod = path.kind != PathKind::Plain; 147 let skip_to_mod = path.kind != PathKind::Plain;
151 for scope in self.scopes.iter().rev() { 148 for scope in self.scopes.iter().rev() {
152 match scope { 149 match scope {
@@ -163,13 +160,13 @@ impl Resolver {
163 } 160 }
164 } 161 }
165 Scope::ImplBlockScope(impl_) => { 162 Scope::ImplBlockScope(impl_) => {
166 if first_name == &name::SELF_TYPE { 163 if first_name == &name![Self] {
167 let idx = if path.segments.len() == 1 { None } else { Some(1) }; 164 let idx = if path.segments.len() == 1 { None } else { Some(1) };
168 return Some((TypeNs::SelfType(*impl_), idx)); 165 return Some((TypeNs::SelfType(*impl_), idx));
169 } 166 }
170 } 167 }
171 Scope::AdtScope(adt) => { 168 Scope::AdtScope(adt) => {
172 if first_name == &name::SELF_TYPE { 169 if first_name == &name![Self] {
173 let idx = if path.segments.len() == 1 { None } else { Some(1) }; 170 let idx = if path.segments.len() == 1 { None } else { Some(1) };
174 return Some((TypeNs::AdtSelfType(*adt), idx)); 171 return Some((TypeNs::AdtSelfType(*adt), idx));
175 } 172 }
@@ -178,7 +175,7 @@ impl Resolver {
178 let (module_def, idx) = m.crate_def_map.resolve_path( 175 let (module_def, idx) = m.crate_def_map.resolve_path(
179 db, 176 db,
180 m.module_id, 177 m.module_id,
181 path, 178 &path,
182 BuiltinShadowMode::Other, 179 BuiltinShadowMode::Other,
183 ); 180 );
184 let res = match module_def.take_types()? { 181 let res = match module_def.take_types()? {
@@ -205,7 +202,7 @@ impl Resolver {
205 pub fn resolve_path_in_type_ns_fully( 202 pub fn resolve_path_in_type_ns_fully(
206 &self, 203 &self,
207 db: &impl DefDatabase, 204 db: &impl DefDatabase,
208 path: &Path, 205 path: &ModPath,
209 ) -> Option<TypeNs> { 206 ) -> Option<TypeNs> {
210 let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; 207 let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?;
211 if unresolved.is_some() { 208 if unresolved.is_some() {
@@ -214,17 +211,14 @@ impl Resolver {
214 Some(res) 211 Some(res)
215 } 212 }
216 213
217 pub fn resolve_path_in_value_ns<'p>( 214 pub fn resolve_path_in_value_ns(
218 &self, 215 &self,
219 db: &impl DefDatabase, 216 db: &impl DefDatabase,
220 path: &'p Path, 217 path: &ModPath,
221 ) -> Option<ResolveValueResult> { 218 ) -> Option<ResolveValueResult> {
222 if path.is_type_relative() {
223 return None;
224 }
225 let n_segments = path.segments.len(); 219 let n_segments = path.segments.len();
226 let tmp = name::SELF_PARAM; 220 let tmp = name![self];
227 let first_name = if path.is_self() { &tmp } else { &path.segments.first()?.name }; 221 let first_name = if path.is_self() { &tmp } else { &path.segments.first()? };
228 let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); 222 let skip_to_mod = path.kind != PathKind::Plain && !path.is_self();
229 for scope in self.scopes.iter().rev() { 223 for scope in self.scopes.iter().rev() {
230 match scope { 224 match scope {
@@ -259,13 +253,13 @@ impl Resolver {
259 Scope::GenericParams { .. } => continue, 253 Scope::GenericParams { .. } => continue,
260 254
261 Scope::ImplBlockScope(impl_) if n_segments > 1 => { 255 Scope::ImplBlockScope(impl_) if n_segments > 1 => {
262 if first_name == &name::SELF_TYPE { 256 if first_name == &name![Self] {
263 let ty = TypeNs::SelfType(*impl_); 257 let ty = TypeNs::SelfType(*impl_);
264 return Some(ResolveValueResult::Partial(ty, 1)); 258 return Some(ResolveValueResult::Partial(ty, 1));
265 } 259 }
266 } 260 }
267 Scope::AdtScope(adt) if n_segments > 1 => { 261 Scope::AdtScope(adt) if n_segments > 1 => {
268 if first_name == &name::SELF_TYPE { 262 if first_name == &name![Self] {
269 let ty = TypeNs::AdtSelfType(*adt); 263 let ty = TypeNs::AdtSelfType(*adt);
270 return Some(ResolveValueResult::Partial(ty, 1)); 264 return Some(ResolveValueResult::Partial(ty, 1));
271 } 265 }
@@ -276,7 +270,7 @@ impl Resolver {
276 let (module_def, idx) = m.crate_def_map.resolve_path( 270 let (module_def, idx) = m.crate_def_map.resolve_path(
277 db, 271 db,
278 m.module_id, 272 m.module_id,
279 path, 273 &path,
280 BuiltinShadowMode::Other, 274 BuiltinShadowMode::Other,
281 ); 275 );
282 return match idx { 276 return match idx {
@@ -322,7 +316,7 @@ impl Resolver {
322 pub fn resolve_path_in_value_ns_fully( 316 pub fn resolve_path_in_value_ns_fully(
323 &self, 317 &self,
324 db: &impl DefDatabase, 318 db: &impl DefDatabase,
325 path: &Path, 319 path: &ModPath,
326 ) -> Option<ValueNs> { 320 ) -> Option<ValueNs> {
327 match self.resolve_path_in_value_ns(db, path)? { 321 match self.resolve_path_in_value_ns(db, path)? {
328 ResolveValueResult::ValueNs(it) => Some(it), 322 ResolveValueResult::ValueNs(it) => Some(it),
@@ -330,9 +324,13 @@ impl Resolver {
330 } 324 }
331 } 325 }
332 326
333 pub fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> { 327 pub fn resolve_path_as_macro(
328 &self,
329 db: &impl DefDatabase,
330 path: &ModPath,
331 ) -> Option<MacroDefId> {
334 let (item_map, module) = self.module()?; 332 let (item_map, module) = self.module()?;
335 item_map.resolve_path(db, module, path, BuiltinShadowMode::Other).0.take_macros() 333 item_map.resolve_path(db, module, &path, BuiltinShadowMode::Other).0.take_macros()
336 } 334 }
337 335
338 pub fn process_all_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { 336 pub fn process_all_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) {
@@ -439,10 +437,10 @@ impl Scope {
439 } 437 }
440 } 438 }
441 Scope::ImplBlockScope(i) => { 439 Scope::ImplBlockScope(i) => {
442 f(name::SELF_TYPE, ScopeDef::ImplSelfType((*i).into())); 440 f(name![Self], ScopeDef::ImplSelfType((*i).into()));
443 } 441 }
444 Scope::AdtScope(i) => { 442 Scope::AdtScope(i) => {
445 f(name::SELF_TYPE, ScopeDef::AdtSelfType((*i).into())); 443 f(name![Self], ScopeDef::AdtSelfType((*i).into()));
446 } 444 }
447 Scope::ExprScope(scope) => { 445 Scope::ExprScope(scope) => {
448 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { 446 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| {