aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/nameres')
-rw-r--r--crates/hir_def/src/nameres/collector.rs80
-rw-r--r--crates/hir_def/src/nameres/path_resolution.rs59
-rw-r--r--crates/hir_def/src/nameres/tests/diagnostics.rs6
3 files changed, 90 insertions, 55 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 4ddc791ce..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};
18use hir_expand::{InFile, MacroCallLoc}; 18use hir_expand::{InFile, MacroCallLoc};
19use rustc_hash::{FxHashMap, FxHashSet}; 19use rustc_hash::{FxHashMap, FxHashSet};
@@ -215,8 +215,8 @@ struct MacroDirective {
215 215
216#[derive(Clone, Debug, Eq, PartialEq)] 216#[derive(Clone, Debug, Eq, PartialEq)]
217enum MacroDirectiveKind { 217enum MacroDirectiveKind {
218 FnLike { ast_id: AstIdWithPath<ast::MacroCall>, legacy: Option<MacroCallId> }, 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
222struct DefData<'a> { 222struct 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()
@@ -806,13 +807,7 @@ impl DefCollector<'_> {
806 let mut res = ReachedFixedPoint::Yes; 807 let mut res = ReachedFixedPoint::Yes;
807 macros.retain(|directive| { 808 macros.retain(|directive| {
808 match &directive.kind { 809 match &directive.kind {
809 MacroDirectiveKind::FnLike { ast_id, legacy } => { 810 MacroDirectiveKind::FnLike { ast_id } => {
810 if let Some(call_id) = legacy {
811 res = ReachedFixedPoint::No;
812 resolved.push((directive.module_id, *call_id, directive.depth));
813 return false;
814 }
815
816 match macro_call_as_call_id( 811 match macro_call_as_call_id(
817 ast_id, 812 ast_id,
818 self.db, 813 self.db,
@@ -834,19 +829,23 @@ impl DefCollector<'_> {
834 res = ReachedFixedPoint::No; 829 res = ReachedFixedPoint::No;
835 return false; 830 return false;
836 } 831 }
837 Err(UnresolvedMacro) | Ok(Err(_)) => {} 832 Err(UnresolvedMacro { .. }) | Ok(Err(_)) => {}
838 } 833 }
839 } 834 }
840 MacroDirectiveKind::Derive { ast_id } => { 835 MacroDirectiveKind::Derive { ast_id, derive_attr } => {
841 match derive_macro_as_call_id(ast_id, self.db, self.def_map.krate, |path| { 836 match derive_macro_as_call_id(
842 self.resolve_derive_macro(directive.module_id, &path) 837 ast_id,
843 }) { 838 *derive_attr,
839 self.db,
840 self.def_map.krate,
841 |path| self.resolve_derive_macro(directive.module_id, &path),
842 ) {
844 Ok(call_id) => { 843 Ok(call_id) => {
845 resolved.push((directive.module_id, call_id, 0)); 844 resolved.push((directive.module_id, call_id, directive.depth));
846 res = ReachedFixedPoint::No; 845 res = ReachedFixedPoint::No;
847 return false; 846 return false;
848 } 847 }
849 Err(UnresolvedMacro) => (), 848 Err(UnresolvedMacro { .. }) => (),
850 } 849 }
851 } 850 }
852 } 851 }
@@ -944,10 +943,11 @@ impl DefCollector<'_> {
944 &mut |_| (), 943 &mut |_| (),
945 ) { 944 ) {
946 Ok(_) => (), 945 Ok(_) => (),
947 Err(UnresolvedMacro) => { 946 Err(UnresolvedMacro { path }) => {
948 self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call( 947 self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
949 directive.module_id, 948 directive.module_id,
950 ast_id.ast_id, 949 ast_id.ast_id,
950 path,
951 )); 951 ));
952 } 952 }
953 }, 953 },
@@ -1169,19 +1169,27 @@ impl ModCollector<'_, '_> {
1169 } 1169 }
1170 ModItem::Const(id) => { 1170 ModItem::Const(id) => {
1171 let it = &self.item_tree[id]; 1171 let it = &self.item_tree[id];
1172 1172 let const_id = ConstLoc {
1173 if let Some(name) = &it.name { 1173 container: module.into(),
1174 def = Some(DefData { 1174 id: ItemTreeId::new(self.file_id, id),
1175 id: ConstLoc { 1175 }
1176 container: module.into(), 1176 .intern(self.def_collector.db);
1177 id: ItemTreeId::new(self.file_id, id), 1177
1178 } 1178 match &it.name {
1179 .intern(self.def_collector.db) 1179 Some(name) => {
1180 .into(), 1180 def = Some(DefData {
1181 name, 1181 id: const_id.into(),
1182 visibility: &self.item_tree[it.visibility], 1182 name,
1183 has_constructor: false, 1183 visibility: &self.item_tree[it.visibility],
1184 }); 1184 has_constructor: false,
1185 });
1186 }
1187 None => {
1188 // const _: T = ...;
1189 self.def_collector.def_map.modules[self.module_id]
1190 .scope
1191 .define_unnamed_const(const_id);
1192 }
1185 } 1193 }
1186 } 1194 }
1187 ModItem::Static(id) => { 1195 ModItem::Static(id) => {
@@ -1366,7 +1374,7 @@ impl ModCollector<'_, '_> {
1366 self.def_collector.unexpanded_macros.push(MacroDirective { 1374 self.def_collector.unexpanded_macros.push(MacroDirective {
1367 module_id: self.module_id, 1375 module_id: self.module_id,
1368 depth: self.macro_depth + 1, 1376 depth: self.macro_depth + 1,
1369 kind: MacroDirectiveKind::Derive { ast_id }, 1377 kind: MacroDirectiveKind::Derive { ast_id, derive_attr: derive.id },
1370 }); 1378 });
1371 } 1379 }
1372 } 1380 }
@@ -1518,12 +1526,12 @@ impl ModCollector<'_, '_> {
1518 // Built-in macro failed eager expansion. 1526 // Built-in macro failed eager expansion.
1519 self.def_collector.def_map.diagnostics.push(DefDiagnostic::macro_error( 1527 self.def_collector.def_map.diagnostics.push(DefDiagnostic::macro_error(
1520 self.module_id, 1528 self.module_id,
1521 MacroCallKind::FnLike(ast_id.ast_id), 1529 MacroCallKind::FnLike { ast_id: ast_id.ast_id },
1522 error.unwrap().to_string(), 1530 error.unwrap().to_string(),
1523 )); 1531 ));
1524 return; 1532 return;
1525 } 1533 }
1526 Err(UnresolvedMacro) => (), 1534 Err(UnresolvedMacro { .. }) => (),
1527 } 1535 }
1528 1536
1529 // Case 2: resolve in module scope, expand during name resolution. 1537 // Case 2: resolve in module scope, expand during name resolution.
@@ -1535,7 +1543,7 @@ impl ModCollector<'_, '_> {
1535 self.def_collector.unexpanded_macros.push(MacroDirective { 1543 self.def_collector.unexpanded_macros.push(MacroDirective {
1536 module_id: self.module_id, 1544 module_id: self.module_id,
1537 depth: self.macro_depth + 1, 1545 depth: self.macro_depth + 1,
1538 kind: MacroDirectiveKind::FnLike { ast_id, legacy: None }, 1546 kind: MacroDirectiveKind::FnLike { ast_id },
1539 }); 1547 });
1540 } 1548 }
1541 1549
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
62impl DefMap { 62impl 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 fefdadb22..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}
@@ -233,7 +233,7 @@ fn good_out_dir_diagnostic() {
233 macro_rules! concat { () => {} } 233 macro_rules! concat { () => {} }
234 234
235 include!(concat!(env!("OUT_DIR"), "/out.rs")); 235 include!(concat!(env!("OUT_DIR"), "/out.rs"));
236 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "load out dirs from check" to fix 236 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `OUT_DIR` not set, enable "run build scripts" to fix
237 "#, 237 "#,
238 ); 238 );
239} 239}