diff options
Diffstat (limited to 'crates/hir_def/src/nameres')
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 34 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/path_resolution.rs | 59 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/diagnostics.rs | 4 |
3 files changed, 65 insertions, 32 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 492d8c71f..05ceb1efb 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -13,7 +13,7 @@ use hir_expand::{ | |||
13 | builtin_macro::find_builtin_macro, | 13 | builtin_macro::find_builtin_macro, |
14 | name::{AsName, Name}, | 14 | name::{AsName, Name}, |
15 | proc_macro::ProcMacroExpander, | 15 | proc_macro::ProcMacroExpander, |
16 | HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, | 16 | AttrId, HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, |
17 | }; | 17 | }; |
18 | use hir_expand::{InFile, MacroCallLoc}; | 18 | use hir_expand::{InFile, MacroCallLoc}; |
19 | use rustc_hash::{FxHashMap, FxHashSet}; | 19 | use rustc_hash::{FxHashMap, FxHashSet}; |
@@ -216,7 +216,7 @@ struct MacroDirective { | |||
216 | #[derive(Clone, Debug, Eq, PartialEq)] | 216 | #[derive(Clone, Debug, Eq, PartialEq)] |
217 | enum MacroDirectiveKind { | 217 | enum MacroDirectiveKind { |
218 | FnLike { ast_id: AstIdWithPath<ast::MacroCall> }, | 218 | FnLike { ast_id: AstIdWithPath<ast::MacroCall> }, |
219 | Derive { ast_id: AstIdWithPath<ast::Item> }, | 219 | Derive { ast_id: AstIdWithPath<ast::Item>, derive_attr: AttrId }, |
220 | } | 220 | } |
221 | 221 | ||
222 | struct DefData<'a> { | 222 | struct DefData<'a> { |
@@ -478,7 +478,7 @@ impl DefCollector<'_> { | |||
478 | self.def_map.edition, | 478 | self.def_map.edition, |
479 | ); | 479 | ); |
480 | 480 | ||
481 | let res = self.def_map.resolve_name_in_extern_prelude(&extern_crate.name); | 481 | let res = self.def_map.resolve_name_in_extern_prelude(self.db, &extern_crate.name); |
482 | 482 | ||
483 | if let Some(ModuleDefId::ModuleId(m)) = res.take_types() { | 483 | if let Some(ModuleDefId::ModuleId(m)) = res.take_types() { |
484 | cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use); | 484 | cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use); |
@@ -534,6 +534,7 @@ impl DefCollector<'_> { | |||
534 | log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); | 534 | log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); |
535 | if import.is_extern_crate { | 535 | if import.is_extern_crate { |
536 | let res = self.def_map.resolve_name_in_extern_prelude( | 536 | let res = self.def_map.resolve_name_in_extern_prelude( |
537 | self.db, | ||
537 | &import | 538 | &import |
538 | .path | 539 | .path |
539 | .as_ident() | 540 | .as_ident() |
@@ -828,19 +829,23 @@ impl DefCollector<'_> { | |||
828 | res = ReachedFixedPoint::No; | 829 | res = ReachedFixedPoint::No; |
829 | return false; | 830 | return false; |
830 | } | 831 | } |
831 | Err(UnresolvedMacro) | Ok(Err(_)) => {} | 832 | Err(UnresolvedMacro { .. }) | Ok(Err(_)) => {} |
832 | } | 833 | } |
833 | } | 834 | } |
834 | MacroDirectiveKind::Derive { ast_id } => { | 835 | MacroDirectiveKind::Derive { ast_id, derive_attr } => { |
835 | match derive_macro_as_call_id(ast_id, self.db, self.def_map.krate, |path| { | 836 | match derive_macro_as_call_id( |
836 | self.resolve_derive_macro(directive.module_id, &path) | 837 | ast_id, |
837 | }) { | 838 | *derive_attr, |
839 | self.db, | ||
840 | self.def_map.krate, | ||
841 | |path| self.resolve_derive_macro(directive.module_id, &path), | ||
842 | ) { | ||
838 | Ok(call_id) => { | 843 | Ok(call_id) => { |
839 | resolved.push((directive.module_id, call_id, 0)); | 844 | resolved.push((directive.module_id, call_id, directive.depth)); |
840 | res = ReachedFixedPoint::No; | 845 | res = ReachedFixedPoint::No; |
841 | return false; | 846 | return false; |
842 | } | 847 | } |
843 | Err(UnresolvedMacro) => (), | 848 | Err(UnresolvedMacro { .. }) => (), |
844 | } | 849 | } |
845 | } | 850 | } |
846 | } | 851 | } |
@@ -938,10 +943,11 @@ impl DefCollector<'_> { | |||
938 | &mut |_| (), | 943 | &mut |_| (), |
939 | ) { | 944 | ) { |
940 | Ok(_) => (), | 945 | Ok(_) => (), |
941 | Err(UnresolvedMacro) => { | 946 | Err(UnresolvedMacro { path }) => { |
942 | self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call( | 947 | self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call( |
943 | directive.module_id, | 948 | directive.module_id, |
944 | ast_id.ast_id, | 949 | ast_id.ast_id, |
950 | path, | ||
945 | )); | 951 | )); |
946 | } | 952 | } |
947 | }, | 953 | }, |
@@ -1368,7 +1374,7 @@ impl ModCollector<'_, '_> { | |||
1368 | self.def_collector.unexpanded_macros.push(MacroDirective { | 1374 | self.def_collector.unexpanded_macros.push(MacroDirective { |
1369 | module_id: self.module_id, | 1375 | module_id: self.module_id, |
1370 | depth: self.macro_depth + 1, | 1376 | depth: self.macro_depth + 1, |
1371 | kind: MacroDirectiveKind::Derive { ast_id }, | 1377 | kind: MacroDirectiveKind::Derive { ast_id, derive_attr: derive.id }, |
1372 | }); | 1378 | }); |
1373 | } | 1379 | } |
1374 | } | 1380 | } |
@@ -1520,12 +1526,12 @@ impl ModCollector<'_, '_> { | |||
1520 | // Built-in macro failed eager expansion. | 1526 | // Built-in macro failed eager expansion. |
1521 | self.def_collector.def_map.diagnostics.push(DefDiagnostic::macro_error( | 1527 | self.def_collector.def_map.diagnostics.push(DefDiagnostic::macro_error( |
1522 | self.module_id, | 1528 | self.module_id, |
1523 | MacroCallKind::FnLike(ast_id.ast_id), | 1529 | MacroCallKind::FnLike { ast_id: ast_id.ast_id }, |
1524 | error.unwrap().to_string(), | 1530 | error.unwrap().to_string(), |
1525 | )); | 1531 | )); |
1526 | return; | 1532 | return; |
1527 | } | 1533 | } |
1528 | Err(UnresolvedMacro) => (), | 1534 | Err(UnresolvedMacro { .. }) => (), |
1529 | } | 1535 | } |
1530 | 1536 | ||
1531 | // Case 2: resolve in module scope, expand during name resolution. | 1537 | // Case 2: resolve in module scope, expand during name resolution. |
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs index 60471937c..c984148c3 100644 --- a/crates/hir_def/src/nameres/path_resolution.rs +++ b/crates/hir_def/src/nameres/path_resolution.rs | |||
@@ -60,12 +60,26 @@ impl ResolvePathResult { | |||
60 | } | 60 | } |
61 | 61 | ||
62 | impl DefMap { | 62 | impl DefMap { |
63 | pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { | 63 | pub(super) fn resolve_name_in_extern_prelude( |
64 | &self, | ||
65 | db: &dyn DefDatabase, | ||
66 | name: &Name, | ||
67 | ) -> PerNs { | ||
64 | if name == &name!(self) { | 68 | if name == &name!(self) { |
65 | cov_mark::hit!(extern_crate_self_as); | 69 | cov_mark::hit!(extern_crate_self_as); |
66 | return PerNs::types(self.module_id(self.root).into(), Visibility::Public); | 70 | return PerNs::types(self.module_id(self.root).into(), Visibility::Public); |
67 | } | 71 | } |
68 | self.extern_prelude | 72 | |
73 | let arc; | ||
74 | let root = match self.block { | ||
75 | Some(_) => { | ||
76 | arc = self.crate_root(db).def_map(db); | ||
77 | &*arc | ||
78 | } | ||
79 | None => self, | ||
80 | }; | ||
81 | |||
82 | root.extern_prelude | ||
69 | .get(name) | 83 | .get(name) |
70 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) | 84 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) |
71 | } | 85 | } |
@@ -191,7 +205,7 @@ impl DefMap { | |||
191 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), | 205 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), |
192 | }; | 206 | }; |
193 | log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); | 207 | log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); |
194 | self.resolve_name_in_crate_root_or_extern_prelude(&segment) | 208 | self.resolve_name_in_crate_root_or_extern_prelude(db, &segment) |
195 | } | 209 | } |
196 | PathKind::Plain => { | 210 | PathKind::Plain => { |
197 | let (_, segment) = match segments.next() { | 211 | let (_, segment) = match segments.next() { |
@@ -373,7 +387,13 @@ impl DefMap { | |||
373 | .get_legacy_macro(name) | 387 | .get_legacy_macro(name) |
374 | .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public)); | 388 | .map_or_else(PerNs::none, |m| PerNs::macros(m, Visibility::Public)); |
375 | let from_scope = self[module].scope.get(name); | 389 | let from_scope = self[module].scope.get(name); |
376 | let from_builtin = BUILTIN_SCOPE.get(name).copied().unwrap_or_else(PerNs::none); | 390 | let from_builtin = match self.block { |
391 | Some(_) => { | ||
392 | // Only resolve to builtins in the root `DefMap`. | ||
393 | PerNs::none() | ||
394 | } | ||
395 | None => BUILTIN_SCOPE.get(name).copied().unwrap_or_else(PerNs::none), | ||
396 | }; | ||
377 | let from_scope_or_builtin = match shadow { | 397 | let from_scope_or_builtin = match shadow { |
378 | BuiltinShadowMode::Module => from_scope.or(from_builtin), | 398 | BuiltinShadowMode::Module => from_scope.or(from_builtin), |
379 | BuiltinShadowMode::Other => { | 399 | BuiltinShadowMode::Other => { |
@@ -384,24 +404,31 @@ impl DefMap { | |||
384 | } | 404 | } |
385 | } | 405 | } |
386 | }; | 406 | }; |
387 | // Give precedence to names in outer `DefMap`s over the extern prelude; only check prelude | 407 | let from_extern_prelude = self |
388 | // from the crate DefMap. | 408 | .extern_prelude |
389 | let from_extern_prelude = match self.block { | 409 | .get(name) |
390 | Some(_) => PerNs::none(), | 410 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)); |
391 | None => self | ||
392 | .extern_prelude | ||
393 | .get(name) | ||
394 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)), | ||
395 | }; | ||
396 | 411 | ||
397 | let from_prelude = self.resolve_in_prelude(db, name); | 412 | let from_prelude = self.resolve_in_prelude(db, name); |
398 | 413 | ||
399 | from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude) | 414 | from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude) |
400 | } | 415 | } |
401 | 416 | ||
402 | fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> PerNs { | 417 | fn resolve_name_in_crate_root_or_extern_prelude( |
403 | let from_crate_root = self[self.root].scope.get(name); | 418 | &self, |
404 | let from_extern_prelude = self.resolve_name_in_extern_prelude(name); | 419 | db: &dyn DefDatabase, |
420 | name: &Name, | ||
421 | ) -> PerNs { | ||
422 | let arc; | ||
423 | let crate_def_map = match self.block { | ||
424 | Some(_) => { | ||
425 | arc = self.crate_root(db).def_map(db); | ||
426 | &arc | ||
427 | } | ||
428 | None => self, | ||
429 | }; | ||
430 | let from_crate_root = crate_def_map[crate_def_map.root].scope.get(name); | ||
431 | let from_extern_prelude = self.resolve_name_in_extern_prelude(db, name); | ||
405 | 432 | ||
406 | from_crate_root.or(from_extern_prelude) | 433 | from_crate_root.or(from_extern_prelude) |
407 | } | 434 | } |
diff --git a/crates/hir_def/src/nameres/tests/diagnostics.rs b/crates/hir_def/src/nameres/tests/diagnostics.rs index 1ac88fc89..543975e07 100644 --- a/crates/hir_def/src/nameres/tests/diagnostics.rs +++ b/crates/hir_def/src/nameres/tests/diagnostics.rs | |||
@@ -170,7 +170,7 @@ fn unresolved_legacy_scope_macro() { | |||
170 | 170 | ||
171 | m!(); | 171 | m!(); |
172 | m2!(); | 172 | m2!(); |
173 | //^^^^^^ unresolved macro call | 173 | //^^^^^^ unresolved macro `self::m2!` |
174 | "#, | 174 | "#, |
175 | ); | 175 | ); |
176 | } | 176 | } |
@@ -187,7 +187,7 @@ fn unresolved_module_scope_macro() { | |||
187 | 187 | ||
188 | self::m!(); | 188 | self::m!(); |
189 | self::m2!(); | 189 | self::m2!(); |
190 | //^^^^^^^^^^^^ unresolved macro call | 190 | //^^^^^^^^^^^^ unresolved macro `self::m2!` |
191 | "#, | 191 | "#, |
192 | ); | 192 | ); |
193 | } | 193 | } |