]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_resolve/src/imports.rs
New upstream version 1.71.1+dfsg1
[rustc.git] / compiler / rustc_resolve / src / imports.rs
CommitLineData
e1599b0c
XL
1//! A bunch of methods and structures more or less related to resolving imports.
2
9c376795 3use crate::diagnostics::{import_candidates, DiagnosticMode, Suggestion};
dfeec247 4use crate::Determinacy::{self, *};
2b03887a
FG
5use crate::Namespace::*;
6use crate::{module_to_string, names_to_string, ImportSuggestion};
487cf647
FG
7use crate::{
8 AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, ModuleKind, ResolutionError,
9 Resolver, Segment,
10};
04454e1e
FG
11use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
12use crate::{NameBinding, NameBindingKind, PathResult};
dfeec247 13
3dfed10e 14use rustc_ast::NodeId;
dfeec247 15use rustc_data_structures::fx::FxHashSet;
5099ac24 16use rustc_data_structures::intern::Interned;
04454e1e 17use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
923072b8 18use rustc_hir::def::{self, DefKind, PartialRes};
5099ac24 19use rustc_middle::metadata::ModChild;
353b0b11 20use rustc_middle::metadata::Reexport;
6a06907d 21use rustc_middle::span_bug;
ba9703b0 22use rustc_middle::ty;
353b0b11
FG
23use rustc_session::lint::builtin::{
24 AMBIGUOUS_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS,
25};
dfeec247 26use rustc_session::lint::BuiltinLintDiagnostics;
9ffffee4 27use rustc_span::edit_distance::find_best_match_for_name;
136023e0 28use rustc_span::hygiene::LocalExpnId;
f9f354fc 29use rustc_span::symbol::{kw, Ident, Symbol};
04454e1e 30use rustc_span::Span;
353b0b11 31use smallvec::SmallVec;
60c5eb7d 32
e1599b0c 33use std::cell::Cell;
83c7162d 34use std::{mem, ptr};
3157f602 35
48663c56
XL
36type Res = def::Res<NodeId>;
37
74b04a01 38/// Contains data for specific kinds of imports.
f2b60f7d 39#[derive(Clone)]
9ffffee4 40pub(crate) enum ImportKind<'a> {
74b04a01 41 Single {
0731742a 42 /// `source` in `use prefix::source as target`.
32a655c1 43 source: Ident,
0731742a 44 /// `target` in `use prefix::source as target`.
69743fb6 45 target: Ident,
0731742a 46 /// Bindings to which `source` refers to.
69743fb6 47 source_bindings: PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
0731742a 48 /// Bindings introduced by `target`.
69743fb6 49 target_bindings: PerNS<Cell<Option<&'a NameBinding<'a>>>>,
0731742a 50 /// `true` for `...::{self [as target]}` imports, `false` otherwise.
32a655c1 51 type_ns_only: bool,
9fa01778
XL
52 /// Did this import result from a nested import? ie. `use foo::{bar, baz};`
53 nested: bool,
487cf647
FG
54 /// The ID of the `UseTree` that imported this `Import`.
55 ///
56 /// In the case where the `Import` was expanded from a "nested" use tree,
57 /// this id is the ID of the leaf tree. For example:
58 ///
59 /// ```ignore (pacify the merciless tidy)
60 /// use foo::bar::{a, b}
61 /// ```
62 ///
63 /// If this is the import for `foo::bar::a`, we would have the ID of the `UseTree`
64 /// for `a` in this field.
65 id: NodeId,
9e0c209e 66 },
74b04a01 67 Glob {
9e0c209e 68 is_prelude: bool,
487cf647
FG
69 // The visibility of the greatest re-export.
70 // n.b. `max_vis` is only used in `finalize_import` to check for re-export errors.
71 max_vis: Cell<Option<ty::Visibility>>,
72 id: NodeId,
54a0048b 73 },
0bf4aa26 74 ExternCrate {
f9f354fc 75 source: Option<Symbol>,
0bf4aa26 76 target: Ident,
487cf647 77 id: NodeId,
0bf4aa26 78 },
32a655c1 79 MacroUse,
487cf647 80 MacroExport,
c34b1796
AL
81}
82
f2b60f7d
FG
83/// Manually implement `Debug` for `ImportKind` because the `source/target_bindings`
84/// contain `Cell`s which can introduce infinite loops while printing.
85impl<'a> std::fmt::Debug for ImportKind<'a> {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 use ImportKind::*;
88 match self {
89 Single {
90 ref source,
91 ref target,
353b0b11
FG
92 ref source_bindings,
93 ref target_bindings,
f2b60f7d
FG
94 ref type_ns_only,
95 ref nested,
487cf647 96 ref id,
f2b60f7d
FG
97 } => f
98 .debug_struct("Single")
99 .field("source", source)
100 .field("target", target)
353b0b11
FG
101 // Ignore the nested bindings to avoid an infinite loop while printing.
102 .field(
103 "source_bindings",
104 &source_bindings.clone().map(|b| b.into_inner().map(|_| format_args!(".."))),
105 )
106 .field(
107 "target_bindings",
108 &target_bindings.clone().map(|b| b.into_inner().map(|_| format_args!(".."))),
109 )
f2b60f7d
FG
110 .field("type_ns_only", type_ns_only)
111 .field("nested", nested)
487cf647 112 .field("id", id)
353b0b11 113 .finish(),
487cf647 114 Glob { ref is_prelude, ref max_vis, ref id } => f
f2b60f7d
FG
115 .debug_struct("Glob")
116 .field("is_prelude", is_prelude)
117 .field("max_vis", max_vis)
487cf647 118 .field("id", id)
f2b60f7d 119 .finish(),
487cf647 120 ExternCrate { ref source, ref target, ref id } => f
f2b60f7d
FG
121 .debug_struct("ExternCrate")
122 .field("source", source)
123 .field("target", target)
487cf647 124 .field("id", id)
f2b60f7d
FG
125 .finish(),
126 MacroUse => f.debug_struct("MacroUse").finish(),
487cf647 127 MacroExport => f.debug_struct("MacroExport").finish(),
f2b60f7d
FG
128 }
129 }
130}
131
74b04a01 132/// One import.
e1599b0c 133#[derive(Debug, Clone)]
923072b8 134pub(crate) struct Import<'a> {
74b04a01
XL
135 pub kind: ImportKind<'a>,
136
487cf647
FG
137 /// Node ID of the "root" use item -- this is always the same as `ImportKind`'s `id`
138 /// (if it exists) except in the case of "nested" use trees, in which case
139 /// it will be the ID of the root use tree. e.g., in the example
140 /// ```ignore (incomplete code)
94b46f34
XL
141 /// use foo::bar::{a, b}
142 /// ```
487cf647
FG
143 /// this would be the ID of the `use foo::bar` `UseTree` node.
144 /// In case of imports without their own node ID it's the closest node that can be used,
145 /// for example, for reporting lints.
94b46f34
XL
146 pub root_id: NodeId,
147
9fa01778
XL
148 /// Span of the entire use statement.
149 pub use_span: Span,
150
151 /// Span of the entire use statement with attributes.
152 pub use_span_with_attributes: Span,
153
154 /// Did the use statement have any attributes?
155 pub has_attributes: bool,
156
94b46f34
XL
157 /// Span of this use tree.
158 pub span: Span,
159
160 /// Span of the *root* use tree (see `root_id`).
161 pub root_span: Span,
162
0bf4aa26 163 pub parent_scope: ParentScope<'a>,
13cf67c4 164 pub module_path: Vec<Segment>,
b7449926
XL
165 /// The resolution of `module_path`.
166 pub imported_module: Cell<Option<ModuleOrUniformRoot<'a>>>,
f2b60f7d 167 pub vis: Cell<Option<ty::Visibility>>,
32a655c1 168 pub used: Cell<bool>,
c34b1796
AL
169}
170
74b04a01 171impl<'a> Import<'a> {
9ffffee4 172 pub(crate) fn is_glob(&self) -> bool {
29967ef6 173 matches!(self.kind, ImportKind::Glob { .. })
a7813a04 174 }
94b46f34 175
9ffffee4 176 pub(crate) fn is_nested(&self) -> bool {
74b04a01
XL
177 match self.kind {
178 ImportKind::Single { nested, .. } => nested,
dfeec247 179 _ => false,
9fa01778
XL
180 }
181 }
f2b60f7d
FG
182
183 pub(crate) fn expect_vis(&self) -> ty::Visibility {
184 self.vis.get().expect("encountered cleared import visibility")
185 }
487cf647
FG
186
187 pub(crate) fn id(&self) -> Option<NodeId> {
188 match self.kind {
189 ImportKind::Single { id, .. }
190 | ImportKind::Glob { id, .. }
191 | ImportKind::ExternCrate { id, .. } => Some(id),
192 ImportKind::MacroUse | ImportKind::MacroExport => None,
193 }
194 }
353b0b11
FG
195
196 fn simplify(&self, r: &Resolver<'_, '_>) -> Reexport {
197 let to_def_id = |id| r.local_def_id(id).to_def_id();
198 match self.kind {
199 ImportKind::Single { id, .. } => Reexport::Single(to_def_id(id)),
200 ImportKind::Glob { id, .. } => Reexport::Glob(to_def_id(id)),
201 ImportKind::ExternCrate { id, .. } => Reexport::ExternCrate(to_def_id(id)),
202 ImportKind::MacroUse => Reexport::MacroUse,
203 ImportKind::MacroExport => Reexport::MacroExport,
204 }
205 }
c34b1796
AL
206}
207
54a0048b 208/// Records information about the resolution of a name in a namespace of a module.
04454e1e 209#[derive(Clone, Default, Debug)]
923072b8 210pub(crate) struct NameResolution<'a> {
8faf50e0 211 /// Single imports that may define the name in the namespace.
74b04a01 212 /// Imports are arena-allocated, so it's ok to use pointers as keys.
04454e1e 213 pub single_imports: FxHashSet<Interned<'a, Import<'a>>>,
7453a54e
SL
214 /// The least shadowable known binding for this name, or None if there are no known bindings.
215 pub binding: Option<&'a NameBinding<'a>>,
04454e1e 216 pub shadowed_glob: Option<&'a NameBinding<'a>>,
9cc50fc6
SL
217}
218
7453a54e 219impl<'a> NameResolution<'a> {
487cf647 220 /// Returns the binding for the name if it is known or None if it not known.
48663c56 221 pub(crate) fn binding(&self) -> Option<&'a NameBinding<'a>> {
8faf50e0 222 self.binding.and_then(|binding| {
dfeec247
XL
223 if !binding.is_glob_import() || self.single_imports.is_empty() {
224 Some(binding)
225 } else {
226 None
227 }
54a0048b
SL
228 })
229 }
416331ca 230
923072b8 231 pub(crate) fn add_single_import(&mut self, import: &'a Import<'a>) {
5099ac24 232 self.single_imports.insert(Interned::new_unchecked(import));
416331ca 233 }
9e0c209e
SL
234}
235
9ffffee4
FG
236/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved
237/// import errors within the same use tree into a single diagnostic.
238#[derive(Debug, Clone)]
239struct UnresolvedImportError {
240 span: Span,
241 label: Option<String>,
242 note: Option<String>,
243 suggestion: Option<Suggestion>,
244 candidates: Option<Vec<ImportSuggestion>>,
245}
246
6a06907d
XL
247// Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;`
248// are permitted for backward-compatibility under a deprecation lint.
249fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBinding<'_>) -> bool {
250 match (&import.kind, &binding.kind) {
251 (
252 ImportKind::Single { .. },
253 NameBindingKind::Import {
254 import: Import { kind: ImportKind::ExternCrate { .. }, .. },
255 ..
256 },
f2b60f7d 257 ) => import.expect_vis().is_public(),
6a06907d
XL
258 _ => false,
259 }
260}
261
9ffffee4 262impl<'a, 'tcx> Resolver<'a, 'tcx> {
487cf647
FG
263 /// Given a binding and an import that resolves to it,
264 /// return the corresponding binding defined by the import.
923072b8 265 pub(crate) fn import(
dfeec247
XL
266 &self,
267 binding: &'a NameBinding<'a>,
74b04a01 268 import: &'a Import<'a>,
dfeec247 269 ) -> &'a NameBinding<'a> {
f2b60f7d 270 let import_vis = import.expect_vis().to_def_id();
353b0b11 271 let vis = if binding.vis.is_at_least(import_vis, self.tcx)
6a06907d 272 || pub_use_of_private_extern_crate_hack(import, binding)
dfeec247 273 {
f2b60f7d 274 import_vis
9e0c209e 275 } else {
6a06907d 276 binding.vis
9e0c209e
SL
277 };
278
74b04a01 279 if let ImportKind::Glob { ref max_vis, .. } = import.kind {
f2b60f7d 280 if vis == import_vis
353b0b11 281 || max_vis.get().map_or(true, |max_vis| vis.is_at_least(max_vis, self.tcx))
f2b60f7d
FG
282 {
283 max_vis.set(Some(vis.expect_local()))
9e0c209e
SL
284 }
285 }
286
32a655c1 287 self.arenas.alloc_name_binding(NameBinding {
74b04a01 288 kind: NameBindingKind::Import { binding, import, used: Cell::new(false) },
0731742a 289 ambiguity: None,
74b04a01 290 span: import.span,
3b2f2976 291 vis,
74b04a01 292 expansion: import.parent_scope.expansion,
32a655c1 293 })
5bcae85e 294 }
54a0048b 295
487cf647 296 /// Define the name or return the existing binding if there is a collision.
923072b8 297 pub(crate) fn try_define(
e1599b0c
XL
298 &mut self,
299 module: Module<'a>,
e74abb32 300 key: BindingKey,
e1599b0c
XL
301 binding: &'a NameBinding<'a>,
302 ) -> Result<(), &'a NameBinding<'a>> {
416331ca 303 let res = binding.res();
e74abb32 304 self.check_reserved_macro_name(key.ident, res);
4462d4a0 305 self.set_binding_parent_module(binding, module);
e74abb32 306 self.update_resolution(module, key, |this, resolution| {
5bcae85e 307 if let Some(old_binding) = resolution.binding {
2b03887a 308 if res == Res::Err && old_binding.res() != Res::Err {
48663c56 309 // Do not override real bindings with `Res::Err`s from error recovery.
69743fb6
XL
310 return Ok(());
311 }
13cf67c4
XL
312 match (old_binding.is_glob_import(), binding.is_glob_import()) {
313 (true, true) => {
416331ca 314 if res != old_binding.res() {
dfeec247
XL
315 resolution.binding = Some(this.ambiguity(
316 AmbiguityKind::GlobVsGlob,
317 old_binding,
318 binding,
319 ));
353b0b11 320 } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
13cf67c4
XL
321 // We are glob-importing the same item but with greater visibility.
322 resolution.binding = Some(binding);
323 }
9e0c209e 324 }
13cf67c4 325 (old_glob @ true, false) | (old_glob @ false, true) => {
dfeec247
XL
326 let (glob_binding, nonglob_binding) =
327 if old_glob { (old_binding, binding) } else { (binding, old_binding) };
e74abb32 328 if glob_binding.res() != nonglob_binding.res()
dfeec247 329 && key.ns == MacroNS
136023e0 330 && nonglob_binding.expansion != LocalExpnId::ROOT
e74abb32 331 {
e1599b0c
XL
332 resolution.binding = Some(this.ambiguity(
333 AmbiguityKind::GlobVsExpanded,
334 nonglob_binding,
335 glob_binding,
336 ));
13cf67c4
XL
337 } else {
338 resolution.binding = Some(nonglob_binding);
13cf67c4 339 }
0731742a 340 resolution.shadowed_glob = Some(glob_binding);
13cf67c4
XL
341 }
342 (false, false) => {
dfeec247 343 return Err(old_binding);
476ff2be 344 }
5bcae85e
SL
345 }
346 } else {
347 resolution.binding = Some(binding);
348 }
349
350 Ok(())
351 })
352 }
353
e1599b0c 354 fn ambiguity(
dfeec247
XL
355 &self,
356 kind: AmbiguityKind,
e1599b0c
XL
357 primary_binding: &'a NameBinding<'a>,
358 secondary_binding: &'a NameBinding<'a>,
359 ) -> &'a NameBinding<'a> {
476ff2be 360 self.arenas.alloc_name_binding(NameBinding {
0731742a 361 ambiguity: Some((secondary_binding, kind)),
9fa01778 362 ..primary_binding.clone()
476ff2be
SL
363 })
364 }
365
5bcae85e 366 // Use `f` to mutate the resolution of the name in the module.
54a0048b 367 // If the resolution becomes a success, define it in the module's glob importers.
dfeec247
XL
368 fn update_resolution<T, F>(&mut self, module: Module<'a>, key: BindingKey, f: F) -> T
369 where
9ffffee4 370 F: FnOnce(&mut Resolver<'a, 'tcx>, &mut NameResolution<'a>) -> T,
54a0048b 371 {
5bcae85e
SL
372 // Ensure that `resolution` isn't borrowed when defining in the module's glob importers,
373 // during which the resolution might end up getting re-defined via a glob cycle.
9e0c209e 374 let (binding, t) = {
e74abb32 375 let resolution = &mut *self.resolution(module, key).borrow_mut();
9e0c209e 376 let old_binding = resolution.binding();
54a0048b 377
5bcae85e 378 let t = f(self, resolution);
54a0048b 379
54a0048b 380 match resolution.binding() {
476ff2be 381 _ if old_binding.is_some() => return t,
54a0048b 382 None => return t,
9e0c209e 383 Some(binding) => match old_binding {
8faf50e0 384 Some(old_binding) if ptr::eq(old_binding, binding) => return t,
9e0c209e 385 _ => (binding, t),
dfeec247 386 },
54a0048b
SL
387 }
388 };
c34b1796 389
9e0c209e 390 // Define `binding` in `module`s glob importers.
74b04a01 391 for import in module.glob_importers.borrow_mut().iter() {
e74abb32 392 let mut ident = key.ident;
74b04a01 393 let scope = match ident.span.reverse_glob_adjust(module.expansion, import.span) {
c295e0f8 394 Some(Some(def)) => self.expn_def_scope(def),
74b04a01 395 Some(None) => import.parent_scope.module,
7cac9316
XL
396 None => continue,
397 };
398 if self.is_accessible_from(binding.vis, scope) {
74b04a01 399 let imported_binding = self.import(binding, import);
e74abb32 400 let key = BindingKey { ident, ..key };
74b04a01 401 let _ = self.try_define(import.parent_scope.module, key, imported_binding);
5bcae85e 402 }
54a0048b 403 }
5bcae85e
SL
404
405 t
c34b1796 406 }
476ff2be 407
49aad941
FG
408 // Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
409 // or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
410 fn import_dummy_binding(&mut self, import: &'a Import<'a>, is_indeterminate: bool) {
04454e1e 411 if let ImportKind::Single { target, ref target_bindings, .. } = import.kind {
49aad941
FG
412 if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().is_none()))
413 {
04454e1e
FG
414 return; // Has resolution, do not create the dummy binding
415 }
476ff2be 416 let dummy_binding = self.dummy_binding;
74b04a01 417 let dummy_binding = self.import(dummy_binding, import);
476ff2be 418 self.per_ns(|this, ns| {
49aad941 419 let key = BindingKey::new(target, ns);
74b04a01 420 let _ = this.try_define(import.parent_scope.module, key, dummy_binding);
476ff2be 421 });
94222f64 422 self.record_use(target, dummy_binding, false);
04454e1e
FG
423 } else if import.imported_module.get().is_none() {
424 import.used.set(true);
487cf647
FG
425 if let Some(id) = import.id() {
426 self.used_imports.insert(id);
427 }
476ff2be
SL
428 }
429 }
5bcae85e 430
c34b1796
AL
431 // Import resolution
432 //
433 // This is a fixed-point algorithm. We resolve imports until our efforts
434 // are stymied by an unresolved import; then we bail out of the current
435 // module and continue. We terminate successfully once no more imports
436 // remain or unsuccessfully when no forward progress in resolving imports
437 // is made.
438
439 /// Resolves all imports for the crate. This method performs the fixed-
440 /// point iteration.
9ffffee4 441 pub(crate) fn resolve_imports(&mut self) {
353b0b11
FG
442 let mut prev_indeterminate_count = usize::MAX;
443 let mut indeterminate_count = self.indeterminate_imports.len() * 3;
444 while indeterminate_count < prev_indeterminate_count {
445 prev_indeterminate_count = indeterminate_count;
446 indeterminate_count = 0;
9ffffee4 447 for import in mem::take(&mut self.indeterminate_imports) {
353b0b11
FG
448 let import_indeterminate_count = self.resolve_import(&import);
449 indeterminate_count += import_indeterminate_count;
450 match import_indeterminate_count {
451 0 => self.determined_imports.push(import),
452 _ => self.indeterminate_imports.push(import),
a7813a04 453 }
c34b1796 454 }
9e0c209e 455 }
476ff2be 456 }
9e0c209e 457
9ffffee4
FG
458 pub(crate) fn finalize_imports(&mut self) {
459 for module in self.arenas.local_modules().iter() {
9e0c209e
SL
460 self.finalize_resolutions_in(module);
461 }
462
0bf4aa26 463 let mut seen_spans = FxHashSet::default();
532ac7d7 464 let mut errors = vec![];
a1dfa0c6 465 let mut prev_root_id: NodeId = NodeId::from_u32(0);
9ffffee4
FG
466 let determined_imports = mem::take(&mut self.determined_imports);
467 let indeterminate_imports = mem::take(&mut self.indeterminate_imports);
e1599b0c
XL
468
469 for (is_indeterminate, import) in determined_imports
470 .into_iter()
471 .map(|i| (false, i))
472 .chain(indeterminate_imports.into_iter().map(|i| (true, i)))
473 {
04454e1e
FG
474 let unresolved_import_error = self.finalize_import(import);
475
476 // If this import is unresolved then create a dummy import
477 // resolution for it so that later resolve stages won't complain.
49aad941 478 self.import_dummy_binding(import, is_indeterminate);
04454e1e
FG
479
480 if let Some(err) = unresolved_import_error {
74b04a01 481 if let ImportKind::Single { source, ref source_bindings, .. } = import.kind {
dc9dc135 482 if source.name == kw::SelfLower {
041b39d2 483 // Silence `unresolved import` error if E0429 is already emitted
69743fb6 484 if let Err(Determined) = source_bindings.value_ns.get() {
0bf4aa26 485 continue;
041b39d2
XL
486 }
487 }
488 }
489
532ac7d7 490 if prev_root_id.as_u32() != 0
dfeec247
XL
491 && prev_root_id.as_u32() != import.root_id.as_u32()
492 && !errors.is_empty()
493 {
532ac7d7
XL
494 // In the case of a new import line, throw a diagnostic message
495 // for the previous line.
487cf647 496 self.throw_unresolved_import_error(errors);
532ac7d7 497 errors = vec![];
b7449926 498 }
e74abb32 499 if seen_spans.insert(err.span) {
9c376795 500 errors.push((import, err));
b7449926 501 prev_root_id = import.root_id;
3b2f2976 502 }
e1599b0c 503 } else if is_indeterminate {
e1599b0c
XL
504 let path = import_path_to_string(
505 &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
74b04a01 506 &import.kind,
e1599b0c
XL
507 import.span,
508 );
509 let err = UnresolvedImportError {
510 span: import.span,
511 label: None,
064997fb 512 note: None,
e1599b0c 513 suggestion: None,
9c376795 514 candidates: None,
e1599b0c 515 };
9c376795
FG
516 // FIXME: there should be a better way of doing this than
517 // formatting this as a string then checking for `::`
5e7ed085 518 if path.contains("::") {
9c376795 519 errors.push((import, err))
5e7ed085 520 }
c34b1796 521 }
9e0c209e 522 }
c34b1796 523
532ac7d7 524 if !errors.is_empty() {
487cf647 525 self.throw_unresolved_import_error(errors);
b7449926 526 }
b7449926
XL
527 }
528
353b0b11
FG
529 pub(crate) fn check_reexport_ambiguities(
530 &mut self,
531 exported_ambiguities: FxHashSet<Interned<'a, NameBinding<'a>>>,
532 ) {
533 for module in self.arenas.local_modules().iter() {
534 module.for_each_child(self, |this, ident, ns, binding| {
535 if let NameBindingKind::Import { import, .. } = binding.kind
536 && let Some((amb_binding, _)) = binding.ambiguity
537 && binding.res() != Res::Err
538 && exported_ambiguities.contains(&Interned::new_unchecked(binding))
539 {
540 this.lint_buffer.buffer_lint_with_diagnostic(
541 AMBIGUOUS_GLOB_REEXPORTS,
542 import.root_id,
543 import.root_span,
544 "ambiguous glob re-exports",
545 BuiltinLintDiagnostics::AmbiguousGlobReexports {
546 name: ident.to_string(),
547 namespace: ns.descr().to_string(),
548 first_reexport_span: import.root_span,
549 duplicate_reexport_span: amb_binding.span,
550 },
551 );
552 }
553 });
554 }
555 }
556
9c376795 557 fn throw_unresolved_import_error(&self, errors: Vec<(&Import<'_>, UnresolvedImportError)>) {
487cf647
FG
558 if errors.is_empty() {
559 return;
560 }
561
532ac7d7
XL
562 /// Upper limit on the number of `span_label` messages.
563 const MAX_LABEL_COUNT: usize = 10;
564
487cf647 565 let span = MultiSpan::from_spans(errors.iter().map(|(_, err)| err.span).collect());
9c376795
FG
566 let paths = errors
567 .iter()
568 .map(|(import, err)| {
569 let path = import_path_to_string(
570 &import.module_path.iter().map(|seg| seg.ident).collect::<Vec<_>>(),
571 &import.kind,
572 err.span,
573 );
574 format!("`{path}`")
575 })
576 .collect::<Vec<_>>();
487cf647 577 let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),);
0bf4aa26 578
9ffffee4 579 let mut diag = struct_span_err!(self.tcx.sess, span, E0432, "{}", &msg);
532ac7d7 580
064997fb 581 if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() {
49aad941 582 diag.note(note.clone());
c34b1796 583 }
532ac7d7 584
9c376795 585 for (import, err) in errors.into_iter().take(MAX_LABEL_COUNT) {
532ac7d7
XL
586 if let Some(label) = err.label {
587 diag.span_label(err.span, label);
588 }
589
48663c56 590 if let Some((suggestions, msg, applicability)) = err.suggestion {
923072b8 591 if suggestions.is_empty() {
49aad941 592 diag.help(msg);
923072b8
FG
593 continue;
594 }
49aad941 595 diag.multipart_suggestion(msg, suggestions, applicability);
532ac7d7 596 }
2b03887a 597
9c376795
FG
598 if let Some(candidates) = &err.candidates {
599 match &import.kind {
600 ImportKind::Single { nested: false, source, target, .. } => import_candidates(
9ffffee4 601 self.tcx,
9c376795
FG
602 &mut diag,
603 Some(err.span),
604 &candidates,
605 DiagnosticMode::Import,
606 (source != target)
607 .then(|| format!(" as {target}"))
608 .as_deref()
609 .unwrap_or(""),
610 ),
611 ImportKind::Single { nested: true, source, target, .. } => {
612 import_candidates(
9ffffee4 613 self.tcx,
9c376795
FG
614 &mut diag,
615 None,
616 &candidates,
617 DiagnosticMode::Normal,
618 (source != target)
619 .then(|| format!(" as {target}"))
620 .as_deref()
621 .unwrap_or(""),
622 );
623 }
624 _ => {}
625 }
2b03887a 626 }
0bf4aa26 627 }
532ac7d7
XL
628
629 diag.emit();
c34b1796
AL
630 }
631
353b0b11
FG
632 /// Attempts to resolve the given import, returning:
633 /// - `0` means its resolution is determined.
634 /// - Other values mean that indeterminate exists under certain namespaces.
635 ///
636 /// Meanwhile, if resolve successful, the resolved bindings are written
637 /// into the module.
638 fn resolve_import(&mut self, import: &'a Import<'a>) -> usize {
416331ca
XL
639 debug!(
640 "(resolving import for module) resolving import `{}::...` in `{}`",
74b04a01
XL
641 Segment::names_to_string(&import.module_path),
642 module_to_string(import.parent_scope.module).unwrap_or_else(|| "???".to_string()),
416331ca 643 );
9e0c209e 644
74b04a01 645 let module = if let Some(module) = import.imported_module.get() {
9e0c209e
SL
646 module
647 } else {
13cf67c4
XL
648 // For better failure detection, pretend that the import will
649 // not define any names while resolving its module path.
f2b60f7d 650 let orig_vis = import.vis.take();
9ffffee4 651 let path_res = self.maybe_resolve_path(&import.module_path, None, &import.parent_scope);
74b04a01 652 import.vis.set(orig_vis);
9e0c209e 653
13cf67c4 654 match path_res {
476ff2be 655 PathResult::Module(module) => module,
353b0b11
FG
656 PathResult::Indeterminate => return 3,
657 PathResult::NonModule(..) | PathResult::Failed { .. } => return 0,
9e0c209e 658 }
c34b1796
AL
659 };
660
74b04a01
XL
661 import.imported_module.set(Some(module));
662 let (source, target, source_bindings, target_bindings, type_ns_only) = match import.kind {
663 ImportKind::Single {
664 source,
665 target,
666 ref source_bindings,
667 ref target_bindings,
668 type_ns_only,
669 ..
670 } => (source, target, source_bindings, target_bindings, type_ns_only),
671 ImportKind::Glob { .. } => {
672 self.resolve_glob_import(import);
353b0b11 673 return 0;
74b04a01
XL
674 }
675 _ => unreachable!(),
676 };
c34b1796 677
353b0b11 678 let mut indeterminate_count = 0;
9ffffee4 679 self.per_ns(|this, ns| {
dfeec247
XL
680 if !type_ns_only || ns == TypeNS {
681 if let Err(Undetermined) = source_bindings[ns].get() {
682 // For better failure detection, pretend that the import will
683 // not define any names while resolving its module path.
f2b60f7d 684 let orig_vis = import.vis.take();
dfeec247
XL
685 let binding = this.resolve_ident_in_module(
686 module,
687 source,
688 ns,
74b04a01 689 &import.parent_scope,
5e7ed085 690 None,
04454e1e 691 None,
dfeec247 692 );
74b04a01 693 import.vis.set(orig_vis);
dfeec247
XL
694 source_bindings[ns].set(binding);
695 } else {
696 return;
697 };
9e0c209e 698
74b04a01 699 let parent = import.parent_scope.module;
dfeec247 700 match source_bindings[ns].get() {
353b0b11 701 Err(Undetermined) => indeterminate_count += 1,
dfeec247
XL
702 // Don't update the resolution, because it was never added.
703 Err(Determined) if target.name == kw::Underscore => {}
04454e1e
FG
704 Ok(binding) if binding.is_importable() => {
705 let imported_binding = this.import(binding, import);
706 target_bindings[ns].set(Some(imported_binding));
707 this.define(parent, target, ns, imported_binding);
708 }
709 source_binding @ (Ok(..) | Err(Determined)) => {
710 if source_binding.is_ok() {
711 let msg = format!("`{}` is not directly importable", target);
9ffffee4 712 struct_span_err!(this.tcx.sess, import.span, E0253, "{}", &msg)
04454e1e
FG
713 .span_label(import.span, "cannot be imported directly")
714 .emit();
715 }
49aad941 716 let key = BindingKey::new(target, ns);
dfeec247 717 this.update_resolution(parent, key, |_, resolution| {
5099ac24 718 resolution.single_imports.remove(&Interned::new_unchecked(import));
dfeec247
XL
719 });
720 }
54a0048b 721 }
54a0048b 722 }
476ff2be 723 });
c34b1796 724
353b0b11 725 indeterminate_count
9e0c209e
SL
726 }
727
532ac7d7
XL
728 /// Performs final import resolution, consistency checks and error reporting.
729 ///
730 /// Optionally returns an unresolved import error. This error is buffered and used to
731 /// consolidate multiple unresolved import errors into a single diagnostic.
9ffffee4 732 fn finalize_import(&mut self, import: &'a Import<'a>) -> Option<UnresolvedImportError> {
f2b60f7d 733 let orig_vis = import.vis.take();
04454e1e
FG
734 let ignore_binding = match &import.kind {
735 ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(),
2a314972
XL
736 _ => None,
737 };
9ffffee4 738 let prev_ambiguity_errors_len = self.ambiguity_errors.len();
04454e1e 739 let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span);
9ffffee4 740 let path_res = self.resolve_path(
04454e1e
FG
741 &import.module_path,
742 None,
743 &import.parent_scope,
744 Some(finalize),
745 ignore_binding,
746 );
2b03887a 747
9ffffee4 748 let no_ambiguity = self.ambiguity_errors.len() == prev_ambiguity_errors_len;
74b04a01 749 import.vis.set(orig_vis);
13cf67c4
XL
750 let module = match path_res {
751 PathResult::Module(module) => {
e1599b0c 752 // Consistency checks, analogous to `finalize_macro_resolutions`.
74b04a01 753 if let Some(initial_module) = import.imported_module.get() {
0731742a 754 if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity {
2a314972 755 span_bug!(import.span, "inconsistent resolution for an import");
13cf67c4 756 }
9ffffee4 757 } else if self.privacy_errors.is_empty() {
29967ef6
XL
758 let msg = "cannot determine resolution for the import";
759 let msg_note = "import resolution is stuck, try simplifying other imports";
9ffffee4 760 self.tcx.sess.struct_span_err(import.span, msg).note(msg_note).emit();
13cf67c4
XL
761 }
762
763 module
764 }
532ac7d7 765 PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => {
0731742a 766 if no_ambiguity {
74b04a01 767 assert!(import.imported_module.get().is_none());
9ffffee4 768 self.report_error(span, ResolutionError::FailedToResolve { label, suggestion });
0731742a 769 }
ff7c6d11
XL
770 return None;
771 }
532ac7d7 772 PathResult::Failed { is_error_from_last_segment: true, span, label, suggestion } => {
0731742a 773 if no_ambiguity {
2a314972 774 assert!(import.imported_module.get().is_none());
532ac7d7
XL
775 let err = match self.make_path_suggestion(
776 span,
74b04a01
XL
777 import.module_path.clone(),
778 &import.parent_scope,
532ac7d7 779 ) {
dfeec247
XL
780 Some((suggestion, note)) => UnresolvedImportError {
781 span,
782 label: None,
783 note,
784 suggestion: Some((
785 vec![(span, Segment::names_to_string(&suggestion))],
786 String::from("a similar path exists"),
787 Applicability::MaybeIncorrect,
788 )),
9c376795 789 candidates: None,
dfeec247
XL
790 },
791 None => UnresolvedImportError {
792 span,
793 label: Some(label),
064997fb 794 note: None,
dfeec247 795 suggestion,
9c376795 796 candidates: None,
dfeec247 797 },
532ac7d7 798 };
532ac7d7 799 return Some(err);
0731742a
XL
800 }
801 return None;
13cf67c4 802 }
cdc7bbd5 803 PathResult::NonModule(_) => {
0731742a 804 if no_ambiguity {
74b04a01 805 assert!(import.imported_module.get().is_none());
0731742a 806 }
13cf67c4 807 // The error was already reported earlier.
13cf67c4
XL
808 return None;
809 }
cdc7bbd5 810 PathResult::Indeterminate => unreachable!(),
9e0c209e
SL
811 };
812
487cf647
FG
813 let (ident, target, source_bindings, target_bindings, type_ns_only, import_id) =
814 match import.kind {
815 ImportKind::Single {
816 source,
817 target,
818 ref source_bindings,
819 ref target_bindings,
820 type_ns_only,
821 id,
822 ..
823 } => (source, target, source_bindings, target_bindings, type_ns_only, id),
824 ImportKind::Glob { is_prelude, ref max_vis, id } => {
825 if import.module_path.len() <= 1 {
826 // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
827 // 2 segments, so the `resolve_path` above won't trigger it.
828 let mut full_path = import.module_path.clone();
829 full_path.push(Segment::from_ident(Ident::empty()));
9ffffee4 830 self.lint_if_path_starts_with_module(Some(finalize), &full_path, None);
487cf647 831 }
b7449926 832
487cf647
FG
833 if let ModuleOrUniformRoot::Module(module) = module {
834 if ptr::eq(module, import.parent_scope.module) {
835 // Importing a module into itself is not allowed.
836 return Some(UnresolvedImportError {
837 span: import.span,
838 label: Some(String::from(
839 "cannot glob-import a module into itself",
840 )),
841 note: None,
842 suggestion: None,
9c376795 843 candidates: None,
487cf647
FG
844 });
845 }
b7449926 846 }
487cf647 847 if !is_prelude
f2b60f7d 848 && let Some(max_vis) = max_vis.get()
353b0b11 849 && !max_vis.is_at_least(import.expect_vis(), self.tcx)
dfeec247
XL
850 {
851 let msg = "glob import doesn't reexport anything because no candidate is public enough";
9ffffee4 852 self.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, msg);
9e0c209e 853 }
487cf647
FG
854 return None;
855 }
856 _ => unreachable!(),
857 };
9e0c209e 858
476ff2be 859 let mut all_ns_err = true;
9ffffee4 860 self.per_ns(|this, ns| {
dfeec247 861 if !type_ns_only || ns == TypeNS {
f2b60f7d 862 let orig_vis = import.vis.take();
dfeec247
XL
863 let binding = this.resolve_ident_in_module(
864 module,
865 ident,
866 ns,
74b04a01 867 &import.parent_scope,
04454e1e
FG
868 Some(Finalize { report_private: false, ..finalize }),
869 target_bindings[ns].get(),
dfeec247 870 );
74b04a01 871 import.vis.set(orig_vis);
13cf67c4 872
dfeec247
XL
873 match binding {
874 Ok(binding) => {
875 // Consistency checks, analogous to `finalize_macro_resolutions`.
487cf647 876 let initial_binding = source_bindings[ns].get().map(|initial_binding| {
dfeec247
XL
877 all_ns_err = false;
878 if let Some(target_binding) = target_bindings[ns].get() {
3dfed10e 879 if target.name == kw::Underscore
dfeec247
XL
880 && initial_binding.is_extern_crate()
881 && !initial_binding.is_import()
882 {
883 this.record_use(
884 ident,
dfeec247 885 target_binding,
74b04a01 886 import.module_path.is_empty(),
dfeec247
XL
887 );
888 }
889 }
487cf647 890 initial_binding
dfeec247
XL
891 });
892 let res = binding.res();
487cf647
FG
893 if let Ok(initial_binding) = initial_binding {
894 let initial_res = initial_binding.res();
dfeec247 895 if res != initial_res && this.ambiguity_errors.is_empty() {
487cf647
FG
896 this.ambiguity_errors.push(AmbiguityError {
897 kind: AmbiguityKind::Import,
898 ident,
899 b1: initial_binding,
900 b2: binding,
901 misc1: AmbiguityErrorMisc::None,
902 misc2: AmbiguityErrorMisc::None,
903 });
dfeec247 904 }
29967ef6
XL
905 } else if res != Res::Err
906 && this.ambiguity_errors.is_empty()
907 && this.privacy_errors.is_empty()
908 {
909 let msg = "cannot determine resolution for the import";
910 let msg_note =
911 "import resolution is stuck, try simplifying other imports";
9ffffee4 912 this.tcx.sess.struct_span_err(import.span, msg).note(msg_note).emit();
13cf67c4 913 }
b7449926 914 }
dfeec247
XL
915 Err(..) => {
916 // FIXME: This assert may fire if public glob is later shadowed by a private
917 // single import (see test `issue-55884-2.rs`). In theory single imports should
918 // always block globs, even if they are not yet resolved, so that this kind of
919 // self-inconsistent resolution never happens.
74b04a01 920 // Re-enable the assert when the issue is fixed.
dfeec247
XL
921 // assert!(result[ns].get().is_err());
922 }
0bf4aa26 923 }
9e0c209e 924 }
476ff2be 925 });
9e0c209e 926
476ff2be
SL
927 if all_ns_err {
928 let mut all_ns_failed = true;
9ffffee4 929 self.per_ns(|this, ns| {
dfeec247
XL
930 if !type_ns_only || ns == TypeNS {
931 let binding = this.resolve_ident_in_module(
932 module,
933 ident,
934 ns,
74b04a01 935 &import.parent_scope,
04454e1e
FG
936 Some(finalize),
937 None,
dfeec247
XL
938 );
939 if binding.is_ok() {
940 all_ns_failed = false;
941 }
476ff2be
SL
942 }
943 });
9e0c209e 944
476ff2be 945 return if all_ns_failed {
b7449926 946 let resolutions = match module {
9ffffee4 947 ModuleOrUniformRoot::Module(module) => Some(self.resolutions(module).borrow()),
13cf67c4 948 _ => None,
b7449926
XL
949 };
950 let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
fc512014
XL
951 let names = resolutions
952 .filter_map(|(BindingKey { ident: i, .. }, resolution)| {
9c376795 953 if i.name == ident.name {
fc512014
XL
954 return None;
955 } // Never suggest the same name
956 match *resolution.borrow() {
957 NameResolution { binding: Some(name_binding), .. } => {
958 match name_binding.kind {
959 NameBindingKind::Import { binding, .. } => {
960 match binding.kind {
961 // Never suggest the name that has binding error
962 // i.e., the name that cannot be previously resolved
487cf647 963 NameBindingKind::Res(Res::Err) => None,
fc512014
XL
964 _ => Some(i.name),
965 }
8bb4bdeb 966 }
fc512014 967 _ => Some(i.name),
dfeec247 968 }
8bb4bdeb 969 }
fc512014
XL
970 NameResolution { ref single_imports, .. }
971 if single_imports.is_empty() =>
972 {
973 None
974 }
975 _ => Some(i.name),
dfeec247 976 }
fc512014
XL
977 })
978 .collect::<Vec<Symbol>>();
532ac7d7 979
dfeec247 980 let lev_suggestion =
fc512014 981 find_best_match_for_name(&names, ident.name, None).map(|suggestion| {
dfeec247
XL
982 (
983 vec![(ident.span, suggestion.to_string())],
984 String::from("a similar name exists in the module"),
985 Applicability::MaybeIncorrect,
986 )
987 });
48663c56 988
dfeec247 989 let (suggestion, note) =
74b04a01 990 match self.check_for_module_export_macro(import, module, ident) {
dfeec247 991 Some((suggestion, note)) => (suggestion.or(lev_suggestion), note),
064997fb 992 _ => (lev_suggestion, None),
dfeec247 993 };
532ac7d7
XL
994
995 let label = match module {
b7449926
XL
996 ModuleOrUniformRoot::Module(module) => {
997 let module_str = module_to_string(module);
998 if let Some(module_str) = module_str {
532ac7d7 999 format!("no `{}` in `{}`", ident, module_str)
b7449926 1000 } else {
532ac7d7 1001 format!("no `{}` in the root", ident)
b7449926
XL
1002 }
1003 }
13cf67c4 1004 _ => {
b7449926 1005 if !ident.is_path_segment_keyword() {
1b1a35ee 1006 format!("no external crate `{}`", ident)
b7449926
XL
1007 } else {
1008 // HACK(eddyb) this shows up for `self` & `super`, which
1009 // should work instead - for now keep the same error message.
532ac7d7 1010 format!("no `{}` in the root", ident)
b7449926
XL
1011 }
1012 }
a7813a04 1013 };
48663c56 1014
2b03887a 1015 let parent_suggestion =
9ffffee4 1016 self.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true);
2b03887a 1017
532ac7d7 1018 Some(UnresolvedImportError {
74b04a01 1019 span: import.span,
532ac7d7 1020 label: Some(label),
48663c56
XL
1021 note,
1022 suggestion,
9c376795 1023 candidates: if !parent_suggestion.is_empty() {
2b03887a
FG
1024 Some(parent_suggestion)
1025 } else {
1026 None
1027 },
532ac7d7 1028 })
9e0c209e 1029 } else {
32a655c1 1030 // `resolve_ident_in_module` reported a privacy error.
476ff2be 1031 None
dfeec247 1032 };
7453a54e 1033 }
c34b1796 1034
476ff2be
SL
1035 let mut reexport_error = None;
1036 let mut any_successful_reexport = false;
3c0e092e 1037 let mut crate_private_reexport = false;
9ffffee4 1038 self.per_ns(|this, ns| {
69743fb6 1039 if let Ok(binding) = source_bindings[ns].get() {
353b0b11 1040 if !binding.vis.is_at_least(import.expect_vis(), this.tcx) {
476ff2be 1041 reexport_error = Some((ns, binding));
3c0e092e
XL
1042 if let ty::Visibility::Restricted(binding_def_id) = binding.vis {
1043 if binding_def_id.is_top_level_module() {
1044 crate_private_reexport = true;
1045 }
1046 }
54a0048b 1047 } else {
476ff2be 1048 any_successful_reexport = true;
c34b1796
AL
1049 }
1050 }
476ff2be 1051 });
c34b1796 1052
476ff2be
SL
1053 // All namespaces must be re-exported with extra visibility for an error to occur.
1054 if !any_successful_reexport {
1055 let (ns, binding) = reexport_error.unwrap();
6a06907d 1056 if pub_use_of_private_extern_crate_hack(import, binding) {
dfeec247
XL
1057 let msg = format!(
1058 "extern crate `{}` is private, and cannot be \
2c00a5a8
XL
1059 re-exported (error E0365), consider declaring with \
1060 `pub`",
dfeec247
XL
1061 ident
1062 );
9ffffee4 1063 self.lint_buffer.buffer_lint(
dfeec247 1064 PUB_USE_OF_PRIVATE_EXTERN_CRATE,
487cf647 1065 import_id,
74b04a01 1066 import.span,
49aad941 1067 msg,
dfeec247 1068 );
476ff2be 1069 } else {
3c0e092e
XL
1070 let error_msg = if crate_private_reexport {
1071 format!(
1072 "`{}` is only public within the crate, and cannot be re-exported outside",
1073 ident
1074 )
1075 } else {
1076 format!("`{}` is private, and cannot be re-exported", ident)
1077 };
1078
1079 if ns == TypeNS {
1080 let label_msg = if crate_private_reexport {
1081 format!("re-export of crate public `{}`", ident)
1082 } else {
1083 format!("re-export of private `{}`", ident)
1084 };
1085
9ffffee4 1086 struct_span_err!(self.tcx.sess, import.span, E0365, "{}", error_msg)
3c0e092e 1087 .span_label(import.span, label_msg)
49aad941 1088 .note(format!("consider declaring type or module `{}` with `pub`", ident))
3c0e092e
XL
1089 .emit();
1090 } else {
923072b8 1091 let mut err =
9ffffee4 1092 struct_span_err!(self.tcx.sess, import.span, E0364, "{error_msg}");
923072b8 1093 match binding.kind {
487cf647 1094 NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id))
923072b8 1095 // exclude decl_macro
9ffffee4 1096 if self.get_macro_by_def_id(def_id).macro_rules =>
923072b8
FG
1097 {
1098 err.span_help(
1099 binding.span,
1100 "consider adding a `#[macro_export]` to the macro in the imported module",
1101 );
1102 }
1103 _ => {
1104 err.span_note(
1105 import.span,
49aad941 1106 format!(
923072b8
FG
1107 "consider marking `{ident}` as `pub` in the imported module"
1108 ),
1109 );
1110 }
1111 }
1112 err.emit();
3c0e092e 1113 }
476ff2be 1114 }
c34b1796
AL
1115 }
1116
74b04a01 1117 if import.module_path.len() <= 1 {
b7449926
XL
1118 // HACK(eddyb) `lint_if_path_starts_with_module` needs at least
1119 // 2 segments, so the `resolve_path` above won't trigger it.
74b04a01 1120 let mut full_path = import.module_path.clone();
13cf67c4 1121 full_path.push(Segment::from_ident(ident));
9ffffee4 1122 self.per_ns(|this, ns| {
69743fb6 1123 if let Ok(binding) = source_bindings[ns].get() {
04454e1e 1124 this.lint_if_path_starts_with_module(Some(finalize), &full_path, Some(binding));
94b46f34 1125 }
94b46f34
XL
1126 });
1127 }
1128
c34b1796
AL
1129 // Record what this import resolves to for later uses in documentation,
1130 // this may resolve to either a value or a type, but for documentation
1131 // purposes it's good enough to just favor one over the other.
9ffffee4 1132 self.per_ns(|this, ns| {
74b04a01 1133 if let Ok(binding) = source_bindings[ns].get() {
487cf647 1134 this.import_res_map.entry(import_id).or_default()[ns] = Some(binding.res());
dfeec247 1135 }
476ff2be 1136 });
c34b1796 1137
74b04a01 1138 self.check_for_redundant_imports(ident, import, source_bindings, target_bindings, target);
532ac7d7 1139
c34b1796 1140 debug!("(resolving single import) successfully resolved import");
476ff2be 1141 None
c34b1796
AL
1142 }
1143
532ac7d7
XL
1144 fn check_for_redundant_imports(
1145 &mut self,
1146 ident: Ident,
9ffffee4
FG
1147 import: &'a Import<'a>,
1148 source_bindings: &PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
1149 target_bindings: &PerNS<Cell<Option<&'a NameBinding<'a>>>>,
532ac7d7
XL
1150 target: Ident,
1151 ) {
487cf647
FG
1152 // This function is only called for single imports.
1153 let ImportKind::Single { id, .. } = import.kind else { unreachable!() };
1154
532ac7d7 1155 // Skip if the import was produced by a macro.
136023e0 1156 if import.parent_scope.expansion != LocalExpnId::ROOT {
532ac7d7
XL
1157 return;
1158 }
1159
1160 // Skip if we are inside a named module (in contrast to an anonymous
1161 // module defined by a block).
74b04a01 1162 if let ModuleKind::Def(..) = import.parent_scope.module.kind {
532ac7d7
XL
1163 return;
1164 }
1165
dfeec247 1166 let mut is_redundant = PerNS { value_ns: None, type_ns: None, macro_ns: None };
532ac7d7 1167
dfeec247 1168 let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None };
532ac7d7 1169
9ffffee4 1170 self.per_ns(|this, ns| {
74b04a01 1171 if let Ok(binding) = source_bindings[ns].get() {
dfeec247
XL
1172 if binding.res() == Res::Err {
1173 return;
1174 }
532ac7d7 1175
dfeec247
XL
1176 match this.early_resolve_ident_in_lexical_scope(
1177 target,
1178 ScopeSet::All(ns, false),
74b04a01 1179 &import.parent_scope,
5e7ed085 1180 None,
dfeec247 1181 false,
04454e1e 1182 target_bindings[ns].get(),
dfeec247
XL
1183 ) {
1184 Ok(other_binding) => {
1185 is_redundant[ns] = Some(
1186 binding.res() == other_binding.res() && !other_binding.is_ambiguity(),
1187 );
1188 redundant_span[ns] = Some((other_binding.span, other_binding.is_import()));
1189 }
1190 Err(_) => is_redundant[ns] = Some(false),
532ac7d7 1191 }
dfeec247 1192 }
532ac7d7
XL
1193 });
1194
dfeec247 1195 if !is_redundant.is_empty() && is_redundant.present_items().all(|is_redundant| is_redundant)
532ac7d7 1196 {
48663c56
XL
1197 let mut redundant_spans: Vec<_> = redundant_span.present_items().collect();
1198 redundant_spans.sort();
1199 redundant_spans.dedup();
9ffffee4 1200 self.lint_buffer.buffer_lint_with_diagnostic(
532ac7d7 1201 UNUSED_IMPORTS,
487cf647 1202 id,
74b04a01 1203 import.span,
49aad941 1204 format!("the item `{}` is imported redundantly", ident),
48663c56 1205 BuiltinLintDiagnostics::RedundantImport(redundant_spans, ident),
532ac7d7
XL
1206 );
1207 }
1208 }
1209
9ffffee4 1210 fn resolve_glob_import(&mut self, import: &'a Import<'a>) {
487cf647
FG
1211 // This function is only called for glob imports.
1212 let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() };
1213
5e7ed085 1214 let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else {
9ffffee4 1215 self.tcx.sess.span_err(import.span, "cannot glob-import all possible crates");
5e7ed085 1216 return;
b7449926
XL
1217 };
1218
532ac7d7 1219 if module.is_trait() {
9ffffee4 1220 self.tcx.sess.span_err(import.span, "items in traits are not importable");
9e0c209e 1221 return;
c295e0f8 1222 } else if ptr::eq(module, import.parent_scope.module) {
9e0c209e 1223 return;
487cf647 1224 } else if is_prelude {
9ffffee4 1225 self.prelude = Some(module);
9e0c209e 1226 return;
54a0048b
SL
1227 }
1228
9e0c209e 1229 // Add to module's glob_importers
74b04a01 1230 module.glob_importers.borrow_mut().push(import);
54a0048b 1231
5bcae85e 1232 // Ensure that `resolutions` isn't borrowed during `try_define`,
54a0048b 1233 // since it might get updated via a glob cycle.
dfeec247 1234 let bindings = self
dfeec247
XL
1235 .resolutions(module)
1236 .borrow()
1237 .iter()
1238 .filter_map(|(key, resolution)| {
1239 resolution.borrow().binding().map(|binding| (*key, binding))
1240 })
1241 .collect::<Vec<_>>();
e74abb32 1242 for (mut key, binding) in bindings {
74b04a01 1243 let scope = match key.ident.span.reverse_glob_adjust(module.expansion, import.span) {
9ffffee4 1244 Some(Some(def)) => self.expn_def_scope(def),
74b04a01 1245 Some(None) => import.parent_scope.module,
7cac9316
XL
1246 None => continue,
1247 };
9ffffee4
FG
1248 if self.is_accessible_from(binding.vis, scope) {
1249 let imported_binding = self.import(binding, import);
1250 let _ = self.try_define(import.parent_scope.module, key, imported_binding);
7453a54e 1251 }
54a0048b 1252 }
c34b1796 1253
c34b1796 1254 // Record the destination of this import
9ffffee4 1255 self.record_partial_res(id, PartialRes::new(module.res().unwrap()));
c34b1796
AL
1256 }
1257
2c00a5a8 1258 // Miscellaneous post-processing, including recording re-exports,
7cac9316 1259 // reporting conflicts, and reporting unresolved imports.
9ffffee4 1260 fn finalize_resolutions_in(&mut self, module: Module<'a>) {
54a0048b
SL
1261 // Since import resolution is finished, globs will not define any more names.
1262 *module.globs.borrow_mut() = Vec::new();
1263
064997fb 1264 if let Some(def_id) = module.opt_def_id() {
49aad941 1265 let mut children = Vec::new();
064997fb 1266
9ffffee4 1267 module.for_each_child(self, |this, ident, _, binding| {
353b0b11 1268 let res = binding.res().expect_non_local();
49aad941 1269 if res != def::Res::Err && !binding.is_ambiguity() {
353b0b11
FG
1270 let mut reexport_chain = SmallVec::new();
1271 let mut next_binding = binding;
1272 while let NameBindingKind::Import { binding, import, .. } = next_binding.kind {
1273 reexport_chain.push(import.simplify(this));
1274 next_binding = binding;
1275 }
1276
49aad941 1277 children.push(ModChild { ident, res, vis: binding.vis, reexport_chain });
54a0048b 1278 }
064997fb 1279 });
c34b1796 1280
49aad941
FG
1281 if !children.is_empty() {
1282 // Should be fine because this code is only called for local modules.
1283 self.module_children.insert(def_id.expect_local(), children);
54a0048b 1284 }
c34b1796 1285 }
c34b1796
AL
1286 }
1287}
1288
74b04a01 1289fn import_path_to_string(names: &[Ident], import_kind: &ImportKind<'_>, span: Span) -> String {
dfeec247 1290 let pos = names.iter().position(|p| span == p.span && p.name != kw::PathRoot);
dc9dc135 1291 let global = !names.is_empty() && names[0].name == kw::PathRoot;
3b2f2976
XL
1292 if let Some(pos) = pos {
1293 let names = if global { &names[1..pos + 1] } else { &names[..pos + 1] };
e1599b0c 1294 names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>())
c34b1796 1295 } else {
3b2f2976
XL
1296 let names = if global { &names[1..] } else { names };
1297 if names.is_empty() {
74b04a01 1298 import_kind_to_string(import_kind)
3b2f2976 1299 } else {
e1599b0c
XL
1300 format!(
1301 "{}::{}",
1302 names_to_string(&names.iter().map(|ident| ident.name).collect::<Vec<_>>()),
74b04a01 1303 import_kind_to_string(import_kind),
e1599b0c 1304 )
3b2f2976 1305 }
c34b1796
AL
1306 }
1307}
1308
74b04a01
XL
1309fn import_kind_to_string(import_kind: &ImportKind<'_>) -> String {
1310 match import_kind {
1311 ImportKind::Single { source, .. } => source.to_string(),
1312 ImportKind::Glob { .. } => "*".to_string(),
1313 ImportKind::ExternCrate { .. } => "<extern crate>".to_string(),
1314 ImportKind::MacroUse => "#[macro_use]".to_string(),
487cf647 1315 ImportKind::MacroExport => "#[macro_export]".to_string(),
c34b1796
AL
1316 }
1317}