aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r--crates/ra_hir_def/src/body.rs12
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs5
-rw-r--r--crates/ra_hir_def/src/path.rs41
-rw-r--r--crates/ra_hir_def/src/path/lower.rs6
4 files changed, 34 insertions, 30 deletions
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index 7787cb87f..d4cab0561 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -15,7 +15,7 @@ use crate::{
15 db::DefDatabase, 15 db::DefDatabase,
16 expr::{Expr, ExprId, Pat, PatId}, 16 expr::{Expr, ExprId, Pat, PatId},
17 nameres::{BuiltinShadowMode, CrateDefMap}, 17 nameres::{BuiltinShadowMode, CrateDefMap},
18 path::Path, 18 path::{ModPath, Path},
19 src::HasSource, 19 src::HasSource,
20 DefWithBodyId, HasModule, Lookup, ModuleId, 20 DefWithBodyId, HasModule, Lookup, ModuleId,
21}; 21};
@@ -44,7 +44,7 @@ impl Expander {
44 db.ast_id_map(self.current_file_id).ast_id(&macro_call), 44 db.ast_id_map(self.current_file_id).ast_id(&macro_call),
45 ); 45 );
46 46
47 if let Some(path) = macro_call.path().and_then(|path| self.parse_path(path)) { 47 if let Some(path) = macro_call.path().and_then(|path| self.parse_mod_path(path)) {
48 if let Some(def) = self.resolve_path_as_macro(db, &path) { 48 if let Some(def) = self.resolve_path_as_macro(db, &path) {
49 let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id)); 49 let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id));
50 let file_id = call_id.as_file(); 50 let file_id = call_id.as_file();
@@ -81,9 +81,13 @@ impl Expander {
81 Path::from_src(path, &self.hygiene) 81 Path::from_src(path, &self.hygiene)
82 } 82 }
83 83
84 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option<MacroDefId> { 84 fn parse_mod_path(&mut self, path: ast::Path) -> Option<ModPath> {
85 ModPath::from_src(path, &self.hygiene)
86 }
87
88 fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &ModPath) -> Option<MacroDefId> {
85 self.crate_def_map 89 self.crate_def_map
86 .resolve_path(db, self.module.local_id, path.mod_path(), BuiltinShadowMode::Other) 90 .resolve_path(db, self.module.local_id, path, BuiltinShadowMode::Other)
87 .0 91 .0
88 .take_macros() 92 .take_macros()
89 } 93 }
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs
index 1dbc4f371..2dd779b66 100644
--- a/crates/ra_hir_def/src/nameres/path_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/path_resolution.rs
@@ -145,11 +145,6 @@ impl CrateDefMap {
145 return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude 145 return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
146 } 146 }
147 } 147 }
148 PathKind::Type(_) => {
149 // This is handled in `infer::infer_path_expr`
150 // The result returned here does not matter
151 return ResolvePathResult::empty(ReachedFixedPoint::Yes);
152 }
153 }; 148 };
154 149
155 for (i, segment) in segments { 150 for (i, segment) in segments {
diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs
index 3b26e8337..7302cf0f1 100644
--- a/crates/ra_hir_def/src/path.rs
+++ b/crates/ra_hir_def/src/path.rs
@@ -18,6 +18,18 @@ pub struct ModPath {
18 pub segments: Vec<Name>, 18 pub segments: Vec<Name>,
19} 19}
20 20
21#[derive(Debug, Clone, PartialEq, Eq, Hash)]
22pub enum PathKind {
23 Plain,
24 /// `self::` is `Super(0)`
25 Super(u8),
26 Crate,
27 /// Absolute path (::foo)
28 Abs,
29 /// `$crate` from macro expansion
30 DollarCrate(CrateId),
31}
32
21impl ModPath { 33impl ModPath {
22 pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> { 34 pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option<ModPath> {
23 lower::lower_path(path, hygiene).map(|it| it.mod_path) 35 lower::lower_path(path, hygiene).map(|it| it.mod_path)
@@ -70,6 +82,9 @@ impl ModPath {
70 82
71#[derive(Debug, Clone, PartialEq, Eq, Hash)] 83#[derive(Debug, Clone, PartialEq, Eq, Hash)]
72pub struct Path { 84pub struct Path {
85 /// Type based path like `<T>::foo`.
86 /// Note that paths like `<Type as Trait>::foo` are desugard to `Trait::<Self=Type>::foo`.
87 type_anchor: Option<Box<TypeRef>>,
73 mod_path: ModPath, 88 mod_path: ModPath,
74 /// Invariant: the same len as self.path.segments 89 /// Invariant: the same len as self.path.segments
75 generic_args: Vec<Option<Arc<GenericArgs>>>, 90 generic_args: Vec<Option<Arc<GenericArgs>>>,
@@ -97,19 +112,6 @@ pub enum GenericArg {
97 // or lifetime... 112 // or lifetime...
98} 113}
99 114
100#[derive(Debug, Clone, PartialEq, Eq, Hash)]
101pub enum PathKind {
102 Plain,
103 Super(u8),
104 Crate,
105 // Absolute path
106 Abs,
107 // Type based path like `<T>::foo`
108 Type(Box<TypeRef>),
109 // `$crate` from macro expansion
110 DollarCrate(CrateId),
111}
112
113impl Path { 115impl Path {
114 /// Converts an `ast::Path` to `Path`. Works with use trees. 116 /// Converts an `ast::Path` to `Path`. Works with use trees.
115 /// DEPRECATED: It does not handle `$crate` from macro call. 117 /// DEPRECATED: It does not handle `$crate` from macro call.
@@ -125,18 +127,17 @@ impl Path {
125 127
126 /// Converts an `ast::NameRef` into a single-identifier `Path`. 128 /// Converts an `ast::NameRef` into a single-identifier `Path`.
127 pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path { 129 pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path {
128 Path { mod_path: name_ref.as_name().into(), generic_args: vec![None] } 130 Path { type_anchor: None, mod_path: name_ref.as_name().into(), generic_args: vec![None] }
129 }
130
131 /// `true` if this path is just a standalone `self`
132 pub fn is_self(&self) -> bool {
133 self.mod_path.is_self()
134 } 131 }
135 132
136 pub fn kind(&self) -> &PathKind { 133 pub fn kind(&self) -> &PathKind {
137 &self.mod_path.kind 134 &self.mod_path.kind
138 } 135 }
139 136
137 pub fn type_anchor(&self) -> Option<&TypeRef> {
138 self.type_anchor.as_ref().map(|it| &**it)
139 }
140
140 pub fn segments(&self) -> PathSegments<'_> { 141 pub fn segments(&self) -> PathSegments<'_> {
141 PathSegments { 142 PathSegments {
142 segments: self.mod_path.segments.as_slice(), 143 segments: self.mod_path.segments.as_slice(),
@@ -153,6 +154,7 @@ impl Path {
153 return None; 154 return None;
154 } 155 }
155 let res = Path { 156 let res = Path {
157 type_anchor: self.type_anchor.clone(),
156 mod_path: ModPath { 158 mod_path: ModPath {
157 kind: self.mod_path.kind.clone(), 159 kind: self.mod_path.kind.clone(),
158 segments: self.mod_path.segments[..self.mod_path.segments.len() - 1].to_vec(), 160 segments: self.mod_path.segments[..self.mod_path.segments.len() - 1].to_vec(),
@@ -225,6 +227,7 @@ impl GenericArgs {
225impl From<Name> for Path { 227impl From<Name> for Path {
226 fn from(name: Name) -> Path { 228 fn from(name: Name) -> Path {
227 Path { 229 Path {
230 type_anchor: None,
228 mod_path: ModPath::from_simple_segments(PathKind::Plain, iter::once(name)), 231 mod_path: ModPath::from_simple_segments(PathKind::Plain, iter::once(name)),
229 generic_args: vec![None], 232 generic_args: vec![None],
230 } 233 }
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs
index c71b52d89..62aafd508 100644
--- a/crates/ra_hir_def/src/path/lower.rs
+++ b/crates/ra_hir_def/src/path/lower.rs
@@ -22,6 +22,7 @@ pub(super) use lower_use::lower_use_tree;
22/// It correctly handles `$crate` based path from macro call. 22/// It correctly handles `$crate` based path from macro call.
23pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> { 23pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> {
24 let mut kind = PathKind::Plain; 24 let mut kind = PathKind::Plain;
25 let mut type_anchor = None;
25 let mut segments = Vec::new(); 26 let mut segments = Vec::new();
26 let mut generic_args = Vec::new(); 27 let mut generic_args = Vec::new();
27 loop { 28 loop {
@@ -63,7 +64,8 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
63 match trait_ref { 64 match trait_ref {
64 // <T>::foo 65 // <T>::foo
65 None => { 66 None => {
66 kind = PathKind::Type(Box::new(self_type)); 67 type_anchor = Some(Box::new(self_type));
68 kind = PathKind::Plain;
67 } 69 }
68 // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo 70 // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::Foo
69 Some(trait_ref) => { 71 Some(trait_ref) => {
@@ -111,7 +113,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
111 segments.reverse(); 113 segments.reverse();
112 generic_args.reverse(); 114 generic_args.reverse();
113 let mod_path = ModPath { kind, segments }; 115 let mod_path = ModPath { kind, segments };
114 return Some(Path { mod_path, generic_args }); 116 return Some(Path { type_anchor, mod_path, generic_args });
115 117
116 fn qualifier(path: &ast::Path) -> Option<ast::Path> { 118 fn qualifier(path: &ast::Path) -> Option<ast::Path> {
117 if let Some(q) = path.qualifier() { 119 if let Some(q) = path.qualifier() {