match *self {
Def::AssociatedTy(..) | Def::AssociatedConst(..) | Def::AssociatedExistential(..) |
Def::Enum(..) | Def::Existential(..) | Def::Err => "an",
+ Def::Macro(.., macro_kind) => macro_kind.article(),
_ => "a",
}
}
impl fmt::Debug for DefId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "DefId({:?}/{}:{}",
- self.krate.index(),
+ write!(f, "DefId({}/{}:{}",
+ self.krate,
self.index.address_space().index(),
self.index.as_array_index())?;
UniformRoot(UniformRootKind),
}
+impl<'a> PartialEq for ModuleOrUniformRoot<'a> {
+ fn eq(&self, other: &Self) -> bool {
+ match (*self, *other) {
+ (ModuleOrUniformRoot::Module(lhs), ModuleOrUniformRoot::Module(rhs)) =>
+ ptr::eq(lhs, rhs),
+ (ModuleOrUniformRoot::UniformRoot(lhs), ModuleOrUniformRoot::UniformRoot(rhs)) =>
+ lhs == rhs,
+ _ => false,
+ }
+ }
+}
+
#[derive(Clone, Debug)]
enum PathResult<'a> {
Module(ModuleOrUniformRoot<'a>),
normal_ancestor_id: DefId,
resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
- legacy_macro_resolutions: RefCell<Vec<(Ident, MacroKind, ParentScope<'a>,
- Option<&'a NameBinding<'a>>)>>,
- macro_resolutions: RefCell<Vec<(Vec<Segment>, ParentScope<'a>, Span)>>,
+ single_segment_macro_resolutions: RefCell<Vec<(Ident, MacroKind, ParentScope<'a>,
+ Option<&'a NameBinding<'a>>)>>,
+ multi_segment_macro_resolutions: RefCell<Vec<(Vec<Segment>, Span, MacroKind, ParentScope<'a>,
+ Option<Def>)>>,
builtin_attrs: RefCell<Vec<(Ident, ParentScope<'a>)>>,
// Macro invocations that can expand into items in this module.
kind,
normal_ancestor_id,
resolutions: Default::default(),
- legacy_macro_resolutions: RefCell::new(Vec::new()),
- macro_resolutions: RefCell::new(Vec::new()),
+ single_segment_macro_resolutions: RefCell::new(Vec::new()),
+ multi_segment_macro_resolutions: RefCell::new(Vec::new()),
builtin_attrs: RefCell::new(Vec::new()),
unresolved_invocations: Default::default(),
no_implicit_prelude: false,
/// The current self item if inside an ADT (used for better errors).
current_self_item: Option<NodeId>,
+ /// FIXME: Refactor things so that this is passed through arguments and not resolver.
+ last_import_segment: bool,
+
/// The idents for the primitive types.
primitive_type_table: PrimitiveTypeTable,
current_trait_ref: None,
current_self_type: None,
current_self_item: None,
+ last_import_segment: false,
primitive_type_table: PrimitiveTypeTable::new(),
self.arenas.alloc_module(module)
}
- fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>)
- -> bool /* true if an error was reported */ {
+ fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>) {
match binding.kind {
- NameBindingKind::Import { directive, binding, ref used }
- if !used.get() => {
+ NameBindingKind::Import { directive, binding, ref used } if !used.get() => {
used.set(true);
directive.used.set(true);
self.used_imports.insert((directive.id, ns));
self.add_to_glob_map(directive.id, ident);
- self.record_use(ident, ns, binding)
+ self.record_use(ident, ns, binding);
}
- NameBindingKind::Import { .. } => false,
NameBindingKind::Ambiguity { kind, b1, b2 } => {
self.ambiguity_errors.push(AmbiguityError {
kind, ident, b1, b2,
misc1: AmbiguityErrorMisc::None,
misc2: AmbiguityErrorMisc::None,
});
- true
}
- _ => false
+ _ => {}
}
}
fn report_errors(&mut self, krate: &Crate) {
self.report_with_use_injections(krate);
- let mut reported_spans = FxHashSet::default();
for &(span_use, span_def) in &self.macro_expanded_macro_export_errors {
let msg = "macro-expanded `macro_export` macros from the current crate \
}
for ambiguity_error in &self.ambiguity_errors {
- if reported_spans.insert(ambiguity_error.ident.span) {
- self.report_ambiguity_error(ambiguity_error);
- }
+ self.report_ambiguity_error(ambiguity_error);
}
+ let mut reported_spans = FxHashSet::default();
for &PrivacyError(dedup_span, ident, binding) in &self.privacy_errors {
if reported_spans.insert(dedup_span) {
span_err!(self.session, ident.span, E0603, "{} `{}` is private",
// except according to those terms.
use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};
-use {CrateLint, DeterminacyExt, Resolver, ResolutionError, is_known_tool, resolve_error};
+use {CrateLint, DeterminacyExt, Resolver, ResolutionError};
use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding};
+use {is_known_tool, names_to_string, resolve_error};
use ModuleOrUniformRoot;
use Namespace::{self, *};
use build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport};
if path.len() > 1 {
let def = match self.resolve_path(&path, Some(MacroNS), parent_scope,
false, path_span, CrateLint::No) {
- PathResult::NonModule(path_res) => match path_res.base_def() {
- Def::Err => Err(Determinacy::Determined),
- def @ _ => {
- if path_res.unresolved_segments() > 0 {
- self.found_unresolved_macro = true;
- self.session.span_err(path_span,
- "fail to resolve non-ident macro path");
- Err(Determinacy::Determined)
- } else {
- Ok(def)
- }
- }
- },
- PathResult::Module(..) => unreachable!(),
+ PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
+ Ok(path_res.base_def())
+ }
PathResult::Indeterminate if !force => return Err(Determinacy::Undetermined),
- _ => {
+ PathResult::NonModule(..) | PathResult::Indeterminate | PathResult::Failed(..) => {
self.found_unresolved_macro = true;
Err(Determinacy::Determined)
- },
+ }
+ PathResult::Module(..) => unreachable!(),
};
- parent_scope.module.macro_resolutions.borrow_mut()
- .push((path, parent_scope.clone(), path_span));
+ parent_scope.module.multi_segment_macro_resolutions.borrow_mut()
+ .push((path, path_span, kind, parent_scope.clone(), def.ok()));
def
} else {
Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined),
}
- parent_scope.module.legacy_macro_resolutions.borrow_mut()
+ parent_scope.module.single_segment_macro_resolutions.borrow_mut()
.push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
binding.map(|binding| binding.def_ignoring_ambiguity())
pub fn finalize_current_module_macro_resolutions(&mut self) {
let module = self.current_module;
+ let check_consistency = |this: &mut Self, path: &[Ident], span,
+ kind: MacroKind, initial_def, def| {
+ if let Some(initial_def) = initial_def {
+ if def != initial_def && def != Def::Err && this.ambiguity_errors.is_empty() {
+ // Make sure compilation does not succeed if preferred macro resolution
+ // has changed after the macro had been expanded. In theory all such
+ // situations should be reported as ambiguity errors, so this is a bug.
+ span_bug!(span, "inconsistent resolution for a macro");
+ }
+ } else {
+ // It's possible that the macro was unresolved (indeterminate) and silently
+ // expanded into a dummy fragment for recovery during expansion.
+ // Now, post-expansion, the resolution may succeed, but we can't change the
+ // past and need to report an error.
+ // However, non-speculative `resolve_path` can successfully return private items
+ // even if speculative `resolve_path` returned nothing previously, so we skip this
+ // less informative error if the privacy error is reported elsewhere.
+ if this.privacy_errors.is_empty() {
+ let msg = format!("cannot determine resolution for the {} `{}`",
+ kind.descr(), names_to_string(path));
+ let msg_note = "import resolution is stuck, try simplifying macro imports";
+ this.session.struct_span_err(span, &msg).note(msg_note).emit();
+ }
+ }
+ };
+
let macro_resolutions =
- mem::replace(&mut *module.macro_resolutions.borrow_mut(), Vec::new());
- for (mut path, parent_scope, path_span) in macro_resolutions {
+ mem::replace(&mut *module.multi_segment_macro_resolutions.borrow_mut(), Vec::new());
+ for (mut path, path_span, kind, parent_scope, initial_def) in macro_resolutions {
// FIXME: Path resolution will ICE if segment IDs present.
for seg in &mut path { seg.id = None; }
match self.resolve_path(&path, Some(MacroNS), &parent_scope,
true, path_span, CrateLint::No) {
- PathResult::NonModule(_) => {},
- PathResult::Failed(span, msg, _) => {
+ PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
+ let def = path_res.base_def();
+ check_consistency(self, &path, path_span, kind, initial_def, def);
+ }
+ path_res @ PathResult::NonModule(..) | path_res @ PathResult::Failed(..) => {
+ let (span, msg) = if let PathResult::Failed(span, msg, ..) = path_res {
+ (span, msg)
+ } else {
+ (path_span, format!("partially resolved path in {} {}",
+ kind.article(), kind.descr()))
+ };
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
}
- _ => unreachable!(),
+ PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
}
}
- let legacy_macro_resolutions =
- mem::replace(&mut *module.legacy_macro_resolutions.borrow_mut(), Vec::new());
- for (ident, kind, parent_scope, initial_binding) in legacy_macro_resolutions {
- let binding = self.early_resolve_ident_in_lexical_scope(
- ident, MacroNS, Some(kind), false, &parent_scope, true, true, ident.span
- );
- match binding {
+ let macro_resolutions =
+ mem::replace(&mut *module.single_segment_macro_resolutions.borrow_mut(), Vec::new());
+ for (ident, kind, parent_scope, initial_binding) in macro_resolutions {
+ match self.early_resolve_ident_in_lexical_scope(ident, MacroNS, Some(kind), false,
+ &parent_scope, true, true, ident.span) {
Ok(binding) => {
- let def = binding.def_ignoring_ambiguity();
- if let Some(initial_binding) = initial_binding {
+ let initial_def = initial_binding.map(|initial_binding| {
self.record_use(ident, MacroNS, initial_binding);
- let initial_def = initial_binding.def_ignoring_ambiguity();
- if self.ambiguity_errors.is_empty() &&
- def != initial_def && def != Def::Err {
- // Make sure compilation does not succeed if preferred macro resolution
- // has changed after the macro had been expanded. In theory all such
- // situations should be reported as ambiguity errors, so this is a bug.
- span_bug!(ident.span, "inconsistent resolution for a macro");
- }
- } else {
- // It's possible that the macro was unresolved (indeterminate) and silently
- // expanded into a dummy fragment for recovery during expansion.
- // Now, post-expansion, the resolution may succeed, but we can't change the
- // past and need to report an error.
- let msg = format!("cannot determine resolution for the {} `{}`",
- kind.descr(), ident);
- let msg_note = "import resolution is stuck, try simplifying macro imports";
- self.session.struct_span_err(ident.span, &msg).note(msg_note).emit();
- }
+ initial_binding.def_ignoring_ambiguity()
+ });
+ let def = binding.def_ignoring_ambiguity();
+ check_consistency(self, &[ident], ident.span, kind, initial_def, def);
}
Err(..) => {
assert!(initial_binding.is_none());
}
}
- if record_used {
- if let Some(binding) = resolution.binding {
- if let Some(shadowed_glob) = resolution.shadowed_glob {
- // Forbid expanded shadowing to avoid time travel.
- if restricted_shadowing &&
- binding.expansion != Mark::root() &&
- binding.def() != shadowed_glob.def() {
- self.ambiguity_errors.push(AmbiguityError {
- kind: AmbiguityKind::GlobVsExpanded,
- ident,
- b1: binding,
- b2: shadowed_glob,
- misc1: AmbiguityErrorMisc::None,
- misc2: AmbiguityErrorMisc::None,
- });
- }
- }
- if self.record_use(ident, ns, binding) {
- return Ok(self.dummy_binding);
- }
- if !self.is_accessible(binding.vis) {
- self.privacy_errors.push(PrivacyError(path_span, ident, binding));
- }
- }
-
- return resolution.binding.ok_or(DeterminacyExt::Determined);
- }
-
let check_usable = |this: &mut Self, binding: &'a NameBinding<'a>| {
- // `extern crate` are always usable for backwards compatibility, see issue #37020.
+ // `extern crate` are always usable for backwards compatibility, see issue #37020,
+ // remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`.
let usable = this.is_accessible(binding.vis) || binding.is_extern_crate();
if usable { Ok(binding) } else { Err(DeterminacyExt::Determined) }
};
+ if record_used {
+ return resolution.binding.ok_or(DeterminacyExt::Determined).and_then(|binding| {
+ if self.last_import_segment && check_usable(self, binding).is_err() {
+ Err(DeterminacyExt::Determined)
+ } else {
+ self.record_use(ident, ns, binding);
+
+ if let Some(shadowed_glob) = resolution.shadowed_glob {
+ // Forbid expanded shadowing to avoid time travel.
+ if restricted_shadowing &&
+ binding.expansion != Mark::root() &&
+ binding.def() != shadowed_glob.def() {
+ self.ambiguity_errors.push(AmbiguityError {
+ kind: AmbiguityKind::GlobVsExpanded,
+ ident,
+ b1: binding,
+ b2: shadowed_glob,
+ misc1: AmbiguityErrorMisc::None,
+ misc2: AmbiguityErrorMisc::None,
+ });
+ }
+ }
+
+ if !self.is_accessible(binding.vis) &&
+ // Remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`
+ !(self.last_import_segment && binding.is_extern_crate()) {
+ self.privacy_errors.push(PrivacyError(path_span, ident, binding));
+ }
+
+ Ok(binding)
+ }
+ })
+ }
+
// Items and single imports are not shadowable, if we have one, then it's determined.
if let Some(binding) = resolution.binding {
if !binding.is_glob_import() {
let mut prev_root_id: NodeId = NodeId::from_u32(0);
for i in 0 .. self.determined_imports.len() {
let import = self.determined_imports[i];
- let error = self.finalize_import(import);
- if let Some((span, err, note)) = error {
+ if let Some((span, err, note)) = self.finalize_import(import) {
errors = true;
if let SingleImport { source, ref result, .. } = import.subclass {
/// If successful, the resolved bindings are written into the module.
fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool {
debug!("(resolving import for module) resolving import `{}::...` in `{}`",
- Segment::names_to_string(&directive.module_path[..]),
+ Segment::names_to_string(&directive.module_path),
module_to_string(self.current_module).unwrap_or_else(|| "???".to_string()));
self.current_module = directive.parent_scope.module;
// For better failure detection, pretend that the import will
// not define any names while resolving its module path.
let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
- let result = self.resolve_path(
- &directive.module_path[..],
+ let path_res = self.resolve_path(
+ &directive.module_path,
None,
&directive.parent_scope,
false,
);
directive.vis.set(orig_vis);
- match result {
+ match path_res {
PathResult::Module(module) => module,
PathResult::Indeterminate => return false,
- _ => return true,
+ PathResult::NonModule(..) | PathResult::Failed(..) => return true,
}
};
directive: &'b ImportDirective<'b>
) -> Option<(Span, String, Option<String>)> {
self.current_module = directive.parent_scope.module;
- let ImportDirective { ref module_path, span, .. } = *directive;
- let module_result = self.resolve_path(
- &module_path,
- None,
- &directive.parent_scope,
- true,
- span,
- directive.crate_lint(),
- );
- let module = match module_result {
- PathResult::Module(module) => module,
+ let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
+ let path_res = self.resolve_path(&directive.module_path, None, &directive.parent_scope,
+ true, directive.span, directive.crate_lint());
+ directive.vis.set(orig_vis);
+ let module = match path_res {
+ PathResult::Module(module) => {
+ // Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
+ if let Some(initial_module) = directive.imported_module.get() {
+ if module != initial_module && self.ambiguity_errors.is_empty() {
+ span_bug!(directive.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.session.struct_span_err(directive.span, msg).note(msg_note).emit();
+ }
+ }
+
+ module
+ }
PathResult::Failed(span, msg, false) => {
+ assert!(directive.imported_module.get().is_none());
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
return None;
}
PathResult::Failed(span, msg, true) => {
+ assert!(directive.imported_module.get().is_none());
return if let Some((suggested_path, note)) = self.make_path_suggestion(
- span, module_path.clone(), &directive.parent_scope
+ span, directive.module_path.clone(), &directive.parent_scope
) {
Some((
span,
} else {
Some((span, msg, None))
};
- },
- _ => return None,
+ }
+ PathResult::NonModule(path_res) if path_res.base_def() == Def::Err => {
+ // The error was already reported earlier.
+ assert!(directive.imported_module.get().is_none());
+ return None;
+ }
+ PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(),
};
let (ident, result, type_ns_only) = match directive.subclass {
SingleImport { source, ref result, type_ns_only, .. } => (source, result, type_ns_only),
GlobImport { is_prelude, ref max_vis } => {
- if module_path.len() <= 1 {
+ if directive.module_path.len() <= 1 {
// HACK(eddyb) `lint_if_path_starts_with_module` needs at least
// 2 segments, so the `resolve_path` above won't trigger it.
- let mut full_path = module_path.clone();
+ let mut full_path = directive.module_path.clone();
full_path.push(Segment::from_ident(keywords::Invalid.ident()));
self.lint_if_path_starts_with_module(
directive.crate_lint(),
let mut all_ns_err = true;
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
- if let Ok(binding) = result[ns].get() {
- all_ns_err = false;
- if this.record_use(ident, ns, binding) {
- if let ModuleOrUniformRoot::Module(module) = module {
- this.resolution(module, ident, ns).borrow_mut().binding =
- Some(this.dummy_binding);
+ let orig_vis = directive.vis.replace(ty::Visibility::Invisible);
+ let orig_last_import_segment = mem::replace(&mut this.last_import_segment, true);
+ let binding = this.resolve_ident_in_module(
+ module, ident, ns, Some(&directive.parent_scope), true, directive.span
+ );
+ this.last_import_segment = orig_last_import_segment;
+ directive.vis.set(orig_vis);
+
+ match binding {
+ Ok(binding) => {
+ // Consistency checks, analogous to `finalize_current_module_macro_resolutions`.
+ let initial_def = result[ns].get().map(|initial_binding| {
+ all_ns_err = false;
+ this.record_use(ident, MacroNS, initial_binding);
+ initial_binding.def_ignoring_ambiguity()
+ });
+ let def = binding.def_ignoring_ambiguity();
+ if let Ok(initial_def) = initial_def {
+ if def != initial_def && this.ambiguity_errors.is_empty() {
+ span_bug!(directive.span, "inconsistent resolution for an import");
+ }
+ } else {
+ if def != Def::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.session.struct_span_err(directive.span, msg).note(msg_note).emit();
+ }
}
}
- if ns == TypeNS {
- if let ModuleOrUniformRoot::UniformRoot(..) = module {
- // Make sure single-segment import is resolved non-speculatively
- // at least once to report the feature error.
- this.extern_prelude_get(ident, false, false);
- }
+ Err(..) => {
+ assert!(result[ns].get().is_err());
}
}
});
let mut all_ns_failed = true;
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
let binding = this.resolve_ident_in_module(
- module, ident, ns, Some(&directive.parent_scope), true, span
+ module, ident, ns, Some(&directive.parent_scope), true, directive.span
);
if binding.is_ok() {
all_ns_failed = false;
}
}
};
- Some((span, msg, None))
+ Some((directive.span, msg, None))
} else {
// `resolve_ident_in_module` reported a privacy error.
self.import_dummy_binding(directive);
}
}
- if module_path.len() <= 1 {
+ if directive.module_path.len() <= 1 {
// HACK(eddyb) `lint_if_path_starts_with_module` needs at least
// 2 segments, so the `resolve_path` above won't trigger it.
- let mut full_path = module_path.clone();
+ let mut full_path = directive.module_path.clone();
full_path.push(Segment::from_ident(ident));
self.per_ns(|this, ns| {
if let Ok(binding) = result[ns].get() {
MacroKind::ProcMacroStub => "crate-local procedural macro",
}
}
+
+ pub fn article(self) -> &'static str {
+ match self {
+ MacroKind::Attr => "an",
+ _ => "a",
+ }
+ }
}
/// An enum representing the different kinds of syntax extensions.
fn main() {
enum Foo {}
- let _ = Foo::bar!(); //~ ERROR fail to resolve non-ident macro path
+ let _ = Foo::bar!(); //~ ERROR failed to resolve. partially resolved path in a macro
}
-error: fail to resolve non-ident macro path
+error[E0433]: failed to resolve. partially resolved path in a macro
--> $DIR/extern-macro.rs:15:13
|
-LL | let _ = Foo::bar!(); //~ ERROR fail to resolve non-ident macro path
- | ^^^^^^^^
+LL | let _ = Foo::bar!(); //~ ERROR failed to resolve. partially resolved path in a macro
+ | ^^^^^^^^ partially resolved path in a macro
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0433`.
mod m {
fn check() {
- Result::Ok!(); //~ ERROR fail to resolve non-ident macro path
+ Result::Ok!(); //~ ERROR failed to resolve. partially resolved path in a macro
}
}
-error: fail to resolve non-ident macro path
+error[E0433]: failed to resolve. partially resolved path in a macro
--> $DIR/macro-path-prelude-fail-2.rs:13:9
|
-LL | Result::Ok!(); //~ ERROR fail to resolve non-ident macro path
- | ^^^^^^^^^^
+LL | Result::Ok!(); //~ ERROR failed to resolve. partially resolved path in a macro
+ | ^^^^^^^^^^ partially resolved path in a macro
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0433`.
--- /dev/null
+#![feature(decl_macro)]
+
+mod m {
+ macro mac() {}
+}
+
+fn main() {
+ m::mac!(); //~ ERROR macro `mac` is private
+}
--- /dev/null
+error[E0603]: macro `mac` is private
+ --> $DIR/decl-macro.rs:8:8
+ |
+LL | m::mac!(); //~ ERROR macro `mac` is private
+ | ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0603`.
--> $DIR/non-existent-1.rs:13:5
|
LL | use xcrate::S; //~ ERROR unresolved import `xcrate`
- | ^^^^^^ Could not find `xcrate` in `{{root}}`
+ | ^^^^^^ Use of undeclared type or module `xcrate`
error: aborting due to previous error
fn std() {}
enum std {}
use std as foo;
- //~^ ERROR `std` import is ambiguous
- //~| ERROR `std` import is ambiguous
+ //~^ ERROR `std` is ambiguous
+ //~| ERROR `std` is ambiguous
}
-error: `std` import is ambiguous
+error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
--> $DIR/block-scoped-shadow.rs:18:9
|
-LL | struct std;
- | ----------- may refer to `self::std` in the future
-...
-LL | enum std {}
- | ----------- shadowed by block-scoped `std`
LL | use std as foo;
- | ^^^ can refer to external crate `::std`
+ | ^^^ ambiguous name
|
- = help: write `::std` or `self::std` explicitly instead
- = note: in the future, `#![feature(uniform_paths)]` may become the default
+note: `std` could refer to the enum defined here
+ --> $DIR/block-scoped-shadow.rs:17:5
+ |
+LL | enum std {}
+ | ^^^^^^^^^^^
+note: `std` could also refer to the struct defined here
+ --> $DIR/block-scoped-shadow.rs:13:1
+ |
+LL | struct std;
+ | ^^^^^^^^^^^
+ = help: use `self::std` to refer to the struct unambiguously
-error: `std` import is ambiguous
+error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
--> $DIR/block-scoped-shadow.rs:18:9
|
-LL | struct std;
- | ----------- may refer to `self::std` in the future
-...
-LL | fn std() {}
- | ----------- shadowed by block-scoped `std`
-LL | enum std {}
LL | use std as foo;
- | ^^^
+ | ^^^ ambiguous name
+ |
+note: `std` could refer to the function defined here
+ --> $DIR/block-scoped-shadow.rs:16:5
|
- = help: write `self::std` explicitly instead
- = note: in the future, `#![feature(uniform_paths)]` may become the default
+LL | fn std() {}
+ | ^^^^^^^^^^^
+note: `std` could also refer to the unit struct defined here
+ --> $DIR/block-scoped-shadow.rs:13:1
+ |
+LL | struct std;
+ | ^^^^^^^^^^^
+ = help: use `self::std` to refer to the unit struct unambiguously
error: aborting due to 2 previous errors
+For more information about this error, try `rustc --explain E0659`.
--- /dev/null
+// edition:2018
+
+mod my {
+ pub mod sub {
+ pub fn bar() {}
+ }
+}
+
+mod sub {
+ pub fn bar() {}
+}
+
+fn foo() {
+ use my::sub;
+ {
+ use sub::bar; //~ ERROR `sub` is ambiguous
+ }
+}
+
+fn main() {}
--- /dev/null
+error[E0659]: `sub` is ambiguous (name vs any other name during import resolution)
+ --> $DIR/block-scoped-shadow-nested.rs:16:13
+ |
+LL | use sub::bar; //~ ERROR `sub` is ambiguous
+ | ^^^ ambiguous name
+ |
+note: `sub` could refer to the module imported here
+ --> $DIR/block-scoped-shadow-nested.rs:14:9
+ |
+LL | use my::sub;
+ | ^^^^^^^
+note: `sub` could also refer to the module defined here
+ --> $DIR/block-scoped-shadow-nested.rs:9:1
+ |
+LL | / mod sub {
+LL | | pub fn bar() {}
+LL | | }
+ | |_^
+ = help: use `self::sub` to refer to the module unambiguously
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0659`.
#![feature(uniform_paths)]
-enum Foo { A, B }
+enum Foo {}
struct std;
fn main() {
- enum Foo {}
+ enum Foo { A, B }
use Foo::*;
- //~^ ERROR `Foo` import is ambiguous
+ //~^ ERROR `Foo` is ambiguous
let _ = (A, B);
fn std() {}
enum std {}
use std as foo;
- //~^ ERROR `std` import is ambiguous
- //~| ERROR `std` import is ambiguous
+ //~^ ERROR `std` is ambiguous
+ //~| ERROR `std` is ambiguous
}
-error: `Foo` import is ambiguous
+error[E0659]: `Foo` is ambiguous (name vs any other name during import resolution)
--> $DIR/block-scoped-shadow.rs:21:9
|
-LL | enum Foo { A, B }
- | ----------------- can refer to `self::Foo`
-...
-LL | enum Foo {}
- | ----------- shadowed by block-scoped `Foo`
LL | use Foo::*;
- | ^^^
+ | ^^^ ambiguous name
|
- = help: write `self::Foo` explicitly instead
- = note: relative `use` paths enabled by `#![feature(uniform_paths)]`
+note: `Foo` could refer to the enum defined here
+ --> $DIR/block-scoped-shadow.rs:20:5
+ |
+LL | enum Foo { A, B }
+ | ^^^^^^^^^^^^^^^^^
+note: `Foo` could also refer to the enum defined here
+ --> $DIR/block-scoped-shadow.rs:15:1
+ |
+LL | enum Foo {}
+ | ^^^^^^^^^^^
+ = help: use `self::Foo` to refer to the enum unambiguously
-error: `std` import is ambiguous
+error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
--> $DIR/block-scoped-shadow.rs:28:9
|
-LL | struct std;
- | ----------- can refer to `self::std`
-...
-LL | enum std {}
- | ----------- shadowed by block-scoped `std`
LL | use std as foo;
- | ^^^ can refer to external crate `::std`
+ | ^^^ ambiguous name
|
- = help: write `::std` or `self::std` explicitly instead
- = note: relative `use` paths enabled by `#![feature(uniform_paths)]`
+note: `std` could refer to the enum defined here
+ --> $DIR/block-scoped-shadow.rs:27:5
+ |
+LL | enum std {}
+ | ^^^^^^^^^^^
+note: `std` could also refer to the struct defined here
+ --> $DIR/block-scoped-shadow.rs:17:1
+ |
+LL | struct std;
+ | ^^^^^^^^^^^
+ = help: use `self::std` to refer to the struct unambiguously
-error: `std` import is ambiguous
+error[E0659]: `std` is ambiguous (name vs any other name during import resolution)
--> $DIR/block-scoped-shadow.rs:28:9
|
-LL | struct std;
- | ----------- can refer to `self::std`
-...
-LL | fn std() {}
- | ----------- shadowed by block-scoped `std`
-LL | enum std {}
LL | use std as foo;
- | ^^^
+ | ^^^ ambiguous name
+ |
+note: `std` could refer to the function defined here
+ --> $DIR/block-scoped-shadow.rs:26:5
|
- = help: write `self::std` explicitly instead
- = note: relative `use` paths enabled by `#![feature(uniform_paths)]`
+LL | fn std() {}
+ | ^^^^^^^^^^^
+note: `std` could also refer to the unit struct defined here
+ --> $DIR/block-scoped-shadow.rs:17:1
+ |
+LL | struct std;
+ | ^^^^^^^^^^^
+ = help: use `self::std` to refer to the unit struct unambiguously
error: aborting due to 3 previous errors
+For more information about this error, try `rustc --explain E0659`.
--- /dev/null
+// compile-pass
+// edition:2018
+
+fn main() {
+ enum E { A, B, C }
+
+ use E::*;
+ match A {
+ A => {}
+ B => {}
+ C => {}
+ }
+}