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