1 //! A bunch of methods and structures more or less related to resolving imports.
3 use crate::diagnostics
::{import_candidates, DiagnosticMode, Suggestion}
;
5 CannotBeReexportedCratePublic
, CannotBeReexportedCratePublicNS
, CannotBeReexportedPrivate
,
6 CannotBeReexportedPrivateNS
, CannotDetermineImportResolution
, CannotGlobImportAllCrates
,
7 ConsiderAddingMacroExport
, ConsiderMarkingAsPub
, IsNotDirectlyImportable
,
8 ItemsInTraitsAreNotImportable
,
10 use crate::Determinacy
::{self, *}
;
11 use crate::{fluent_generated as fluent, Namespace::*}
;
12 use crate::{module_to_string, names_to_string, ImportSuggestion}
;
13 use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment}
;
14 use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet}
;
15 use crate::{NameBinding, NameBindingData, NameBindingKind, PathResult}
;
17 use rustc_ast
::NodeId
;
18 use rustc_data_structures
::fx
::FxHashSet
;
19 use rustc_data_structures
::intern
::Interned
;
20 use rustc_errors
::{pluralize, struct_span_err, Applicability, MultiSpan}
;
21 use rustc_hir
::def
::{self, DefKind, PartialRes}
;
22 use rustc_middle
::metadata
::ModChild
;
23 use rustc_middle
::metadata
::Reexport
;
24 use rustc_middle
::span_bug
;
26 use rustc_session
::lint
::builtin
::{
27 AMBIGUOUS_GLOB_REEXPORTS
, HIDDEN_GLOB_REEXPORTS
, PUB_USE_OF_PRIVATE_EXTERN_CRATE
,
30 use rustc_session
::lint
::BuiltinLintDiagnostics
;
31 use rustc_span
::edit_distance
::find_best_match_for_name
;
32 use rustc_span
::hygiene
::LocalExpnId
;
33 use rustc_span
::symbol
::{kw, Ident, Symbol}
;
35 use smallvec
::SmallVec
;
40 type Res
= def
::Res
<NodeId
>;
42 /// Contains data for specific kinds of imports.
44 pub(crate) enum ImportKind
<'a
> {
46 /// `source` in `use prefix::source as target`.
48 /// `target` in `use prefix::source as target`.
50 /// Bindings to which `source` refers to.
51 source_bindings
: PerNS
<Cell
<Result
<NameBinding
<'a
>, Determinacy
>>>,
52 /// Bindings introduced by `target`.
53 target_bindings
: PerNS
<Cell
<Option
<NameBinding
<'a
>>>>,
54 /// `true` for `...::{self [as target]}` imports, `false` otherwise.
56 /// Did this import result from a nested import? ie. `use foo::{bar, baz};`
58 /// The ID of the `UseTree` that imported this `Import`.
60 /// In the case where the `Import` was expanded from a "nested" use tree,
61 /// this id is the ID of the leaf tree. For example:
63 /// ```ignore (pacify the merciless tidy)
64 /// use foo::bar::{a, b}
67 /// If this is the import for `foo::bar::a`, we would have the ID of the `UseTree`
68 /// for `a` in this field.
73 // The visibility of the greatest re-export.
74 // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors.
75 max_vis
: Cell
<Option
<ty
::Visibility
>>,
79 source
: Option
<Symbol
>,
87 /// Manually implement `Debug` for `ImportKind` because the `source/target_bindings`
88 /// contain `Cell`s which can introduce infinite loops while printing.
89 impl<'a
> std
::fmt
::Debug
for ImportKind
<'a
> {
90 fn fmt(&self, f
: &mut std
::fmt
::Formatter
<'_
>) -> std
::fmt
::Result
{
102 .debug_struct("Single")
103 .field("source", source
)
104 .field("target", target
)
105 // Ignore the nested bindings to avoid an infinite loop while printing.
108 &source_bindings
.clone().map(|b
| b
.into_inner().map(|_
| format_args
!(".."))),
112 &target_bindings
.clone().map(|b
| b
.into_inner().map(|_
| format_args
!(".."))),
114 .field("type_ns_only", type_ns_only
)
115 .field("nested", nested
)
118 Glob { ref is_prelude, ref max_vis, ref id }
=> f
119 .debug_struct("Glob")
120 .field("is_prelude", is_prelude
)
121 .field("max_vis", max_vis
)
124 ExternCrate { ref source, ref target, ref id }
=> f
125 .debug_struct("ExternCrate")
126 .field("source", source
)
127 .field("target", target
)
130 MacroUse
=> f
.debug_struct("MacroUse").finish(),
131 MacroExport
=> f
.debug_struct("MacroExport").finish(),
137 #[derive(Debug, Clone)]
138 pub(crate) struct ImportData
<'a
> {
139 pub kind
: ImportKind
<'a
>,
141 /// Node ID of the "root" use item -- this is always the same as `ImportKind`'s `id`
142 /// (if it exists) except in the case of "nested" use trees, in which case
143 /// it will be the ID of the root use tree. e.g., in the example
144 /// ```ignore (incomplete code)
145 /// use foo::bar::{a, b}
147 /// this would be the ID of the `use foo::bar` `UseTree` node.
148 /// In case of imports without their own node ID it's the closest node that can be used,
149 /// for example, for reporting lints.
152 /// Span of the entire use statement.
155 /// Span of the entire use statement with attributes.
156 pub use_span_with_attributes
: Span
,
158 /// Did the use statement have any attributes?
159 pub has_attributes
: bool
,
161 /// Span of this use tree.
164 /// Span of the *root* use tree (see `root_id`).
167 pub parent_scope
: ParentScope
<'a
>,
168 pub module_path
: Vec
<Segment
>,
169 /// The resolution of `module_path`.
170 pub imported_module
: Cell
<Option
<ModuleOrUniformRoot
<'a
>>>,
171 pub vis
: Cell
<Option
<ty
::Visibility
>>,
172 pub used
: Cell
<bool
>,
175 /// All imports are unique and allocated on a same arena,
176 /// so we can use referential equality to compare them.
177 pub(crate) type Import
<'a
> = Interned
<'a
, ImportData
<'a
>>;
179 impl<'a
> ImportData
<'a
> {
180 pub(crate) fn is_glob(&self) -> bool
{
181 matches
!(self.kind
, ImportKind
::Glob { .. }
)
184 pub(crate) fn is_nested(&self) -> bool
{
186 ImportKind
::Single { nested, .. }
=> nested
,
191 pub(crate) fn expect_vis(&self) -> ty
::Visibility
{
192 self.vis
.get().expect("encountered cleared import visibility")
195 pub(crate) fn id(&self) -> Option
<NodeId
> {
197 ImportKind
::Single { id, .. }
198 | ImportKind
::Glob { id, .. }
199 | ImportKind
::ExternCrate { id, .. }
=> Some(id
),
200 ImportKind
::MacroUse
| ImportKind
::MacroExport
=> None
,
204 fn simplify(&self, r
: &Resolver
<'_
, '_
>) -> Reexport
{
205 let to_def_id
= |id
| r
.local_def_id(id
).to_def_id();
207 ImportKind
::Single { id, .. }
=> Reexport
::Single(to_def_id(id
)),
208 ImportKind
::Glob { id, .. }
=> Reexport
::Glob(to_def_id(id
)),
209 ImportKind
::ExternCrate { id, .. }
=> Reexport
::ExternCrate(to_def_id(id
)),
210 ImportKind
::MacroUse
=> Reexport
::MacroUse
,
211 ImportKind
::MacroExport
=> Reexport
::MacroExport
,
216 /// Records information about the resolution of a name in a namespace of a module.
217 #[derive(Clone, Default, Debug)]
218 pub(crate) struct NameResolution
<'a
> {
219 /// Single imports that may define the name in the namespace.
220 /// Imports are arena-allocated, so it's ok to use pointers as keys.
221 pub single_imports
: FxHashSet
<Import
<'a
>>,
222 /// The least shadowable known binding for this name, or None if there are no known bindings.
223 pub binding
: Option
<NameBinding
<'a
>>,
224 pub shadowed_glob
: Option
<NameBinding
<'a
>>,
227 impl<'a
> NameResolution
<'a
> {
228 /// Returns the binding for the name if it is known or None if it not known.
229 pub(crate) fn binding(&self) -> Option
<NameBinding
<'a
>> {
230 self.binding
.and_then(|binding
| {
231 if !binding
.is_glob_import() || self.single_imports
.is_empty() {
240 /// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved
241 /// import errors within the same use tree into a single diagnostic.
242 #[derive(Debug, Clone)]
243 struct UnresolvedImportError
{
245 label
: Option
<String
>,
246 note
: Option
<String
>,
247 suggestion
: Option
<Suggestion
>,
248 candidates
: Option
<Vec
<ImportSuggestion
>>,
251 // Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;`
252 // are permitted for backward-compatibility under a deprecation lint.
253 fn pub_use_of_private_extern_crate_hack(import
: Import
<'_
>, binding
: NameBinding
<'_
>) -> bool
{
254 match (&import
.kind
, &binding
.kind
) {
255 (ImportKind
::Single { .. }
, NameBindingKind
::Import { import: binding_import, .. }
) => {
256 matches
!(binding_import
.kind
, ImportKind
::ExternCrate { .. }
)
257 && import
.expect_vis().is_public()
263 impl<'a
, 'tcx
> Resolver
<'a
, 'tcx
> {
264 /// Given a binding and an import that resolves to it,
265 /// return the corresponding binding defined by the import.
266 pub(crate) fn import(&self, binding
: NameBinding
<'a
>, import
: Import
<'a
>) -> NameBinding
<'a
> {
267 let import_vis
= import
.expect_vis().to_def_id();
268 let vis
= if binding
.vis
.is_at_least(import_vis
, self.tcx
)
269 || pub_use_of_private_extern_crate_hack(import
, binding
)
276 if let ImportKind
::Glob { ref max_vis, .. }
= import
.kind
{
278 || max_vis
.get().map_or(true, |max_vis
| vis
.is_at_least(max_vis
, self.tcx
))
280 max_vis
.set(Some(vis
.expect_local()))
284 self.arenas
.alloc_name_binding(NameBindingData
{
285 kind
: NameBindingKind
::Import { binding, import, used: Cell::new(false) }
,
287 warn_ambiguity
: false,
290 expansion
: import
.parent_scope
.expansion
,
294 /// Define the name or return the existing binding if there is a collision.
295 /// `update` indicates if the definition is a redefinition of an existing binding.
296 pub(crate) fn try_define(
300 binding
: NameBinding
<'a
>,
301 warn_ambiguity
: bool
,
302 ) -> Result
<(), NameBinding
<'a
>> {
303 let res
= binding
.res();
304 self.check_reserved_macro_name(key
.ident
, res
);
305 self.set_binding_parent_module(binding
, module
);
306 self.update_resolution(module
, key
, warn_ambiguity
, |this
, resolution
| {
307 if let Some(old_binding
) = resolution
.binding
{
308 if res
== Res
::Err
&& old_binding
.res() != Res
::Err
{
309 // Do not override real bindings with `Res::Err`s from error recovery.
312 match (old_binding
.is_glob_import(), binding
.is_glob_import()) {
314 // FIXME: remove `!binding.is_ambiguity()` after delete the warning ambiguity.
315 if !binding
.is_ambiguity()
316 && let NameBindingKind
::Import { import: old_import, .. }
=
318 && let NameBindingKind
::Import { import, .. }
= binding
.kind
319 && old_import
== import
321 // We should replace the `old_binding` with `binding` regardless
322 // of whether they has same resolution or not when they are
323 // imported from the same glob-import statement.
324 resolution
.binding
= Some(binding
);
325 } else if res
!= old_binding
.res() {
326 let binding
= if warn_ambiguity
{
327 this
.warn_ambiguity(AmbiguityKind
::GlobVsGlob
, old_binding
, binding
)
329 this
.ambiguity(AmbiguityKind
::GlobVsGlob
, old_binding
, binding
)
331 resolution
.binding
= Some(binding
);
332 } else if !old_binding
.vis
.is_at_least(binding
.vis
, this
.tcx
) {
333 // We are glob-importing the same item but with greater visibility.
334 resolution
.binding
= Some(binding
);
335 } else if binding
.is_ambiguity() {
337 Some(self.arenas
.alloc_name_binding(NameBindingData
{
338 warn_ambiguity
: true,
343 (old_glob @
true, false) | (old_glob @
false, true) => {
344 let (glob_binding
, nonglob_binding
) =
345 if old_glob { (old_binding, binding) }
else { (binding, old_binding) }
;
346 if glob_binding
.res() != nonglob_binding
.res()
348 && nonglob_binding
.expansion
!= LocalExpnId
::ROOT
350 resolution
.binding
= Some(this
.ambiguity(
351 AmbiguityKind
::GlobVsExpanded
,
356 resolution
.binding
= Some(nonglob_binding
);
359 if let Some(old_binding
) = resolution
.shadowed_glob
{
360 assert
!(old_binding
.is_glob_import());
361 if glob_binding
.res() != old_binding
.res() {
362 resolution
.shadowed_glob
= Some(this
.ambiguity(
363 AmbiguityKind
::GlobVsGlob
,
367 } else if !old_binding
.vis
.is_at_least(binding
.vis
, this
.tcx
) {
368 resolution
.shadowed_glob
= Some(glob_binding
);
371 resolution
.shadowed_glob
= Some(glob_binding
);
375 return Err(old_binding
);
379 resolution
.binding
= Some(binding
);
389 primary_binding
: NameBinding
<'a
>,
390 secondary_binding
: NameBinding
<'a
>,
391 ) -> NameBinding
<'a
> {
392 self.arenas
.alloc_name_binding(NameBindingData
{
393 ambiguity
: Some((secondary_binding
, kind
)),
394 ..(*primary_binding
).clone()
401 primary_binding
: NameBinding
<'a
>,
402 secondary_binding
: NameBinding
<'a
>,
403 ) -> NameBinding
<'a
> {
404 self.arenas
.alloc_name_binding(NameBindingData
{
405 ambiguity
: Some((secondary_binding
, kind
)),
406 warn_ambiguity
: true,
407 ..(*primary_binding
).clone()
411 // Use `f` to mutate the resolution of the name in the module.
412 // If the resolution becomes a success, define it in the module's glob importers.
413 fn update_resolution
<T
, F
>(
417 warn_ambiguity
: bool
,
421 F
: FnOnce(&mut Resolver
<'a
, 'tcx
>, &mut NameResolution
<'a
>) -> T
,
423 // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
424 // during which the resolution might end up getting re-defined via a glob cycle.
425 let (binding
, t
, warn_ambiguity
) = {
426 let resolution
= &mut *self.resolution(module
, key
).borrow_mut();
427 let old_binding
= resolution
.binding();
429 let t
= f(self, resolution
);
431 if let Some(binding
) = resolution
.binding()
432 && old_binding
!= Some(binding
)
434 (binding
, t
, warn_ambiguity
|| old_binding
.is_some())
440 let Ok(glob_importers
) = module
.glob_importers
.try_borrow_mut() else {
444 // Define or update `binding` in `module`s glob importers.
445 for import
in glob_importers
.iter() {
446 let mut ident
= key
.ident
;
447 let scope
= match ident
.span
.reverse_glob_adjust(module
.expansion
, import
.span
) {
448 Some(Some(def
)) => self.expn_def_scope(def
),
449 Some(None
) => import
.parent_scope
.module
,
452 if self.is_accessible_from(binding
.vis
, scope
) {
453 let imported_binding
= self.import(binding
, *import
);
454 let key
= BindingKey { ident, ..key }
;
455 let _
= self.try_define(
456 import
.parent_scope
.module
,
467 // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
468 // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
469 fn import_dummy_binding(&mut self, import
: Import
<'a
>, is_indeterminate
: bool
) {
470 if let ImportKind
::Single { target, ref target_bindings, .. }
= import
.kind
{
471 if !(is_indeterminate
|| target_bindings
.iter().all(|binding
| binding
.get().is_none()))
473 return; // Has resolution, do not create the dummy binding
475 let dummy_binding
= self.dummy_binding
;
476 let dummy_binding
= self.import(dummy_binding
, import
);
477 self.per_ns(|this
, ns
| {
478 let key
= BindingKey
::new(target
, ns
);
479 let _
= this
.try_define(import
.parent_scope
.module
, key
, dummy_binding
, false);
481 self.record_use(target
, dummy_binding
, false);
482 } else if import
.imported_module
.get().is_none() {
483 import
.used
.set(true);
484 if let Some(id
) = import
.id() {
485 self.used_imports
.insert(id
);
492 // This is a fixed-point algorithm. We resolve imports until our efforts
493 // are stymied by an unresolved import; then we bail out of the current
494 // module and continue. We terminate successfully once no more imports
495 // remain or unsuccessfully when no forward progress in resolving imports
498 /// Resolves all imports for the crate. This method performs the fixed-
500 pub(crate) fn resolve_imports(&mut self) {
501 let mut prev_indeterminate_count
= usize::MAX
;
502 let mut indeterminate_count
= self.indeterminate_imports
.len() * 3;
503 while indeterminate_count
< prev_indeterminate_count
{
504 prev_indeterminate_count
= indeterminate_count
;
505 indeterminate_count
= 0;
506 for import
in mem
::take(&mut self.indeterminate_imports
) {
507 let import_indeterminate_count
= self.resolve_import(import
);
508 indeterminate_count
+= import_indeterminate_count
;
509 match import_indeterminate_count
{
510 0 => self.determined_imports
.push(import
),
511 _
=> self.indeterminate_imports
.push(import
),
517 pub(crate) fn finalize_imports(&mut self) {
518 for module
in self.arenas
.local_modules().iter() {
519 self.finalize_resolutions_in(*module
);
522 let mut seen_spans
= FxHashSet
::default();
523 let mut errors
= vec
![];
524 let mut prev_root_id
: NodeId
= NodeId
::from_u32(0);
525 let determined_imports
= mem
::take(&mut self.determined_imports
);
526 let indeterminate_imports
= mem
::take(&mut self.indeterminate_imports
);
528 for (is_indeterminate
, import
) in determined_imports
531 .chain(indeterminate_imports
.iter().map(|i
| (true, i
)))
533 let unresolved_import_error
= self.finalize_import(*import
);
535 // If this import is unresolved then create a dummy import
536 // resolution for it so that later resolve stages won't complain.
537 self.import_dummy_binding(*import
, is_indeterminate
);
539 if let Some(err
) = unresolved_import_error
{
540 if let ImportKind
::Single { source, ref source_bindings, .. }
= import
.kind
{
541 if source
.name
== kw
::SelfLower
{
542 // Silence `unresolved import` error if E0429 is already emitted
543 if let Err(Determined
) = source_bindings
.value_ns
.get() {
549 if prev_root_id
.as_u32() != 0
550 && prev_root_id
.as_u32() != import
.root_id
.as_u32()
551 && !errors
.is_empty()
553 // In the case of a new import line, throw a diagnostic message
554 // for the previous line.
555 self.throw_unresolved_import_error(errors
);
558 if seen_spans
.insert(err
.span
) {
559 errors
.push((*import
, err
));
560 prev_root_id
= import
.root_id
;
565 if !errors
.is_empty() {
566 self.throw_unresolved_import_error(errors
);
570 for import
in &indeterminate_imports
{
571 let path
= import_path_to_string(
572 &import
.module_path
.iter().map(|seg
| seg
.ident
).collect
::<Vec
<_
>>(),
576 let err
= UnresolvedImportError
{
583 // FIXME: there should be a better way of doing this than
584 // formatting this as a string then checking for `::`
585 if path
.contains("::") {
586 errors
.push((*import
, err
))
590 if !errors
.is_empty() {
591 self.throw_unresolved_import_error(errors
);
595 pub(crate) fn check_hidden_glob_reexports(
597 exported_ambiguities
: FxHashSet
<NameBinding
<'a
>>,
599 for module
in self.arenas
.local_modules().iter() {
600 for (key
, resolution
) in self.resolutions(*module
).borrow().iter() {
601 let resolution
= resolution
.borrow();
603 if let Some(binding
) = resolution
.binding
{
604 if let NameBindingKind
::Import { import, .. }
= binding
.kind
605 && let Some((amb_binding
, _
)) = binding
.ambiguity
606 && binding
.res() != Res
::Err
607 && exported_ambiguities
.contains(&binding
)
609 self.lint_buffer
.buffer_lint_with_diagnostic(
610 AMBIGUOUS_GLOB_REEXPORTS
,
613 "ambiguous glob re-exports",
614 BuiltinLintDiagnostics
::AmbiguousGlobReexports
{
615 name
: key
.ident
.to_string(),
616 namespace
: key
.ns
.descr().to_string(),
617 first_reexport_span
: import
.root_span
,
618 duplicate_reexport_span
: amb_binding
.span
,
623 if let Some(glob_binding
) = resolution
.shadowed_glob
{
624 let binding_id
= match binding
.kind
{
625 NameBindingKind
::Res(res
) => {
626 Some(self.def_id_to_node_id
[res
.def_id().expect_local()])
628 NameBindingKind
::Module(module
) => {
629 Some(self.def_id_to_node_id
[module
.def_id().expect_local()])
631 NameBindingKind
::Import { import, .. }
=> import
.id(),
634 if binding
.res() != Res
::Err
635 && glob_binding
.res() != Res
::Err
636 && let NameBindingKind
::Import { import: glob_import, .. }
=
638 && let Some(binding_id
) = binding_id
639 && let Some(glob_import_id
) = glob_import
.id()
640 && let glob_import_def_id
= self.local_def_id(glob_import_id
)
641 && self.effective_visibilities
.is_exported(glob_import_def_id
)
642 && glob_binding
.vis
.is_public()
643 && !binding
.vis
.is_public()
645 self.lint_buffer
.buffer_lint_with_diagnostic(
646 HIDDEN_GLOB_REEXPORTS
,
649 "private item shadows public glob re-export",
650 BuiltinLintDiagnostics
::HiddenGlobReexports
{
651 name
: key
.ident
.name
.to_string(),
652 namespace
: key
.ns
.descr().to_owned(),
653 glob_reexport_span
: glob_binding
.span
,
654 private_item_span
: binding
.span
,
664 fn throw_unresolved_import_error(&mut self, errors
: Vec
<(Import
<'_
>, UnresolvedImportError
)>) {
665 if errors
.is_empty() {
669 /// Upper limit on the number of `span_label` messages.
670 const MAX_LABEL_COUNT
: usize = 10;
672 let span
= MultiSpan
::from_spans(errors
.iter().map(|(_
, err
)| err
.span
).collect());
675 .map(|(import
, err
)| {
676 let path
= import_path_to_string(
677 &import
.module_path
.iter().map(|seg
| seg
.ident
).collect
::<Vec
<_
>>(),
683 .collect
::<Vec
<_
>>();
684 let msg
= format
!("unresolved import{} {}", pluralize
!(paths
.len()), paths
.join(", "),);
686 let mut diag
= struct_span_err
!(self.tcx
.sess
, span
, E0432
, "{}", &msg
);
688 if let Some((_
, UnresolvedImportError { note: Some(note), .. }
)) = errors
.iter().last() {
689 diag
.note(note
.clone());
692 for (import
, err
) in errors
.into_iter().take(MAX_LABEL_COUNT
) {
693 if let Some(label
) = err
.label
{
694 diag
.span_label(err
.span
, label
);
697 if let Some((suggestions
, msg
, applicability
)) = err
.suggestion
{
698 if suggestions
.is_empty() {
702 diag
.multipart_suggestion(msg
, suggestions
, applicability
);
705 if let Some(candidates
) = &err
.candidates
{
707 ImportKind
::Single { nested: false, source, target, .. }
=> import_candidates(
712 DiagnosticMode
::Import
,
714 .then(|| format
!(" as {target}"))
718 ImportKind
::Single { nested: true, source, target, .. }
=> {
724 DiagnosticMode
::Normal
,
726 .then(|| format
!(" as {target}"))
736 ImportKind
::Single { source, .. }
=> {
737 if let Some(ModuleOrUniformRoot
::Module(module
)) = import
.imported_module
.get()
738 && let Some(module
) = module
.opt_def_id()
740 self.find_cfg_stripped(&mut diag
, &source
.name
, module
)
750 /// Attempts to resolve the given import, returning:
751 /// - `0` means its resolution is determined.
752 /// - Other values mean that indeterminate exists under certain namespaces.
754 /// Meanwhile, if resolve successful, the resolved bindings are written
756 fn resolve_import(&mut self, import
: Import
<'a
>) -> usize {
758 "(resolving import for module) resolving import `{}::...` in `{}`",
759 Segment
::names_to_string(&import
.module_path
),
760 module_to_string(import
.parent_scope
.module
).unwrap_or_else(|| "???".to_string()),
762 let module
= if let Some(module
) = import
.imported_module
.get() {
765 // For better failure detection, pretend that the import will
766 // not define any names while resolving its module path.
767 let orig_vis
= import
.vis
.take();
768 let path_res
= self.maybe_resolve_path(&import
.module_path
, None
, &import
.parent_scope
);
769 import
.vis
.set(orig_vis
);
772 PathResult
::Module(module
) => module
,
773 PathResult
::Indeterminate
=> return 3,
774 PathResult
::NonModule(..) | PathResult
::Failed { .. }
=> return 0,
778 import
.imported_module
.set(Some(module
));
779 let (source
, target
, source_bindings
, target_bindings
, type_ns_only
) = match import
.kind
{
787 } => (source
, target
, source_bindings
, target_bindings
, type_ns_only
),
788 ImportKind
::Glob { .. }
=> {
789 self.resolve_glob_import(import
);
795 let mut indeterminate_count
= 0;
796 self.per_ns(|this
, ns
| {
797 if !type_ns_only
|| ns
== TypeNS
{
798 if let Err(Undetermined
) = source_bindings
[ns
].get() {
799 // For better failure detection, pretend that the import will
800 // not define any names while resolving its module path.
801 let orig_vis
= import
.vis
.take();
802 let binding
= this
.maybe_resolve_ident_in_module(
806 &import
.parent_scope
,
808 import
.vis
.set(orig_vis
);
809 source_bindings
[ns
].set(binding
);
814 let parent
= import
.parent_scope
.module
;
815 match source_bindings
[ns
].get() {
816 Err(Undetermined
) => indeterminate_count
+= 1,
817 // Don't update the resolution, because it was never added.
818 Err(Determined
) if target
.name
== kw
::Underscore
=> {}
819 Ok(binding
) if binding
.is_importable() => {
820 let imported_binding
= this
.import(binding
, import
);
821 target_bindings
[ns
].set(Some(imported_binding
));
822 this
.define(parent
, target
, ns
, imported_binding
);
824 source_binding @
(Ok(..) | Err(Determined
)) => {
825 if source_binding
.is_ok() {
828 .create_err(IsNotDirectlyImportable { span: import.span, target }
)
831 let key
= BindingKey
::new(target
, ns
);
832 this
.update_resolution(parent
, key
, false, |_
, resolution
| {
833 resolution
.single_imports
.remove(&import
);
843 /// Performs final import resolution, consistency checks and error reporting.
845 /// Optionally returns an unresolved import error. This error is buffered and used to
846 /// consolidate multiple unresolved import errors into a single diagnostic.
847 fn finalize_import(&mut self, import
: Import
<'a
>) -> Option
<UnresolvedImportError
> {
848 let orig_vis
= import
.vis
.take();
849 let ignore_binding
= match &import
.kind
{
850 ImportKind
::Single { target_bindings, .. }
=> target_bindings
[TypeNS
].get(),
853 let prev_ambiguity_errors_len
= self.ambiguity_errors
.len();
854 let finalize
= Finalize
::with_root_span(import
.root_id
, import
.span
, import
.root_span
);
856 // We'll provide more context to the privacy errors later, up to `len`.
857 let privacy_errors_len
= self.privacy_errors
.len();
859 let path_res
= self.resolve_path(
862 &import
.parent_scope
,
867 let no_ambiguity
= self.ambiguity_errors
.len() == prev_ambiguity_errors_len
;
868 import
.vis
.set(orig_vis
);
869 let module
= match path_res
{
870 PathResult
::Module(module
) => {
871 // Consistency checks, analogous to `finalize_macro_resolutions`.
872 if let Some(initial_module
) = import
.imported_module
.get() {
873 if module
!= initial_module
&& no_ambiguity
{
874 span_bug
!(import
.span
, "inconsistent resolution for an import");
876 } else if self.privacy_errors
.is_empty() {
879 .create_err(CannotDetermineImportResolution { span: import.span }
)
886 is_error_from_last_segment
: false,
893 assert
!(import
.imported_module
.get().is_none());
896 ResolutionError
::FailedToResolve
{
907 is_error_from_last_segment
: true,
914 assert
!(import
.imported_module
.get().is_none());
915 let err
= match self.make_path_suggestion(
917 import
.module_path
.clone(),
918 &import
.parent_scope
,
920 Some((suggestion
, note
)) => UnresolvedImportError
{
925 vec
![(span
, Segment
::names_to_string(&suggestion
))],
926 String
::from("a similar path exists"),
927 Applicability
::MaybeIncorrect
,
931 None
=> UnresolvedImportError
{
943 PathResult
::NonModule(partial_res
) => {
944 if no_ambiguity
&& partial_res
.full_res() != Some(Res
::Err
) {
945 // Check if there are no ambiguities and the result is not dummy.
946 assert
!(import
.imported_module
.get().is_none());
948 // The error was already reported earlier.
951 PathResult
::Indeterminate
=> unreachable
!(),
954 let (ident
, target
, source_bindings
, target_bindings
, type_ns_only
, import_id
) =
964 } => (source
, target
, source_bindings
, target_bindings
, type_ns_only
, id
),
965 ImportKind
::Glob { is_prelude, ref max_vis, id }
=> {
966 if import
.module_path
.len() <= 1 {
967 // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
968 // 2 segments, so the `resolve_path` above won't trigger it.
969 let mut full_path
= import
.module_path
.clone();
970 full_path
.push(Segment
::from_ident(Ident
::empty()));
971 self.lint_if_path_starts_with_module(Some(finalize
), &full_path
, None
);
974 if let ModuleOrUniformRoot
::Module(module
) = module
{
975 if module
== import
.parent_scope
.module
{
976 // Importing a module into itself is not allowed.
977 return Some(UnresolvedImportError
{
979 label
: Some(String
::from(
980 "cannot glob-import a module into itself",
989 && let Some(max_vis
) = max_vis
.get()
990 && !max_vis
.is_at_least(import
.expect_vis(), self.tcx
)
992 self.lint_buffer
.buffer_lint(
996 fluent
::resolve_glob_import_doesnt_reexport
,
1001 _
=> unreachable
!(),
1004 if self.privacy_errors
.len() != privacy_errors_len
{
1005 // Get the Res for the last element, so that we can point to alternative ways of
1006 // importing it if available.
1007 let mut path
= import
.module_path
.clone();
1008 path
.push(Segment
::from_ident(ident
));
1009 if let PathResult
::Module(ModuleOrUniformRoot
::Module(module
)) =
1010 self.resolve_path(&path
, None
, &import
.parent_scope
, Some(finalize
), ignore_binding
)
1012 let res
= module
.res().map(|r
| (r
, ident
));
1013 for error
in &mut self.privacy_errors
[privacy_errors_len
..] {
1014 error
.outermost_res
= res
;
1019 let mut all_ns_err
= true;
1020 self.per_ns(|this
, ns
| {
1021 if !type_ns_only
|| ns
== TypeNS
{
1022 let orig_vis
= import
.vis
.take();
1023 let binding
= this
.resolve_ident_in_module(
1027 &import
.parent_scope
,
1028 Some(Finalize { report_private: false, ..finalize }
),
1029 target_bindings
[ns
].get(),
1031 import
.vis
.set(orig_vis
);
1035 // Consistency checks, analogous to `finalize_macro_resolutions`.
1036 let initial_res
= source_bindings
[ns
].get().map(|initial_binding
| {
1038 if let Some(target_binding
) = target_bindings
[ns
].get() {
1039 if target
.name
== kw
::Underscore
1040 && initial_binding
.is_extern_crate()
1041 && !initial_binding
.is_import()
1046 import
.module_path
.is_empty(),
1050 initial_binding
.res()
1052 let res
= binding
.res();
1053 let has_ambiguity_error
= this
1056 .filter(|error
| !error
.warning
)
1059 if res
== Res
::Err
|| has_ambiguity_error
{
1062 .delay_span_bug(import
.span
, "some error happened for an import");
1065 if let Ok(initial_res
) = initial_res
{
1066 if res
!= initial_res
{
1067 span_bug
!(import
.span
, "inconsistent resolution for an import");
1069 } else if this
.privacy_errors
.is_empty() {
1072 .create_err(CannotDetermineImportResolution { span: import.span }
)
1077 // FIXME: This assert may fire if public glob is later shadowed by a private
1078 // single import (see test `issue-55884-2.rs`). In theory single imports should
1079 // always block globs, even if they are not yet resolved, so that this kind of
1080 // self-inconsistent resolution never happens.
1081 // Re-enable the assert when the issue is fixed.
1082 // assert!(result[ns].get().is_err());
1089 let mut all_ns_failed
= true;
1090 self.per_ns(|this
, ns
| {
1091 if !type_ns_only
|| ns
== TypeNS
{
1092 let binding
= this
.resolve_ident_in_module(
1096 &import
.parent_scope
,
1100 if binding
.is_ok() {
1101 all_ns_failed
= false;
1106 return if all_ns_failed
{
1107 let resolutions
= match module
{
1108 ModuleOrUniformRoot
::Module(module
) => Some(self.resolutions(module
).borrow()),
1111 let resolutions
= resolutions
.as_ref().into_iter().flat_map(|r
| r
.iter());
1112 let names
= resolutions
1113 .filter_map(|(BindingKey { ident: i, .. }
, resolution
)| {
1114 if i
.name
== ident
.name
{
1116 } // Never suggest the same name
1117 match *resolution
.borrow() {
1118 NameResolution { binding: Some(name_binding), .. }
=> {
1119 match name_binding
.kind
{
1120 NameBindingKind
::Import { binding, .. }
=> {
1121 match binding
.kind
{
1122 // Never suggest the name that has binding error
1123 // i.e., the name that cannot be previously resolved
1124 NameBindingKind
::Res(Res
::Err
) => None
,
1131 NameResolution { ref single_imports, .. }
1132 if single_imports
.is_empty() =>
1139 .collect
::<Vec
<Symbol
>>();
1141 let lev_suggestion
=
1142 find_best_match_for_name(&names
, ident
.name
, None
).map(|suggestion
| {
1144 vec
![(ident
.span
, suggestion
.to_string())],
1145 String
::from("a similar name exists in the module"),
1146 Applicability
::MaybeIncorrect
,
1150 let (suggestion
, note
) =
1151 match self.check_for_module_export_macro(import
, module
, ident
) {
1152 Some((suggestion
, note
)) => (suggestion
.or(lev_suggestion
), note
),
1153 _
=> (lev_suggestion
, None
),
1156 let label
= match module
{
1157 ModuleOrUniformRoot
::Module(module
) => {
1158 let module_str
= module_to_string(module
);
1159 if let Some(module_str
) = module_str
{
1160 format
!("no `{ident}` in `{module_str}`")
1162 format
!("no `{ident}` in the root")
1166 if !ident
.is_path_segment_keyword() {
1167 format
!("no external crate `{ident}`")
1169 // HACK(eddyb) this shows up for `self` & `super`, which
1170 // should work instead - for now keep the same error message.
1171 format
!("no `{ident}` in the root")
1176 let parent_suggestion
=
1177 self.lookup_import_candidates(ident
, TypeNS
, &import
.parent_scope
, |_
| true);
1179 Some(UnresolvedImportError
{
1184 candidates
: if !parent_suggestion
.is_empty() {
1185 Some(parent_suggestion
)
1191 // `resolve_ident_in_module` reported a privacy error.
1196 let mut reexport_error
= None
;
1197 let mut any_successful_reexport
= false;
1198 let mut crate_private_reexport
= false;
1199 self.per_ns(|this
, ns
| {
1200 if let Ok(binding
) = source_bindings
[ns
].get() {
1201 if !binding
.vis
.is_at_least(import
.expect_vis(), this
.tcx
) {
1202 reexport_error
= Some((ns
, binding
));
1203 if let ty
::Visibility
::Restricted(binding_def_id
) = binding
.vis
{
1204 if binding_def_id
.is_top_level_module() {
1205 crate_private_reexport
= true;
1209 any_successful_reexport
= true;
1214 // All namespaces must be re-exported with extra visibility for an error to occur.
1215 if !any_successful_reexport
{
1216 let (ns
, binding
) = reexport_error
.unwrap();
1217 if pub_use_of_private_extern_crate_hack(import
, binding
) {
1219 "extern crate `{ident}` is private, and cannot be \
1220 re-exported (error E0365), consider declaring with \
1223 self.lint_buffer
.buffer_lint(
1224 PUB_USE_OF_PRIVATE_EXTERN_CRATE
,
1231 let mut err
= if crate_private_reexport
{
1232 self.tcx
.sess
.create_err(CannotBeReexportedCratePublicNS
{
1239 .create_err(CannotBeReexportedPrivateNS { span: import.span, ident }
)
1243 let mut err
= if crate_private_reexport
{
1246 .create_err(CannotBeReexportedCratePublic { span: import.span, ident }
)
1250 .create_err(CannotBeReexportedPrivate { span: import.span, ident }
)
1253 match binding
.kind
{
1254 NameBindingKind
::Res(Res
::Def(DefKind
::Macro(_
), def_id
))
1255 // exclude decl_macro
1256 if self.get_macro_by_def_id(def_id
).macro_rules
=>
1258 err
.subdiagnostic(ConsiderAddingMacroExport
{
1263 err
.subdiagnostic(ConsiderMarkingAsPub
{
1274 if import
.module_path
.len() <= 1 {
1275 // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
1276 // 2 segments, so the `resolve_path` above won't trigger it.
1277 let mut full_path
= import
.module_path
.clone();
1278 full_path
.push(Segment
::from_ident(ident
));
1279 self.per_ns(|this
, ns
| {
1280 if let Ok(binding
) = source_bindings
[ns
].get() {
1281 this
.lint_if_path_starts_with_module(Some(finalize
), &full_path
, Some(binding
));
1286 // Record what this import resolves to for later uses in documentation,
1287 // this may resolve to either a value or a type, but for documentation
1288 // purposes it's good enough to just favor one over the other.
1289 self.per_ns(|this
, ns
| {
1290 if let Ok(binding
) = source_bindings
[ns
].get() {
1291 this
.import_res_map
.entry(import_id
).or_default()[ns
] = Some(binding
.res());
1295 self.check_for_redundant_imports(ident
, import
, source_bindings
, target_bindings
, target
);
1297 debug
!("(resolving single import) successfully resolved import");
1301 fn check_for_redundant_imports(
1305 source_bindings
: &PerNS
<Cell
<Result
<NameBinding
<'a
>, Determinacy
>>>,
1306 target_bindings
: &PerNS
<Cell
<Option
<NameBinding
<'a
>>>>,
1309 // This function is only called for single imports.
1310 let ImportKind
::Single { id, .. }
= import
.kind
else { unreachable!() }
;
1312 // Skip if the import was produced by a macro.
1313 if import
.parent_scope
.expansion
!= LocalExpnId
::ROOT
{
1317 // Skip if we are inside a named module (in contrast to an anonymous
1318 // module defined by a block).
1319 if let ModuleKind
::Def(..) = import
.parent_scope
.module
.kind
{
1323 let mut is_redundant
= PerNS { value_ns: None, type_ns: None, macro_ns: None }
;
1325 let mut redundant_span
= PerNS { value_ns: None, type_ns: None, macro_ns: None }
;
1327 self.per_ns(|this
, ns
| {
1328 if let Ok(binding
) = source_bindings
[ns
].get() {
1329 if binding
.res() == Res
::Err
{
1333 match this
.early_resolve_ident_in_lexical_scope(
1336 &import
.parent_scope
,
1339 target_bindings
[ns
].get(),
1341 Ok(other_binding
) => {
1342 is_redundant
[ns
] = Some(
1343 binding
.res() == other_binding
.res() && !other_binding
.is_ambiguity(),
1345 redundant_span
[ns
] = Some((other_binding
.span
, other_binding
.is_import()));
1347 Err(_
) => is_redundant
[ns
] = Some(false),
1352 if !is_redundant
.is_empty() && is_redundant
.present_items().all(|is_redundant
| is_redundant
)
1354 let mut redundant_spans
: Vec
<_
> = redundant_span
.present_items().collect();
1355 redundant_spans
.sort();
1356 redundant_spans
.dedup();
1357 self.lint_buffer
.buffer_lint_with_diagnostic(
1361 format
!("the item `{ident}` is imported redundantly"),
1362 BuiltinLintDiagnostics
::RedundantImport(redundant_spans
, ident
),
1367 fn resolve_glob_import(&mut self, import
: Import
<'a
>) {
1368 // This function is only called for glob imports.
1369 let ImportKind
::Glob { id, is_prelude, .. }
= import
.kind
else { unreachable!() }
;
1371 let ModuleOrUniformRoot
::Module(module
) = import
.imported_module
.get().unwrap() else {
1372 self.tcx
.sess
.create_err(CannotGlobImportAllCrates { span: import.span }
).emit();
1376 if module
.is_trait() {
1377 self.tcx
.sess
.create_err(ItemsInTraitsAreNotImportable { span: import.span }
).emit();
1379 } else if module
== import
.parent_scope
.module
{
1381 } else if is_prelude
{
1382 self.prelude
= Some(module
);
1386 // Add to module's glob_importers
1387 module
.glob_importers
.borrow_mut().push(import
);
1389 // Ensure that `resolutions` isn't borrowed during `try_define`,
1390 // since it might get updated via a glob cycle.
1392 .resolutions(module
)
1395 .filter_map(|(key
, resolution
)| {
1396 resolution
.borrow().binding().map(|binding
| (*key
, binding
))
1398 .collect
::<Vec
<_
>>();
1399 for (mut key
, binding
) in bindings
{
1400 let scope
= match key
.ident
.span
.reverse_glob_adjust(module
.expansion
, import
.span
) {
1401 Some(Some(def
)) => self.expn_def_scope(def
),
1402 Some(None
) => import
.parent_scope
.module
,
1405 if self.is_accessible_from(binding
.vis
, scope
) {
1406 let imported_binding
= self.import(binding
, import
);
1407 let warn_ambiguity
= self
1408 .resolution(import
.parent_scope
.module
, key
)
1411 .is_some_and(|binding
| binding
.is_warn_ambiguity());
1412 let _
= self.try_define(
1413 import
.parent_scope
.module
,
1421 // Record the destination of this import
1422 self.record_partial_res(id
, PartialRes
::new(module
.res().unwrap()));
1425 // Miscellaneous post-processing, including recording re-exports,
1426 // reporting conflicts, and reporting unresolved imports.
1427 fn finalize_resolutions_in(&mut self, module
: Module
<'a
>) {
1428 // Since import resolution is finished, globs will not define any more names.
1429 *module
.globs
.borrow_mut() = Vec
::new();
1431 if let Some(def_id
) = module
.opt_def_id() {
1432 let mut children
= Vec
::new();
1434 module
.for_each_child(self, |this
, ident
, _
, binding
| {
1435 let res
= binding
.res().expect_non_local();
1436 let error_ambiguity
= binding
.is_ambiguity() && !binding
.warn_ambiguity
;
1437 if res
!= def
::Res
::Err
&& !error_ambiguity
{
1438 let mut reexport_chain
= SmallVec
::new();
1439 let mut next_binding
= binding
;
1440 while let NameBindingKind
::Import { binding, import, .. }
= next_binding
.kind
{
1441 reexport_chain
.push(import
.simplify(this
));
1442 next_binding
= binding
;
1445 children
.push(ModChild { ident, res, vis: binding.vis, reexport_chain }
);
1449 if !children
.is_empty() {
1450 // Should be fine because this code is only called for local modules.
1451 self.module_children
.insert(def_id
.expect_local(), children
);
1457 fn import_path_to_string(names
: &[Ident
], import_kind
: &ImportKind
<'_
>, span
: Span
) -> String
{
1458 let pos
= names
.iter().position(|p
| span
== p
.span
&& p
.name
!= kw
::PathRoot
);
1459 let global
= !names
.is_empty() && names
[0].name
== kw
::PathRoot
;
1460 if let Some(pos
) = pos
{
1461 let names
= if global { &names[1..pos + 1] }
else { &names[..pos + 1] }
;
1462 names_to_string(&names
.iter().map(|ident
| ident
.name
).collect
::<Vec
<_
>>())
1464 let names
= if global { &names[1..] }
else { names }
;
1465 if names
.is_empty() {
1466 import_kind_to_string(import_kind
)
1470 names_to_string(&names
.iter().map(|ident
| ident
.name
).collect
::<Vec
<_
>>()),
1471 import_kind_to_string(import_kind
),
1477 fn import_kind_to_string(import_kind
: &ImportKind
<'_
>) -> String
{
1479 ImportKind
::Single { source, .. }
=> source
.to_string(),
1480 ImportKind
::Glob { .. }
=> "*".to_string(),
1481 ImportKind
::ExternCrate { .. }
=> "<extern crate>".to_string(),
1482 ImportKind
::MacroUse
=> "#[macro_use]".to_string(),
1483 ImportKind
::MacroExport
=> "#[macro_export]".to_string(),