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