summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_resolve/src/imports.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_resolve/src/imports.rs')
-rw-r--r--compiler/rustc_resolve/src/imports.rs382
1 files changed, 236 insertions, 146 deletions
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 7c4c05d4b..d37fe783b 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -1,15 +1,18 @@
//! A bunch of methods and structures more or less related to resolving imports.
use crate::diagnostics::{import_candidates, DiagnosticMode, Suggestion};
+use crate::errors::{
+ CannotBeReexportedCratePublic, CannotBeReexportedCratePublicNS, CannotBeReexportedPrivate,
+ CannotBeReexportedPrivateNS, CannotDetermineImportResolution, CannotGlobImportAllCrates,
+ ConsiderAddingMacroExport, ConsiderMarkingAsPub, IsNotDirectlyImportable,
+ ItemsInTraitsAreNotImportable,
+};
use crate::Determinacy::{self, *};
-use crate::Namespace::*;
+use crate::{fluent_generated as fluent, Namespace::*};
use crate::{module_to_string, names_to_string, ImportSuggestion};
-use crate::{
- AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingKey, ModuleKind, ResolutionError,
- Resolver, Segment,
-};
+use crate::{AmbiguityKind, BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
use crate::{Finalize, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet};
-use crate::{NameBinding, NameBindingKind, PathResult};
+use crate::{NameBinding, NameBindingData, NameBindingKind, PathResult};
use rustc_ast::NodeId;
use rustc_data_structures::fx::FxHashSet;
@@ -21,7 +24,8 @@ use rustc_middle::metadata::Reexport;
use rustc_middle::span_bug;
use rustc_middle::ty;
use rustc_session::lint::builtin::{
- AMBIGUOUS_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS,
+ AMBIGUOUS_GLOB_REEXPORTS, HIDDEN_GLOB_REEXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE,
+ UNUSED_IMPORTS,
};
use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_span::edit_distance::find_best_match_for_name;
@@ -31,7 +35,7 @@ use rustc_span::Span;
use smallvec::SmallVec;
use std::cell::Cell;
-use std::{mem, ptr};
+use std::mem;
type Res = def::Res<NodeId>;
@@ -44,9 +48,9 @@ pub(crate) enum ImportKind<'a> {
/// `target` in `use prefix::source as target`.
target: Ident,
/// Bindings to which `source` refers to.
- source_bindings: PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
+ source_bindings: PerNS<Cell<Result<NameBinding<'a>, Determinacy>>>,
/// Bindings introduced by `target`.
- target_bindings: PerNS<Cell<Option<&'a NameBinding<'a>>>>,
+ target_bindings: PerNS<Cell<Option<NameBinding<'a>>>>,
/// `true` for `...::{self [as target]}` imports, `false` otherwise.
type_ns_only: bool,
/// Did this import result from a nested import? ie. `use foo::{bar, baz};`
@@ -131,7 +135,7 @@ impl<'a> std::fmt::Debug for ImportKind<'a> {
/// One import.
#[derive(Debug, Clone)]
-pub(crate) struct Import<'a> {
+pub(crate) struct ImportData<'a> {
pub kind: ImportKind<'a>,
/// Node ID of the "root" use item -- this is always the same as `ImportKind`'s `id`
@@ -168,7 +172,11 @@ pub(crate) struct Import<'a> {
pub used: Cell<bool>,
}
-impl<'a> Import<'a> {
+/// All imports are unique and allocated on a same arena,
+/// so we can use referential equality to compare them.
+pub(crate) type Import<'a> = Interned<'a, ImportData<'a>>;
+
+impl<'a> ImportData<'a> {
pub(crate) fn is_glob(&self) -> bool {
matches!(self.kind, ImportKind::Glob { .. })
}
@@ -210,15 +218,15 @@ impl<'a> Import<'a> {
pub(crate) struct NameResolution<'a> {
/// Single imports that may define the name in the namespace.
/// Imports are arena-allocated, so it's ok to use pointers as keys.
- pub single_imports: FxHashSet<Interned<'a, Import<'a>>>,
+ pub single_imports: FxHashSet<Import<'a>>,
/// The least shadowable known binding for this name, or None if there are no known bindings.
- pub binding: Option<&'a NameBinding<'a>>,
- pub shadowed_glob: Option<&'a NameBinding<'a>>,
+ pub binding: Option<NameBinding<'a>>,
+ pub shadowed_glob: Option<NameBinding<'a>>,
}
impl<'a> NameResolution<'a> {
/// Returns the binding for the name if it is known or None if it not known.
- pub(crate) fn binding(&self) -> Option<&'a NameBinding<'a>> {
+ pub(crate) fn binding(&self) -> Option<NameBinding<'a>> {
self.binding.and_then(|binding| {
if !binding.is_glob_import() || self.single_imports.is_empty() {
Some(binding)
@@ -227,10 +235,6 @@ impl<'a> NameResolution<'a> {
}
})
}
-
- pub(crate) fn add_single_import(&mut self, import: &'a Import<'a>) {
- self.single_imports.insert(Interned::new_unchecked(import));
- }
}
/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved
@@ -246,15 +250,12 @@ struct UnresolvedImportError {
// Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;`
// are permitted for backward-compatibility under a deprecation lint.
-fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBinding<'_>) -> bool {
+fn pub_use_of_private_extern_crate_hack(import: Import<'_>, binding: NameBinding<'_>) -> bool {
match (&import.kind, &binding.kind) {
- (
- ImportKind::Single { .. },
- NameBindingKind::Import {
- import: Import { kind: ImportKind::ExternCrate { .. }, .. },
- ..
- },
- ) => import.expect_vis().is_public(),
+ (ImportKind::Single { .. }, NameBindingKind::Import { import: binding_import, .. }) => {
+ matches!(binding_import.kind, ImportKind::ExternCrate { .. })
+ && import.expect_vis().is_public()
+ }
_ => false,
}
}
@@ -262,11 +263,7 @@ fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBindi
impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// Given a binding and an import that resolves to it,
/// return the corresponding binding defined by the import.
- pub(crate) fn import(
- &self,
- binding: &'a NameBinding<'a>,
- import: &'a Import<'a>,
- ) -> &'a NameBinding<'a> {
+ pub(crate) fn import(&self, binding: NameBinding<'a>, import: Import<'a>) -> NameBinding<'a> {
let import_vis = import.expect_vis().to_def_id();
let vis = if binding.vis.is_at_least(import_vis, self.tcx)
|| pub_use_of_private_extern_crate_hack(import, binding)
@@ -284,7 +281,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
- self.arenas.alloc_name_binding(NameBinding {
+ self.arenas.alloc_name_binding(NameBindingData {
kind: NameBindingKind::Import { binding, import, used: Cell::new(false) },
ambiguity: None,
span: import.span,
@@ -298,8 +295,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&mut self,
module: Module<'a>,
key: BindingKey,
- binding: &'a NameBinding<'a>,
- ) -> Result<(), &'a NameBinding<'a>> {
+ binding: NameBinding<'a>,
+ ) -> Result<(), NameBinding<'a>> {
let res = binding.res();
self.check_reserved_macro_name(key.ident, res);
self.set_binding_parent_module(binding, module);
@@ -337,7 +334,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} else {
resolution.binding = Some(nonglob_binding);
}
- resolution.shadowed_glob = Some(glob_binding);
+
+ if let Some(old_binding) = resolution.shadowed_glob {
+ assert!(old_binding.is_glob_import());
+ if glob_binding.res() != old_binding.res() {
+ resolution.shadowed_glob = Some(this.ambiguity(
+ AmbiguityKind::GlobVsGlob,
+ old_binding,
+ glob_binding,
+ ));
+ } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) {
+ resolution.shadowed_glob = Some(glob_binding);
+ }
+ } else {
+ resolution.shadowed_glob = Some(glob_binding);
+ }
}
(false, false) => {
return Err(old_binding);
@@ -354,12 +365,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn ambiguity(
&self,
kind: AmbiguityKind,
- primary_binding: &'a NameBinding<'a>,
- secondary_binding: &'a NameBinding<'a>,
- ) -> &'a NameBinding<'a> {
- self.arenas.alloc_name_binding(NameBinding {
+ primary_binding: NameBinding<'a>,
+ secondary_binding: NameBinding<'a>,
+ ) -> NameBinding<'a> {
+ self.arenas.alloc_name_binding(NameBindingData {
ambiguity: Some((secondary_binding, kind)),
- ..primary_binding.clone()
+ ..(*primary_binding).clone()
})
}
@@ -377,13 +388,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let t = f(self, resolution);
- match resolution.binding() {
- _ if old_binding.is_some() => return t,
- None => return t,
- Some(binding) => match old_binding {
- Some(old_binding) if ptr::eq(old_binding, binding) => return t,
- _ => (binding, t),
- },
+ if old_binding.is_none() && let Some(binding) = resolution.binding() {
+ (binding, t)
+ } else {
+ return t;
}
};
@@ -396,7 +404,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
None => continue,
};
if self.is_accessible_from(binding.vis, scope) {
- let imported_binding = self.import(binding, import);
+ let imported_binding = self.import(binding, *import);
let key = BindingKey { ident, ..key };
let _ = self.try_define(import.parent_scope.module, key, imported_binding);
}
@@ -407,7 +415,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// Define a dummy resolution containing a `Res::Err` as a placeholder for a failed
// or indeterminate resolution, also mark such failed imports as used to avoid duplicate diagnostics.
- fn import_dummy_binding(&mut self, import: &'a Import<'a>, is_indeterminate: bool) {
+ fn import_dummy_binding(&mut self, import: Import<'a>, is_indeterminate: bool) {
if let ImportKind::Single { target, ref target_bindings, .. } = import.kind {
if !(is_indeterminate || target_bindings.iter().all(|binding| binding.get().is_none()))
{
@@ -445,7 +453,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
prev_indeterminate_count = indeterminate_count;
indeterminate_count = 0;
for import in mem::take(&mut self.indeterminate_imports) {
- let import_indeterminate_count = self.resolve_import(&import);
+ let import_indeterminate_count = self.resolve_import(import);
indeterminate_count += import_indeterminate_count;
match import_indeterminate_count {
0 => self.determined_imports.push(import),
@@ -457,7 +465,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
pub(crate) fn finalize_imports(&mut self) {
for module in self.arenas.local_modules().iter() {
- self.finalize_resolutions_in(module);
+ self.finalize_resolutions_in(*module);
}
let mut seen_spans = FxHashSet::default();
@@ -526,35 +534,75 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
- pub(crate) fn check_reexport_ambiguities(
+ pub(crate) fn check_hidden_glob_reexports(
&mut self,
- exported_ambiguities: FxHashSet<Interned<'a, NameBinding<'a>>>,
+ exported_ambiguities: FxHashSet<NameBinding<'a>>,
) {
for module in self.arenas.local_modules().iter() {
- module.for_each_child(self, |this, ident, ns, binding| {
- if let NameBindingKind::Import { import, .. } = binding.kind
- && let Some((amb_binding, _)) = binding.ambiguity
- && binding.res() != Res::Err
- && exported_ambiguities.contains(&Interned::new_unchecked(binding))
- {
- this.lint_buffer.buffer_lint_with_diagnostic(
- AMBIGUOUS_GLOB_REEXPORTS,
- import.root_id,
- import.root_span,
- "ambiguous glob re-exports",
- BuiltinLintDiagnostics::AmbiguousGlobReexports {
- name: ident.to_string(),
- namespace: ns.descr().to_string(),
- first_reexport_span: import.root_span,
- duplicate_reexport_span: amb_binding.span,
- },
- );
+ for (key, resolution) in self.resolutions(*module).borrow().iter() {
+ let resolution = resolution.borrow();
+
+ if let Some(binding) = resolution.binding {
+ if let NameBindingKind::Import { import, .. } = binding.kind
+ && let Some((amb_binding, _)) = binding.ambiguity
+ && binding.res() != Res::Err
+ && exported_ambiguities.contains(&binding)
+ {
+ self.lint_buffer.buffer_lint_with_diagnostic(
+ AMBIGUOUS_GLOB_REEXPORTS,
+ import.root_id,
+ import.root_span,
+ "ambiguous glob re-exports",
+ BuiltinLintDiagnostics::AmbiguousGlobReexports {
+ name: key.ident.to_string(),
+ namespace: key.ns.descr().to_string(),
+ first_reexport_span: import.root_span,
+ duplicate_reexport_span: amb_binding.span,
+ },
+ );
+ }
+
+ if let Some(glob_binding) = resolution.shadowed_glob {
+ let binding_id = match binding.kind {
+ NameBindingKind::Res(res) => {
+ Some(self.def_id_to_node_id[res.def_id().expect_local()])
+ }
+ NameBindingKind::Module(module) => {
+ Some(self.def_id_to_node_id[module.def_id().expect_local()])
+ }
+ NameBindingKind::Import { import, .. } => import.id(),
+ };
+
+ if binding.res() != Res::Err
+ && glob_binding.res() != Res::Err
+ && let NameBindingKind::Import { import: glob_import, .. } = glob_binding.kind
+ && let Some(binding_id) = binding_id
+ && let Some(glob_import_id) = glob_import.id()
+ && let glob_import_def_id = self.local_def_id(glob_import_id)
+ && self.effective_visibilities.is_exported(glob_import_def_id)
+ && glob_binding.vis.is_public()
+ && !binding.vis.is_public()
+ {
+ self.lint_buffer.buffer_lint_with_diagnostic(
+ HIDDEN_GLOB_REEXPORTS,
+ binding_id,
+ binding.span,
+ "private item shadows public glob re-export",
+ BuiltinLintDiagnostics::HiddenGlobReexports {
+ name: key.ident.name.to_string(),
+ namespace: key.ns.descr().to_owned(),
+ glob_reexport_span: glob_binding.span,
+ private_item_span: binding.span,
+ },
+ );
+ }
+ }
}
- });
+ }
}
}
- fn throw_unresolved_import_error(&self, errors: Vec<(&Import<'_>, UnresolvedImportError)>) {
+ fn throw_unresolved_import_error(&mut self, errors: Vec<(Import<'_>, UnresolvedImportError)>) {
if errors.is_empty() {
return;
}
@@ -624,6 +672,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
_ => {}
}
}
+
+ match &import.kind {
+ ImportKind::Single { source, .. } => {
+ if let Some(ModuleOrUniformRoot::Module(module)) = import.imported_module.get()
+ && let Some(module) = module.opt_def_id()
+ {
+ self.find_cfg_stripped(&mut diag, &source.name, module)
+ }
+ },
+ _ => {}
+ }
}
diag.emit();
@@ -635,7 +694,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
///
/// Meanwhile, if resolve successful, the resolved bindings are written
/// into the module.
- fn resolve_import(&mut self, import: &'a Import<'a>) -> usize {
+ fn resolve_import(&mut self, import: Import<'a>) -> usize {
debug!(
"(resolving import for module) resolving import `{}::...` in `{}`",
Segment::names_to_string(&import.module_path),
@@ -708,14 +767,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
source_binding @ (Ok(..) | Err(Determined)) => {
if source_binding.is_ok() {
- let msg = format!("`{}` is not directly importable", target);
- struct_span_err!(this.tcx.sess, import.span, E0253, "{}", &msg)
- .span_label(import.span, "cannot be imported directly")
+ this.tcx
+ .sess
+ .create_err(IsNotDirectlyImportable { span: import.span, target })
.emit();
}
let key = BindingKey::new(target, ns);
this.update_resolution(parent, key, |_, resolution| {
- resolution.single_imports.remove(&Interned::new_unchecked(import));
+ resolution.single_imports.remove(&import);
});
}
}
@@ -729,7 +788,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
///
/// Optionally returns an unresolved import error. This error is buffered and used to
/// consolidate multiple unresolved import errors into a single diagnostic.
- fn finalize_import(&mut self, import: &'a Import<'a>) -> Option<UnresolvedImportError> {
+ fn finalize_import(&mut self, import: Import<'a>) -> Option<UnresolvedImportError> {
let orig_vis = import.vis.take();
let ignore_binding = match &import.kind {
ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(),
@@ -737,6 +796,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
};
let prev_ambiguity_errors_len = self.ambiguity_errors.len();
let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span);
+
+ // We'll provide more context to the privacy errors later, up to `len`.
+ let privacy_errors_len = self.privacy_errors.len();
+
let path_res = self.resolve_path(
&import.module_path,
None,
@@ -751,25 +814,46 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
PathResult::Module(module) => {
// Consistency checks, analogous to `finalize_macro_resolutions`.
if let Some(initial_module) = import.imported_module.get() {
- if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity {
+ if module != initial_module && no_ambiguity {
span_bug!(import.span, "inconsistent resolution for an import");
}
} else if self.privacy_errors.is_empty() {
- let msg = "cannot determine resolution for the import";
- let msg_note = "import resolution is stuck, try simplifying other imports";
- self.tcx.sess.struct_span_err(import.span, msg).note(msg_note).emit();
+ self.tcx
+ .sess
+ .create_err(CannotDetermineImportResolution { span: import.span })
+ .emit();
}
module
}
- PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => {
+ PathResult::Failed {
+ is_error_from_last_segment: false,
+ span,
+ label,
+ suggestion,
+ module,
+ } => {
if no_ambiguity {
assert!(import.imported_module.get().is_none());
- self.report_error(span, ResolutionError::FailedToResolve { label, suggestion });
+ self.report_error(
+ span,
+ ResolutionError::FailedToResolve {
+ last_segment: None,
+ label,
+ suggestion,
+ module,
+ },
+ );
}
return None;
}
- PathResult::Failed { is_error_from_last_segment: true, span, label, suggestion } => {
+ PathResult::Failed {
+ is_error_from_last_segment: true,
+ span,
+ label,
+ suggestion,
+ ..
+ } => {
if no_ambiguity {
assert!(import.imported_module.get().is_none());
let err = match self.make_path_suggestion(
@@ -800,8 +884,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
return None;
}
- PathResult::NonModule(_) => {
- if no_ambiguity {
+ PathResult::NonModule(partial_res) => {
+ if no_ambiguity && partial_res.full_res() != Some(Res::Err) {
+ // Check if there are no ambiguities and the result is not dummy.
assert!(import.imported_module.get().is_none());
}
// The error was already reported earlier.
@@ -831,7 +916,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
if let ModuleOrUniformRoot::Module(module) = module {
- if ptr::eq(module, import.parent_scope.module) {
+ if module == import.parent_scope.module {
// Importing a module into itself is not allowed.
return Some(UnresolvedImportError {
span: import.span,
@@ -848,14 +933,28 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&& let Some(max_vis) = max_vis.get()
&& !max_vis.is_at_least(import.expect_vis(), self.tcx)
{
- let msg = "glob import doesn't reexport anything because no candidate is public enough";
- self.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, msg);
+ self.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, fluent::resolve_glob_import_doesnt_reexport);
}
return None;
}
_ => unreachable!(),
};
+ if self.privacy_errors.len() != privacy_errors_len {
+ // Get the Res for the last element, so that we can point to alternative ways of
+ // importing it if available.
+ let mut path = import.module_path.clone();
+ path.push(Segment::from_ident(ident));
+ if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
+ self.resolve_path(&path, None, &import.parent_scope, Some(finalize), ignore_binding)
+ {
+ let res = module.res().map(|r| (r, ident));
+ for error in &mut self.privacy_errors[privacy_errors_len..] {
+ error.outermost_res = res;
+ }
+ }
+ }
+
let mut all_ns_err = true;
self.per_ns(|this, ns| {
if !type_ns_only || ns == TypeNS {
@@ -873,7 +972,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
match binding {
Ok(binding) => {
// Consistency checks, analogous to `finalize_macro_resolutions`.
- let initial_binding = source_bindings[ns].get().map(|initial_binding| {
+ let initial_res = source_bindings[ns].get().map(|initial_binding| {
all_ns_err = false;
if let Some(target_binding) = target_bindings[ns].get() {
if target.name == kw::Underscore
@@ -887,29 +986,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
);
}
}
- initial_binding
+ initial_binding.res()
});
let res = binding.res();
- if let Ok(initial_binding) = initial_binding {
- let initial_res = initial_binding.res();
+ if let Ok(initial_res) = initial_res {
if res != initial_res && this.ambiguity_errors.is_empty() {
- this.ambiguity_errors.push(AmbiguityError {
- kind: AmbiguityKind::Import,
- ident,
- b1: initial_binding,
- b2: binding,
- misc1: AmbiguityErrorMisc::None,
- misc2: AmbiguityErrorMisc::None,
- });
+ span_bug!(import.span, "inconsistent resolution for an import");
}
} else if res != Res::Err
&& this.ambiguity_errors.is_empty()
&& this.privacy_errors.is_empty()
{
- let msg = "cannot determine resolution for the import";
- let msg_note =
- "import resolution is stuck, try simplifying other imports";
- this.tcx.sess.struct_span_err(import.span, msg).note(msg_note).emit();
+ this.tcx
+ .sess
+ .create_err(CannotDetermineImportResolution { span: import.span })
+ .emit();
}
}
Err(..) => {
@@ -1067,46 +1158,43 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
msg,
);
} else {
- let error_msg = if crate_private_reexport {
- format!(
- "`{}` is only public within the crate, and cannot be re-exported outside",
- ident
- )
- } else {
- format!("`{}` is private, and cannot be re-exported", ident)
- };
-
if ns == TypeNS {
- let label_msg = if crate_private_reexport {
- format!("re-export of crate public `{}`", ident)
+ let mut err = if crate_private_reexport {
+ self.tcx.sess.create_err(CannotBeReexportedCratePublicNS {
+ span: import.span,
+ ident,
+ })
} else {
- format!("re-export of private `{}`", ident)
+ self.tcx
+ .sess
+ .create_err(CannotBeReexportedPrivateNS { span: import.span, ident })
};
-
- struct_span_err!(self.tcx.sess, import.span, E0365, "{}", error_msg)
- .span_label(import.span, label_msg)
- .note(format!("consider declaring type or module `{}` with `pub`", ident))
- .emit();
+ err.emit();
} else {
- let mut err =
- struct_span_err!(self.tcx.sess, import.span, E0364, "{error_msg}");
+ let mut err = if crate_private_reexport {
+ self.tcx
+ .sess
+ .create_err(CannotBeReexportedCratePublic { span: import.span, ident })
+ } else {
+ self.tcx
+ .sess
+ .create_err(CannotBeReexportedPrivate { span: import.span, ident })
+ };
+
match binding.kind {
NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id))
// exclude decl_macro
if self.get_macro_by_def_id(def_id).macro_rules =>
{
- err.span_help(
- binding.span,
- "consider adding a `#[macro_export]` to the macro in the imported module",
- );
+ err.subdiagnostic(ConsiderAddingMacroExport {
+ span: binding.span,
+ });
}
_ => {
- err.span_note(
- import.span,
- format!(
- "consider marking `{ident}` as `pub` in the imported module"
- ),
- );
+ err.subdiagnostic(ConsiderMarkingAsPub {
+ span: import.span,
+ ident,
+ });
}
}
err.emit();
@@ -1144,9 +1232,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn check_for_redundant_imports(
&mut self,
ident: Ident,
- import: &'a Import<'a>,
- source_bindings: &PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>,
- target_bindings: &PerNS<Cell<Option<&'a NameBinding<'a>>>>,
+ import: Import<'a>,
+ source_bindings: &PerNS<Cell<Result<NameBinding<'a>, Determinacy>>>,
+ target_bindings: &PerNS<Cell<Option<NameBinding<'a>>>>,
target: Ident,
) {
// This function is only called for single imports.
@@ -1175,7 +1263,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
match this.early_resolve_ident_in_lexical_scope(
target,
- ScopeSet::All(ns, false),
+ ScopeSet::All(ns),
&import.parent_scope,
None,
false,
@@ -1207,19 +1295,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
- fn resolve_glob_import(&mut self, import: &'a Import<'a>) {
+ fn resolve_glob_import(&mut self, import: Import<'a>) {
// This function is only called for glob imports.
let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() };
let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else {
- self.tcx.sess.span_err(import.span, "cannot glob-import all possible crates");
+ self.tcx.sess.create_err(CannotGlobImportAllCrates {
+ span: import.span,
+ }).emit();
return;
};
if module.is_trait() {
- self.tcx.sess.span_err(import.span, "items in traits are not importable");
+ self.tcx.sess.create_err(ItemsInTraitsAreNotImportable { span: import.span }).emit();
return;
- } else if ptr::eq(module, import.parent_scope.module) {
+ } else if module == import.parent_scope.module {
return;
} else if is_prelude {
self.prelude = Some(module);