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