1use std::cell::Cell;
4use std::mem;
5
6use rustc_ast::NodeId;
7use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
8use rustc_data_structures::intern::Interned;
9use rustc_errors::codes::*;
10use rustc_errors::{Applicability, MultiSpan, pluralize, struct_span_code_err};
11use rustc_hir::def::{self, DefKind, PartialRes};
12use rustc_hir::def_id::DefId;
13use rustc_middle::metadata::{ModChild, Reexport};
14use rustc_middle::{span_bug, ty};
15use rustc_session::lint::BuiltinLintDiag;
16use rustc_session::lint::builtin::{
17 AMBIGUOUS_GLOB_REEXPORTS, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE,
18 REDUNDANT_IMPORTS, UNUSED_IMPORTS,
19};
20use rustc_session::parse::feature_err;
21use rustc_span::edit_distance::find_best_match_for_name;
22use rustc_span::hygiene::LocalExpnId;
23use rustc_span::{Ident, Span, Symbol, kw, sym};
24use smallvec::SmallVec;
25use tracing::debug;
26
27use crate::Determinacy::{self, *};
28use crate::Namespace::*;
29use crate::diagnostics::{DiagMode, Suggestion, import_candidates};
30use crate::errors::{
31 CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate,
32 CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates,
33 ConsiderAddingMacroExport, ConsiderMarkingAsPub,
34};
35use crate::{
36 AmbiguityError, AmbiguityKind, BindingKey, Finalize, ImportSuggestion, Module,
37 ModuleOrUniformRoot, NameBinding, NameBindingData, NameBindingKind, ParentScope, PathResult,
38 PerNS, ResolutionError, Resolver, ScopeSet, Segment, Used, module_to_string, names_to_string,
39};
40
41type Res = def::Res<NodeId>;
42
43#[derive(Clone)]
45pub(crate) enum ImportKind<'ra> {
46 Single {
47 source: Ident,
49 target: Ident,
52 source_bindings: PerNS<Cell<Result<NameBinding<'ra>, Determinacy>>>,
54 target_bindings: PerNS<Cell<Option<NameBinding<'ra>>>>,
56 type_ns_only: bool,
58 nested: bool,
60 id: NodeId,
72 },
73 Glob {
74 is_prelude: bool,
75 max_vis: Cell<Option<ty::Visibility>>,
78 id: NodeId,
79 },
80 ExternCrate {
81 source: Option<Symbol>,
82 target: Ident,
83 id: NodeId,
84 },
85 MacroUse {
86 warn_private: bool,
89 },
90 MacroExport,
91}
92
93impl<'ra> std::fmt::Debug for ImportKind<'ra> {
96 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 use ImportKind::*;
98 match self {
99 Single {
100 source,
101 target,
102 source_bindings,
103 target_bindings,
104 type_ns_only,
105 nested,
106 id,
107 } => f
108 .debug_struct("Single")
109 .field("source", source)
110 .field("target", target)
111 .field(
113 "source_bindings",
114 &source_bindings.clone().map(|b| b.into_inner().map(|_| format_args!(".."))),
115 )
116 .field(
117 "target_bindings",
118 &target_bindings.clone().map(|b| b.into_inner().map(|_| format_args!(".."))),
119 )
120 .field("type_ns_only", type_ns_only)
121 .field("nested", nested)
122 .field("id", id)
123 .finish(),
124 Glob { is_prelude, max_vis, id } => f
125 .debug_struct("Glob")
126 .field("is_prelude", is_prelude)
127 .field("max_vis", max_vis)
128 .field("id", id)
129 .finish(),
130 ExternCrate { source, target, id } => f
131 .debug_struct("ExternCrate")
132 .field("source", source)
133 .field("target", target)
134 .field("id", id)
135 .finish(),
136 MacroUse { warn_private } => {
137 f.debug_struct("MacroUse").field("warn_private", warn_private).finish()
138 }
139 MacroExport => f.debug_struct("MacroExport").finish(),
140 }
141 }
142}
143
144#[derive(Debug, Clone)]
146pub(crate) struct ImportData<'ra> {
147 pub kind: ImportKind<'ra>,
148
149 pub root_id: NodeId,
159
160 pub use_span: Span,
162
163 pub use_span_with_attributes: Span,
165
166 pub has_attributes: bool,
168
169 pub span: Span,
171
172 pub root_span: Span,
174
175 pub parent_scope: ParentScope<'ra>,
176 pub module_path: Vec<Segment>,
177 pub imported_module: Cell<Option<ModuleOrUniformRoot<'ra>>>,
186 pub vis: ty::Visibility,
187}
188
189pub(crate) type Import<'ra> = Interned<'ra, ImportData<'ra>>;
192
193impl std::hash::Hash for ImportData<'_> {
198 fn hash<H>(&self, _: &mut H)
199 where
200 H: std::hash::Hasher,
201 {
202 unreachable!()
203 }
204}
205
206impl<'ra> ImportData<'ra> {
207 pub(crate) fn is_glob(&self) -> bool {
208 matches!(self.kind, ImportKind::Glob { .. })
209 }
210
211 pub(crate) fn is_nested(&self) -> bool {
212 match self.kind {
213 ImportKind::Single { nested, .. } => nested,
214 _ => false,
215 }
216 }
217
218 pub(crate) fn id(&self) -> Option<NodeId> {
219 match self.kind {
220 ImportKind::Single { id, .. }
221 | ImportKind::Glob { id, .. }
222 | ImportKind::ExternCrate { id, .. } => Some(id),
223 ImportKind::MacroUse { .. } | ImportKind::MacroExport => None,
224 }
225 }
226
227 fn simplify(&self, r: &Resolver<'_, '_>) -> Reexport {
228 let to_def_id = |id| r.local_def_id(id).to_def_id();
229 match self.kind {
230 ImportKind::Single { id, .. } => Reexport::Single(to_def_id(id)),
231 ImportKind::Glob { id, .. } => Reexport::Glob(to_def_id(id)),
232 ImportKind::ExternCrate { id, .. } => Reexport::ExternCrate(to_def_id(id)),
233 ImportKind::MacroUse { .. } => Reexport::MacroUse,
234 ImportKind::MacroExport => Reexport::MacroExport,
235 }
236 }
237}
238
239#[derive(Clone, Default, Debug)]
241pub(crate) struct NameResolution<'ra> {
242 pub single_imports: FxIndexSet<Import<'ra>>,
245 pub binding: Option<NameBinding<'ra>>,
247 pub shadowed_glob: Option<NameBinding<'ra>>,
248}
249
250impl<'ra> NameResolution<'ra> {
251 pub(crate) fn binding(&self) -> Option<NameBinding<'ra>> {
253 self.binding.and_then(|binding| {
254 if !binding.is_glob_import() || self.single_imports.is_empty() {
255 Some(binding)
256 } else {
257 None
258 }
259 })
260 }
261}
262
263#[derive(Debug, Clone)]
266struct UnresolvedImportError {
267 span: Span,
268 label: Option<String>,
269 note: Option<String>,
270 suggestion: Option<Suggestion>,
271 candidates: Option<Vec<ImportSuggestion>>,
272 segment: Option<Symbol>,
273 module: Option<DefId>,
275}
276
277fn pub_use_of_private_extern_crate_hack(
280 import: Import<'_>,
281 binding: NameBinding<'_>,
282) -> Option<NodeId> {
283 match (&import.kind, &binding.kind) {
284 (ImportKind::Single { .. }, NameBindingKind::Import { import: binding_import, .. })
285 if let ImportKind::ExternCrate { id, .. } = binding_import.kind
286 && import.vis.is_public() =>
287 {
288 Some(id)
289 }
290 _ => None,
291 }
292}
293
294impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
295 pub(crate) fn import(
298 &self,
299 binding: NameBinding<'ra>,
300 import: Import<'ra>,
301 ) -> NameBinding<'ra> {
302 let import_vis = import.vis.to_def_id();
303 let vis = if binding.vis.is_at_least(import_vis, self.tcx)
304 || pub_use_of_private_extern_crate_hack(import, binding).is_some()
305 {
306 import_vis
307 } else {
308 binding.vis
309 };
310
311 if let ImportKind::Glob { ref max_vis, .. } = import.kind
312 && (vis == import_vis
313 || max_vis.get().is_none_or(|max_vis| vis.is_at_least(max_vis, self.tcx)))
314 {
315 max_vis.set(Some(vis.expect_local()))
316 }
317
318 self.arenas.alloc_name_binding(NameBindingData {
319 kind: NameBindingKind::Import { binding, import },
320 ambiguity: None,
321 warn_ambiguity: false,
322 span: import.span,
323 vis,
324 expansion: import.parent_scope.expansion,
325 })
326 }
327
328 pub(crate) fn try_define(
331 &mut self,
332 module: Module<'ra>,
333 key: BindingKey,
334 binding: NameBinding<'ra>,
335 warn_ambiguity: bool,
336 ) -> Result<(), NameBinding<'ra>> {
337 let res = binding.res();
338 self.check_reserved_macro_name(key.ident, res);
339 self.set_binding_parent_module(binding, module);
340 self.update_resolution(module, key, warn_ambiguity, |this, resolution| {
341 if let Some(old_binding) = resolution.binding {
342 if res == Res::Err && old_binding.res() != Res::Err {
343 return Ok(());
345 }
346 match (old_binding.is_glob_import(), binding.is_glob_import()) {
347 (true, true) => {
348 if !binding.is_ambiguity_recursive()
350 && let NameBindingKind::Import { import: old_import, .. } =
351 old_binding.kind
352 && let NameBindingKind::Import { import, .. } = binding.kind
353 && old_import == import
354 {
355 resolution.binding = Some(binding);
359 } else if res != old_binding.res() {
360 resolution.binding = Some(this.new_ambiguity_binding(
361 AmbiguityKind::GlobVsGlob,
362 old_binding,
363 binding,
364 warn_ambiguity,
365 ));
366 } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
367 resolution.binding = Some(binding);
369 } else if binding.is_ambiguity_recursive() {
370 resolution.binding = Some(this.new_warn_ambiguity_binding(binding));
371 }
372 }
373 (old_glob @ true, false) | (old_glob @ false, true) => {
374 let (glob_binding, nonglob_binding) =
375 if old_glob { (old_binding, binding) } else { (binding, old_binding) };
376 if key.ns == MacroNS
377 && nonglob_binding.expansion != LocalExpnId::ROOT
378 && glob_binding.res() != nonglob_binding.res()
379 {
380 resolution.binding = Some(this.new_ambiguity_binding(
381 AmbiguityKind::GlobVsExpanded,
382 nonglob_binding,
383 glob_binding,
384 false,
385 ));
386 } else {
387 resolution.binding = Some(nonglob_binding);
388 }
389
390 if let Some(old_shadowed_glob) = resolution.shadowed_glob {
391 assert!(old_shadowed_glob.is_glob_import());
392 if glob_binding.res() != old_shadowed_glob.res() {
393 resolution.shadowed_glob = Some(this.new_ambiguity_binding(
394 AmbiguityKind::GlobVsGlob,
395 old_shadowed_glob,
396 glob_binding,
397 false,
398 ));
399 } else if !old_shadowed_glob.vis.is_at_least(binding.vis, this.tcx) {
400 resolution.shadowed_glob = Some(glob_binding);
401 }
402 } else {
403 resolution.shadowed_glob = Some(glob_binding);
404 }
405 }
406 (false, false) => {
407 return Err(old_binding);
408 }
409 }
410 } else {
411 resolution.binding = Some(binding);
412 }
413
414 Ok(())
415 })
416 }
417
418 fn new_ambiguity_binding(
419 &self,
420 ambiguity_kind: AmbiguityKind,
421 primary_binding: NameBinding<'ra>,
422 secondary_binding: NameBinding<'ra>,
423 warn_ambiguity: bool,
424 ) -> NameBinding<'ra> {
425 let ambiguity = Some((secondary_binding, ambiguity_kind));
426 let data = NameBindingData { ambiguity, warn_ambiguity, ..*primary_binding };
427 self.arenas.alloc_name_binding(data)
428 }
429
430 fn new_warn_ambiguity_binding(&self, binding: NameBinding<'ra>) -> NameBinding<'ra> {
431 assert!(binding.is_ambiguity_recursive());
432 self.arenas.alloc_name_binding(NameBindingData { warn_ambiguity: true, ..*binding })
433 }
434
435 fn update_resolution<T, F>(
438 &mut self,
439 module: Module<'ra>,
440 key: BindingKey,
441 warn_ambiguity: bool,
442 f: F,
443 ) -> T
444 where
445 F: FnOnce(&mut Resolver<'ra, 'tcx>, &mut NameResolution<'ra>) -> T,
446 {
447 let (binding, t, warn_ambiguity) = {
450 let resolution = &mut *self.resolution(module, key).borrow_mut();
451 let old_binding = resolution.binding();
452
453 let t = f(self, resolution);
454
455 if let Some(binding) = resolution.binding()
456 && old_binding != Some(binding)
457 {
458 (binding, t, warn_ambiguity || old_binding.is_some())
459 } else {
460 return t;
461 }
462 };
463
464 let Ok(glob_importers) = module.glob_importers.try_borrow_mut() else {
465 return t;
466 };
467
468 for import in glob_importers.iter() {
470 let mut ident = key.ident;
471 let scope = match ident.span.reverse_glob_adjust(module.expansion, import.span) {
472 Some(Some(def)) => self.expn_def_scope(def),
473 Some(None) => import.parent_scope.module,
474 None => continue,
475 };
476 if self.is_accessible_from(binding.vis, scope) {
477 let imported_binding = self.import(binding, *import);
478 let key = BindingKey { ident, ..key };
479 let _ = self.try_define(
480 import.parent_scope.module,
481 key,
482 imported_binding,
483 warn_ambiguity,
484 );
485 }
486 }
487
488 t
489 }
490
491 fn import_dummy_binding(&mut self, import: Import<'ra>, is_indeterminate: bool) {
494 if let ImportKind::Single { target, ref target_bindings, .. } = import.kind {
495 if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().is_none()))
496 {
497 return; }
499 let dummy_binding = self.dummy_binding;
500 let dummy_binding = self.import(dummy_binding, import);
501 self.per_ns(|this, ns| {
502 let key = BindingKey::new(target, ns);
503 let _ = this.try_define(import.parent_scope.module, key, dummy_binding, false);
504 this.update_resolution(import.parent_scope.module, key, false, |_, resolution| {
505 resolution.single_imports.swap_remove(&import);
506 })
507 });
508 self.record_use(target, dummy_binding, Used::Other);
509 } else if import.imported_module.get().is_none() {
510 self.import_use_map.insert(import, Used::Other);
511 if let Some(id) = import.id() {
512 self.used_imports.insert(id);
513 }
514 }
515 }
516
517 pub(crate) fn resolve_imports(&mut self) {
528 let mut prev_indeterminate_count = usize::MAX;
529 let mut indeterminate_count = self.indeterminate_imports.len() * 3;
530 while indeterminate_count < prev_indeterminate_count {
531 prev_indeterminate_count = indeterminate_count;
532 indeterminate_count = 0;
533 for import in mem::take(&mut self.indeterminate_imports) {
534 let import_indeterminate_count = self.resolve_import(import);
535 indeterminate_count += import_indeterminate_count;
536 match import_indeterminate_count {
537 0 => self.determined_imports.push(import),
538 _ => self.indeterminate_imports.push(import),
539 }
540 }
541 }
542 }
543
544 pub(crate) fn finalize_imports(&mut self) {
545 for module in self.arenas.local_modules().iter() {
546 self.finalize_resolutions_in(*module);
547 }
548
549 let mut seen_spans = FxHashSet::default();
550 let mut errors = vec![];
551 let mut prev_root_id: NodeId = NodeId::ZERO;
552 let determined_imports = mem::take(&mut self.determined_imports);
553 let indeterminate_imports = mem::take(&mut self.indeterminate_imports);
554
555 let mut glob_error = false;
556 for (is_indeterminate, import) in determined_imports
557 .iter()
558 .map(|i| (false, i))
559 .chain(indeterminate_imports.iter().map(|i| (true, i)))
560 {
561 let unresolved_import_error = self.finalize_import(*import);
562 self.import_dummy_binding(*import, is_indeterminate);
565
566 let Some(err) = unresolved_import_error else { continue };
567
568 glob_error |= import.is_glob();
569
570 if let ImportKind::Single { source, ref source_bindings, .. } = import.kind
571 && source.name == kw::SelfLower
572 && let Err(Determined) = source_bindings.value_ns.get()
574 {
575 continue;
576 }
577
578 if prev_root_id != NodeId::ZERO && prev_root_id != import.root_id && !errors.is_empty()
579 {
580 self.throw_unresolved_import_error(errors, glob_error);
583 errors = vec![];
584 }
585 if seen_spans.insert(err.span) {
586 errors.push((*import, err));
587 prev_root_id = import.root_id;
588 }
589 }
590
591 if !errors.is_empty() {
592 self.throw_unresolved_import_error(errors, glob_error);
593 return;
594 }
595
596 for import in &indeterminate_imports {
597 let path = import_path_to_string(
598 &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
599 &import.kind,
600 import.span,
601 );
602 if path.contains("::") {
605 let err = UnresolvedImportError {
606 span: import.span,
607 label: None,
608 note: None,
609 suggestion: None,
610 candidates: None,
611 segment: None,
612 module: None,
613 };
614 errors.push((*import, err))
615 }
616 }
617
618 if !errors.is_empty() {
619 self.throw_unresolved_import_error(errors, glob_error);
620 }
621 }
622
623 pub(crate) fn check_hidden_glob_reexports(
624 &mut self,
625 exported_ambiguities: FxHashSet<NameBinding<'ra>>,
626 ) {
627 for module in self.arenas.local_modules().iter() {
628 for (key, resolution) in self.resolutions(*module).borrow().iter() {
629 let resolution = resolution.borrow();
630
631 let Some(binding) = resolution.binding else { continue };
632
633 if let NameBindingKind::Import { import, .. } = binding.kind
634 && let Some((amb_binding, _)) = binding.ambiguity
635 && binding.res() != Res::Err
636 && exported_ambiguities.contains(&binding)
637 {
638 self.lint_buffer.buffer_lint(
639 AMBIGUOUS_GLOB_REEXPORTS,
640 import.root_id,
641 import.root_span,
642 BuiltinLintDiag::AmbiguousGlobReexports {
643 name: key.ident.to_string(),
644 namespace: key.ns.descr().to_string(),
645 first_reexport_span: import.root_span,
646 duplicate_reexport_span: amb_binding.span,
647 },
648 );
649 }
650
651 if let Some(glob_binding) = resolution.shadowed_glob {
652 if binding.res() != Res::Err
653 && glob_binding.res() != Res::Err
654 && let NameBindingKind::Import { import: glob_import, .. } =
655 glob_binding.kind
656 && let Some(glob_import_id) = glob_import.id()
657 && let glob_import_def_id = self.local_def_id(glob_import_id)
658 && self.effective_visibilities.is_exported(glob_import_def_id)
659 && glob_binding.vis.is_public()
660 && !binding.vis.is_public()
661 {
662 let binding_id = match binding.kind {
663 NameBindingKind::Res(res) => {
664 Some(self.def_id_to_node_id(res.def_id().expect_local()))
665 }
666 NameBindingKind::Module(module) => {
667 Some(self.def_id_to_node_id(module.def_id().expect_local()))
668 }
669 NameBindingKind::Import { import, .. } => import.id(),
670 };
671 if let Some(binding_id) = binding_id {
672 self.lint_buffer.buffer_lint(
673 HIDDEN_GLOB_REEXPORTS,
674 binding_id,
675 binding.span,
676 BuiltinLintDiag::HiddenGlobReexports {
677 name: key.ident.name.to_string(),
678 namespace: key.ns.descr().to_owned(),
679 glob_reexport_span: glob_binding.span,
680 private_item_span: binding.span,
681 },
682 );
683 }
684 }
685 }
686 }
687 }
688 }
689
690 fn throw_unresolved_import_error(
691 &mut self,
692 mut errors: Vec<(Import<'_>, UnresolvedImportError)>,
693 glob_error: bool,
694 ) {
695 errors.retain(|(_import, err)| match err.module {
696 Some(def_id) if self.mods_with_parse_errors.contains(&def_id) => false,
698 _ => true,
699 });
700 errors.retain(|(_import, err)| {
701 err.segment != Some(kw::Underscore)
704 });
705
706 if errors.is_empty() {
707 self.tcx.dcx().delayed_bug("expected a parse or \"`_` can't be an identifier\" error");
708 return;
709 }
710
711 let span = MultiSpan::from_spans(errors.iter().map(|(_, err)| err.span).collect());
712
713 let paths = errors
714 .iter()
715 .map(|(import, err)| {
716 let path = import_path_to_string(
717 &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
718 &import.kind,
719 err.span,
720 );
721 format!("`{path}`")
722 })
723 .collect::<Vec<_>>();
724 let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),);
725
726 let mut diag = struct_span_code_err!(self.dcx(), span, E0432, "{msg}");
727
728 if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() {
729 diag.note(note.clone());
730 }
731
732 const MAX_LABEL_COUNT: usize = 10;
734
735 for (import, err) in errors.into_iter().take(MAX_LABEL_COUNT) {
736 if let Some(label) = err.label {
737 diag.span_label(err.span, label);
738 }
739
740 if let Some((suggestions, msg, applicability)) = err.suggestion {
741 if suggestions.is_empty() {
742 diag.help(msg);
743 continue;
744 }
745 diag.multipart_suggestion(msg, suggestions, applicability);
746 }
747
748 if let Some(candidates) = &err.candidates {
749 match &import.kind {
750 ImportKind::Single { nested: false, source, target, .. } => import_candidates(
751 self.tcx,
752 &mut diag,
753 Some(err.span),
754 candidates,
755 DiagMode::Import { append: false, unresolved_import: true },
756 (source != target)
757 .then(|| format!(" as {target}"))
758 .as_deref()
759 .unwrap_or(""),
760 ),
761 ImportKind::Single { nested: true, source, target, .. } => {
762 import_candidates(
763 self.tcx,
764 &mut diag,
765 None,
766 candidates,
767 DiagMode::Normal,
768 (source != target)
769 .then(|| format!(" as {target}"))
770 .as_deref()
771 .unwrap_or(""),
772 );
773 }
774 _ => {}
775 }
776 }
777
778 if matches!(import.kind, ImportKind::Single { .. })
779 && let Some(segment) = err.segment
780 && let Some(module) = err.module
781 {
782 self.find_cfg_stripped(&mut diag, &segment, module)
783 }
784 }
785
786 let guar = diag.emit();
787 if glob_error {
788 self.glob_error = Some(guar);
789 }
790 }
791
792 fn resolve_import(&mut self, import: Import<'ra>) -> usize {
799 debug!(
800 "(resolving import for module) resolving import `{}::...` in `{}`",
801 Segment::names_to_string(&import.module_path),
802 module_to_string(import.parent_scope.module).unwrap_or_else(|| "???".to_string()),
803 );
804 let module = if let Some(module) = import.imported_module.get() {
805 module
806 } else {
807 let path_res = self.maybe_resolve_path(
808 &import.module_path,
809 None,
810 &import.parent_scope,
811 Some(import),
812 );
813
814 match path_res {
815 PathResult::Module(module) => module,
816 PathResult::Indeterminate => return 3,
817 PathResult::NonModule(..) | PathResult::Failed { .. } => return 0,
818 }
819 };
820
821 import.imported_module.set(Some(module));
822 let (source, target, source_bindings, target_bindings, type_ns_only) = match import.kind {
823 ImportKind::Single {
824 source,
825 target,
826 ref source_bindings,
827 ref target_bindings,
828 type_ns_only,
829 ..
830 } => (source, target, source_bindings, target_bindings, type_ns_only),
831 ImportKind::Glob { .. } => {
832 self.resolve_glob_import(import);
833 return 0;
834 }
835 _ => unreachable!(),
836 };
837
838 let mut indeterminate_count = 0;
839 self.per_ns(|this, ns| {
840 if !type_ns_only || ns == TypeNS {
841 if let Err(Undetermined) = source_bindings[ns].get() {
842 let binding = this.maybe_resolve_ident_in_module(
843 module,
844 source,
845 ns,
846 &import.parent_scope,
847 Some(import),
848 );
849 source_bindings[ns].set(binding);
850 } else {
851 return;
852 };
853
854 let parent = import.parent_scope.module;
855 match source_bindings[ns].get() {
856 Ok(binding) => {
857 if binding.is_assoc_item()
858 && !this.tcx.features().import_trait_associated_functions()
859 {
860 feature_err(
861 this.tcx.sess,
862 sym::import_trait_associated_functions,
863 import.span,
864 "`use` associated items of traits is unstable",
865 )
866 .emit();
867 }
868
869 let imported_binding = this.import(binding, import);
870 target_bindings[ns].set(Some(imported_binding));
871 this.define(parent, target, ns, imported_binding);
872 }
873 Err(Determined) => {
874 if target.name != kw::Underscore {
876 let key = BindingKey::new(target, ns);
877 this.update_resolution(parent, key, false, |_, resolution| {
878 resolution.single_imports.swap_remove(&import);
879 });
880 }
881 }
882 Err(Undetermined) => indeterminate_count += 1,
883 }
884 }
885 });
886
887 indeterminate_count
888 }
889
890 fn finalize_import(&mut self, import: Import<'ra>) -> Option<UnresolvedImportError> {
895 let ignore_binding = match &import.kind {
896 ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(),
897 _ => None,
898 };
899 let ambiguity_errors_len =
900 |errors: &Vec<AmbiguityError<'_>>| errors.iter().filter(|error| !error.warning).count();
901 let prev_ambiguity_errors_len = ambiguity_errors_len(&self.ambiguity_errors);
902 let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span);
903
904 let privacy_errors_len = self.privacy_errors.len();
906
907 let path_res = self.resolve_path(
908 &import.module_path,
909 None,
910 &import.parent_scope,
911 Some(finalize),
912 ignore_binding,
913 Some(import),
914 );
915
916 let no_ambiguity =
917 ambiguity_errors_len(&self.ambiguity_errors) == prev_ambiguity_errors_len;
918
919 let module = match path_res {
920 PathResult::Module(module) => {
921 if let Some(initial_module) = import.imported_module.get() {
923 if module != initial_module && no_ambiguity {
924 span_bug!(import.span, "inconsistent resolution for an import");
925 }
926 } else if self.privacy_errors.is_empty() {
927 self.dcx()
928 .create_err(CannotDetermineImportResolution { span: import.span })
929 .emit();
930 }
931
932 module
933 }
934 PathResult::Failed {
935 is_error_from_last_segment: false,
936 span,
937 segment_name,
938 label,
939 suggestion,
940 module,
941 error_implied_by_parse_error: _,
942 } => {
943 if no_ambiguity {
944 assert!(import.imported_module.get().is_none());
945 self.report_error(
946 span,
947 ResolutionError::FailedToResolve {
948 segment: Some(segment_name),
949 label,
950 suggestion,
951 module,
952 },
953 );
954 }
955 return None;
956 }
957 PathResult::Failed {
958 is_error_from_last_segment: true,
959 span,
960 label,
961 suggestion,
962 module,
963 segment_name,
964 ..
965 } => {
966 if no_ambiguity {
967 assert!(import.imported_module.get().is_none());
968 let module = if let Some(ModuleOrUniformRoot::Module(m)) = module {
969 m.opt_def_id()
970 } else {
971 None
972 };
973 let err = match self
974 .make_path_suggestion(import.module_path.clone(), &import.parent_scope)
975 {
976 Some((suggestion, note)) => UnresolvedImportError {
977 span,
978 label: None,
979 note,
980 suggestion: Some((
981 vec![(span, Segment::names_to_string(&suggestion))],
982 String::from("a similar path exists"),
983 Applicability::MaybeIncorrect,
984 )),
985 candidates: None,
986 segment: Some(segment_name),
987 module,
988 },
989 None => UnresolvedImportError {
990 span,
991 label: Some(label),
992 note: None,
993 suggestion,
994 candidates: None,
995 segment: Some(segment_name),
996 module,
997 },
998 };
999 return Some(err);
1000 }
1001 return None;
1002 }
1003 PathResult::NonModule(partial_res) => {
1004 if no_ambiguity && partial_res.full_res() != Some(Res::Err) {
1005 assert!(import.imported_module.get().is_none());
1007 }
1008 return None;
1010 }
1011 PathResult::Indeterminate => unreachable!(),
1012 };
1013
1014 let (ident, target, source_bindings, target_bindings, type_ns_only, import_id) =
1015 match import.kind {
1016 ImportKind::Single {
1017 source,
1018 target,
1019 ref source_bindings,
1020 ref target_bindings,
1021 type_ns_only,
1022 id,
1023 ..
1024 } => (source, target, source_bindings, target_bindings, type_ns_only, id),
1025 ImportKind::Glob { is_prelude, ref max_vis, id } => {
1026 if import.module_path.len() <= 1 {
1027 let mut full_path = import.module_path.clone();
1030 full_path.push(Segment::from_ident(Ident::dummy()));
1031 self.lint_if_path_starts_with_module(Some(finalize), &full_path, None);
1032 }
1033
1034 if let ModuleOrUniformRoot::Module(module) = module
1035 && module == import.parent_scope.module
1036 {
1037 return Some(UnresolvedImportError {
1039 span: import.span,
1040 label: Some(String::from("cannot glob-import a module into itself")),
1041 note: None,
1042 suggestion: None,
1043 candidates: None,
1044 segment: None,
1045 module: None,
1046 });
1047 }
1048 if !is_prelude
1049 && let Some(max_vis) = max_vis.get()
1050 && !max_vis.is_at_least(import.vis, self.tcx)
1051 {
1052 let def_id = self.local_def_id(id);
1053 self.lint_buffer.buffer_lint(
1054 UNUSED_IMPORTS,
1055 id,
1056 import.span,
1057 BuiltinLintDiag::RedundantImportVisibility {
1058 max_vis: max_vis.to_string(def_id, self.tcx),
1059 import_vis: import.vis.to_string(def_id, self.tcx),
1060 span: import.span,
1061 },
1062 );
1063 }
1064 return None;
1065 }
1066 _ => unreachable!(),
1067 };
1068
1069 if self.privacy_errors.len() != privacy_errors_len {
1070 let mut path = import.module_path.clone();
1073 path.push(Segment::from_ident(ident));
1074 if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = self.resolve_path(
1075 &path,
1076 None,
1077 &import.parent_scope,
1078 Some(finalize),
1079 ignore_binding,
1080 None,
1081 ) {
1082 let res = module.res().map(|r| (r, ident));
1083 for error in &mut self.privacy_errors[privacy_errors_len..] {
1084 error.outermost_res = res;
1085 }
1086 }
1087 }
1088
1089 let mut all_ns_err = true;
1090 self.per_ns(|this, ns| {
1091 if !type_ns_only || ns == TypeNS {
1092 let binding = this.resolve_ident_in_module(
1093 module,
1094 ident,
1095 ns,
1096 &import.parent_scope,
1097 Some(Finalize { report_private: false, ..finalize }),
1098 target_bindings[ns].get(),
1099 Some(import),
1100 );
1101
1102 match binding {
1103 Ok(binding) => {
1104 let initial_res = source_bindings[ns].get().map(|initial_binding| {
1106 all_ns_err = false;
1107 if let Some(target_binding) = target_bindings[ns].get()
1108 && target.name == kw::Underscore
1109 && initial_binding.is_extern_crate()
1110 && !initial_binding.is_import()
1111 {
1112 let used = if import.module_path.is_empty() {
1113 Used::Scope
1114 } else {
1115 Used::Other
1116 };
1117 this.record_use(ident, target_binding, used);
1118 }
1119 initial_binding.res()
1120 });
1121 let res = binding.res();
1122 let has_ambiguity_error =
1123 this.ambiguity_errors.iter().any(|error| !error.warning);
1124 if res == Res::Err || has_ambiguity_error {
1125 this.dcx()
1126 .span_delayed_bug(import.span, "some error happened for an import");
1127 return;
1128 }
1129 if let Ok(initial_res) = initial_res {
1130 if res != initial_res {
1131 span_bug!(import.span, "inconsistent resolution for an import");
1132 }
1133 } else if this.privacy_errors.is_empty() {
1134 this.dcx()
1135 .create_err(CannotDetermineImportResolution { span: import.span })
1136 .emit();
1137 }
1138 }
1139 Err(..) => {
1140 }
1147 }
1148 }
1149 });
1150
1151 if all_ns_err {
1152 let mut all_ns_failed = true;
1153 self.per_ns(|this, ns| {
1154 if !type_ns_only || ns == TypeNS {
1155 let binding = this.resolve_ident_in_module(
1156 module,
1157 ident,
1158 ns,
1159 &import.parent_scope,
1160 Some(finalize),
1161 None,
1162 None,
1163 );
1164 if binding.is_ok() {
1165 all_ns_failed = false;
1166 }
1167 }
1168 });
1169
1170 return if all_ns_failed {
1171 let resolutions = match module {
1172 ModuleOrUniformRoot::Module(module) => Some(self.resolutions(module).borrow()),
1173 _ => None,
1174 };
1175 let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
1176 let names = resolutions
1177 .filter_map(|(BindingKey { ident: i, .. }, resolution)| {
1178 if i.name == ident.name {
1179 return None;
1180 } match *resolution.borrow() {
1182 NameResolution { binding: Some(name_binding), .. } => {
1183 match name_binding.kind {
1184 NameBindingKind::Import { binding, .. } => {
1185 match binding.kind {
1186 NameBindingKind::Res(Res::Err) => None,
1189 _ => Some(i.name),
1190 }
1191 }
1192 _ => Some(i.name),
1193 }
1194 }
1195 NameResolution { ref single_imports, .. }
1196 if single_imports.is_empty() =>
1197 {
1198 None
1199 }
1200 _ => Some(i.name),
1201 }
1202 })
1203 .collect::<Vec<Symbol>>();
1204
1205 let lev_suggestion =
1206 find_best_match_for_name(&names, ident.name, None).map(|suggestion| {
1207 (
1208 vec![(ident.span, suggestion.to_string())],
1209 String::from("a similar name exists in the module"),
1210 Applicability::MaybeIncorrect,
1211 )
1212 });
1213
1214 let (suggestion, note) =
1215 match self.check_for_module_export_macro(import, module, ident) {
1216 Some((suggestion, note)) => (suggestion.or(lev_suggestion), note),
1217 _ => (lev_suggestion, None),
1218 };
1219
1220 let label = match module {
1221 ModuleOrUniformRoot::Module(module) => {
1222 let module_str = module_to_string(module);
1223 if let Some(module_str) = module_str {
1224 format!("no `{ident}` in `{module_str}`")
1225 } else {
1226 format!("no `{ident}` in the root")
1227 }
1228 }
1229 _ => {
1230 if !ident.is_path_segment_keyword() {
1231 format!("no external crate `{ident}`")
1232 } else {
1233 format!("no `{ident}` in the root")
1236 }
1237 }
1238 };
1239
1240 let parent_suggestion =
1241 self.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true);
1242
1243 Some(UnresolvedImportError {
1244 span: import.span,
1245 label: Some(label),
1246 note,
1247 suggestion,
1248 candidates: if !parent_suggestion.is_empty() {
1249 Some(parent_suggestion)
1250 } else {
1251 None
1252 },
1253 module: import.imported_module.get().and_then(|module| {
1254 if let ModuleOrUniformRoot::Module(m) = module {
1255 m.opt_def_id()
1256 } else {
1257 None
1258 }
1259 }),
1260 segment: Some(ident.name),
1261 })
1262 } else {
1263 None
1265 };
1266 }
1267
1268 let mut reexport_error = None;
1269 let mut any_successful_reexport = false;
1270 let mut crate_private_reexport = false;
1271 self.per_ns(|this, ns| {
1272 let Ok(binding) = source_bindings[ns].get() else {
1273 return;
1274 };
1275
1276 if !binding.vis.is_at_least(import.vis, this.tcx) {
1277 reexport_error = Some((ns, binding));
1278 if let ty::Visibility::Restricted(binding_def_id) = binding.vis
1279 && binding_def_id.is_top_level_module()
1280 {
1281 crate_private_reexport = true;
1282 }
1283 } else {
1284 any_successful_reexport = true;
1285 }
1286 });
1287
1288 if !any_successful_reexport {
1290 let (ns, binding) = reexport_error.unwrap();
1291 if let Some(extern_crate_id) = pub_use_of_private_extern_crate_hack(import, binding) {
1292 self.lint_buffer.buffer_lint(
1293 PUB_USE_OF_PRIVATE_EXTERN_CRATE,
1294 import_id,
1295 import.span,
1296 BuiltinLintDiag::PrivateExternCrateReexport {
1297 source: ident,
1298 extern_crate_span: self.tcx.source_span(self.local_def_id(extern_crate_id)),
1299 },
1300 );
1301 } else if ns == TypeNS {
1302 let err = if crate_private_reexport {
1303 self.dcx()
1304 .create_err(CannotBeReexportedCratePublicNS { span: import.span, ident })
1305 } else {
1306 self.dcx().create_err(CannotBeReexportedPrivateNS { span: import.span, ident })
1307 };
1308 err.emit();
1309 } else {
1310 let mut err = if crate_private_reexport {
1311 self.dcx()
1312 .create_err(CannotBeReexportedCratePublic { span: import.span, ident })
1313 } else {
1314 self.dcx().create_err(CannotBeReexportedPrivate { span: import.span, ident })
1315 };
1316
1317 match binding.kind {
1318 NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id))
1319 if self.get_macro_by_def_id(def_id).macro_rules =>
1321 {
1322 err.subdiagnostic( ConsiderAddingMacroExport {
1323 span: binding.span,
1324 });
1325 }
1326 _ => {
1327 err.subdiagnostic( ConsiderMarkingAsPub {
1328 span: import.span,
1329 ident,
1330 });
1331 }
1332 }
1333 err.emit();
1334 }
1335 }
1336
1337 if import.module_path.len() <= 1 {
1338 let mut full_path = import.module_path.clone();
1341 full_path.push(Segment::from_ident(ident));
1342 self.per_ns(|this, ns| {
1343 if let Ok(binding) = source_bindings[ns].get() {
1344 this.lint_if_path_starts_with_module(Some(finalize), &full_path, Some(binding));
1345 }
1346 });
1347 }
1348
1349 self.per_ns(|this, ns| {
1353 if let Ok(binding) = source_bindings[ns].get() {
1354 this.import_res_map.entry(import_id).or_default()[ns] = Some(binding.res());
1355 }
1356 });
1357
1358 debug!("(resolving single import) successfully resolved import");
1359 None
1360 }
1361
1362 pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'ra>) -> bool {
1363 let ImportKind::Single {
1365 source, target, ref source_bindings, ref target_bindings, id, ..
1366 } = import.kind
1367 else {
1368 unreachable!()
1369 };
1370
1371 if source != target {
1373 return false;
1374 }
1375
1376 if import.parent_scope.expansion != LocalExpnId::ROOT {
1378 return false;
1379 }
1380
1381 if self.import_use_map.get(&import) == Some(&Used::Other)
1386 || self.effective_visibilities.is_exported(self.local_def_id(id))
1387 {
1388 return false;
1389 }
1390
1391 let mut is_redundant = true;
1392 let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None };
1393 self.per_ns(|this, ns| {
1394 if is_redundant && let Ok(binding) = source_bindings[ns].get() {
1395 if binding.res() == Res::Err {
1396 return;
1397 }
1398
1399 match this.early_resolve_ident_in_lexical_scope(
1400 target,
1401 ScopeSet::All(ns),
1402 &import.parent_scope,
1403 None,
1404 false,
1405 target_bindings[ns].get(),
1406 None,
1407 ) {
1408 Ok(other_binding) => {
1409 is_redundant = binding.res() == other_binding.res()
1410 && !other_binding.is_ambiguity_recursive();
1411 if is_redundant {
1412 redundant_span[ns] =
1413 Some((other_binding.span, other_binding.is_import()));
1414 }
1415 }
1416 Err(_) => is_redundant = false,
1417 }
1418 }
1419 });
1420
1421 if is_redundant && !redundant_span.is_empty() {
1422 let mut redundant_spans: Vec<_> = redundant_span.present_items().collect();
1423 redundant_spans.sort();
1424 redundant_spans.dedup();
1425 self.lint_buffer.buffer_lint(
1426 REDUNDANT_IMPORTS,
1427 id,
1428 import.span,
1429 BuiltinLintDiag::RedundantImport(redundant_spans, source),
1430 );
1431 return true;
1432 }
1433
1434 false
1435 }
1436
1437 fn resolve_glob_import(&mut self, import: Import<'ra>) {
1438 let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() };
1440
1441 let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else {
1442 self.dcx().emit_err(CannotGlobImportAllCrates { span: import.span });
1443 return;
1444 };
1445
1446 if module.is_trait() && !self.tcx.features().import_trait_associated_functions() {
1447 feature_err(
1448 self.tcx.sess,
1449 sym::import_trait_associated_functions,
1450 import.span,
1451 "`use` associated items of traits is unstable",
1452 )
1453 .emit();
1454 }
1455
1456 if module == import.parent_scope.module {
1457 return;
1458 } else if is_prelude {
1459 self.prelude = Some(module);
1460 return;
1461 }
1462
1463 module.glob_importers.borrow_mut().push(import);
1465
1466 let bindings = self
1469 .resolutions(module)
1470 .borrow()
1471 .iter()
1472 .filter_map(|(key, resolution)| {
1473 resolution.borrow().binding().map(|binding| (*key, binding))
1474 })
1475 .collect::<Vec<_>>();
1476 for (mut key, binding) in bindings {
1477 let scope = match key.ident.span.reverse_glob_adjust(module.expansion, import.span) {
1478 Some(Some(def)) => self.expn_def_scope(def),
1479 Some(None) => import.parent_scope.module,
1480 None => continue,
1481 };
1482 if self.is_accessible_from(binding.vis, scope) {
1483 let imported_binding = self.import(binding, import);
1484 let warn_ambiguity = self
1485 .resolution(import.parent_scope.module, key)
1486 .borrow()
1487 .binding()
1488 .is_some_and(|binding| binding.warn_ambiguity_recursive());
1489 let _ = self.try_define(
1490 import.parent_scope.module,
1491 key,
1492 imported_binding,
1493 warn_ambiguity,
1494 );
1495 }
1496 }
1497
1498 self.record_partial_res(id, PartialRes::new(module.res().unwrap()));
1500 }
1501
1502 fn finalize_resolutions_in(&mut self, module: Module<'ra>) {
1505 *module.globs.borrow_mut() = Vec::new();
1507
1508 let Some(def_id) = module.opt_def_id() else { return };
1509
1510 let mut children = Vec::new();
1511
1512 module.for_each_child(self, |this, ident, _, binding| {
1513 let res = binding.res().expect_non_local();
1514 let error_ambiguity = binding.is_ambiguity_recursive() && !binding.warn_ambiguity;
1515 if res != def::Res::Err && !error_ambiguity {
1516 let mut reexport_chain = SmallVec::new();
1517 let mut next_binding = binding;
1518 while let NameBindingKind::Import { binding, import, .. } = next_binding.kind {
1519 reexport_chain.push(import.simplify(this));
1520 next_binding = binding;
1521 }
1522
1523 children.push(ModChild { ident, res, vis: binding.vis, reexport_chain });
1524 }
1525 });
1526
1527 if !children.is_empty() {
1528 self.module_children.insert(def_id.expect_local(), children);
1530 }
1531 }
1532}
1533
1534fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Span) -> String {
1535 let pos = names.iter().position(|p| span == p.span && p.name != kw::PathRoot);
1536 let global = !names.is_empty() && names[0].name == kw::PathRoot;
1537 if let Some(pos) = pos {
1538 let names = if global { &names[1..pos + 1] } else { &names[..pos + 1] };
1539 names_to_string(names.iter().map(|ident| ident.name))
1540 } else {
1541 let names = if global { &names[1..] } else { names };
1542 if names.is_empty() {
1543 import_kind_to_string(import_kind)
1544 } else {
1545 format!(
1546 "{}::{}",
1547 names_to_string(names.iter().map(|ident| ident.name)),
1548 import_kind_to_string(import_kind),
1549 )
1550 }
1551 }
1552}
1553
1554fn import_kind_to_string(import_kind: &ImportKind<'_>) -> String {
1555 match import_kind {
1556 ImportKind::Single { source, .. } => source.to_string(),
1557 ImportKind::Glob { .. } => "*".to_string(),
1558 ImportKind::ExternCrate { .. } => "<extern crate>".to_string(),
1559 ImportKind::MacroUse { .. } => "#[macro_use]".to_string(),
1560 ImportKind::MacroExport => "#[macro_export]".to_string(),
1561 }
1562}