1use std::mem;
4
5use rustc_ast::NodeId;
6use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
7use rustc_data_structures::intern::Interned;
8use rustc_errors::codes::*;
9use rustc_errors::{Applicability, MultiSpan, pluralize, struct_span_code_err};
10use rustc_hir::def::{self, DefKind, PartialRes};
11use rustc_hir::def_id::{DefId, LocalDefIdMap};
12use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport};
13use rustc_middle::span_bug;
14use rustc_middle::ty::Visibility;
15use rustc_session::lint::BuiltinLintDiag;
16use rustc_session::lint::builtin::{
17 AMBIGUOUS_GLOB_REEXPORTS, EXPORTED_PRIVATE_DEPENDENCIES, HIDDEN_GLOB_REEXPORTS,
18 PUB_USE_OF_PRIVATE_EXTERN_CRATE, 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, Macros20NormalizedIdent, Span, Symbol, kw, sym};
24use tracing::debug;
25
26use crate::Namespace::{self, *};
27use crate::diagnostics::{DiagMode, Suggestion, import_candidates};
28use crate::errors::{
29 CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate,
30 CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates,
31 ConsiderAddingMacroExport, ConsiderMarkingAsPub, ConsiderMarkingAsPubCrate,
32};
33use crate::ref_mut::CmCell;
34use crate::{
35 AmbiguityError, BindingKey, CmResolver, Decl, DeclData, DeclKind, Determinacy, Finalize,
36 ImportSuggestion, Module, ModuleOrUniformRoot, ParentScope, PathResult, PerNS, ResolutionError,
37 Resolver, ScopeSet, Segment, Used, module_to_string, names_to_string,
38};
39
40type Res = def::Res<NodeId>;
41
42#[derive(Clone, Copy, Default, PartialEq)]
45pub(crate) enum PendingDecl<'ra> {
46 Ready(Option<Decl<'ra>>),
47 #[default]
48 Pending,
49}
50
51impl<'ra> PendingDecl<'ra> {
52 pub(crate) fn decl(self) -> Option<Decl<'ra>> {
53 match self {
54 PendingDecl::Ready(decl) => decl,
55 PendingDecl::Pending => None,
56 }
57 }
58}
59
60#[derive(Clone)]
62pub(crate) enum ImportKind<'ra> {
63 Single {
64 source: Ident,
66 target: Ident,
69 decls: PerNS<CmCell<PendingDecl<'ra>>>,
71 type_ns_only: bool,
73 nested: bool,
75 id: NodeId,
87 },
88 Glob {
89 max_vis: CmCell<Option<Visibility>>,
92 id: NodeId,
93 },
94 ExternCrate {
95 source: Option<Symbol>,
96 target: Ident,
97 id: NodeId,
98 },
99 MacroUse {
100 warn_private: bool,
103 },
104 MacroExport,
105}
106
107impl<'ra> std::fmt::Debug for ImportKind<'ra> {
110 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
111 use ImportKind::*;
112 match self {
113 Single { source, target, decls, type_ns_only, nested, id, .. } => f
114 .debug_struct("Single")
115 .field("source", source)
116 .field("target", target)
117 .field(
119 "decls",
120 &decls.clone().map(|b| b.into_inner().decl().map(|_| format_args!(".."))),
121 )
122 .field("type_ns_only", type_ns_only)
123 .field("nested", nested)
124 .field("id", id)
125 .finish(),
126 Glob { max_vis, id } => {
127 f.debug_struct("Glob").field("max_vis", max_vis).field("id", id).finish()
128 }
129 ExternCrate { source, target, id } => f
130 .debug_struct("ExternCrate")
131 .field("source", source)
132 .field("target", target)
133 .field("id", id)
134 .finish(),
135 MacroUse { warn_private } => {
136 f.debug_struct("MacroUse").field("warn_private", warn_private).finish()
137 }
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: CmCell<Option<ModuleOrUniformRoot<'ra>>>,
185 pub vis: Visibility,
186
187 pub vis_span: Span,
189}
190
191pub(crate) type Import<'ra> = Interned<'ra, ImportData<'ra>>;
194
195impl std::hash::Hash for ImportData<'_> {
200 fn hash<H>(&self, _: &mut H)
201 where
202 H: std::hash::Hasher,
203 {
204 unreachable!()
205 }
206}
207
208impl<'ra> ImportData<'ra> {
209 pub(crate) fn is_glob(&self) -> bool {
210 matches!(self.kind, ImportKind::Glob { .. })
211 }
212
213 pub(crate) fn is_nested(&self) -> bool {
214 match self.kind {
215 ImportKind::Single { nested, .. } => nested,
216 _ => false,
217 }
218 }
219
220 pub(crate) fn id(&self) -> Option<NodeId> {
221 match self.kind {
222 ImportKind::Single { id, .. }
223 | ImportKind::Glob { id, .. }
224 | ImportKind::ExternCrate { id, .. } => Some(id),
225 ImportKind::MacroUse { .. } | ImportKind::MacroExport => None,
226 }
227 }
228
229 pub(crate) fn simplify(&self, r: &Resolver<'_, '_>) -> Reexport {
230 let to_def_id = |id| r.local_def_id(id).to_def_id();
231 match self.kind {
232 ImportKind::Single { id, .. } => Reexport::Single(to_def_id(id)),
233 ImportKind::Glob { id, .. } => Reexport::Glob(to_def_id(id)),
234 ImportKind::ExternCrate { id, .. } => Reexport::ExternCrate(to_def_id(id)),
235 ImportKind::MacroUse { .. } => Reexport::MacroUse,
236 ImportKind::MacroExport => Reexport::MacroExport,
237 }
238 }
239}
240
241#[derive(Clone, Default, Debug)]
243pub(crate) struct NameResolution<'ra> {
244 pub single_imports: FxIndexSet<Import<'ra>>,
247 pub non_glob_decl: Option<Decl<'ra>>,
249 pub glob_decl: Option<Decl<'ra>>,
251}
252
253impl<'ra> NameResolution<'ra> {
254 pub(crate) fn binding(&self) -> Option<Decl<'ra>> {
256 self.best_decl().and_then(|binding| {
257 if !binding.is_glob_import() || self.single_imports.is_empty() {
258 Some(binding)
259 } else {
260 None
261 }
262 })
263 }
264
265 pub(crate) fn best_decl(&self) -> Option<Decl<'ra>> {
266 self.non_glob_decl.or(self.glob_decl)
267 }
268}
269
270#[derive(Debug, Clone)]
273struct UnresolvedImportError {
274 span: Span,
275 label: Option<String>,
276 note: Option<String>,
277 suggestion: Option<Suggestion>,
278 candidates: Option<Vec<ImportSuggestion>>,
279 segment: Option<Symbol>,
280 module: Option<DefId>,
282}
283
284fn pub_use_of_private_extern_crate_hack(import: Import<'_>, decl: Decl<'_>) -> Option<NodeId> {
287 match (&import.kind, &decl.kind) {
288 (ImportKind::Single { .. }, DeclKind::Import { import: decl_import, .. })
289 if let ImportKind::ExternCrate { id, .. } = decl_import.kind
290 && import.vis.is_public() =>
291 {
292 Some(id)
293 }
294 _ => None,
295 }
296}
297
298fn remove_same_import<'ra>(d1: Decl<'ra>, d2: Decl<'ra>) -> (Decl<'ra>, Decl<'ra>) {
300 if let DeclKind::Import { import: import1, source_decl: d1_next } = d1.kind
301 && let DeclKind::Import { import: import2, source_decl: d2_next } = d2.kind
302 && import1 == import2
303 && d1.warn_ambiguity.get() == d2.warn_ambiguity.get()
304 {
305 assert_eq!(d1.ambiguity.get(), d2.ambiguity.get());
306 assert!(!d1.warn_ambiguity.get());
307 assert_eq!(d1.expansion, d2.expansion);
308 assert_eq!(d1.span, d2.span);
309 assert_eq!(d1.vis(), d2.vis());
310 remove_same_import(d1_next, d2_next)
311 } else {
312 (d1, d2)
313 }
314}
315
316impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
317 pub(crate) fn new_import_decl(&self, decl: Decl<'ra>, import: Import<'ra>) -> Decl<'ra> {
320 let import_vis = import.vis.to_def_id();
321 let vis = if decl.vis().is_at_least(import_vis, self.tcx)
322 || pub_use_of_private_extern_crate_hack(import, decl).is_some()
323 {
324 import_vis
325 } else {
326 decl.vis()
327 };
328
329 if let ImportKind::Glob { ref max_vis, .. } = import.kind
330 && (vis == import_vis
331 || max_vis.get().is_none_or(|max_vis| vis.is_at_least(max_vis, self.tcx)))
332 {
333 max_vis.set_unchecked(Some(vis.expect_local()))
334 }
335
336 self.arenas.alloc_decl(DeclData {
337 kind: DeclKind::Import { source_decl: decl, import },
338 ambiguity: CmCell::new(None),
339 warn_ambiguity: CmCell::new(false),
340 span: import.span,
341 vis: CmCell::new(vis),
342 expansion: import.parent_scope.expansion,
343 })
344 }
345
346 fn select_glob_decl(
349 &self,
350 glob_decl: Decl<'ra>,
351 old_glob_decl: Decl<'ra>,
352 warn_ambiguity: bool,
353 ) -> Decl<'ra> {
354 assert!(glob_decl.is_glob_import());
355 assert!(old_glob_decl.is_glob_import());
356 assert_ne!(glob_decl, old_glob_decl);
357 let (deep_decl, old_deep_decl) = remove_same_import(glob_decl, old_glob_decl);
372 if deep_decl != glob_decl {
373 assert_ne!(old_deep_decl, old_glob_decl);
375 assert!(!deep_decl.is_glob_import());
379 if glob_decl.is_ambiguity_recursive() {
380 glob_decl.warn_ambiguity.set_unchecked(true);
381 }
382 glob_decl
383 } else if glob_decl.res() != old_glob_decl.res() {
384 old_glob_decl.ambiguity.set_unchecked(Some(glob_decl));
385 old_glob_decl.warn_ambiguity.set_unchecked(warn_ambiguity);
386 if warn_ambiguity {
387 old_glob_decl
388 } else {
389 self.arenas.alloc_decl((*old_glob_decl).clone())
393 }
394 } else if !old_glob_decl.vis().is_at_least(glob_decl.vis(), self.tcx) {
395 old_glob_decl.vis.set_unchecked(glob_decl.vis());
397 old_glob_decl
398 } else if glob_decl.is_ambiguity_recursive() && !old_glob_decl.is_ambiguity_recursive() {
399 old_glob_decl.ambiguity.set_unchecked(Some(glob_decl));
401 old_glob_decl.warn_ambiguity.set_unchecked(true);
402 old_glob_decl
403 } else {
404 old_glob_decl
405 }
406 }
407
408 pub(crate) fn try_plant_decl_into_local_module(
411 &mut self,
412 module: Module<'ra>,
413 ident: Macros20NormalizedIdent,
414 ns: Namespace,
415 decl: Decl<'ra>,
416 warn_ambiguity: bool,
417 ) -> Result<(), Decl<'ra>> {
418 let res = decl.res();
419 self.check_reserved_macro_name(ident.0, res);
420 self.set_decl_parent_module(decl, module);
421 let key = BindingKey::new_disambiguated(ident, ns, || {
425 module.underscore_disambiguator.update_unchecked(|d| d + 1);
426 module.underscore_disambiguator.get()
427 });
428 self.update_local_resolution(module, key, warn_ambiguity, |this, resolution| {
429 if let Some(old_decl) = resolution.best_decl() {
430 assert_ne!(decl, old_decl);
431 assert!(!decl.warn_ambiguity.get());
432 if res == Res::Err && old_decl.res() != Res::Err {
433 return Ok(());
435 }
436 match (old_decl.is_glob_import(), decl.is_glob_import()) {
437 (true, true) => {
438 resolution.glob_decl =
439 Some(this.select_glob_decl(decl, old_decl, warn_ambiguity));
440 }
441 (old_glob @ true, false) | (old_glob @ false, true) => {
442 let (glob_decl, non_glob_decl) =
443 if old_glob { (old_decl, decl) } else { (decl, old_decl) };
444 resolution.non_glob_decl = Some(non_glob_decl);
445 if let Some(old_glob_decl) = resolution.glob_decl
446 && old_glob_decl != glob_decl
447 {
448 resolution.glob_decl =
449 Some(this.select_glob_decl(glob_decl, old_glob_decl, false));
450 } else {
451 resolution.glob_decl = Some(glob_decl);
452 }
453 }
454 (false, false) => {
455 return Err(old_decl);
456 }
457 }
458 } else {
459 if decl.is_glob_import() {
460 resolution.glob_decl = Some(decl);
461 } else {
462 resolution.non_glob_decl = Some(decl);
463 }
464 }
465
466 Ok(())
467 })
468 }
469
470 fn update_local_resolution<T, F>(
473 &mut self,
474 module: Module<'ra>,
475 key: BindingKey,
476 warn_ambiguity: bool,
477 f: F,
478 ) -> T
479 where
480 F: FnOnce(&Resolver<'ra, 'tcx>, &mut NameResolution<'ra>) -> T,
481 {
482 let (binding, t, warn_ambiguity) = {
485 let resolution = &mut *self.resolution_or_default(module, key).borrow_mut_unchecked();
486 let old_decl = resolution.binding();
487
488 let t = f(self, resolution);
489
490 if let Some(binding) = resolution.binding()
491 && old_decl != Some(binding)
492 {
493 (binding, t, warn_ambiguity || old_decl.is_some())
494 } else {
495 return t;
496 }
497 };
498
499 let Ok(glob_importers) = module.glob_importers.try_borrow_mut_unchecked() else {
500 return t;
501 };
502
503 for import in glob_importers.iter() {
505 let mut ident = key.ident;
506 let scope = match ident.0.span.reverse_glob_adjust(module.expansion, import.span) {
507 Some(Some(def)) => self.expn_def_scope(def),
508 Some(None) => import.parent_scope.module,
509 None => continue,
510 };
511 if self.is_accessible_from(binding.vis(), scope) {
512 let import_decl = self.new_import_decl(binding, *import);
513 let _ = self.try_plant_decl_into_local_module(
514 import.parent_scope.module,
515 ident,
516 key.ns,
517 import_decl,
518 warn_ambiguity,
519 );
520 }
521 }
522
523 t
524 }
525
526 fn import_dummy_binding(&mut self, import: Import<'ra>, is_indeterminate: bool) {
529 if let ImportKind::Single { target, ref decls, .. } = import.kind {
530 if !(is_indeterminate || decls.iter().all(|d| d.get().decl().is_none())) {
531 return; }
533 let dummy_decl = self.dummy_decl;
534 let dummy_decl = self.new_import_decl(dummy_decl, import);
535 self.per_ns(|this, ns| {
536 let module = import.parent_scope.module;
537 let ident = Macros20NormalizedIdent::new(target);
538 let _ = this.try_plant_decl_into_local_module(module, ident, ns, dummy_decl, false);
539 if target.name != kw::Underscore {
541 let key = BindingKey::new(ident, ns);
542 this.update_local_resolution(module, key, false, |_, resolution| {
543 resolution.single_imports.swap_remove(&import);
544 })
545 }
546 });
547 self.record_use(target, dummy_decl, Used::Other);
548 } else if import.imported_module.get().is_none() {
549 self.import_use_map.insert(import, Used::Other);
550 if let Some(id) = import.id() {
551 self.used_imports.insert(id);
552 }
553 }
554 }
555
556 pub(crate) fn resolve_imports(&mut self) {
567 let mut prev_indeterminate_count = usize::MAX;
568 let mut indeterminate_count = self.indeterminate_imports.len() * 3;
569 while indeterminate_count < prev_indeterminate_count {
570 prev_indeterminate_count = indeterminate_count;
571 indeterminate_count = 0;
572 self.assert_speculative = true;
573 for import in mem::take(&mut self.indeterminate_imports) {
574 let import_indeterminate_count = self.cm().resolve_import(import);
575 indeterminate_count += import_indeterminate_count;
576 match import_indeterminate_count {
577 0 => self.determined_imports.push(import),
578 _ => self.indeterminate_imports.push(import),
579 }
580 }
581 self.assert_speculative = false;
582 }
583 }
584
585 pub(crate) fn finalize_imports(&mut self) {
586 let mut module_children = Default::default();
587 let mut ambig_module_children = Default::default();
588 for module in &self.local_modules {
589 self.finalize_resolutions_in(*module, &mut module_children, &mut ambig_module_children);
590 }
591 self.module_children = module_children;
592 self.ambig_module_children = ambig_module_children;
593
594 let mut seen_spans = FxHashSet::default();
595 let mut errors = vec![];
596 let mut prev_root_id: NodeId = NodeId::ZERO;
597 let determined_imports = mem::take(&mut self.determined_imports);
598 let indeterminate_imports = mem::take(&mut self.indeterminate_imports);
599
600 let mut glob_error = false;
601 for (is_indeterminate, import) in determined_imports
602 .iter()
603 .map(|i| (false, i))
604 .chain(indeterminate_imports.iter().map(|i| (true, i)))
605 {
606 let unresolved_import_error = self.finalize_import(*import);
607 self.import_dummy_binding(*import, is_indeterminate);
610
611 let Some(err) = unresolved_import_error else { continue };
612
613 glob_error |= import.is_glob();
614
615 if let ImportKind::Single { source, ref decls, .. } = import.kind
616 && source.name == kw::SelfLower
617 && let PendingDecl::Ready(None) = decls.value_ns.get()
619 {
620 continue;
621 }
622
623 if prev_root_id != NodeId::ZERO && prev_root_id != import.root_id && !errors.is_empty()
624 {
625 self.throw_unresolved_import_error(errors, glob_error);
628 errors = vec![];
629 }
630 if seen_spans.insert(err.span) {
631 errors.push((*import, err));
632 prev_root_id = import.root_id;
633 }
634 }
635
636 if !errors.is_empty() {
637 self.throw_unresolved_import_error(errors, glob_error);
638 return;
639 }
640
641 for import in &indeterminate_imports {
642 let path = import_path_to_string(
643 &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
644 &import.kind,
645 import.span,
646 );
647 if path.contains("::") {
650 let err = UnresolvedImportError {
651 span: import.span,
652 label: None,
653 note: None,
654 suggestion: None,
655 candidates: None,
656 segment: None,
657 module: None,
658 };
659 errors.push((*import, err))
660 }
661 }
662
663 if !errors.is_empty() {
664 self.throw_unresolved_import_error(errors, glob_error);
665 }
666 }
667
668 pub(crate) fn lint_reexports(&mut self, exported_ambiguities: FxHashSet<Decl<'ra>>) {
669 for module in &self.local_modules {
670 for (key, resolution) in self.resolutions(*module).borrow().iter() {
671 let resolution = resolution.borrow();
672 let Some(binding) = resolution.best_decl() else { continue };
673
674 if let DeclKind::Import { import, .. } = binding.kind
675 && let Some(amb_binding) = binding.ambiguity.get()
676 && binding.res() != Res::Err
677 && exported_ambiguities.contains(&binding)
678 {
679 self.lint_buffer.buffer_lint(
680 AMBIGUOUS_GLOB_REEXPORTS,
681 import.root_id,
682 import.root_span,
683 BuiltinLintDiag::AmbiguousGlobReexports {
684 name: key.ident.to_string(),
685 namespace: key.ns.descr().to_string(),
686 first_reexport_span: import.root_span,
687 duplicate_reexport_span: amb_binding.span,
688 },
689 );
690 }
691
692 if let Some(glob_decl) = resolution.glob_decl
693 && resolution.non_glob_decl.is_some()
694 {
695 if binding.res() != Res::Err
696 && glob_decl.res() != Res::Err
697 && let DeclKind::Import { import: glob_import, .. } = glob_decl.kind
698 && let Some(glob_import_id) = glob_import.id()
699 && let glob_import_def_id = self.local_def_id(glob_import_id)
700 && self.effective_visibilities.is_exported(glob_import_def_id)
701 && glob_decl.vis().is_public()
702 && !binding.vis().is_public()
703 {
704 let binding_id = match binding.kind {
705 DeclKind::Def(res) => {
706 Some(self.def_id_to_node_id(res.def_id().expect_local()))
707 }
708 DeclKind::Import { import, .. } => import.id(),
709 };
710 if let Some(binding_id) = binding_id {
711 self.lint_buffer.buffer_lint(
712 HIDDEN_GLOB_REEXPORTS,
713 binding_id,
714 binding.span,
715 BuiltinLintDiag::HiddenGlobReexports {
716 name: key.ident.name.to_string(),
717 namespace: key.ns.descr().to_owned(),
718 glob_reexport_span: glob_decl.span,
719 private_item_span: binding.span,
720 },
721 );
722 }
723 }
724 }
725
726 if let DeclKind::Import { import, .. } = binding.kind
727 && let Some(binding_id) = import.id()
728 && let import_def_id = self.local_def_id(binding_id)
729 && self.effective_visibilities.is_exported(import_def_id)
730 && let Res::Def(reexported_kind, reexported_def_id) = binding.res()
731 && !matches!(reexported_kind, DefKind::Ctor(..))
732 && !reexported_def_id.is_local()
733 && self.tcx.is_private_dep(reexported_def_id.krate)
734 {
735 self.lint_buffer.buffer_lint(
736 EXPORTED_PRIVATE_DEPENDENCIES,
737 binding_id,
738 binding.span,
739 crate::errors::ReexportPrivateDependency {
740 name: key.ident.name,
741 kind: binding.res().descr(),
742 krate: self.tcx.crate_name(reexported_def_id.krate),
743 },
744 );
745 }
746 }
747 }
748 }
749
750 fn throw_unresolved_import_error(
751 &mut self,
752 mut errors: Vec<(Import<'_>, UnresolvedImportError)>,
753 glob_error: bool,
754 ) {
755 errors.retain(|(_import, err)| match err.module {
756 Some(def_id) if self.mods_with_parse_errors.contains(&def_id) => false,
758 _ => err.segment != Some(kw::Underscore),
761 });
762 if errors.is_empty() {
763 self.tcx.dcx().delayed_bug("expected a parse or \"`_` can't be an identifier\" error");
764 return;
765 }
766
767 let span = MultiSpan::from_spans(errors.iter().map(|(_, err)| err.span).collect());
768
769 let paths = errors
770 .iter()
771 .map(|(import, err)| {
772 let path = import_path_to_string(
773 &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
774 &import.kind,
775 err.span,
776 );
777 format!("`{path}`")
778 })
779 .collect::<Vec<_>>();
780 let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),);
781
782 let mut diag = struct_span_code_err!(self.dcx(), span, E0432, "{msg}");
783
784 if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() {
785 diag.note(note.clone());
786 }
787
788 const MAX_LABEL_COUNT: usize = 10;
790
791 for (import, err) in errors.into_iter().take(MAX_LABEL_COUNT) {
792 if let Some(label) = err.label {
793 diag.span_label(err.span, label);
794 }
795
796 if let Some((suggestions, msg, applicability)) = err.suggestion {
797 if suggestions.is_empty() {
798 diag.help(msg);
799 continue;
800 }
801 diag.multipart_suggestion(msg, suggestions, applicability);
802 }
803
804 if let Some(candidates) = &err.candidates {
805 match &import.kind {
806 ImportKind::Single { nested: false, source, target, .. } => import_candidates(
807 self.tcx,
808 &mut diag,
809 Some(err.span),
810 candidates,
811 DiagMode::Import { append: false, unresolved_import: true },
812 (source != target)
813 .then(|| format!(" as {target}"))
814 .as_deref()
815 .unwrap_or(""),
816 ),
817 ImportKind::Single { nested: true, source, target, .. } => {
818 import_candidates(
819 self.tcx,
820 &mut diag,
821 None,
822 candidates,
823 DiagMode::Normal,
824 (source != target)
825 .then(|| format!(" as {target}"))
826 .as_deref()
827 .unwrap_or(""),
828 );
829 }
830 _ => {}
831 }
832 }
833
834 if matches!(import.kind, ImportKind::Single { .. })
835 && let Some(segment) = err.segment
836 && let Some(module) = err.module
837 {
838 self.find_cfg_stripped(&mut diag, &segment, module)
839 }
840 }
841
842 let guar = diag.emit();
843 if glob_error {
844 self.glob_error = Some(guar);
845 }
846 }
847
848 fn resolve_import<'r>(mut self: CmResolver<'r, 'ra, 'tcx>, import: Import<'ra>) -> usize {
855 debug!(
856 "(resolving import for module) resolving import `{}::...` in `{}`",
857 Segment::names_to_string(&import.module_path),
858 module_to_string(import.parent_scope.module).unwrap_or_else(|| "???".to_string()),
859 );
860 let module = if let Some(module) = import.imported_module.get() {
861 module
862 } else {
863 let path_res = self.reborrow().maybe_resolve_path(
864 &import.module_path,
865 None,
866 &import.parent_scope,
867 Some(import),
868 );
869
870 match path_res {
871 PathResult::Module(module) => module,
872 PathResult::Indeterminate => return 3,
873 PathResult::NonModule(..) | PathResult::Failed { .. } => return 0,
874 }
875 };
876
877 import.imported_module.set_unchecked(Some(module));
878 let (source, target, bindings, type_ns_only) = match import.kind {
879 ImportKind::Single { source, target, ref decls, type_ns_only, .. } => {
880 (source, target, decls, type_ns_only)
881 }
882 ImportKind::Glob { .. } => {
883 self.get_mut_unchecked().resolve_glob_import(import);
884 return 0;
885 }
886 _ => unreachable!(),
887 };
888
889 let mut indeterminate_count = 0;
890 self.per_ns_cm(|this, ns| {
891 if !type_ns_only || ns == TypeNS {
892 if bindings[ns].get() != PendingDecl::Pending {
893 return;
894 };
895 let binding_result = this.reborrow().maybe_resolve_ident_in_module(
896 module,
897 source,
898 ns,
899 &import.parent_scope,
900 Some(import),
901 );
902 let parent = import.parent_scope.module;
903 let binding = match binding_result {
904 Ok(binding) => {
905 if binding.is_assoc_item()
906 && !this.tcx.features().import_trait_associated_functions()
907 {
908 feature_err(
909 this.tcx.sess,
910 sym::import_trait_associated_functions,
911 import.span,
912 "`use` associated items of traits is unstable",
913 )
914 .emit();
915 }
916 let import_decl = this.new_import_decl(binding, import);
918 this.get_mut_unchecked().plant_decl_into_local_module(
919 parent,
920 Macros20NormalizedIdent::new(target),
921 ns,
922 import_decl,
923 );
924 PendingDecl::Ready(Some(import_decl))
925 }
926 Err(Determinacy::Determined) => {
927 if target.name != kw::Underscore {
929 let key = BindingKey::new(Macros20NormalizedIdent::new(target), ns);
930 this.get_mut_unchecked().update_local_resolution(
931 parent,
932 key,
933 false,
934 |_, resolution| {
935 resolution.single_imports.swap_remove(&import);
936 },
937 );
938 }
939 PendingDecl::Ready(None)
940 }
941 Err(Determinacy::Undetermined) => {
942 indeterminate_count += 1;
943 PendingDecl::Pending
944 }
945 };
946 bindings[ns].set_unchecked(binding);
947 }
948 });
949
950 indeterminate_count
951 }
952
953 fn finalize_import(&mut self, import: Import<'ra>) -> Option<UnresolvedImportError> {
958 let ignore_decl = match &import.kind {
959 ImportKind::Single { decls, .. } => decls[TypeNS].get().decl(),
960 _ => None,
961 };
962 let ambiguity_errors_len =
963 |errors: &Vec<AmbiguityError<'_>>| errors.iter().filter(|error| !error.warning).count();
964 let prev_ambiguity_errors_len = ambiguity_errors_len(&self.ambiguity_errors);
965 let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span);
966
967 let privacy_errors_len = self.privacy_errors.len();
969
970 let path_res = self.cm().resolve_path(
971 &import.module_path,
972 None,
973 &import.parent_scope,
974 Some(finalize),
975 ignore_decl,
976 Some(import),
977 );
978
979 let no_ambiguity =
980 ambiguity_errors_len(&self.ambiguity_errors) == prev_ambiguity_errors_len;
981
982 let module = match path_res {
983 PathResult::Module(module) => {
984 if let Some(initial_module) = import.imported_module.get() {
986 if module != initial_module && no_ambiguity {
987 span_bug!(import.span, "inconsistent resolution for an import");
988 }
989 } else if self.privacy_errors.is_empty() {
990 self.dcx()
991 .create_err(CannotDetermineImportResolution { span: import.span })
992 .emit();
993 }
994
995 module
996 }
997 PathResult::Failed {
998 is_error_from_last_segment: false,
999 span,
1000 segment_name,
1001 label,
1002 suggestion,
1003 module,
1004 error_implied_by_parse_error: _,
1005 } => {
1006 if no_ambiguity {
1007 assert!(import.imported_module.get().is_none());
1008 self.report_error(
1009 span,
1010 ResolutionError::FailedToResolve {
1011 segment: Some(segment_name),
1012 label,
1013 suggestion,
1014 module,
1015 },
1016 );
1017 }
1018 return None;
1019 }
1020 PathResult::Failed {
1021 is_error_from_last_segment: true,
1022 span,
1023 label,
1024 suggestion,
1025 module,
1026 segment_name,
1027 ..
1028 } => {
1029 if no_ambiguity {
1030 assert!(import.imported_module.get().is_none());
1031 let module = if let Some(ModuleOrUniformRoot::Module(m)) = module {
1032 m.opt_def_id()
1033 } else {
1034 None
1035 };
1036 let err = match self
1037 .make_path_suggestion(import.module_path.clone(), &import.parent_scope)
1038 {
1039 Some((suggestion, note)) => UnresolvedImportError {
1040 span,
1041 label: None,
1042 note,
1043 suggestion: Some((
1044 vec![(span, Segment::names_to_string(&suggestion))],
1045 String::from("a similar path exists"),
1046 Applicability::MaybeIncorrect,
1047 )),
1048 candidates: None,
1049 segment: Some(segment_name),
1050 module,
1051 },
1052 None => UnresolvedImportError {
1053 span,
1054 label: Some(label),
1055 note: None,
1056 suggestion,
1057 candidates: None,
1058 segment: Some(segment_name),
1059 module,
1060 },
1061 };
1062 return Some(err);
1063 }
1064 return None;
1065 }
1066 PathResult::NonModule(partial_res) => {
1067 if no_ambiguity && partial_res.full_res() != Some(Res::Err) {
1068 assert!(import.imported_module.get().is_none());
1070 }
1071 return None;
1073 }
1074 PathResult::Indeterminate => unreachable!(),
1075 };
1076
1077 let (ident, target, bindings, type_ns_only, import_id) = match import.kind {
1078 ImportKind::Single { source, target, ref decls, type_ns_only, id, .. } => {
1079 (source, target, decls, type_ns_only, id)
1080 }
1081 ImportKind::Glob { ref max_vis, id } => {
1082 if import.module_path.len() <= 1 {
1083 let mut full_path = import.module_path.clone();
1086 full_path.push(Segment::from_ident(Ident::dummy()));
1087 self.lint_if_path_starts_with_module(finalize, &full_path, None);
1088 }
1089
1090 if let ModuleOrUniformRoot::Module(module) = module
1091 && module == import.parent_scope.module
1092 {
1093 return Some(UnresolvedImportError {
1095 span: import.span,
1096 label: Some(String::from("cannot glob-import a module into itself")),
1097 note: None,
1098 suggestion: None,
1099 candidates: None,
1100 segment: None,
1101 module: None,
1102 });
1103 }
1104 if let Some(max_vis) = max_vis.get()
1105 && !max_vis.is_at_least(import.vis, self.tcx)
1106 {
1107 let def_id = self.local_def_id(id);
1108 self.lint_buffer.buffer_lint(
1109 UNUSED_IMPORTS,
1110 id,
1111 import.span,
1112 crate::errors::RedundantImportVisibility {
1113 span: import.span,
1114 help: (),
1115 max_vis: max_vis.to_string(def_id, self.tcx),
1116 import_vis: import.vis.to_string(def_id, self.tcx),
1117 },
1118 );
1119 }
1120 return None;
1121 }
1122 _ => unreachable!(),
1123 };
1124
1125 if self.privacy_errors.len() != privacy_errors_len {
1126 let mut path = import.module_path.clone();
1129 path.push(Segment::from_ident(ident));
1130 if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = self.cm().resolve_path(
1131 &path,
1132 None,
1133 &import.parent_scope,
1134 Some(finalize),
1135 ignore_decl,
1136 None,
1137 ) {
1138 let res = module.res().map(|r| (r, ident));
1139 for error in &mut self.privacy_errors[privacy_errors_len..] {
1140 error.outermost_res = res;
1141 }
1142 }
1143 }
1144
1145 let mut all_ns_err = true;
1146 self.per_ns(|this, ns| {
1147 if !type_ns_only || ns == TypeNS {
1148 let binding = this.cm().resolve_ident_in_module(
1149 module,
1150 ident,
1151 ns,
1152 &import.parent_scope,
1153 Some(Finalize { report_private: false, ..finalize }),
1154 bindings[ns].get().decl(),
1155 Some(import),
1156 );
1157
1158 match binding {
1159 Ok(binding) => {
1160 let initial_res = bindings[ns].get().decl().map(|binding| {
1162 let initial_binding = binding.import_source();
1163 all_ns_err = false;
1164 if target.name == kw::Underscore
1165 && initial_binding.is_extern_crate()
1166 && !initial_binding.is_import()
1167 {
1168 let used = if import.module_path.is_empty() {
1169 Used::Scope
1170 } else {
1171 Used::Other
1172 };
1173 this.record_use(ident, binding, used);
1174 }
1175 initial_binding.res()
1176 });
1177 let res = binding.res();
1178 let has_ambiguity_error =
1179 this.ambiguity_errors.iter().any(|error| !error.warning);
1180 if res == Res::Err || has_ambiguity_error {
1181 this.dcx()
1182 .span_delayed_bug(import.span, "some error happened for an import");
1183 return;
1184 }
1185 if let Some(initial_res) = initial_res {
1186 if res != initial_res && !this.issue_145575_hack_applied {
1187 span_bug!(import.span, "inconsistent resolution for an import");
1188 }
1189 } else if this.privacy_errors.is_empty() {
1190 this.dcx()
1191 .create_err(CannotDetermineImportResolution { span: import.span })
1192 .emit();
1193 }
1194 }
1195 Err(..) => {
1196 }
1203 }
1204 }
1205 });
1206
1207 if all_ns_err {
1208 let mut all_ns_failed = true;
1209 self.per_ns(|this, ns| {
1210 if !type_ns_only || ns == TypeNS {
1211 let binding = this.cm().resolve_ident_in_module(
1212 module,
1213 ident,
1214 ns,
1215 &import.parent_scope,
1216 Some(finalize),
1217 None,
1218 None,
1219 );
1220 if binding.is_ok() {
1221 all_ns_failed = false;
1222 }
1223 }
1224 });
1225
1226 return if all_ns_failed {
1227 let names = match module {
1228 ModuleOrUniformRoot::Module(module) => {
1229 self.resolutions(module)
1230 .borrow()
1231 .iter()
1232 .filter_map(|(BindingKey { ident: i, .. }, resolution)| {
1233 if i.name == ident.name {
1234 return None;
1235 } let resolution = resolution.borrow();
1238 if let Some(name_binding) = resolution.best_decl() {
1239 match name_binding.kind {
1240 DeclKind::Import { source_decl, .. } => {
1241 match source_decl.kind {
1242 DeclKind::Def(Res::Err) => None,
1245 _ => Some(i.name),
1246 }
1247 }
1248 _ => Some(i.name),
1249 }
1250 } else if resolution.single_imports.is_empty() {
1251 None
1252 } else {
1253 Some(i.name)
1254 }
1255 })
1256 .collect()
1257 }
1258 _ => Vec::new(),
1259 };
1260
1261 let lev_suggestion =
1262 find_best_match_for_name(&names, ident.name, None).map(|suggestion| {
1263 (
1264 vec![(ident.span, suggestion.to_string())],
1265 String::from("a similar name exists in the module"),
1266 Applicability::MaybeIncorrect,
1267 )
1268 });
1269
1270 let (suggestion, note) =
1271 match self.check_for_module_export_macro(import, module, ident) {
1272 Some((suggestion, note)) => (suggestion.or(lev_suggestion), note),
1273 _ => (lev_suggestion, None),
1274 };
1275
1276 let label = match module {
1277 ModuleOrUniformRoot::Module(module) => {
1278 let module_str = module_to_string(module);
1279 if let Some(module_str) = module_str {
1280 format!("no `{ident}` in `{module_str}`")
1281 } else {
1282 format!("no `{ident}` in the root")
1283 }
1284 }
1285 _ => {
1286 if !ident.is_path_segment_keyword() {
1287 format!("no external crate `{ident}`")
1288 } else {
1289 format!("no `{ident}` in the root")
1292 }
1293 }
1294 };
1295
1296 let parent_suggestion =
1297 self.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true);
1298
1299 Some(UnresolvedImportError {
1300 span: import.span,
1301 label: Some(label),
1302 note,
1303 suggestion,
1304 candidates: if !parent_suggestion.is_empty() {
1305 Some(parent_suggestion)
1306 } else {
1307 None
1308 },
1309 module: import.imported_module.get().and_then(|module| {
1310 if let ModuleOrUniformRoot::Module(m) = module {
1311 m.opt_def_id()
1312 } else {
1313 None
1314 }
1315 }),
1316 segment: Some(ident.name),
1317 })
1318 } else {
1319 None
1321 };
1322 }
1323
1324 let mut reexport_error = None;
1325 let mut any_successful_reexport = false;
1326 let mut crate_private_reexport = false;
1327 self.per_ns(|this, ns| {
1328 let Some(binding) = bindings[ns].get().decl().map(|b| b.import_source()) else {
1329 return;
1330 };
1331
1332 if !binding.vis().is_at_least(import.vis, this.tcx) {
1333 reexport_error = Some((ns, binding));
1334 if let Visibility::Restricted(binding_def_id) = binding.vis()
1335 && binding_def_id.is_top_level_module()
1336 {
1337 crate_private_reexport = true;
1338 }
1339 } else {
1340 any_successful_reexport = true;
1341 }
1342 });
1343
1344 if !any_successful_reexport {
1346 let (ns, binding) = reexport_error.unwrap();
1347 if let Some(extern_crate_id) = pub_use_of_private_extern_crate_hack(import, binding) {
1348 let extern_crate_sp = self.tcx.source_span(self.local_def_id(extern_crate_id));
1349 self.lint_buffer.buffer_lint(
1350 PUB_USE_OF_PRIVATE_EXTERN_CRATE,
1351 import_id,
1352 import.span,
1353 crate::errors::PrivateExternCrateReexport {
1354 ident,
1355 sugg: extern_crate_sp.shrink_to_lo(),
1356 },
1357 );
1358 } else if ns == TypeNS {
1359 let err = if crate_private_reexport {
1360 self.dcx()
1361 .create_err(CannotBeReexportedCratePublicNS { span: import.span, ident })
1362 } else {
1363 self.dcx().create_err(CannotBeReexportedPrivateNS { span: import.span, ident })
1364 };
1365 err.emit();
1366 } else {
1367 let mut err = if crate_private_reexport {
1368 self.dcx()
1369 .create_err(CannotBeReexportedCratePublic { span: import.span, ident })
1370 } else {
1371 self.dcx().create_err(CannotBeReexportedPrivate { span: import.span, ident })
1372 };
1373
1374 match binding.kind {
1375 DeclKind::Def(Res::Def(DefKind::Macro(_), def_id))
1376 if self.get_macro_by_def_id(def_id).macro_rules =>
1378 {
1379 err.subdiagnostic( ConsiderAddingMacroExport {
1380 span: binding.span,
1381 });
1382 err.subdiagnostic( ConsiderMarkingAsPubCrate {
1383 vis_span: import.vis_span,
1384 });
1385 }
1386 _ => {
1387 err.subdiagnostic( ConsiderMarkingAsPub {
1388 span: import.span,
1389 ident,
1390 });
1391 }
1392 }
1393 err.emit();
1394 }
1395 }
1396
1397 if import.module_path.len() <= 1 {
1398 let mut full_path = import.module_path.clone();
1401 full_path.push(Segment::from_ident(ident));
1402 self.per_ns(|this, ns| {
1403 if let Some(binding) = bindings[ns].get().decl().map(|b| b.import_source()) {
1404 this.lint_if_path_starts_with_module(finalize, &full_path, Some(binding));
1405 }
1406 });
1407 }
1408
1409 self.per_ns(|this, ns| {
1413 if let Some(binding) = bindings[ns].get().decl().map(|b| b.import_source()) {
1414 this.import_res_map.entry(import_id).or_default()[ns] = Some(binding.res());
1415 }
1416 });
1417
1418 debug!("(resolving single import) successfully resolved import");
1419 None
1420 }
1421
1422 pub(crate) fn check_for_redundant_imports(&mut self, import: Import<'ra>) -> bool {
1423 let ImportKind::Single { source, target, ref decls, id, .. } = import.kind else {
1425 unreachable!()
1426 };
1427
1428 if source != target {
1430 return false;
1431 }
1432
1433 if import.parent_scope.expansion != LocalExpnId::ROOT {
1435 return false;
1436 }
1437
1438 if self.import_use_map.get(&import) == Some(&Used::Other)
1443 || self.effective_visibilities.is_exported(self.local_def_id(id))
1444 {
1445 return false;
1446 }
1447
1448 let mut is_redundant = true;
1449 let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None };
1450 self.per_ns(|this, ns| {
1451 let binding = decls[ns].get().decl().map(|b| b.import_source());
1452 if is_redundant && let Some(binding) = binding {
1453 if binding.res() == Res::Err {
1454 return;
1455 }
1456
1457 match this.cm().resolve_ident_in_scope_set(
1458 target,
1459 ScopeSet::All(ns),
1460 &import.parent_scope,
1461 None,
1462 false,
1463 decls[ns].get().decl(),
1464 None,
1465 ) {
1466 Ok(other_binding) => {
1467 is_redundant = binding.res() == other_binding.res()
1468 && !other_binding.is_ambiguity_recursive();
1469 if is_redundant {
1470 redundant_span[ns] =
1471 Some((other_binding.span, other_binding.is_import()));
1472 }
1473 }
1474 Err(_) => is_redundant = false,
1475 }
1476 }
1477 });
1478
1479 if is_redundant && !redundant_span.is_empty() {
1480 let mut redundant_spans: Vec<_> = redundant_span.present_items().collect();
1481 redundant_spans.sort();
1482 redundant_spans.dedup();
1483 self.lint_buffer.buffer_lint(
1484 REDUNDANT_IMPORTS,
1485 id,
1486 import.span,
1487 BuiltinLintDiag::RedundantImport(redundant_spans, source),
1488 );
1489 return true;
1490 }
1491
1492 false
1493 }
1494
1495 fn resolve_glob_import(&mut self, import: Import<'ra>) {
1496 let ImportKind::Glob { id, .. } = import.kind else { unreachable!() };
1498
1499 let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else {
1500 self.dcx().emit_err(CannotGlobImportAllCrates { span: import.span });
1501 return;
1502 };
1503
1504 if module.is_trait() && !self.tcx.features().import_trait_associated_functions() {
1505 feature_err(
1506 self.tcx.sess,
1507 sym::import_trait_associated_functions,
1508 import.span,
1509 "`use` associated items of traits is unstable",
1510 )
1511 .emit();
1512 }
1513
1514 if module == import.parent_scope.module {
1515 return;
1516 }
1517
1518 module.glob_importers.borrow_mut_unchecked().push(import);
1520
1521 let bindings = self
1524 .resolutions(module)
1525 .borrow()
1526 .iter()
1527 .filter_map(|(key, resolution)| {
1528 resolution.borrow().binding().map(|binding| (*key, binding))
1529 })
1530 .collect::<Vec<_>>();
1531 for (mut key, binding) in bindings {
1532 let scope = match key.ident.0.span.reverse_glob_adjust(module.expansion, import.span) {
1533 Some(Some(def)) => self.expn_def_scope(def),
1534 Some(None) => import.parent_scope.module,
1535 None => continue,
1536 };
1537 if self.is_accessible_from(binding.vis(), scope) {
1538 let import_decl = self.new_import_decl(binding, import);
1539 let warn_ambiguity = self
1540 .resolution(import.parent_scope.module, key)
1541 .and_then(|r| r.binding())
1542 .is_some_and(|binding| binding.warn_ambiguity_recursive());
1543 let _ = self.try_plant_decl_into_local_module(
1544 import.parent_scope.module,
1545 key.ident,
1546 key.ns,
1547 import_decl,
1548 warn_ambiguity,
1549 );
1550 }
1551 }
1552
1553 self.record_partial_res(id, PartialRes::new(module.res().unwrap()));
1555 }
1556
1557 fn finalize_resolutions_in(
1560 &self,
1561 module: Module<'ra>,
1562 module_children: &mut LocalDefIdMap<Vec<ModChild>>,
1563 ambig_module_children: &mut LocalDefIdMap<Vec<AmbigModChild>>,
1564 ) {
1565 *module.globs.borrow_mut(self) = Vec::new();
1567
1568 let Some(def_id) = module.opt_def_id() else { return };
1569
1570 let mut children = Vec::new();
1571 let mut ambig_children = Vec::new();
1572
1573 module.for_each_child(self, |this, ident, _, binding| {
1574 let res = binding.res().expect_non_local();
1575 if res != def::Res::Err {
1576 let child = |reexport_chain| ModChild {
1577 ident: ident.0,
1578 res,
1579 vis: binding.vis(),
1580 reexport_chain,
1581 };
1582 if let Some((ambig_binding1, ambig_binding2)) = binding.descent_to_ambiguity() {
1583 let main = child(ambig_binding1.reexport_chain(this));
1584 let second = ModChild {
1585 ident: ident.0,
1586 res: ambig_binding2.res().expect_non_local(),
1587 vis: ambig_binding2.vis(),
1588 reexport_chain: ambig_binding2.reexport_chain(this),
1589 };
1590 ambig_children.push(AmbigModChild { main, second })
1591 } else {
1592 children.push(child(binding.reexport_chain(this)));
1593 }
1594 }
1595 });
1596
1597 if !children.is_empty() {
1598 module_children.insert(def_id.expect_local(), children);
1599 }
1600 if !ambig_children.is_empty() {
1601 ambig_module_children.insert(def_id.expect_local(), ambig_children);
1602 }
1603 }
1604}
1605
1606fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Span) -> String {
1607 let pos = names.iter().position(|p| span == p.span && p.name != kw::PathRoot);
1608 let global = !names.is_empty() && names[0].name == kw::PathRoot;
1609 if let Some(pos) = pos {
1610 let names = if global { &names[1..pos + 1] } else { &names[..pos + 1] };
1611 names_to_string(names.iter().map(|ident| ident.name))
1612 } else {
1613 let names = if global { &names[1..] } else { names };
1614 if names.is_empty() {
1615 import_kind_to_string(import_kind)
1616 } else {
1617 format!(
1618 "{}::{}",
1619 names_to_string(names.iter().map(|ident| ident.name)),
1620 import_kind_to_string(import_kind),
1621 )
1622 }
1623 }
1624}
1625
1626fn import_kind_to_string(import_kind: &ImportKind<'_>) -> String {
1627 match import_kind {
1628 ImportKind::Single { source, .. } => source.to_string(),
1629 ImportKind::Glob { .. } => "*".to_string(),
1630 ImportKind::ExternCrate { .. } => "<extern crate>".to_string(),
1631 ImportKind::MacroUse { .. } => "#[macro_use]".to_string(),
1632 ImportKind::MacroExport => "#[macro_export]".to_string(),
1633 }
1634}