diff options
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/path_resolution.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir_def/src/path.rs | 41 | ||||
-rw-r--r-- | crates/ra_hir_def/src/path/lower.rs | 6 |
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(¯o_call), | 44 | db.ast_id_map(self.current_file_id).ast_id(¯o_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)] | ||
22 | pub 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 | |||
21 | impl ModPath { | 33 | impl 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)] |
72 | pub struct Path { | 84 | pub 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)] | ||
101 | pub 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 | |||
113 | impl Path { | 115 | impl 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 { | |||
225 | impl From<Name> for Path { | 227 | impl 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. |
23 | pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> { | 23 | pub(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() { |