diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-07-22 13:17:51 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-07-22 13:17:51 +0100 |
commit | dba534a103dc9fb374bc313ac96d54d331cbd54a (patch) | |
tree | e6be02ef8733e33ae9a9a316e2769dd6ccbab793 /crates/ra_hir_def/src/nameres/collector.rs | |
parent | 2dd8ba2b21e3262f25e4245e37549206c8a3bc2d (diff) | |
parent | dce99874368e3e42402b4443c5eb39495c8c162a (diff) |
Merge #5475
5475: Support `Trait as _` imports r=matklad a=jonas-schievink
Fixes https://github.com/rust-analyzer/rust-analyzer/issues/2736
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/ra_hir_def/src/nameres/collector.rs')
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 72 |
1 files changed, 54 insertions, 18 deletions
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index d85a86c0a..a030cab47 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -310,7 +310,7 @@ impl DefCollector<'_> { | |||
310 | if export { | 310 | if export { |
311 | self.update( | 311 | self.update( |
312 | self.def_map.root, | 312 | self.def_map.root, |
313 | &[(name, PerNs::macros(macro_, Visibility::Public))], | 313 | &[(Some(name), PerNs::macros(macro_, Visibility::Public))], |
314 | Visibility::Public, | 314 | Visibility::Public, |
315 | ImportType::Named, | 315 | ImportType::Named, |
316 | ); | 316 | ); |
@@ -336,7 +336,7 @@ impl DefCollector<'_> { | |||
336 | fn define_proc_macro(&mut self, name: Name, macro_: MacroDefId) { | 336 | fn define_proc_macro(&mut self, name: Name, macro_: MacroDefId) { |
337 | self.update( | 337 | self.update( |
338 | self.def_map.root, | 338 | self.def_map.root, |
339 | &[(name, PerNs::macros(macro_, Visibility::Public))], | 339 | &[(Some(name), PerNs::macros(macro_, Visibility::Public))], |
340 | Visibility::Public, | 340 | Visibility::Public, |
341 | ImportType::Named, | 341 | ImportType::Named, |
342 | ); | 342 | ); |
@@ -534,7 +534,7 @@ impl DefCollector<'_> { | |||
534 | let name = variant_data.name.clone(); | 534 | let name = variant_data.name.clone(); |
535 | let variant = EnumVariantId { parent: e, local_id }; | 535 | let variant = EnumVariantId { parent: e, local_id }; |
536 | let res = PerNs::both(variant.into(), variant.into(), vis); | 536 | let res = PerNs::both(variant.into(), variant.into(), vis); |
537 | (name, res) | 537 | (Some(name), res) |
538 | }) | 538 | }) |
539 | .collect::<Vec<_>>(); | 539 | .collect::<Vec<_>>(); |
540 | self.update(module_id, &resolutions, vis, ImportType::Glob); | 540 | self.update(module_id, &resolutions, vis, ImportType::Glob); |
@@ -550,15 +550,15 @@ impl DefCollector<'_> { | |||
550 | match import.path.segments.last() { | 550 | match import.path.segments.last() { |
551 | Some(last_segment) => { | 551 | Some(last_segment) => { |
552 | let name = match &import.alias { | 552 | let name = match &import.alias { |
553 | Some(ImportAlias::Alias(name)) => name.clone(), | 553 | Some(ImportAlias::Alias(name)) => Some(name.clone()), |
554 | Some(ImportAlias::Underscore) => last_segment.clone(), // FIXME rust-analyzer#2736 | 554 | Some(ImportAlias::Underscore) => None, |
555 | None => last_segment.clone(), | 555 | None => Some(last_segment.clone()), |
556 | }; | 556 | }; |
557 | log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); | 557 | log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); |
558 | 558 | ||
559 | // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 | 559 | // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 |
560 | if import.is_extern_crate && module_id == self.def_map.root { | 560 | if import.is_extern_crate && module_id == self.def_map.root { |
561 | if let Some(def) = def.take_types() { | 561 | if let (Some(def), Some(name)) = (def.take_types(), name.as_ref()) { |
562 | self.def_map.extern_prelude.insert(name.clone(), def); | 562 | self.def_map.extern_prelude.insert(name.clone(), def); |
563 | } | 563 | } |
564 | } | 564 | } |
@@ -573,7 +573,7 @@ impl DefCollector<'_> { | |||
573 | fn update( | 573 | fn update( |
574 | &mut self, | 574 | &mut self, |
575 | module_id: LocalModuleId, | 575 | module_id: LocalModuleId, |
576 | resolutions: &[(Name, PerNs)], | 576 | resolutions: &[(Option<Name>, PerNs)], |
577 | vis: Visibility, | 577 | vis: Visibility, |
578 | import_type: ImportType, | 578 | import_type: ImportType, |
579 | ) { | 579 | ) { |
@@ -584,7 +584,7 @@ impl DefCollector<'_> { | |||
584 | fn update_recursive( | 584 | fn update_recursive( |
585 | &mut self, | 585 | &mut self, |
586 | module_id: LocalModuleId, | 586 | module_id: LocalModuleId, |
587 | resolutions: &[(Name, PerNs)], | 587 | resolutions: &[(Option<Name>, PerNs)], |
588 | // All resolutions are imported with this visibility; the visibilies in | 588 | // All resolutions are imported with this visibility; the visibilies in |
589 | // the `PerNs` values are ignored and overwritten | 589 | // the `PerNs` values are ignored and overwritten |
590 | vis: Visibility, | 590 | vis: Visibility, |
@@ -595,15 +595,51 @@ impl DefCollector<'_> { | |||
595 | // prevent stack overflows (but this shouldn't be possible) | 595 | // prevent stack overflows (but this shouldn't be possible) |
596 | panic!("infinite recursion in glob imports!"); | 596 | panic!("infinite recursion in glob imports!"); |
597 | } | 597 | } |
598 | let scope = &mut self.def_map.modules[module_id].scope; | ||
599 | let mut changed = false; | 598 | let mut changed = false; |
599 | |||
600 | for (name, res) in resolutions { | 600 | for (name, res) in resolutions { |
601 | changed |= scope.push_res_with_import( | 601 | match name { |
602 | &mut self.from_glob_import, | 602 | Some(name) => { |
603 | (module_id, name.clone()), | 603 | let scope = &mut self.def_map.modules[module_id].scope; |
604 | res.with_visibility(vis), | 604 | changed |= scope.push_res_with_import( |
605 | import_type, | 605 | &mut self.from_glob_import, |
606 | ); | 606 | (module_id, name.clone()), |
607 | res.with_visibility(vis), | ||
608 | import_type, | ||
609 | ); | ||
610 | } | ||
611 | None => { | ||
612 | let tr = match res.take_types() { | ||
613 | Some(ModuleDefId::TraitId(tr)) => tr, | ||
614 | Some(other) => { | ||
615 | log::debug!("non-trait `_` import of {:?}", other); | ||
616 | continue; | ||
617 | } | ||
618 | None => continue, | ||
619 | }; | ||
620 | let old_vis = self.def_map.modules[module_id].scope.unnamed_trait_vis(tr); | ||
621 | let should_update = match old_vis { | ||
622 | None => true, | ||
623 | Some(old_vis) => { | ||
624 | let max_vis = old_vis.max(vis, &self.def_map).unwrap_or_else(|| { | ||
625 | panic!("`Tr as _` imports with unrelated visibilities {:?} and {:?} (trait {:?})", old_vis, vis, tr); | ||
626 | }); | ||
627 | |||
628 | if max_vis == old_vis { | ||
629 | false | ||
630 | } else { | ||
631 | mark::hit!(upgrade_underscore_visibility); | ||
632 | true | ||
633 | } | ||
634 | } | ||
635 | }; | ||
636 | |||
637 | if should_update { | ||
638 | changed = true; | ||
639 | self.def_map.modules[module_id].scope.push_unnamed_trait(tr, vis); | ||
640 | } | ||
641 | } | ||
642 | } | ||
607 | } | 643 | } |
608 | 644 | ||
609 | if !changed { | 645 | if !changed { |
@@ -950,7 +986,7 @@ impl ModCollector<'_, '_> { | |||
950 | .unwrap_or(Visibility::Public); | 986 | .unwrap_or(Visibility::Public); |
951 | self.def_collector.update( | 987 | self.def_collector.update( |
952 | self.module_id, | 988 | self.module_id, |
953 | &[(name.clone(), PerNs::from_def(id, vis, has_constructor))], | 989 | &[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))], |
954 | vis, | 990 | vis, |
955 | ImportType::Named, | 991 | ImportType::Named, |
956 | ) | 992 | ) |
@@ -1057,7 +1093,7 @@ impl ModCollector<'_, '_> { | |||
1057 | self.def_collector.def_map.modules[self.module_id].scope.define_def(def); | 1093 | self.def_collector.def_map.modules[self.module_id].scope.define_def(def); |
1058 | self.def_collector.update( | 1094 | self.def_collector.update( |
1059 | self.module_id, | 1095 | self.module_id, |
1060 | &[(name, PerNs::from_def(def, vis, false))], | 1096 | &[(Some(name), PerNs::from_def(def, vis, false))], |
1061 | vis, | 1097 | vis, |
1062 | ImportType::Named, | 1098 | ImportType::Named, |
1063 | ); | 1099 | ); |