Auto merge of #56042 - petrochenkov:nuni, r=petrochenkov

[nightly] resolve: Implement uniform paths 2.0

Forward-port of https://github.com/rust-lang/rust/pull/55884 to nightly.

r? @ghost
This commit is contained in:
bors 2018-11-19 02:59:29 +00:00
commit 7e82eda000
186 changed files with 2227 additions and 1561 deletions

View File

@ -11,8 +11,8 @@ introducing `extern crate` items, using keyword `extern`.
For example, `extern::my_crat::a::b` will resolve to path `a::b` in crate `my_crate`.
`feature(extern_absolute_paths)` mode provides the same effect by resolving absolute paths like
`::my_crate::a::b` to paths from extern crates by default.
Absolute paths on 2018 edition (e.g. `::my_crate::a::b`) provide the same effect
and resolve to extern crates (built-in or passed with `--extern`).
```rust,ignore
#![feature(extern_in_paths)]

View File

@ -128,14 +128,6 @@ impl PathResolution {
pub fn unresolved_segments(&self) -> usize {
self.unresolved_segments
}
pub fn kind_name(&self) -> &'static str {
if self.unresolved_segments != 0 {
"associated item"
} else {
self.base_def.kind_name()
}
}
}
/// Different kinds of symbols don't influence each other.
@ -269,6 +261,12 @@ impl NonMacroAttrKind {
impl Def {
pub fn def_id(&self) -> DefId {
self.opt_def_id().unwrap_or_else(|| {
bug!("attempted .def_id() on invalid def: {:?}", self)
})
}
pub fn opt_def_id(&self) -> Option<DefId> {
match *self {
Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) |
Def::Variant(id) | Def::VariantCtor(id, ..) | Def::Enum(id) |
@ -276,9 +274,8 @@ impl Def {
Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::StructCtor(id, ..) |
Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) |
Def::AssociatedConst(id) | Def::Macro(id, ..) |
Def::Existential(id) | Def::AssociatedExistential(id) | Def::ForeignTy(id) |
Def::SelfCtor(id) => {
id
Def::Existential(id) | Def::AssociatedExistential(id) | Def::ForeignTy(id) => {
Some(id)
}
Def::Local(..) |
@ -286,10 +283,11 @@ impl Def {
Def::Label(..) |
Def::PrimTy(..) |
Def::SelfTy(..) |
Def::SelfCtor(..) |
Def::ToolMod |
Def::NonMacroAttr(..) |
Def::Err => {
bug!("attempted .def_id() on invalid def: {:?}", self)
None
}
}
}
@ -333,4 +331,13 @@ impl Def {
Def::Err => "unresolved item",
}
}
pub fn article(&self) -> &'static str {
match *self {
Def::AssociatedTy(..) | Def::AssociatedConst(..) | Def::AssociatedExistential(..) |
Def::Enum(..) | Def::Existential(..) | Def::Err => "an",
Def::Macro(.., macro_kind) => macro_kind.article(),
_ => "a",
}
}
}

View File

@ -225,8 +225,8 @@ pub struct DefId {
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())?;

View File

@ -80,7 +80,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
self.check_def_id(def.def_id());
}
_ if self.in_pat => (),
Def::PrimTy(..) | Def::SelfTy(..) |
Def::PrimTy(..) | Def::SelfTy(..) | Def::SelfCtor(..) |
Def::Local(..) | Def::Upvar(..) => {}
Def::Variant(variant_id) | Def::VariantCtor(variant_id, ..) => {
if let Some(enum_id) = self.tcx.parent_def_id(variant_id) {

View File

@ -781,10 +781,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Checker<'a, 'tcx> {
fn visit_path(&mut self, path: &'tcx hir::Path, id: hir::HirId) {
let id = self.tcx.hir.hir_to_node_id(id);
match path.def {
Def::Local(..) | Def::Upvar(..) | Def::SelfCtor(..) |
Def::PrimTy(..) | Def::SelfTy(..) | Def::Err => {}
_ => self.tcx.check_stability(path.def.def_id(), Some(id), path.span)
if let Some(def_id) = path.def.opt_def_id() {
self.tcx.check_stability(def_id, Some(id), path.span)
}
intravisit::walk_path(self, path)
}

View File

@ -298,7 +298,8 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
let label_msg = match pat.node {
PatKind::Path(hir::QPath::Resolved(None, ref path))
if path.segments.len() == 1 && path.segments[0].args.is_none() => {
format!("interpreted as a {} pattern, not new variable", path.def.kind_name())
format!("interpreted as {} {} pattern, not new variable",
path.def.article(), path.def.kind_name())
}
_ => format!("pattern `{}` not covered", pattern_string),
};

View File

@ -361,9 +361,11 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> {
let def_id = self.tcx.hir.local_def_id(id);
if let Some(exports) = self.tcx.module_exports(def_id) {
for export in exports.iter() {
if let Some(node_id) = self.tcx.hir.as_local_node_id(export.def.def_id()) {
if export.vis == ty::Visibility::Public {
self.update(node_id, Some(AccessLevel::Exported));
if export.vis == ty::Visibility::Public {
if let Some(def_id) = export.def.opt_def_id() {
if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) {
self.update(node_id, Some(AccessLevel::Exported));
}
}
}
}

View File

@ -116,143 +116,35 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
id: NodeId,
parent_prefix: &[Segment],
nested: bool,
mut uniform_paths_canary_emitted: bool,
// The whole `use` item
parent_scope: ParentScope<'a>,
item: &Item,
vis: ty::Visibility,
root_span: Span,
) {
debug!("build_reduced_graph_for_use_tree(parent_prefix={:?}, \
uniform_paths_canary_emitted={}, \
use_tree={:?}, nested={})",
parent_prefix, uniform_paths_canary_emitted, use_tree, nested);
debug!("build_reduced_graph_for_use_tree(parent_prefix={:?}, use_tree={:?}, nested={})",
parent_prefix, use_tree, nested);
let uniform_paths =
self.session.rust_2018() &&
self.session.features_untracked().uniform_paths;
let mut prefix_iter = parent_prefix.iter().cloned()
.chain(use_tree.prefix.segments.iter().map(|seg| seg.into())).peekable();
let prefix_iter = || parent_prefix.iter().cloned()
.chain(use_tree.prefix.segments.iter().map(|seg| seg.into()));
let prefix_start = prefix_iter().next();
let starts_with_non_keyword = prefix_start.map_or(false, |seg| {
!seg.ident.is_path_segment_keyword()
});
// Imports are resolved as global by default, prepend `CrateRoot`,
// unless `#![feature(uniform_paths)]` is enabled.
let inject_crate_root =
!uniform_paths &&
match use_tree.kind {
// HACK(eddyb) special-case `use *` to mean `use ::*`.
ast::UseTreeKind::Glob if prefix_start.is_none() => true,
_ => starts_with_non_keyword,
};
let root = if inject_crate_root {
let span = use_tree.prefix.span.shrink_to_lo();
Some(Segment::from_ident(Ident::new(keywords::CrateRoot.name(), span)))
// On 2015 edition imports are resolved as crate-relative by default,
// so prefixes are prepended with crate root segment if necessary.
// The root is prepended lazily, when the first non-empty prefix or terminating glob
// appears, so imports in braced groups can have roots prepended independently.
let is_glob = if let ast::UseTreeKind::Glob = use_tree.kind { true } else { false };
let crate_root = if !self.session.rust_2018() &&
prefix_iter.peek().map_or(is_glob, |seg| !seg.ident.is_path_segment_keyword()) {
Some(Segment::from_ident(Ident::new(
keywords::CrateRoot.name(), use_tree.prefix.span.shrink_to_lo()
)))
} else {
None
};
let prefix: Vec<_> = root.into_iter().chain(prefix_iter()).collect();
let prefix = crate_root.into_iter().chain(prefix_iter).collect::<Vec<_>>();
debug!("build_reduced_graph_for_use_tree: prefix={:?}", prefix);
// `#[feature(uniform_paths)]` allows an unqualified import path,
// e.g. `use x::...;` to resolve not just globally (`use ::x::...;`)
// but also relatively (`use self::x::...;`). To catch ambiguities
// that might arise from both of these being available and resolution
// silently picking one of them, an artificial `use self::x as _;`
// import is injected as a "canary", and an error is emitted if it
// successfully resolves while an `x` external crate exists.
//
// For each block scope around the `use` item, one special canary
// import of the form `use x as _;` is also injected, having its
// parent set to that scope; `resolve_imports` will only resolve
// it within its appropriate scope; if any of them successfully
// resolve, an ambiguity error is emitted, since the original
// import can't see the item in the block scope (`self::x` only
// looks in the enclosing module), but a non-`use` path could.
//
// Additionally, the canary might be able to catch limitations of the
// current implementation, where `::x` may be chosen due to `self::x`
// not existing, but `self::x` could appear later, from macro expansion.
//
// NB. The canary currently only errors if the `x::...` path *could*
// resolve as a relative path through the extern crate, i.e. `x` is
// in `extern_prelude`, *even though* `::x` might still forcefully
// load a non-`extern_prelude` crate.
// While always producing an ambiguity errors if `self::x` exists and
// a crate *could* be loaded, would be more conservative, imports for
// local modules named `test` (or less commonly, `syntax` or `log`),
// would need to be qualified (e.g. `self::test`), which is considered
// ergonomically unacceptable.
let emit_uniform_paths_canary =
!uniform_paths_canary_emitted &&
self.session.rust_2018() &&
starts_with_non_keyword;
if emit_uniform_paths_canary {
let source = prefix_start.unwrap();
// Helper closure to emit a canary with the given base path.
let emit = |this: &mut Self, base: Option<Segment>| {
let subclass = SingleImport {
target: Ident {
name: keywords::Underscore.name().gensymed(),
span: source.ident.span,
},
source: source.ident,
result: PerNS {
type_ns: Cell::new(Err(Undetermined)),
value_ns: Cell::new(Err(Undetermined)),
macro_ns: Cell::new(Err(Undetermined)),
},
type_ns_only: false,
};
this.add_import_directive(
base.into_iter().collect(),
subclass,
source.ident.span,
id,
root_span,
item.id,
ty::Visibility::Invisible,
parent_scope.clone(),
true, // is_uniform_paths_canary
);
};
// A single simple `self::x` canary.
emit(self, Some(Segment {
ident: Ident {
name: keywords::SelfValue.name(),
span: source.ident.span,
},
id: source.id
}));
// One special unprefixed canary per block scope around
// the import, to detect items unreachable by `self::x`.
let orig_current_module = self.current_module;
let mut span = source.ident.span.modern();
loop {
match self.current_module.kind {
ModuleKind::Block(..) => emit(self, None),
ModuleKind::Def(..) => break,
}
match self.hygienic_lexical_parent(self.current_module, &mut span) {
Some(module) => {
self.current_module = module;
}
None => break,
}
}
self.current_module = orig_current_module;
uniform_paths_canary_emitted = true;
}
let empty_for_self = |prefix: &[Segment]| {
prefix.is_empty() ||
prefix.len() == 1 && prefix[0].ident.name == keywords::CrateRoot.name()
@ -350,7 +242,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
item.id,
vis,
parent_scope,
false, // is_uniform_paths_canary
);
}
ast::UseTreeKind::Glob => {
@ -367,7 +258,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
item.id,
vis,
parent_scope,
false, // is_uniform_paths_canary
);
}
ast::UseTreeKind::Nested(ref items) => {
@ -396,7 +286,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
for &(ref tree, id) in items {
self.build_reduced_graph_for_use_tree(
// This particular use tree
tree, id, &prefix, true, uniform_paths_canary_emitted,
tree, id, &prefix, true,
// The whole `use` item
parent_scope.clone(), item, vis, root_span,
);
@ -420,7 +310,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
};
self.build_reduced_graph_for_use_tree(
// This particular use tree
&tree, id, &prefix, true, uniform_paths_canary_emitted,
&tree, id, &prefix, true,
// The whole `use` item
parent_scope.clone(), item, ty::Visibility::Invisible, root_span,
);
@ -441,7 +331,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
ItemKind::Use(ref use_tree) => {
self.build_reduced_graph_for_use_tree(
// This particular use tree
use_tree, item.id, &[], false, false,
use_tree, item.id, &[], false,
// The whole `use` item
parent_scope, item, vis, use_tree.span,
);
@ -459,25 +349,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let used = self.process_legacy_macro_imports(item, module, &parent_scope);
let binding =
(module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas);
if ptr::eq(self.current_module, self.graph_root) {
if let Some(entry) = self.extern_prelude.get(&ident.modern()) {
if expansion != Mark::root() && orig_name.is_some() &&
entry.extern_crate_item.is_none() {
self.session.span_err(item.span, "macro-expanded `extern crate` items \
cannot shadow names passed with \
`--extern`");
}
}
let entry = self.extern_prelude.entry(ident.modern())
.or_insert(ExternPreludeEntry {
extern_crate_item: None,
introduced_by_item: true,
});
entry.extern_crate_item = Some(binding);
if orig_name.is_some() {
entry.introduced_by_item = true;
}
}
let directive = self.arenas.alloc_import_directive(ImportDirective {
root_id: item.id,
id: item.id,
@ -492,10 +363,28 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
module_path: Vec::new(),
vis: Cell::new(vis),
used: Cell::new(used),
is_uniform_paths_canary: false,
});
self.potentially_unused_imports.push(directive);
let imported_binding = self.import(binding, directive);
if ptr::eq(self.current_module, self.graph_root) {
if let Some(entry) = self.extern_prelude.get(&ident.modern()) {
if expansion != Mark::root() && orig_name.is_some() &&
entry.extern_crate_item.is_none() {
self.session.span_err(item.span, "macro-expanded `extern crate` items \
cannot shadow names passed with \
`--extern`");
}
}
let entry = self.extern_prelude.entry(ident.modern())
.or_insert(ExternPreludeEntry {
extern_crate_item: None,
introduced_by_item: true,
});
entry.extern_crate_item = Some(imported_binding);
if orig_name.is_some() {
entry.introduced_by_item = true;
}
}
self.define(parent, ident, TypeNS, imported_binding);
}
@ -905,7 +794,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
module_path: Vec::new(),
vis: Cell::new(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))),
used: Cell::new(false),
is_uniform_paths_canary: false,
});
let allow_shadowing = parent_scope.expansion == Mark::root();
@ -923,6 +811,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
ModuleOrUniformRoot::Module(module),
ident,
MacroNS,
None,
false,
span,
);
@ -977,7 +866,6 @@ impl<'a, 'b, 'cl> BuildReducedGraphVisitor<'a, 'b, 'cl> {
let invocation = self.resolver.invocations[&mark];
invocation.module.set(self.resolver.current_module);
invocation.parent_legacy_scope.set(self.current_legacy_scope);
invocation.output_legacy_scope.set(self.current_legacy_scope);
invocation
}
}

View File

@ -1253,7 +1253,7 @@ Erroneous code example:
```compile_fail,E0433
let map = HashMap::new();
// error: failed to resolve. Use of undeclared type or module `HashMap`
// error: failed to resolve: use of undeclared type or module `HashMap`
```
Please verify you didn't misspell the type/module's name or that you didn't

View File

@ -11,46 +11,39 @@
use {CrateLint, PathResult, Segment};
use macros::ParentScope;
use std::collections::BTreeSet;
use syntax::ast::Ident;
use syntax::symbol::{keywords, Symbol};
use syntax::symbol::keywords;
use syntax_pos::Span;
use resolve_imports::ImportResolver;
use std::cmp::Reverse;
impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
/// Add suggestions for a path that cannot be resolved.
pub(crate) fn make_path_suggestion(
&mut self,
span: Span,
path: Vec<Segment>,
mut path: Vec<Segment>,
parent_scope: &ParentScope<'b>,
) -> Option<(Vec<Segment>, Option<String>)> {
debug!("make_path_suggestion: span={:?} path={:?}", span, path);
// If we don't have a path to suggest changes to, then return.
if path.is_empty() {
return None;
}
// Check whether a ident is a path segment that is not root.
let is_special = |ident: Ident| ident.is_path_segment_keyword() &&
ident.name != keywords::CrateRoot.name();
match (path.get(0), path.get(1)) {
// Make suggestions that require at least two non-special path segments.
(Some(fst), Some(snd)) if !is_special(fst.ident) && !is_special(snd.ident) => {
debug!("make_path_suggestion: fst={:?} snd={:?}", fst, snd);
self.make_missing_self_suggestion(span, path.clone(), parent_scope)
.or_else(|| self.make_missing_crate_suggestion(span, path.clone(),
parent_scope))
.or_else(|| self.make_missing_super_suggestion(span, path.clone(),
parent_scope))
.or_else(|| self.make_external_crate_suggestion(span, path, parent_scope))
},
_ => None,
// `{{root}}::ident::...` on both editions.
// On 2015 `{{root}}` is usually added implicitly.
(Some(fst), Some(snd)) if fst.ident.name == keywords::CrateRoot.name() &&
!snd.ident.is_path_segment_keyword() => {}
// `ident::...` on 2018
(Some(fst), _) if self.session.rust_2018() && !fst.ident.is_path_segment_keyword() => {
// Insert a placeholder that's later replaced by `self`/`super`/etc.
path.insert(0, Segment::from_ident(keywords::Invalid.ident()));
}
_ => return None,
}
self.make_missing_self_suggestion(span, path.clone(), parent_scope)
.or_else(|| self.make_missing_crate_suggestion(span, path.clone(), parent_scope))
.or_else(|| self.make_missing_super_suggestion(span, path.clone(), parent_scope))
.or_else(|| self.make_external_crate_suggestion(span, path, parent_scope))
}
/// Suggest a missing `self::` if that resolves to an correct module.
@ -58,7 +51,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
/// ```
/// |
/// LL | use foo::Bar;
/// | ^^^ Did you mean `self::foo`?
/// | ^^^ did you mean `self::foo`?
/// ```
fn make_missing_self_suggestion(
&mut self,
@ -68,7 +61,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
) -> Option<(Vec<Segment>, Option<String>)> {
// Replace first ident with `self` and check if that is valid.
path[0].ident.name = keywords::SelfValue.name();
let result = self.resolve_path(None, &path, None, parent_scope, false, span, CrateLint::No);
let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result);
if let PathResult::Module(..) = result {
Some((path, None))
@ -82,7 +75,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
/// ```
/// |
/// LL | use foo::Bar;
/// | ^^^ Did you mean `crate::foo`?
/// | ^^^ did you mean `crate::foo`?
/// ```
fn make_missing_crate_suggestion(
&mut self,
@ -92,7 +85,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
) -> Option<(Vec<Segment>, Option<String>)> {
// Replace first ident with `crate` and check if that is valid.
path[0].ident.name = keywords::Crate.name();
let result = self.resolve_path(None, &path, None, parent_scope, false, span, CrateLint::No);
let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
debug!("make_missing_crate_suggestion: path={:?} result={:?}", path, result);
if let PathResult::Module(..) = result {
Some((
@ -113,7 +106,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
/// ```
/// |
/// LL | use foo::Bar;
/// | ^^^ Did you mean `super::foo`?
/// | ^^^ did you mean `super::foo`?
/// ```
fn make_missing_super_suggestion(
&mut self,
@ -123,7 +116,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
) -> Option<(Vec<Segment>, Option<String>)> {
// Replace first ident with `crate` and check if that is valid.
path[0].ident.name = keywords::Super.name();
let result = self.resolve_path(None, &path, None, parent_scope, false, span, CrateLint::No);
let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
debug!("make_missing_super_suggestion: path={:?} result={:?}", path, result);
if let PathResult::Module(..) = result {
Some((path, None))
@ -137,7 +130,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
/// ```
/// |
/// LL | use foobar::Baz;
/// | ^^^^^^ Did you mean `baz::foobar`?
/// | ^^^^^^ did you mean `baz::foobar`?
/// ```
///
/// Used when importing a submodule of an external crate but missing that crate's
@ -148,24 +141,21 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
mut path: Vec<Segment>,
parent_scope: &ParentScope<'b>,
) -> Option<(Vec<Segment>, Option<String>)> {
// Need to clone else we can't call `resolve_path` without a borrow error. We also store
// into a `BTreeMap` so we can get consistent ordering (and therefore the same diagnostic)
// each time.
let external_crate_names: BTreeSet<Symbol> = self.resolver.extern_prelude
.iter().map(|(ident, _)| ident.name).collect();
if !self.session.rust_2018() {
return None;
}
// Insert a new path segment that we can replace.
let new_path_segment = path[0].clone();
path.insert(1, new_path_segment);
// Sort extern crate names in reverse order to get
// 1) some consistent ordering for emitted dignostics and
// 2) `std` suggestions before `core` suggestions.
let mut extern_crate_names =
self.resolver.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>();
extern_crate_names.sort_by_key(|name| Reverse(name.as_str()));
// Iterate in reverse so that we start with crates at the end of the alphabet. This means
// that we'll always get `std` before `core`.
for name in external_crate_names.iter().rev() {
// Replace the first after root (a placeholder we inserted) with a crate name
// and check if that is valid.
path[1].ident.name = *name;
let result =
self.resolve_path(None, &path, None, parent_scope, false, span, CrateLint::No);
for name in extern_crate_names.into_iter() {
// Replace first ident with a crate name and check if that is valid.
path[0].ident.name = name;
let result = self.resolve_path(&path, None, parent_scope, false, span, CrateLint::No);
debug!("make_external_crate_suggestion: name={:?} path={:?} result={:?}",
name, path, result);
if let PathResult::Module(..) = result {

View File

@ -97,6 +97,11 @@ fn is_known_tool(name: Name) -> bool {
["clippy", "rustfmt"].contains(&&*name.as_str())
}
enum Weak {
Yes,
No,
}
/// A free importable items suggested in case of resolution failure.
struct ImportSuggestion {
path: Path,
@ -371,7 +376,7 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
}
ResolutionError::FailedToResolve(msg) => {
let mut err = struct_span_err!(resolver.session, span, E0433,
"failed to resolve. {}", msg);
"failed to resolve: {}", msg);
err.span_label(span, msg);
err
}
@ -391,14 +396,13 @@ fn resolve_struct_error<'sess, 'a>(resolver: &'sess Resolver,
err
}
ResolutionError::BindingShadowsSomethingUnacceptable(what_binding, name, binding) => {
let shadows_what = PathResolution::new(binding.def()).kind_name();
let mut err = struct_span_err!(resolver.session,
span,
E0530,
"{}s cannot shadow {}s", what_binding, shadows_what);
err.span_label(span, format!("cannot be named the same as a {}", shadows_what));
let shadows_what = binding.descr();
let mut err = struct_span_err!(resolver.session, span, E0530, "{}s cannot shadow {}s",
what_binding, shadows_what);
err.span_label(span, format!("cannot be named the same as {} {}",
binding.article(), shadows_what));
let participle = if binding.is_import() { "imported" } else { "defined" };
let msg = format!("a {} `{}` is {} here", shadows_what, name, participle);
let msg = format!("the {} `{}` is {} here", shadows_what, name, participle);
err.span_label(binding.span, msg);
err
}
@ -993,15 +997,34 @@ impl<'a> LexicalScopeBinding<'a> {
}
}
#[derive(Clone, Copy, PartialEq, Debug)]
enum UniformRootKind {
CurrentScope,
ExternPrelude,
}
#[derive(Copy, Clone, Debug)]
pub enum ModuleOrUniformRoot<'a> {
enum ModuleOrUniformRoot<'a> {
/// Regular module.
Module(Module<'a>),
/// The `{{root}}` (`CrateRoot` aka "global") / `extern` initial segment
/// in which external crates resolve, and also `crate` (only in `{{root}}`,
/// but *not* `extern`), in the Rust 2018 edition.
UniformRoot(Name),
/// This "virtual module" denotes either resolution in extern prelude
/// for paths starting with `::` on 2018 edition or `extern::`,
/// or resolution in current scope for single-segment imports.
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)]
@ -1045,9 +1068,10 @@ pub struct ModuleData<'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.
@ -1085,8 +1109,8 @@ impl<'a> ModuleData<'a> {
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,
@ -1195,6 +1219,7 @@ enum NameBindingKind<'a> {
used: Cell<bool>,
},
Ambiguity {
kind: AmbiguityKind,
b1: &'a NameBinding<'a>,
b2: &'a NameBinding<'a>,
}
@ -1212,10 +1237,61 @@ struct UseError<'a> {
better: bool,
}
#[derive(Clone, Copy, PartialEq, Debug)]
enum AmbiguityKind {
Import,
BuiltinAttr,
DeriveHelper,
LegacyHelperVsPrelude,
LegacyVsModern,
GlobVsOuter,
GlobVsGlob,
GlobVsExpanded,
MoreExpandedVsOuter,
}
impl AmbiguityKind {
fn descr(self) -> &'static str {
match self {
AmbiguityKind::Import =>
"name vs any other name during import resolution",
AmbiguityKind::BuiltinAttr =>
"built-in attribute vs any other name",
AmbiguityKind::DeriveHelper =>
"derive helper attribute vs any other name",
AmbiguityKind::LegacyHelperVsPrelude =>
"legacy plugin helper attribute vs name from prelude",
AmbiguityKind::LegacyVsModern =>
"`macro_rules` vs non-`macro_rules` from other module",
AmbiguityKind::GlobVsOuter =>
"glob import vs any other name from outer scope during import/macro resolution",
AmbiguityKind::GlobVsGlob =>
"glob import vs glob import in the same module",
AmbiguityKind::GlobVsExpanded =>
"glob import vs macro-expanded name in the same \
module during import/macro resolution",
AmbiguityKind::MoreExpandedVsOuter =>
"macro-expanded name vs less macro-expanded name \
from outer scope during import/macro resolution",
}
}
}
/// Miscellaneous bits of metadata for better ambiguity error reporting.
#[derive(Clone, Copy, PartialEq)]
enum AmbiguityErrorMisc {
SuggestSelf,
FromPrelude,
None,
}
struct AmbiguityError<'a> {
kind: AmbiguityKind,
ident: Ident,
b1: &'a NameBinding<'a>,
b2: &'a NameBinding<'a>,
misc1: AmbiguityErrorMisc,
misc2: AmbiguityErrorMisc,
}
impl<'a> NameBinding<'a> {
@ -1268,6 +1344,9 @@ impl<'a> NameBinding<'a> {
subclass: ImportDirectiveSubclass::ExternCrate { .. }, ..
}, ..
} => true,
NameBindingKind::Module(
&ModuleData { kind: ModuleKind::Def(Def::Mod(def_id), _), .. }
) => def_id.index == CRATE_DEF_INDEX,
_ => false,
}
}
@ -1313,6 +1392,10 @@ impl<'a> NameBinding<'a> {
if self.is_extern_crate() { "extern crate" } else { self.def().kind_name() }
}
fn article(&self) -> &'static str {
if self.is_extern_crate() { "an" } else { self.def().article() }
}
// Suppose that we resolved macro invocation with `invoc_parent_expansion` to binding `binding`
// at some expansion round `max(invoc, binding)` when they both emerged from macros.
// Then this function returns `true` if `self` may emerge from a macro *after* that
@ -1423,6 +1506,9 @@ pub struct Resolver<'a, 'b: 'a> {
/// 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,
@ -1661,8 +1747,8 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
let segments = &path.segments;
let path = Segment::from_path(&path);
// FIXME (Manishearth): Intra doc links won't get warned of epoch changes
let def = match self.resolve_path_without_parent_scope(None, &path, Some(namespace),
true, span, CrateLint::No) {
let def = match self.resolve_path_without_parent_scope(&path, Some(namespace), true,
span, CrateLint::No) {
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
module.def().unwrap(),
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
@ -1772,6 +1858,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
current_trait_ref: None,
current_self_type: None,
current_self_item: None,
last_import_segment: false,
primitive_type_table: PrimitiveTypeTable::new(),
@ -1873,23 +1960,35 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
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 */ {
match binding.kind {
NameBindingKind::Import { directive, binding, ref used }
if !used.get() => {
fn record_use(&mut self, ident: Ident, ns: Namespace,
used_binding: &'a NameBinding<'a>, is_lexical_scope: bool) {
match used_binding.kind {
NameBindingKind::Import { directive, binding, ref used } if !used.get() => {
// Avoid marking `extern crate` items that refer to a name from extern prelude,
// but not introduce it, as used if they are accessed from lexical scope.
if is_lexical_scope {
if let Some(entry) = self.extern_prelude.get(&ident.modern()) {
if let Some(crate_item) = entry.extern_crate_item {
if ptr::eq(used_binding, crate_item) && !entry.introduced_by_item {
return;
}
}
}
}
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, false);
}
NameBindingKind::Import { .. } => false,
NameBindingKind::Ambiguity { b1, b2 } => {
self.ambiguity_errors.push(AmbiguityError { ident, b1, b2 });
true
NameBindingKind::Ambiguity { kind, b1, b2 } => {
self.ambiguity_errors.push(AmbiguityError {
kind, ident, b1, b2,
misc1: AmbiguityErrorMisc::None,
misc2: AmbiguityErrorMisc::None,
});
}
_ => false
_ => {}
}
}
@ -1960,7 +2059,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
ModuleOrUniformRoot::Module(module),
ident,
ns,
false,
record_used,
path_span,
);
@ -1991,7 +2089,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
ModuleOrUniformRoot::Module(module),
ident,
ns,
false,
record_used,
path_span,
);
@ -2024,7 +2121,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
}
if ns == TypeNS && is_known_tool(ident.name) {
let binding = (Def::ToolMod, ty::Visibility::Public,
ident.span, Mark::root()).to_name_binding(self.arenas);
DUMMY_SP, Mark::root()).to_name_binding(self.arenas);
return Some(LexicalScopeBinding::Item(binding));
}
if let Some(prelude) = self.prelude {
@ -2033,7 +2130,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
ident,
ns,
false,
false,
path_span,
) {
return Some(LexicalScopeBinding::Item(binding));
@ -2093,23 +2189,31 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
None
}
fn resolve_ident_in_module(&mut self,
module: ModuleOrUniformRoot<'a>,
mut ident: Ident,
ns: Namespace,
record_used: bool,
span: Span)
-> Result<&'a NameBinding<'a>, Determinacy> {
fn resolve_ident_in_module(
&mut self,
module: ModuleOrUniformRoot<'a>,
mut ident: Ident,
ns: Namespace,
parent_scope: Option<&ParentScope<'a>>,
record_used: bool,
path_span: Span
) -> Result<&'a NameBinding<'a>, Determinacy> {
ident.span = ident.span.modern();
let orig_current_module = self.current_module;
if let ModuleOrUniformRoot::Module(module) = module {
if let Some(def) = ident.span.adjust(module.expansion) {
self.current_module = self.macro_def_scope(def);
match module {
ModuleOrUniformRoot::Module(module) => {
if let Some(def) = ident.span.adjust(module.expansion) {
self.current_module = self.macro_def_scope(def);
}
}
ModuleOrUniformRoot::UniformRoot(UniformRootKind::ExternPrelude) => {
ident.span.adjust(Mark::root());
}
_ => {}
}
let result = self.resolve_ident_in_module_unadjusted(
module, ident, ns, false, record_used, span,
);
let result = self.resolve_ident_in_module_unadjusted_ext(
module, ident, ns, parent_scope, false, record_used, path_span,
).map_err(|(determinacy, _)| determinacy);
self.current_module = orig_current_module;
result
}
@ -2250,6 +2354,36 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
});
}
fn future_proof_import(&mut self, use_tree: &ast::UseTree) {
if !self.session.rust_2018() {
return;
}
let segments = &use_tree.prefix.segments;
if !segments.is_empty() {
let ident = segments[0].ident;
if ident.is_path_segment_keyword() {
return;
}
let nss = match use_tree.kind {
ast::UseTreeKind::Simple(..) if segments.len() == 1 => &[TypeNS, ValueNS][..],
_ => &[TypeNS],
};
for &ns in nss {
if let Some(LexicalScopeBinding::Def(..)) =
self.resolve_ident_in_lexical_scope(ident, ns, None, use_tree.prefix.span) {
let what = if ns == TypeNS { "type parameters" } else { "local variables" };
self.session.span_err(ident.span, &format!("imports cannot refer to {}", what));
}
}
} else if let ast::UseTreeKind::Nested(use_trees) = &use_tree.kind {
for (use_tree, _) in use_trees {
self.future_proof_import(use_tree);
}
}
}
fn resolve_item(&mut self, item: &Item) {
let name = item.ident.name;
debug!("(resolving item) resolving {}", name);
@ -2343,7 +2477,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
});
}
ItemKind::Use(..) | ItemKind::ExternCrate(..) |
ItemKind::Use(ref use_tree) => {
self.future_proof_import(use_tree);
}
ItemKind::ExternCrate(..) |
ItemKind::MacroDef(..) | ItemKind::GlobalAsm(..) => {
// do nothing, these are just around to be encoded
}
@ -2466,7 +2604,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
let span = trait_ref.path.span;
if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
self.resolve_path_without_parent_scope(
None,
&path,
Some(TypeNS),
false,
@ -2607,6 +2744,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
ModuleOrUniformRoot::Module(module),
ident,
ns,
None,
false,
span,
).is_err() {
@ -2863,7 +3001,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
Def::Const(..) if is_syntactic_ambiguity => {
// Disambiguate in favor of a unit struct/variant
// or constant pattern.
self.record_use(ident, ValueNS, binding.unwrap());
self.record_use(ident, ValueNS, binding.unwrap(), false);
Some(PathResolution::new(def))
}
Def::StructCtor(..) | Def::VariantCtor(..) |
@ -2991,7 +3129,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
} else {
let mod_path = &path[..path.len() - 1];
let mod_prefix = match this.resolve_path_without_parent_scope(
None, mod_path, Some(TypeNS), false, span, CrateLint::No
mod_path, Some(TypeNS), false, span, CrateLint::No
) {
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
module.def(),
@ -3480,7 +3618,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
}
let result = match self.resolve_path_without_parent_scope(
None,
&path,
Some(ns),
true,
@ -3527,7 +3664,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
path[0].ident.name != keywords::DollarCrate.name() {
let unqualified_result = {
match self.resolve_path_without_parent_scope(
None,
&[*path.last().unwrap()],
Some(ns),
false,
@ -3551,9 +3687,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
fn resolve_path_without_parent_scope(
&mut self,
base_module: Option<ModuleOrUniformRoot<'a>>,
path: &[Segment],
opt_ns: Option<Namespace>, // `None` indicates a module path
opt_ns: Option<Namespace>, // `None` indicates a module path in import
record_used: bool,
path_span: Span,
crate_lint: CrateLint,
@ -3562,21 +3697,19 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
// other paths will do okay with parent module alone.
assert!(opt_ns != None && opt_ns != Some(MacroNS));
let parent_scope = ParentScope { module: self.current_module, ..self.dummy_parent_scope() };
self.resolve_path(base_module, path, opt_ns, &parent_scope,
record_used, path_span, crate_lint)
self.resolve_path(path, opt_ns, &parent_scope, record_used, path_span, crate_lint)
}
fn resolve_path(
&mut self,
base_module: Option<ModuleOrUniformRoot<'a>>,
path: &[Segment],
opt_ns: Option<Namespace>, // `None` indicates a module path
opt_ns: Option<Namespace>, // `None` indicates a module path in import
parent_scope: &ParentScope<'a>,
record_used: bool,
path_span: Span,
crate_lint: CrateLint,
) -> PathResult<'a> {
let mut module = base_module;
let mut module = None;
let mut allow_super = true;
let mut second_binding = None;
self.current_module = parent_scope.module;
@ -3629,7 +3762,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
continue;
}
}
let msg = "There are too many initial `super`s.".to_string();
let msg = "there are too many initial `super`s.".to_string();
return PathResult::Failed(ident.span, msg, false);
}
if i == 0 {
@ -3640,9 +3773,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
continue;
}
if name == keywords::Extern.name() ||
name == keywords::CrateRoot.name() &&
self.session.rust_2018() {
module = Some(ModuleOrUniformRoot::UniformRoot(name));
name == keywords::CrateRoot.name() && self.session.rust_2018() {
module =
Some(ModuleOrUniformRoot::UniformRoot(UniformRootKind::ExternPrelude));
continue;
}
if name == keywords::CrateRoot.name() ||
@ -3672,11 +3805,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
}
let binding = if let Some(module) = module {
self.resolve_ident_in_module(module, ident, ns, record_used, path_span)
} else if opt_ns == Some(MacroNS) {
self.resolve_ident_in_module(module, ident, ns, None, record_used, path_span)
} else if opt_ns.is_none() || opt_ns == Some(MacroNS) {
assert!(ns == TypeNS);
self.early_resolve_ident_in_lexical_scope(ident, ns, None, parent_scope,
record_used, record_used, path_span)
self.early_resolve_ident_in_lexical_scope(ident, ns, None, opt_ns.is_none(),
parent_scope, record_used, record_used,
path_span)
} else {
let record_used_id =
if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };
@ -3691,7 +3825,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
def, path.len() - 1
));
}
_ => Err(if record_used { Determined } else { Undetermined }),
_ => Err(Determinacy::determined(record_used)),
}
};
@ -3722,7 +3856,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
));
} else {
return PathResult::Failed(ident.span,
format!("Not a module `{}`", ident),
format!("not a module `{}`", ident),
is_last);
}
}
@ -3747,14 +3881,14 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
(c.path.segments.len(), c.path.to_string())
});
if let Some(candidate) = candidates.get(0) {
format!("Did you mean `{}`?", candidate.path)
format!("did you mean `{}`?", candidate.path)
} else {
format!("Maybe a missing `extern crate {};`?", ident)
format!("maybe a missing `extern crate {};`?", ident)
}
} else if i == 0 {
format!("Use of undeclared type or module `{}`", ident)
format!("use of undeclared type or module `{}`", ident)
} else {
format!("Could not find `{}` in `{}`", ident, path[i - 1].ident)
format!("could not find `{}` in `{}`", ident, path[i - 1].ident)
};
return PathResult::Failed(ident.span, msg, is_last);
}
@ -3763,9 +3897,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
self.lint_if_path_starts_with_module(crate_lint, path, path_span, second_binding);
PathResult::Module(module.unwrap_or_else(|| {
span_bug!(path_span, "resolve_path: empty(?) path {:?} has no module", path);
}))
PathResult::Module(match module {
Some(module) => module,
None if path.is_empty() =>
ModuleOrUniformRoot::UniformRoot(UniformRootKind::CurrentScope),
_ => span_bug!(path_span, "resolve_path: non-empty path `{:?}` has no module", path),
})
}
fn lint_if_path_starts_with_module(
@ -3975,6 +4112,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
ModuleOrUniformRoot::Module(module),
ident,
ns,
None,
false,
module.span,
) {
@ -4050,7 +4188,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
// Search in module.
let mod_path = &path[..path.len() - 1];
if let PathResult::Module(module) = self.resolve_path_without_parent_scope(
None, mod_path, Some(TypeNS), false, span, CrateLint::No
mod_path, Some(TypeNS), false, span, CrateLint::No
) {
if let ModuleOrUniformRoot::Module(module) = module {
add_module_candidates(module, &mut names);
@ -4297,6 +4435,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
ModuleOrUniformRoot::Module(module),
ident,
ns,
None,
false,
module.span,
).is_ok() {
@ -4352,7 +4491,6 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
ident,
ns,
false,
false,
module.span,
).is_ok() {
let import_id = match binding.kind {
@ -4634,43 +4772,88 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
}
}
fn report_ambiguity_error(&self, ident: Ident, b1: &NameBinding, b2: &NameBinding) {
let participle = |is_import: bool| if is_import { "imported" } else { "defined" };
let msg1 =
format!("`{}` could refer to the name {} here", ident, participle(b1.is_import()));
let msg2 =
format!("`{}` could also refer to the name {} here", ident, participle(b2.is_import()));
let note = if b1.expansion != Mark::root() {
Some(if let Def::Macro(..) = b1.def() {
format!("macro-expanded {} do not shadow",
if b1.is_import() { "macro imports" } else { "macros" })
fn binding_description(&self, b: &NameBinding, ident: Ident, from_prelude: bool) -> String {
if b.span.is_dummy() {
let add_built_in = match b.def() {
// These already contain the "built-in" prefix or look bad with it.
Def::NonMacroAttr(..) | Def::PrimTy(..) | Def::ToolMod => false,
_ => true,
};
let (built_in, from) = if from_prelude {
("", " from prelude")
} else if b.is_extern_crate() && !b.is_import() &&
self.session.opts.externs.get(&ident.as_str()).is_some() {
("", " passed with `--extern`")
} else if add_built_in {
(" built-in", "")
} else {
format!("macro-expanded {} do not shadow when used in a macro invocation path",
if b1.is_import() { "imports" } else { "items" })
})
} else if b1.is_glob_import() {
Some(format!("consider adding an explicit import of `{}` to disambiguate", ident))
("", "")
};
let article = if built_in.is_empty() { b.article() } else { "a" };
format!("{a}{built_in} {thing}{from}",
a = article, thing = b.descr(), built_in = built_in, from = from)
} else {
None
let introduced = if b.is_import() { "imported" } else { "defined" };
format!("the {thing} {introduced} here",
thing = b.descr(), introduced = introduced)
}
}
fn report_ambiguity_error(&self, ambiguity_error: &AmbiguityError) {
let AmbiguityError { kind, ident, b1, b2, misc1, misc2 } = *ambiguity_error;
let (b1, b2, misc1, misc2, swapped) = if b2.span.is_dummy() && !b1.span.is_dummy() {
// We have to print the span-less alternative first, otherwise formatting looks bad.
(b2, b1, misc2, misc1, true)
} else {
(b1, b2, misc1, misc2, false)
};
let mut err = struct_span_err!(self.session, ident.span, E0659, "`{}` is ambiguous", ident);
let mut err = struct_span_err!(self.session, ident.span, E0659,
"`{ident}` is ambiguous ({why})",
ident = ident, why = kind.descr());
err.span_label(ident.span, "ambiguous name");
err.span_note(b1.span, &msg1);
match b2.def() {
Def::Macro(..) if b2.span.is_dummy() =>
err.note(&format!("`{}` is also a builtin macro", ident)),
_ => err.span_note(b2.span, &msg2),
let mut could_refer_to = |b: &NameBinding, misc: AmbiguityErrorMisc, also: &str| {
let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude);
let note_msg = format!("`{ident}` could{also} refer to {what}",
ident = ident, also = also, what = what);
let mut help_msgs = Vec::new();
if b.is_glob_import() && (kind == AmbiguityKind::GlobVsGlob ||
kind == AmbiguityKind::GlobVsExpanded ||
kind == AmbiguityKind::GlobVsOuter &&
swapped != also.is_empty()) {
help_msgs.push(format!("consider adding an explicit import of \
`{ident}` to disambiguate", ident = ident))
}
if b.is_extern_crate() && self.session.rust_2018() {
help_msgs.push(format!("use `::{ident}` to refer to this {thing} unambiguously",
ident = ident, thing = b.descr()))
}
if misc == AmbiguityErrorMisc::SuggestSelf {
help_msgs.push(format!("use `self::{ident}` to refer to this {thing} unambiguously",
ident = ident, thing = b.descr()))
}
if b.span.is_dummy() {
err.note(&note_msg);
} else {
err.span_note(b.span, &note_msg);
}
for (i, help_msg) in help_msgs.iter().enumerate() {
let or = if i == 0 { "" } else { "or " };
err.help(&format!("{}{}", or, help_msg));
}
};
if let Some(note) = note {
err.note(&note);
}
could_refer_to(b1, misc1, "");
could_refer_to(b2, misc2, " also");
err.emit();
}
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 \
@ -4683,12 +4866,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
);
}
for &AmbiguityError { ident, b1, b2 } in &self.ambiguity_errors {
if reported_spans.insert(ident.span) {
self.report_ambiguity_error(ident, b1, b2);
}
for ambiguity_error in &self.ambiguity_errors {
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",
@ -4842,6 +5024,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
fn extern_prelude_get(&mut self, ident: Ident, speculative: bool, skip_feature_gate: bool)
-> Option<&'a NameBinding<'a>> {
if ident.is_path_segment_keyword() {
// Make sure `self`, `super` etc produce an error when passed to here.
return None;
}
self.extern_prelude.get(&ident.modern()).cloned().and_then(|entry| {
if let Some(binding) = entry.extern_crate_item {
if !speculative && !skip_feature_gate && entry.introduced_by_item &&
@ -4863,7 +5049,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
};
let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
self.populate_module_if_necessary(&crate_root);
Some((crate_root, ty::Visibility::Public, ident.span, Mark::root())
Some((crate_root, ty::Visibility::Public, DUMMY_SP, Mark::root())
.to_name_binding(self.arenas))
}
})

View File

@ -8,8 +8,10 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use {AmbiguityError, CrateLint, Resolver, ResolutionError, is_known_tool, resolve_error};
use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, Segment, ToNameBinding};
use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};
use {CrateLint, Resolver, ResolutionError, Segment, Weak};
use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding};
use {is_known_tool, resolve_error};
use ModuleOrUniformRoot;
use Namespace::{self, *};
use build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport};
@ -53,8 +55,8 @@ pub struct InvocationData<'a> {
crate parent_legacy_scope: Cell<LegacyScope<'a>>,
/// Legacy scope *produced* by expanding this macro invocation,
/// includes all the macro_rules items, other invocations, etc generated by it.
/// Set to the parent scope if the macro is not expanded yet (as if the macro produced nothing).
crate output_legacy_scope: Cell<LegacyScope<'a>>,
/// `None` if the macro is not expanded yet.
crate output_legacy_scope: Cell<Option<LegacyScope<'a>>>,
}
impl<'a> InvocationData<'a> {
@ -63,7 +65,7 @@ impl<'a> InvocationData<'a> {
module: Cell::new(graph_root),
def_index: CRATE_DEF_INDEX,
parent_legacy_scope: Cell::new(LegacyScope::Empty),
output_legacy_scope: Cell::new(LegacyScope::Empty),
output_legacy_scope: Cell::new(Some(LegacyScope::Empty)),
}
}
}
@ -109,7 +111,7 @@ pub struct ParentScope<'a> {
// Macro namespace is separated into two sub-namespaces, one for bang macros and
// one for attribute-like macros (attributes, derives).
// We ignore resolutions from one sub-namespace when searching names in scope for another.
fn sub_namespace_mismatch(requirement: Option<MacroKind>, candidate: Option<MacroKind>) -> bool {
fn sub_namespace_match(candidate: Option<MacroKind>, requirement: Option<MacroKind>) -> bool {
#[derive(PartialEq)]
enum SubNS { Bang, AttrLike }
let sub_ns = |kind| match kind {
@ -120,7 +122,7 @@ fn sub_namespace_mismatch(requirement: Option<MacroKind>, candidate: Option<Macr
let requirement = requirement.and_then(|kind| sub_ns(kind));
let candidate = candidate.and_then(|kind| sub_ns(kind));
// "No specific sub-namespace" means "matches anything" for both requirements and candidates.
candidate.is_some() && requirement.is_some() && candidate != requirement
candidate.is_none() || requirement.is_none() || candidate == requirement
}
impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
@ -135,7 +137,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
module: Cell::new(module),
def_index: module.def_id().unwrap().index,
parent_legacy_scope: Cell::new(LegacyScope::Empty),
output_legacy_scope: Cell::new(LegacyScope::Empty),
output_legacy_scope: Cell::new(Some(LegacyScope::Empty)),
}));
mark
}
@ -211,7 +213,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
expansion: mark,
};
fragment.visit_with(&mut visitor);
invocation.output_legacy_scope.set(visitor.current_legacy_scope);
invocation.output_legacy_scope.set(Some(visitor.current_legacy_scope));
}
fn add_builtin(&mut self, ident: ast::Ident, ext: Lrc<SyntaxExtension>) {
@ -225,7 +227,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
let binding = self.arenas.alloc_name_binding(NameBinding {
kind: NameBindingKind::Def(Def::Macro(def_id, kind), false),
span: DUMMY_SP,
vis: ty::Visibility::Invisible,
vis: ty::Visibility::Public,
expansion: Mark::root(),
});
if self.builtin_macros.insert(ident.name, binding).is_some() {
@ -325,7 +327,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
};
let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope);
let (def, ext) = self.resolve_macro_to_def(path, kind, &parent_scope, force)?;
let (def, ext) = self.resolve_macro_to_def(path, kind, &parent_scope, true, force)?;
if let Def::Macro(def_id, _) = def {
if after_derive {
@ -348,7 +350,7 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
derives_in_scope: Vec<ast::Path>, force: bool)
-> Result<Lrc<SyntaxExtension>, Determinacy> {
let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope);
Ok(self.resolve_macro_to_def(path, kind, &parent_scope, force)?.1)
Ok(self.resolve_macro_to_def(path, kind, &parent_scope, false, force)?.1)
}
fn check_unused_macros(&self) {
@ -370,11 +372,11 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
}
impl<'a, 'cl> Resolver<'a, 'cl> {
pub fn dummy_parent_scope(&mut self) -> ParentScope<'a> {
pub fn dummy_parent_scope(&self) -> ParentScope<'a> {
self.invoc_parent_scope(Mark::root(), Vec::new())
}
fn invoc_parent_scope(&mut self, invoc_id: Mark, derives: Vec<ast::Path>) -> ParentScope<'a> {
fn invoc_parent_scope(&self, invoc_id: Mark, derives: Vec<ast::Path>) -> ParentScope<'a> {
let invoc = self.invocations[&invoc_id];
ParentScope {
module: invoc.module.get().nearest_item_scope(),
@ -389,9 +391,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
path: &ast::Path,
kind: MacroKind,
parent_scope: &ParentScope<'a>,
trace: bool,
force: bool,
) -> Result<(Def, Lrc<SyntaxExtension>), Determinacy> {
let def = self.resolve_macro_to_def_inner(path, kind, parent_scope, force);
let def = self.resolve_macro_to_def_inner(path, kind, parent_scope, trace, force);
// Report errors and enforce feature gates for the resolved macro.
if def != Err(Determinacy::Undetermined) {
@ -463,6 +466,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
path: &ast::Path,
kind: MacroKind,
parent_scope: &ParentScope<'a>,
trace: bool,
force: bool,
) -> Result<Def, Determinacy> {
let path_span = path.span;
@ -477,36 +481,28 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
}
if path.len() > 1 {
let def = match self.resolve_path(None, &path, Some(MacroNS), parent_scope,
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));
if trace {
parent_scope.module.multi_segment_macro_resolutions.borrow_mut()
.push((path, path_span, kind, parent_scope.clone(), def.ok()));
}
def
} else {
let binding = self.early_resolve_ident_in_lexical_scope(
path[0].ident, MacroNS, Some(kind), parent_scope, false, force, path_span
path[0].ident, MacroNS, Some(kind), false, parent_scope, false, force, path_span
);
match binding {
Ok(..) => {}
@ -514,8 +510,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
Err(Determinacy::Undetermined) => return Err(Determinacy::Undetermined),
}
parent_scope.module.legacy_macro_resolutions.borrow_mut()
.push((path[0].ident, kind, parent_scope.clone(), binding.ok()));
if trace {
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())
}
@ -525,12 +523,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// This is a variation of `fn resolve_ident_in_lexical_scope` that can be run during
// expansion and import resolution (perhaps they can be merged in the future).
// The function is used for resolving initial segments of macro paths (e.g. `foo` in
// `foo::bar!(); or `foo!();`) and can be used for "uniform path" imports in the future.
// `foo::bar!(); or `foo!();`) and also for import paths on 2018 edition.
crate fn early_resolve_ident_in_lexical_scope(
&mut self,
mut ident: Ident,
ns: Namespace,
kind: Option<MacroKind>,
macro_kind: Option<MacroKind>,
is_import: bool,
parent_scope: &ParentScope<'a>,
record_used: bool,
force: bool,
@ -596,16 +595,23 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
bitflags! {
struct Flags: u8 {
const DERIVE_HELPERS = 1 << 0;
const MACRO_RULES = 1 << 1;
const MODULE = 1 << 2;
const PRELUDE = 1 << 3;
const MACRO_RULES = 1 << 0;
const MODULE = 1 << 1;
const PRELUDE = 1 << 2;
const MISC_SUGGEST_SELF = 1 << 3;
const MISC_FROM_PRELUDE = 1 << 4;
}
}
assert!(force || !record_used); // `record_used` implies `force`
assert!(macro_kind.is_none() || !is_import); // `is_import` implies no macro kind
ident = ident.modern();
// Make sure `self`, `super` etc produce an error when passed to here.
if ident.is_path_segment_keyword() {
return Err(Determinacy::Determined);
}
// This is *the* result, resolution from the scope closest to the resolved identifier.
// However, sometimes this result is "weak" because it comes from a glob import or
// a macro expansion, and in this case it cannot shadow names from outer scopes, e.g.
@ -617,72 +623,103 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
// }
// So we have to save the innermost solution and continue searching in outer scopes
// to detect potential ambiguities.
let mut innermost_result: Option<(&NameBinding, Flags, /* conflicts with */ Flags)> = None;
let mut innermost_result: Option<(&NameBinding, Flags)> = None;
// Go through all the scopes and try to resolve the name.
let mut where_to_resolve = WhereToResolve::DeriveHelpers;
let mut where_to_resolve = if ns == MacroNS {
WhereToResolve::DeriveHelpers
} else {
WhereToResolve::Module(parent_scope.module)
};
let mut use_prelude = !parent_scope.module.no_implicit_prelude;
let mut determinacy = Determinacy::Determined;
loop {
let result = match where_to_resolve {
WhereToResolve::DeriveHelpers => {
let mut result = Err(Determinacy::Determined);
for derive in &parent_scope.derives {
let parent_scope = ParentScope { derives: Vec::new(), ..*parent_scope };
if let Ok((_, ext)) = self.resolve_macro_to_def(derive, MacroKind::Derive,
&parent_scope, force) {
if let SyntaxExtension::ProcMacroDerive(_, helper_attrs, _) = &*ext {
if helper_attrs.contains(&ident.name) {
let binding =
(Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
ty::Visibility::Public, derive.span, Mark::root())
.to_name_binding(self.arenas);
result = Ok((binding, Flags::DERIVE_HELPERS, Flags::all()));
break;
match self.resolve_macro_to_def(derive, MacroKind::Derive,
&parent_scope, true, force) {
Ok((_, ext)) => {
if let SyntaxExtension::ProcMacroDerive(_, helpers, _) = &*ext {
if helpers.contains(&ident.name) {
let binding =
(Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
ty::Visibility::Public, derive.span, Mark::root())
.to_name_binding(self.arenas);
result = Ok((binding, Flags::empty()));
break;
}
}
}
Err(Determinacy::Determined) => {}
Err(Determinacy::Undetermined) =>
result = Err(Determinacy::Undetermined),
}
}
result
}
WhereToResolve::MacroRules(legacy_scope) => match legacy_scope {
LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident =>
Ok((legacy_binding.binding, Flags::MACRO_RULES, Flags::empty())),
Ok((legacy_binding.binding, Flags::MACRO_RULES)),
LegacyScope::Invocation(invoc) if invoc.output_legacy_scope.get().is_none() =>
Err(Determinacy::Undetermined),
_ => Err(Determinacy::Determined),
}
WhereToResolve::Module(module) => {
let orig_current_module = mem::replace(&mut self.current_module, module);
let binding = self.resolve_ident_in_module_unadjusted(
let binding = self.resolve_ident_in_module_unadjusted_ext(
ModuleOrUniformRoot::Module(module),
ident,
ns,
None,
true,
record_used,
path_span,
);
self.current_module = orig_current_module;
binding.map(|binding| (binding, Flags::MODULE, Flags::empty()))
match binding {
Ok(binding) => {
let misc_flags = if module.is_normal() {
Flags::MISC_SUGGEST_SELF
} else {
Flags::empty()
};
Ok((binding, Flags::MODULE | misc_flags))
}
Err((Determinacy::Undetermined, Weak::No)) =>
return Err(Determinacy::determined(force)),
Err((Determinacy::Undetermined, Weak::Yes)) =>
Err(Determinacy::Undetermined),
Err((Determinacy::Determined, _)) => Err(Determinacy::Determined),
}
}
WhereToResolve::MacroUsePrelude => {
let mut result = Err(Determinacy::Determined);
if use_prelude || self.session.rust_2015() {
if let Some(binding) = self.macro_use_prelude.get(&ident.name).cloned() {
result = Ok((binding, Flags::PRELUDE, Flags::empty()));
match self.macro_use_prelude.get(&ident.name).cloned() {
Some(binding) =>
Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE)),
None => Err(Determinacy::determined(
self.graph_root.unresolved_invocations.borrow().is_empty()
))
}
} else {
Err(Determinacy::Determined)
}
result
}
WhereToResolve::BuiltinMacros => {
match self.builtin_macros.get(&ident.name).cloned() {
Some(binding) => Ok((binding, Flags::PRELUDE, Flags::empty())),
Some(binding) => Ok((binding, Flags::PRELUDE)),
None => Err(Determinacy::Determined),
}
}
WhereToResolve::BuiltinAttrs => {
if is_builtin_attr_name(ident.name) {
let binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin),
ty::Visibility::Public, ident.span, Mark::root())
ty::Visibility::Public, DUMMY_SP, Mark::root())
.to_name_binding(self.arenas);
Ok((binding, Flags::PRELUDE, Flags::empty()))
Ok((binding, Flags::PRELUDE))
} else {
Err(Determinacy::Determined)
}
@ -692,28 +729,31 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
self.session.plugin_attributes.borrow().iter()
.any(|(name, _)| ident.name == &**name) {
let binding = (Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper),
ty::Visibility::Public, ident.span, Mark::root())
ty::Visibility::Public, DUMMY_SP, Mark::root())
.to_name_binding(self.arenas);
Ok((binding, Flags::PRELUDE, Flags::PRELUDE))
Ok((binding, Flags::PRELUDE))
} else {
Err(Determinacy::Determined)
}
}
WhereToResolve::ExternPrelude => {
let mut result = Err(Determinacy::Determined);
if use_prelude {
if let Some(binding) = self.extern_prelude_get(ident, !record_used,
innermost_result.is_some()) {
result = Ok((binding, Flags::PRELUDE, Flags::empty()));
match self.extern_prelude_get(ident, !record_used,
innermost_result.is_some()) {
Some(binding) => Ok((binding, Flags::PRELUDE)),
None => Err(Determinacy::determined(
self.graph_root.unresolved_invocations.borrow().is_empty()
)),
}
} else {
Err(Determinacy::Determined)
}
result
}
WhereToResolve::ToolPrelude => {
if use_prelude && is_known_tool(ident.name) {
let binding = (Def::ToolMod, ty::Visibility::Public,
ident.span, Mark::root()).to_name_binding(self.arenas);
Ok((binding, Flags::PRELUDE, Flags::empty()))
DUMMY_SP, Mark::root()).to_name_binding(self.arenas);
Ok((binding, Flags::PRELUDE))
} else {
Err(Determinacy::Determined)
}
@ -727,10 +767,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
ident,
ns,
false,
false,
path_span,
) {
result = Ok((binding, Flags::PRELUDE, Flags::empty()));
result = Ok((binding, Flags::PRELUDE | Flags::MISC_FROM_PRELUDE));
}
}
}
@ -740,105 +779,157 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
match self.primitive_type_table.primitive_types.get(&ident.name).cloned() {
Some(prim_ty) => {
let binding = (Def::PrimTy(prim_ty), ty::Visibility::Public,
ident.span, Mark::root()).to_name_binding(self.arenas);
Ok((binding, Flags::PRELUDE, Flags::empty()))
DUMMY_SP, Mark::root()).to_name_binding(self.arenas);
Ok((binding, Flags::PRELUDE))
}
None => Err(Determinacy::Determined)
}
}
};
macro_rules! continue_search { () => {
where_to_resolve = match where_to_resolve {
WhereToResolve::DeriveHelpers =>
WhereToResolve::MacroRules(parent_scope.legacy),
WhereToResolve::MacroRules(legacy_scope) => match legacy_scope {
LegacyScope::Binding(binding) =>
WhereToResolve::MacroRules(binding.parent_legacy_scope),
LegacyScope::Invocation(invocation) =>
WhereToResolve::MacroRules(invocation.output_legacy_scope.get()),
LegacyScope::Empty => WhereToResolve::Module(parent_scope.module),
LegacyScope::Uninitialized => unreachable!(),
}
WhereToResolve::Module(module) => {
match self.hygienic_lexical_parent(module, &mut ident.span) {
Some(parent_module) => WhereToResolve::Module(parent_module),
None => {
use_prelude = !module.no_implicit_prelude;
match ns {
TypeNS => WhereToResolve::ExternPrelude,
ValueNS => WhereToResolve::StdLibPrelude,
MacroNS => WhereToResolve::MacroUsePrelude,
}
}
}
}
WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros,
WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs,
WhereToResolve::BuiltinAttrs => WhereToResolve::LegacyPluginHelpers,
WhereToResolve::LegacyPluginHelpers => break, // nowhere else to search
WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude,
WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude,
WhereToResolve::StdLibPrelude => match ns {
TypeNS => WhereToResolve::BuiltinTypes,
ValueNS => break, // nowhere else to search
MacroNS => unreachable!(),
}
WhereToResolve::BuiltinTypes => break, // nowhere else to search
};
continue;
}}
match result {
Ok((binding, flags, ambig_flags)) => {
if sub_namespace_mismatch(kind, binding.macro_kind()) {
continue_search!();
}
Ok((binding, flags)) if sub_namespace_match(binding.macro_kind(), macro_kind) => {
if !record_used {
return Ok(binding);
}
if let Some((innermost_binding, innermost_flags, innermost_ambig_flags))
= innermost_result {
if let Some((innermost_binding, innermost_flags)) = innermost_result {
// Found another solution, if the first one was "weak", report an error.
if binding.def() != innermost_binding.def() &&
(innermost_binding.is_glob_import() ||
innermost_binding.may_appear_after(parent_scope.expansion, binding) ||
innermost_flags.intersects(ambig_flags) ||
flags.intersects(innermost_ambig_flags) ||
(innermost_flags.contains(Flags::MACRO_RULES) &&
flags.contains(Flags::MODULE) &&
!self.disambiguate_legacy_vs_modern(innermost_binding, binding))) {
self.ambiguity_errors.push(AmbiguityError {
ident,
b1: innermost_binding,
b2: binding,
});
return Ok(innermost_binding);
let (def, innermost_def) = (binding.def(), innermost_binding.def());
if def != innermost_def {
let builtin = Def::NonMacroAttr(NonMacroAttrKind::Builtin);
let derive_helper = Def::NonMacroAttr(NonMacroAttrKind::DeriveHelper);
let legacy_helper =
Def::NonMacroAttr(NonMacroAttrKind::LegacyPluginHelper);
let ambiguity_error_kind = if is_import {
Some(AmbiguityKind::Import)
} else if innermost_def == builtin || def == builtin {
Some(AmbiguityKind::BuiltinAttr)
} else if innermost_def == derive_helper || def == derive_helper {
Some(AmbiguityKind::DeriveHelper)
} else if innermost_def == legacy_helper &&
flags.contains(Flags::PRELUDE) ||
def == legacy_helper &&
innermost_flags.contains(Flags::PRELUDE) {
Some(AmbiguityKind::LegacyHelperVsPrelude)
} else if innermost_flags.contains(Flags::MACRO_RULES) &&
flags.contains(Flags::MODULE) &&
!self.disambiguate_legacy_vs_modern(innermost_binding,
binding) {
Some(AmbiguityKind::LegacyVsModern)
} else if innermost_binding.is_glob_import() {
Some(AmbiguityKind::GlobVsOuter)
} else if innermost_binding.may_appear_after(parent_scope.expansion,
binding) {
Some(AmbiguityKind::MoreExpandedVsOuter)
} else {
None
};
if let Some(kind) = ambiguity_error_kind {
let misc = |f: Flags| if f.contains(Flags::MISC_SUGGEST_SELF) {
AmbiguityErrorMisc::SuggestSelf
} else if f.contains(Flags::MISC_FROM_PRELUDE) {
AmbiguityErrorMisc::FromPrelude
} else {
AmbiguityErrorMisc::None
};
self.ambiguity_errors.push(AmbiguityError {
kind,
ident,
b1: innermost_binding,
b2: binding,
misc1: misc(innermost_flags),
misc2: misc(flags),
});
return Ok(innermost_binding);
}
}
} else {
// Found the first solution.
innermost_result = Some((binding, flags, ambig_flags));
innermost_result = Some((binding, flags));
}
continue_search!();
},
Err(Determinacy::Determined) => {
continue_search!();
}
Err(Determinacy::Undetermined) => return Err(Determinacy::determined(force)),
Ok(..) | Err(Determinacy::Determined) => {}
Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined
}
where_to_resolve = match where_to_resolve {
WhereToResolve::DeriveHelpers =>
WhereToResolve::MacroRules(parent_scope.legacy),
WhereToResolve::MacroRules(legacy_scope) => match legacy_scope {
LegacyScope::Binding(binding) => WhereToResolve::MacroRules(
binding.parent_legacy_scope
),
LegacyScope::Invocation(invoc) => WhereToResolve::MacroRules(
invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope.get())
),
LegacyScope::Empty => WhereToResolve::Module(parent_scope.module),
LegacyScope::Uninitialized => unreachable!(),
}
WhereToResolve::Module(module) => {
match self.hygienic_lexical_parent(module, &mut ident.span) {
Some(parent_module) => WhereToResolve::Module(parent_module),
None => {
use_prelude = !module.no_implicit_prelude;
match ns {
TypeNS => WhereToResolve::ExternPrelude,
ValueNS => WhereToResolve::StdLibPrelude,
MacroNS => WhereToResolve::MacroUsePrelude,
}
}
}
}
WhereToResolve::MacroUsePrelude => WhereToResolve::BuiltinMacros,
WhereToResolve::BuiltinMacros => WhereToResolve::BuiltinAttrs,
WhereToResolve::BuiltinAttrs => WhereToResolve::LegacyPluginHelpers,
WhereToResolve::LegacyPluginHelpers => break, // nowhere else to search
WhereToResolve::ExternPrelude => WhereToResolve::ToolPrelude,
WhereToResolve::ToolPrelude => WhereToResolve::StdLibPrelude,
WhereToResolve::StdLibPrelude => match ns {
TypeNS => WhereToResolve::BuiltinTypes,
ValueNS => break, // nowhere else to search
MacroNS => unreachable!(),
}
WhereToResolve::BuiltinTypes => break, // nowhere else to search
};
continue;
}
// The first found solution was the only one, return it.
if let Some((binding, ..)) = innermost_result {
if let Some((binding, flags)) = innermost_result {
if is_import && !self.session.features_untracked().uniform_paths {
// We get to here only if there's no ambiguity, in ambiguous cases an error will
// be reported anyway, so there's no reason to report an additional feature error.
// The `binding` can actually be introduced by something other than `--extern`,
// but its `Def` should coincide with a crate passed with `--extern`
// (otherwise there would be ambiguity) and we can skip feature error in this case.
if ns != TypeNS || !use_prelude ||
self.extern_prelude_get(ident, true, false).is_none() {
let msg = "imports can only refer to extern crate names \
passed with `--extern` on stable channel";
let mut err = feature_err(&self.session.parse_sess, "uniform_paths",
ident.span, GateIssue::Language, msg);
let what = self.binding_description(binding, ident,
flags.contains(Flags::MISC_FROM_PRELUDE));
let note_msg = format!("this import refers to {what}", what = what);
if binding.span.is_dummy() {
err.note(&note_msg);
} else {
err.span_note(binding.span, &note_msg);
err.span_label(binding.span, "not an extern crate passed with `--extern`");
}
err.emit();
}
}
return Ok(binding);
}
let determinacy = Determinacy::determined(force);
if determinacy == Determinacy::Determined && kind == Some(MacroKind::Attr) {
let determinacy = Determinacy::determined(determinacy == Determinacy::Determined || force);
if determinacy == Determinacy::Determined && macro_kind == Some(MacroKind::Attr) {
// For single-segment attributes interpret determinate "no resolution" as a custom
// attribute. (Lexical resolution implies the first segment and attr kind should imply
// the last segment, so we are certainly working with a single-segment attribute here.)
@ -855,50 +946,69 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
pub fn finalize_current_module_macro_resolutions(&mut self) {
let module = self.current_module;
let check_consistency = |this: &mut Self, path: &[Segment], 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(), Segment::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(None, &path, Some(MacroNS), &parent_scope,
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), &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 initial_def = initial_binding.map(|initial_binding| {
self.record_use(ident, MacroNS, initial_binding, false);
initial_binding.def_ignoring_ambiguity()
});
let def = binding.def_ignoring_ambiguity();
if let Some(initial_binding) = 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();
}
let seg = Segment::from_ident(ident);
check_consistency(self, &[seg], ident.span, kind, initial_def, def);
}
Err(..) => {
assert!(initial_binding.is_none());
@ -914,18 +1024,9 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
let builtin_attrs = mem::replace(&mut *module.builtin_attrs.borrow_mut(), Vec::new());
for (ident, parent_scope) in builtin_attrs {
let binding = self.early_resolve_ident_in_lexical_scope(
ident, MacroNS, Some(MacroKind::Attr), &parent_scope, true, true, ident.span
let _ = self.early_resolve_ident_in_lexical_scope(
ident, MacroNS, Some(MacroKind::Attr), false, &parent_scope, true, true, ident.span
);
if let Ok(binding) = binding {
if binding.def_ignoring_ambiguity() !=
Def::NonMacroAttr(NonMacroAttrKind::Builtin) {
let builtin_binding = (Def::NonMacroAttr(NonMacroAttrKind::Builtin),
ty::Visibility::Public, ident.span, Mark::root())
.to_name_binding(self.arenas);
self.report_ambiguity_error(ident, binding, builtin_binding);
}
}
}
}
@ -992,7 +1093,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
def_index: invoc.def_index,
module: Cell::new(graph_root),
parent_legacy_scope: Cell::new(LegacyScope::Uninitialized),
output_legacy_scope: Cell::new(LegacyScope::Uninitialized),
output_legacy_scope: Cell::new(None),
})
});
};

View File

@ -10,7 +10,8 @@
use self::ImportDirectiveSubclass::*;
use {AmbiguityError, CrateLint, Module, ModuleOrUniformRoot, PerNS};
use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};
use {CrateLint, Module, ModuleOrUniformRoot, PerNS, UniformRootKind, Weak};
use Namespace::{self, TypeNS, MacroNS};
use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
use {Resolver, Segment};
@ -22,7 +23,7 @@ use rustc_data_structures::ptr_key::PtrKey;
use rustc::ty;
use rustc::lint::builtin::BuiltinLintDiagnostics;
use rustc::lint::builtin::{DUPLICATE_MACRO_EXPORTS, PUB_USE_OF_PRIVATE_EXTERN_CRATE};
use rustc::hir::def_id::DefId;
use rustc::hir::def_id::{CrateNum, DefId};
use rustc::hir::def::*;
use rustc::session::DiagnosticMessageId;
use rustc::util::nodemap::FxHashSet;
@ -35,7 +36,6 @@ use syntax::util::lev_distance::find_best_match_for_name;
use syntax_pos::{MultiSpan, Span};
use std::cell::{Cell, RefCell};
use std::collections::BTreeMap;
use std::{mem, ptr};
/// Contains data for specific types of import directives.
@ -61,7 +61,7 @@ pub enum ImportDirectiveSubclass<'a> {
/// One import directive.
#[derive(Debug,Clone)]
pub struct ImportDirective<'a> {
crate struct ImportDirective<'a> {
/// The id of the `extern crate`, `UseTree` etc that imported this `ImportDirective`.
///
/// In the case where the `ImportDirective` was expanded from a "nested" use tree,
@ -95,13 +95,6 @@ pub struct ImportDirective<'a> {
pub subclass: ImportDirectiveSubclass<'a>,
pub vis: Cell<ty::Visibility>,
pub used: Cell<bool>,
/// Whether this import is a "canary" for the `uniform_paths` feature,
/// i.e. `use x::...;` results in an `use self::x as _;` canary.
/// This flag affects diagnostics: an error is reported if and only if
/// the import resolves successfully and an external crate with the same
/// name (`x` above) also exists; any resolution failures are ignored.
pub is_uniform_paths_canary: bool,
}
impl<'a> ImportDirective<'a> {
@ -142,102 +135,73 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
.or_insert_with(|| self.arenas.alloc_name_resolution())
}
crate fn resolve_ident_in_module_unadjusted(
&mut self,
module: ModuleOrUniformRoot<'a>,
ident: Ident,
ns: Namespace,
record_used: bool,
path_span: Span,
) -> Result<&'a NameBinding<'a>, Determinacy> {
self.resolve_ident_in_module_unadjusted_ext(
module, ident, ns, None, false, record_used, path_span
).map_err(|(determinacy, _)| determinacy)
}
/// Attempts to resolve `ident` in namespaces `ns` of `module`.
/// Invariant: if `record_used` is `Some`, expansion and import resolution must be complete.
pub fn resolve_ident_in_module_unadjusted(&mut self,
module: ModuleOrUniformRoot<'a>,
ident: Ident,
ns: Namespace,
restricted_shadowing: bool,
record_used: bool,
path_span: Span)
-> Result<&'a NameBinding<'a>, Determinacy> {
crate fn resolve_ident_in_module_unadjusted_ext(
&mut self,
module: ModuleOrUniformRoot<'a>,
ident: Ident,
ns: Namespace,
parent_scope: Option<&ParentScope<'a>>,
restricted_shadowing: bool,
record_used: bool,
path_span: Span,
) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> {
let module = match module {
ModuleOrUniformRoot::Module(module) => module,
ModuleOrUniformRoot::UniformRoot(root) => {
// HACK(eddyb): `resolve_path` uses `keywords::Invalid` to indicate
// paths of length 0, and currently these are relative `use` paths.
let can_be_relative = !ident.is_path_segment_keyword() &&
root == keywords::Invalid.name();
if can_be_relative {
// Relative paths should only get here if the feature-gate is on.
assert!(self.session.rust_2018() &&
self.session.features_untracked().uniform_paths);
// Try first to resolve relatively.
let mut ctxt = ident.span.ctxt().modern();
let self_module = self.resolve_self(&mut ctxt, self.current_module);
let binding = self.resolve_ident_in_module_unadjusted(
ModuleOrUniformRoot::Module(self_module),
ident,
ns,
restricted_shadowing,
record_used,
path_span,
);
// FIXME(eddyb) This may give false negatives, specifically
// if a crate with the same name is found in `extern_prelude`,
// preventing the check below this one from returning `binding`
// in all cases.
//
// That is, if there's no crate with the same name, `binding`
// is always returned, which is the result of doing the exact
// same lookup of `ident`, in the `self` module.
// But when a crate does exist, it will get chosen even when
// macro expansion could result in a success from the lookup
// in the `self` module, later on.
//
// NB. This is currently alleviated by the "ambiguity canaries"
// (see `is_uniform_paths_canary`) that get introduced for the
// maybe-relative imports handled here: if the false negative
// case were to arise, it would *also* cause an ambiguity error.
if binding.is_ok() {
return binding;
ModuleOrUniformRoot::UniformRoot(uniform_root_kind) => {
assert!(!restricted_shadowing);
match uniform_root_kind {
UniformRootKind::ExternPrelude => {
return if let Some(binding) =
self.extern_prelude_get(ident, !record_used, false) {
Ok(binding)
} else if !self.graph_root.unresolved_invocations.borrow().is_empty() {
// Macro-expanded `extern crate` items can add names to extern prelude.
Err((Undetermined, Weak::No))
} else {
Err((Determined, Weak::No))
}
}
UniformRootKind::CurrentScope => {
let parent_scope =
parent_scope.expect("no parent scope for a single-segment import");
// Fall back to resolving to an external crate.
if !(
ns == TypeNS &&
!ident.is_path_segment_keyword() &&
self.extern_prelude.contains_key(&ident.modern())
) {
// ... unless the crate name is not in the `extern_prelude`.
return binding;
if ns == TypeNS {
if ident.name == keywords::Crate.name() ||
ident.name == keywords::DollarCrate.name() {
let module = self.resolve_crate_root(ident);
let binding = (module, ty::Visibility::Public,
module.span, Mark::root())
.to_name_binding(self.arenas);
return Ok(binding);
} else if ident.name == keywords::Super.name() ||
ident.name == keywords::SelfValue.name() {
// FIXME: Implement these with renaming requirements so that e.g.
// `use super;` doesn't work, but `use super as name;` does.
// Fall through here to get an error from `early_resolve_...`.
}
}
let binding = self.early_resolve_ident_in_lexical_scope(
ident, ns, None, true, parent_scope, record_used, record_used, path_span
);
return binding.map_err(|determinacy| (determinacy, Weak::No));
}
}
let crate_root = if
ns == TypeNS &&
root != keywords::Extern.name() &&
(
ident.name == keywords::Crate.name() ||
ident.name == keywords::DollarCrate.name()
)
{
self.resolve_crate_root(ident)
} else if
ns == TypeNS &&
!ident.is_path_segment_keyword()
{
if let Some(binding) = self.extern_prelude_get(ident, !record_used, false) {
let module = self.get_module(binding.def().def_id());
self.populate_module_if_necessary(module);
return Ok(binding);
} else if !self.graph_root.unresolved_invocations.borrow().is_empty() {
// Macro-expanded `extern crate`items still can add names to extern prelude.
return Err(Undetermined);
} else {
return Err(Determined);
}
} else {
return Err(Determined);
};
self.populate_module_if_necessary(crate_root);
let binding = (crate_root, ty::Visibility::Public,
ident.span, Mark::root()).to_name_binding(self.arenas);
return Ok(binding);
}
};
@ -245,7 +209,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
let resolution = self.resolution(module, ident, ns)
.try_borrow_mut()
.map_err(|_| Determined)?; // This happens when there is a cycle of imports
.map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports.
if let Some(binding) = resolution.binding {
if !restricted_shadowing && binding.expansion != Mark::root() {
@ -255,38 +219,47 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
}
}
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() &&
ns != MacroNS && // In MacroNS, `try_define` always forbids this shadowing
binding.def() != shadowed_glob.def() {
self.ambiguity_errors.push(AmbiguityError {
ident,
b1: binding,
b2: shadowed_glob,
});
}
}
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(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(Determined) }
if usable { Ok(binding) } else { Err((Determined, Weak::No)) }
};
if record_used {
return resolution.binding.ok_or((Determined, Weak::No)).and_then(|binding| {
if self.last_import_segment && check_usable(self, binding).is_err() {
Err((Determined, Weak::No))
} else {
self.record_use(ident, ns, binding, restricted_shadowing);
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() {
@ -302,17 +275,19 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
if !self.is_accessible(single_import.vis.get()) {
continue;
}
let module = unwrap_or!(single_import.imported_module.get(), return Err(Undetermined));
let module = unwrap_or!(single_import.imported_module.get(),
return Err((Undetermined, Weak::No)));
let ident = match single_import.subclass {
SingleImport { source, .. } => source,
_ => unreachable!(),
};
match self.resolve_ident_in_module(module, ident, ns, false, path_span) {
match self.resolve_ident_in_module(module, ident, ns, Some(&single_import.parent_scope),
false, path_span) {
Err(Determined) => continue,
Ok(binding) if !self.is_accessible_from(
binding.vis, single_import.parent_scope.module
) => continue,
Ok(_) | Err(Undetermined) => return Err(Undetermined),
Ok(_) | Err(Undetermined) => return Err((Undetermined, Weak::No)),
}
}
@ -333,7 +308,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
if !unexpanded_macros || ns == MacroNS || restricted_shadowing {
return check_usable(self, binding);
} else {
return Err(Undetermined);
return Err((Undetermined, Weak::No));
}
}
@ -342,17 +317,13 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
// Now we are in situation when new item/import can appear only from a glob or a macro
// expansion. With restricted shadowing names from globs and macro expansions cannot
// shadow names from outer scopes, so we can freely fallback from module search to search
// in outer scopes. To continue search in outer scopes we have to lie a bit and return
// `Determined` to `early_resolve_ident_in_lexical_scope` even if the correct answer
// for in-module resolution could be `Undetermined`.
if restricted_shadowing {
return Err(Determined);
}
// in outer scopes. For `early_resolve_ident_in_lexical_scope` to continue search in outer
// scopes we return `Undetermined` with `Weak::Yes`.
// Check if one of unexpanded macros can still define the name,
// if it can then our "no resolution" result is not determined and can be invalidated.
if unexpanded_macros {
return Err(Undetermined);
return Err((Undetermined, Weak::Yes));
}
// Check if one of glob imports can still define the name,
@ -364,7 +335,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
let module = match glob_import.imported_module.get() {
Some(ModuleOrUniformRoot::Module(module)) => module,
Some(ModuleOrUniformRoot::UniformRoot(_)) => continue,
None => return Err(Undetermined),
None => return Err((Undetermined, Weak::Yes)),
};
let (orig_current_module, mut ident) = (self.current_module, ident.modern());
match ident.span.glob_adjust(module.expansion, glob_import.span.ctxt().modern()) {
@ -377,7 +348,6 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
ident,
ns,
false,
false,
path_span,
);
self.current_module = orig_current_module;
@ -387,12 +357,12 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
Ok(binding) if !self.is_accessible_from(
binding.vis, glob_import.parent_scope.module
) => continue,
Ok(_) | Err(Undetermined) => return Err(Undetermined),
Ok(_) | Err(Undetermined) => return Err((Undetermined, Weak::Yes)),
}
}
// No resolution and no one else can define the name - determinate error.
Err(Determined)
Err((Determined, Weak::No))
}
// Add an import directive to the current module.
@ -404,8 +374,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
root_span: Span,
root_id: NodeId,
vis: ty::Visibility,
parent_scope: ParentScope<'a>,
is_uniform_paths_canary: bool) {
parent_scope: ParentScope<'a>) {
let current_module = parent_scope.module;
let directive = self.arenas.alloc_import_directive(ImportDirective {
parent_scope,
@ -418,7 +387,6 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
root_id,
vis: Cell::new(vis),
used: Cell::new(false),
is_uniform_paths_canary,
});
debug!("add_import_directive({:?})", directive);
@ -441,8 +409,8 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
// Given a binding and an import directive that resolves to it,
// return the corresponding binding defined by the import directive.
pub fn import(&self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
-> &'a NameBinding<'a> {
crate fn import(&self, binding: &'a NameBinding<'a>, directive: &'a ImportDirective<'a>)
-> &'a NameBinding<'a> {
let vis = if binding.pseudo_vis().is_at_least(directive.vis.get(), self) ||
// c.f. `PUB_USE_OF_PRIVATE_EXTERN_CRATE`
!directive.is_glob() && binding.is_extern_crate() {
@ -490,38 +458,48 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
self.set_binding_parent_module(binding, module);
self.update_resolution(module, ident, ns, |this, resolution| {
if let Some(old_binding) = resolution.binding {
if binding.is_glob_import() {
if !old_binding.is_glob_import() &&
!(ns == MacroNS && old_binding.expansion != Mark::root()) {
resolution.shadowed_glob = Some(binding);
} else if binding.def() != old_binding.def() {
resolution.binding = Some(this.ambiguity(old_binding, binding));
} else if !old_binding.vis.is_at_least(binding.vis, &*this) {
// We are glob-importing the same item but with greater visibility.
resolution.binding = Some(binding);
match (old_binding.is_glob_import(), binding.is_glob_import()) {
(true, true) => {
if binding.def() != old_binding.def() {
resolution.binding = Some(this.ambiguity(AmbiguityKind::GlobVsGlob,
old_binding, binding));
} else if !old_binding.vis.is_at_least(binding.vis, &*this) {
// We are glob-importing the same item but with greater visibility.
resolution.binding = Some(binding);
}
}
} else if old_binding.is_glob_import() {
if ns == MacroNS && binding.expansion != Mark::root() &&
binding.def() != old_binding.def() {
resolution.binding = Some(this.ambiguity(binding, old_binding));
} else {
resolution.binding = Some(binding);
resolution.shadowed_glob = Some(old_binding);
(old_glob @ true, false) | (old_glob @ false, true) => {
let (glob_binding, nonglob_binding) = if old_glob {
(old_binding, binding)
} else {
(binding, old_binding)
};
if glob_binding.def() != nonglob_binding.def() &&
ns == MacroNS && nonglob_binding.expansion != Mark::root() {
resolution.binding = Some(this.ambiguity(AmbiguityKind::GlobVsExpanded,
nonglob_binding, glob_binding));
} else {
resolution.binding = Some(nonglob_binding);
resolution.shadowed_glob = Some(glob_binding);
}
}
} else if let (&NameBindingKind::Def(_, true), &NameBindingKind::Def(_, true)) =
(&old_binding.kind, &binding.kind) {
(false, false) => {
if let (&NameBindingKind::Def(_, true), &NameBindingKind::Def(_, true)) =
(&old_binding.kind, &binding.kind) {
this.session.buffer_lint_with_diagnostic(
DUPLICATE_MACRO_EXPORTS,
CRATE_NODE_ID,
binding.span,
&format!("a macro named `{}` has already been exported", ident),
BuiltinLintDiagnostics::DuplicatedMacroExports(
ident, old_binding.span, binding.span));
this.session.buffer_lint_with_diagnostic(
DUPLICATE_MACRO_EXPORTS,
CRATE_NODE_ID,
binding.span,
&format!("a macro named `{}` has already been exported", ident),
BuiltinLintDiagnostics::DuplicatedMacroExports(
ident, old_binding.span, binding.span));
resolution.binding = Some(binding);
} else {
return Err(old_binding);
resolution.binding = Some(binding);
} else {
return Err(old_binding);
}
}
}
} else {
resolution.binding = Some(binding);
@ -531,10 +509,10 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
})
}
pub fn ambiguity(&self, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>)
fn ambiguity(&self, kind: AmbiguityKind, b1: &'a NameBinding<'a>, b2: &'a NameBinding<'a>)
-> &'a NameBinding<'a> {
self.arenas.alloc_name_binding(NameBinding {
kind: NameBindingKind::Ambiguity { b1, b2 },
kind: NameBindingKind::Ambiguity { kind, b1, b2 },
vis: if b1.vis.is_at_least(b2.vis, self) { b1.vis } else { b2.vis },
span: b1.span,
expansion: Mark::root(),
@ -648,65 +626,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
self.finalize_resolutions_in(module);
}
struct UniformPathsCanaryResults<'a> {
name: Name,
module_scope: Option<&'a NameBinding<'a>>,
block_scopes: Vec<&'a NameBinding<'a>>,
}
// Collect all tripped `uniform_paths` canaries separately.
let mut uniform_paths_canaries: BTreeMap<
(Span, NodeId, Namespace),
UniformPathsCanaryResults,
> = BTreeMap::new();
let mut errors = false;
let mut seen_spans = FxHashSet::default();
let mut error_vec = Vec::new();
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);
// For a `#![feature(uniform_paths)]` `use self::x as _` canary,
// failure is ignored, while success may cause an ambiguity error.
if import.is_uniform_paths_canary {
if error.is_some() {
continue;
}
let (name, result) = match import.subclass {
SingleImport { source, ref result, .. } => (source.name, result),
_ => bug!(),
};
let has_explicit_self =
!import.module_path.is_empty() &&
import.module_path[0].ident.name == keywords::SelfValue.name();
self.per_ns(|_, ns| {
if let Some(result) = result[ns].get().ok() {
let canary_results =
uniform_paths_canaries.entry((import.span, import.id, ns))
.or_insert(UniformPathsCanaryResults {
name,
module_scope: None,
block_scopes: vec![],
});
// All the canaries with the same `id` should have the same `name`.
assert_eq!(canary_results.name, name);
if has_explicit_self {
// There should only be one `self::x` (module-scoped) canary.
assert!(canary_results.module_scope.is_none());
canary_results.module_scope = Some(result);
} else {
canary_results.block_scopes.push(result);
}
}
});
} else 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 {
@ -743,71 +669,6 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
}
}
let uniform_paths_feature = self.session.features_untracked().uniform_paths;
for ((span, _, ns), results) in uniform_paths_canaries {
let name = results.name;
let external_crate = if ns == TypeNS {
self.extern_prelude_get(Ident::with_empty_ctxt(name), true, false)
.map(|binding| binding.def())
} else {
None
};
// Currently imports can't resolve in non-module scopes,
// we only have canaries in them for future-proofing.
if external_crate.is_none() && results.module_scope.is_none() {
continue;
}
{
let mut all_results = external_crate.into_iter().chain(
results.module_scope.iter()
.chain(&results.block_scopes)
.map(|binding| binding.def())
);
let first = all_results.next().unwrap();
// An ambiguity requires more than one *distinct* possible resolution.
let possible_resultions =
1 + all_results.filter(|&def| def != first).count();
if possible_resultions <= 1 {
continue;
}
}
errors = true;
let msg = format!("`{}` import is ambiguous", name);
let mut err = self.session.struct_span_err(span, &msg);
let mut suggestion_choices = vec![];
if external_crate.is_some() {
suggestion_choices.push(format!("`::{}`", name));
err.span_label(span,
format!("can refer to external crate `::{}`", name));
}
if let Some(result) = results.module_scope {
suggestion_choices.push(format!("`self::{}`", name));
if uniform_paths_feature {
err.span_label(result.span,
format!("can refer to `self::{}`", name));
} else {
err.span_label(result.span,
format!("may refer to `self::{}` in the future", name));
}
}
for result in results.block_scopes {
err.span_label(result.span,
format!("shadowed by block-scoped `{}`", name));
}
err.help(&format!("write {} explicitly instead", suggestion_choices.join(" or ")));
if uniform_paths_feature {
err.note("relative `use` paths enabled by `#![feature(uniform_paths)]`");
} else {
err.note("in the future, `#![feature(uniform_paths)]` may become the default");
}
err.emit();
}
if !error_vec.is_empty() {
self.throw_unresolved_import_error(error_vec.clone(), None);
}
@ -816,9 +677,6 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
// to avoid generating multiple errors on the same import.
if !errors {
for import in &self.indeterminate_imports {
if import.is_uniform_paths_canary {
continue;
}
self.throw_unresolved_import_error(error_vec, Some(MultiSpan::from(import.span)));
break;
}
@ -871,7 +729,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
/// 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;
@ -879,29 +737,23 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
let module = if let Some(module) = directive.imported_module.get() {
module
} else {
let vis = directive.vis.get();
// For better failure detection, pretend that the import will not define any names
// while resolving its module path.
directive.vis.set(ty::Visibility::Invisible);
let result = self.resolve_path(
Some(if directive.is_uniform_paths_canary {
ModuleOrUniformRoot::Module(directive.parent_scope.module)
} else {
ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name())
}),
&directive.module_path[..],
// 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 path_res = self.resolve_path(
&directive.module_path,
None,
&directive.parent_scope,
false,
directive.span,
directive.crate_lint(),
);
directive.vis.set(vis);
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,
}
};
@ -919,11 +771,15 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
let mut indeterminate = false;
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
if let Err(Undetermined) = result[ns].get() {
result[ns].set(this.resolve_ident_in_module(module,
source,
ns,
false,
directive.span));
// 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 binding = this.resolve_ident_in_module(
module, source, ns, Some(&directive.parent_scope), false, directive.span
);
directive.vis.set(orig_vis);
result[ns].set(binding);
} else {
return
};
@ -964,50 +820,62 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
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(
Some(if directive.is_uniform_paths_canary {
ModuleOrUniformRoot::Module(directive.parent_scope.module)
} else {
ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name())
}),
&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,
format!("Did you mean `{}`?", Segment::names_to_string(&suggested_path)),
format!("did you mean `{}`?", Segment::names_to_string(&suggested_path)),
note,
))
} 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(),
@ -1038,26 +906,47 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
_ => unreachable!(),
};
// Do not record uses from canaries, to avoid interfering with other
// diagnostics or suggestions that rely on some items not being used.
let record_used = !directive.is_uniform_paths_canary;
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 record_used && 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, ns, initial_binding,
directive.module_path.is_empty());
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 record_used && 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(..) => {
// FIXME: This assert may fire if public glob is later shadowed by a private
// single import (see test `issue-55884-2.rs`). In theory single imports should
// always block globs, even if they are not yet resolved, so that this kind of
// self-inconsistent resolution never happens.
// Reenable the assert when the issue is fixed.
// assert!(result[ns].get().is_err());
}
}
});
@ -1065,7 +954,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
if all_ns_err {
let mut all_ns_failed = true;
self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS {
if this.resolve_ident_in_module(module, ident, ns, record_used, span).is_ok() {
let binding = this.resolve_ident_in_module(
module, ident, ns, Some(&directive.parent_scope), true, directive.span
);
if binding.is_ok() {
all_ns_failed = false;
}
});
@ -1122,7 +1014,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
}
}
};
Some((span, msg, None))
Some((directive.span, msg, None))
} else {
// `resolve_ident_in_module` reported a privacy error.
self.import_dummy_binding(directive);
@ -1171,10 +1063,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
}
}
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() {
@ -1192,8 +1084,18 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
// this may resolve to either a value or a type, but for documentation
// purposes it's good enough to just favor one over the other.
self.per_ns(|this, ns| if let Some(binding) = result[ns].get().ok() {
let mut def = binding.def();
if let Def::Macro(def_id, _) = def {
// `DefId`s from the "built-in macro crate" should not leak from resolve because
// later stages are not ready to deal with them and produce lots of ICEs. Replace
// them with `Def::Err` until some saner scheme is implemented for built-in macros.
if def_id.krate == CrateNum::BuiltinMacros {
this.session.span_err(directive.span, "cannot import a built-in macro");
def = Def::Err;
}
}
let import = this.import_map.entry(directive.id).or_default();
import[ns] = Some(PathResolution::new(binding.def()));
import[ns] = Some(PathResolution::new(def));
});
debug!("(resolving single import) successfully resolved import");
@ -1262,19 +1164,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
None => continue,
};
// Don't reexport `uniform_path` canaries.
let non_canary_import = match binding.kind {
NameBindingKind::Import { directive, .. } => {
!directive.is_uniform_paths_canary
}
_ => false,
};
if non_canary_import || binding.is_macro_def() {
if binding.is_import() || binding.is_macro_def() {
let def = binding.def();
if def != Def::Err {
if !def.def_id().is_local() {
self.cstore.export_macros_untracked(def.def_id().krate);
if let Some(def_id) = def.opt_def_id() {
if !def_id.is_local() && def_id.krate != CrateNum::BuiltinMacros {
self.cstore.export_macros_untracked(def_id.krate);
}
}
reexports.push(Export {
ident: ident.modern(),

View File

@ -477,7 +477,7 @@ fn macro_resolve(cx: &DocContext, path_str: &str) -> Option<Def> {
let mut resolver = cx.resolver.borrow_mut();
let parent_scope = resolver.dummy_parent_scope();
if let Ok(def) = resolver.resolve_macro_to_def_inner(&path, MacroKind::Bang,
&parent_scope, false) {
&parent_scope, false, false) {
if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(def) {
return Some(def);
}

View File

@ -595,6 +595,13 @@ impl MacroKind {
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.

View File

@ -0,0 +1,13 @@
// compile-pass
// aux-build:plugin.rs
extern crate plugin;
mod inner {
use plugin::WithHelper;
#[derive(WithHelper)]
struct S;
}
fn main() {}

View File

@ -1,19 +1,20 @@
error[E0659]: `helper` is ambiguous
error[E0659]: `helper` is ambiguous (derive helper attribute vs any other name)
--> $DIR/helper-attr-blocked-by-import-ambig.rs:10:3
|
LL | #[helper] //~ ERROR `helper` is ambiguous
| ^^^^^^ ambiguous name
|
note: `helper` could refer to the name defined here
note: `helper` could refer to the derive helper attribute defined here
--> $DIR/helper-attr-blocked-by-import-ambig.rs:9:10
|
LL | #[derive(WithHelper)]
| ^^^^^^^^^^
note: `helper` could also refer to the name imported here
note: `helper` could also refer to the attribute macro imported here
--> $DIR/helper-attr-blocked-by-import-ambig.rs:7:5
|
LL | use plugin::helper;
| ^^^^^^^^^^^^^^
= help: use `self::helper` to refer to this attribute macro unambiguously
error: aborting due to previous error

View File

@ -1,99 +1,79 @@
error[E0659]: `repr` is ambiguous
--> $DIR/ambiguous-builtin-attrs.rs:9:3
|
LL | #[repr(C)] //~ ERROR `repr` is ambiguous
| ^^^^ ambiguous name
|
note: `repr` could refer to the name imported here
--> $DIR/ambiguous-builtin-attrs.rs:7:5
|
LL | use builtin_attrs::*;
| ^^^^^^^^^^^^^^^^
note: `repr` could also refer to the name defined here
--> $DIR/ambiguous-builtin-attrs.rs:9:3
|
LL | #[repr(C)] //~ ERROR `repr` is ambiguous
| ^^^^
= note: consider adding an explicit import of `repr` to disambiguate
error[E0659]: `repr` is ambiguous
--> $DIR/ambiguous-builtin-attrs.rs:11:19
|
LL | #[cfg_attr(all(), repr(C))] //~ ERROR `repr` is ambiguous
| ^^^^ ambiguous name
|
note: `repr` could refer to the name imported here
--> $DIR/ambiguous-builtin-attrs.rs:7:5
|
LL | use builtin_attrs::*;
| ^^^^^^^^^^^^^^^^
note: `repr` could also refer to the name defined here
--> $DIR/ambiguous-builtin-attrs.rs:11:19
|
LL | #[cfg_attr(all(), repr(C))] //~ ERROR `repr` is ambiguous
| ^^^^
= note: consider adding an explicit import of `repr` to disambiguate
error[E0659]: `repr` is ambiguous
--> $DIR/ambiguous-builtin-attrs.rs:20:34
|
LL | fn non_macro_expanded_location<#[repr(C)] T>() { //~ ERROR `repr` is ambiguous
| ^^^^ ambiguous name
|
note: `repr` could refer to the name imported here
--> $DIR/ambiguous-builtin-attrs.rs:7:5
|
LL | use builtin_attrs::*;
| ^^^^^^^^^^^^^^^^
note: `repr` could also refer to the name defined here
--> $DIR/ambiguous-builtin-attrs.rs:20:34
|
LL | fn non_macro_expanded_location<#[repr(C)] T>() { //~ ERROR `repr` is ambiguous
| ^^^^
= note: consider adding an explicit import of `repr` to disambiguate
error[E0659]: `repr` is ambiguous
--> $DIR/ambiguous-builtin-attrs.rs:22:11
|
LL | #[repr(C)] //~ ERROR `repr` is ambiguous
| ^^^^ ambiguous name
|
note: `repr` could refer to the name imported here
--> $DIR/ambiguous-builtin-attrs.rs:7:5
|
LL | use builtin_attrs::*;
| ^^^^^^^^^^^^^^^^
note: `repr` could also refer to the name defined here
--> $DIR/ambiguous-builtin-attrs.rs:22:11
|
LL | #[repr(C)] //~ ERROR `repr` is ambiguous
| ^^^^
= note: consider adding an explicit import of `repr` to disambiguate
error[E0659]: `feature` is ambiguous
--> $DIR/ambiguous-builtin-attrs.rs:3:4
|
LL | #![feature(decl_macro)] //~ ERROR `feature` is ambiguous
| ^^^^^^^ ambiguous name
|
note: `feature` could refer to the name imported here
--> $DIR/ambiguous-builtin-attrs.rs:7:5
|
LL | use builtin_attrs::*;
| ^^^^^^^^^^^^^^^^
note: `feature` could also refer to the name defined here
--> $DIR/ambiguous-builtin-attrs.rs:3:4
|
LL | #![feature(decl_macro)] //~ ERROR `feature` is ambiguous
| ^^^^^^^
= note: consider adding an explicit import of `feature` to disambiguate
error[E0425]: cannot find value `NonExistent` in this scope
--> $DIR/ambiguous-builtin-attrs.rs:30:5
|
LL | NonExistent; //~ ERROR cannot find value `NonExistent` in this scope
| ^^^^^^^^^^^ not found in this scope
error[E0659]: `repr` is ambiguous (built-in attribute vs any other name)
--> $DIR/ambiguous-builtin-attrs.rs:9:3
|
LL | #[repr(C)] //~ ERROR `repr` is ambiguous
| ^^^^ ambiguous name
|
= note: `repr` could refer to a built-in attribute
note: `repr` could also refer to the attribute macro imported here
--> $DIR/ambiguous-builtin-attrs.rs:7:5
|
LL | use builtin_attrs::*;
| ^^^^^^^^^^^^^^^^
= help: use `self::repr` to refer to this attribute macro unambiguously
error[E0659]: `repr` is ambiguous (built-in attribute vs any other name)
--> $DIR/ambiguous-builtin-attrs.rs:11:19
|
LL | #[cfg_attr(all(), repr(C))] //~ ERROR `repr` is ambiguous
| ^^^^ ambiguous name
|
= note: `repr` could refer to a built-in attribute
note: `repr` could also refer to the attribute macro imported here
--> $DIR/ambiguous-builtin-attrs.rs:7:5
|
LL | use builtin_attrs::*;
| ^^^^^^^^^^^^^^^^
= help: use `self::repr` to refer to this attribute macro unambiguously
error[E0659]: `repr` is ambiguous (built-in attribute vs any other name)
--> $DIR/ambiguous-builtin-attrs.rs:20:34
|
LL | fn non_macro_expanded_location<#[repr(C)] T>() { //~ ERROR `repr` is ambiguous
| ^^^^ ambiguous name
|
= note: `repr` could refer to a built-in attribute
note: `repr` could also refer to the attribute macro imported here
--> $DIR/ambiguous-builtin-attrs.rs:7:5
|
LL | use builtin_attrs::*;
| ^^^^^^^^^^^^^^^^
= help: use `self::repr` to refer to this attribute macro unambiguously
error[E0659]: `repr` is ambiguous (built-in attribute vs any other name)
--> $DIR/ambiguous-builtin-attrs.rs:22:11
|
LL | #[repr(C)] //~ ERROR `repr` is ambiguous
| ^^^^ ambiguous name
|
= note: `repr` could refer to a built-in attribute
note: `repr` could also refer to the attribute macro imported here
--> $DIR/ambiguous-builtin-attrs.rs:7:5
|
LL | use builtin_attrs::*;
| ^^^^^^^^^^^^^^^^
= help: use `self::repr` to refer to this attribute macro unambiguously
error[E0659]: `feature` is ambiguous (built-in attribute vs any other name)
--> $DIR/ambiguous-builtin-attrs.rs:3:4
|
LL | #![feature(decl_macro)] //~ ERROR `feature` is ambiguous
| ^^^^^^^ ambiguous name
|
= note: `feature` could refer to a built-in attribute
note: `feature` could also refer to the attribute macro imported here
--> $DIR/ambiguous-builtin-attrs.rs:7:5
|
LL | use builtin_attrs::*;
| ^^^^^^^^^^^^^^^^
= help: use `self::feature` to refer to this attribute macro unambiguously
error: aborting due to 6 previous errors
Some errors occurred: E0425, E0659.

View File

@ -1,19 +1,20 @@
error[E0659]: `my_attr` is ambiguous
error[E0659]: `my_attr` is ambiguous (derive helper attribute vs any other name)
--> $DIR/derive-helper-shadowing.rs:6:3
|
LL | #[my_attr] //~ ERROR `my_attr` is ambiguous
| ^^^^^^^ ambiguous name
|
note: `my_attr` could refer to the name defined here
note: `my_attr` could refer to the derive helper attribute defined here
--> $DIR/derive-helper-shadowing.rs:7:10
|
LL | #[derive(MyTrait)]
| ^^^^^^^
note: `my_attr` could also refer to the name imported here
note: `my_attr` could also refer to the attribute macro imported here
--> $DIR/derive-helper-shadowing.rs:4:5
|
LL | use derive_helper_shadowing::*;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use `self::my_attr` to refer to this attribute macro unambiguously
error: aborting due to previous error

View File

@ -1,16 +1,16 @@
error[E0433]: failed to resolve. crate root in paths can only be used in start position
error[E0433]: failed to resolve: crate root in paths can only be used in start position
--> $DIR/absolute-paths-in-nested-use-groups.rs:16:5
|
LL | ::bar, //~ ERROR crate root in paths can only be used in start position
| ^ crate root in paths can only be used in start position
error[E0433]: failed to resolve. `super` in paths can only be used in start position
error[E0433]: failed to resolve: `super` in paths can only be used in start position
--> $DIR/absolute-paths-in-nested-use-groups.rs:17:5
|
LL | super::bar, //~ ERROR `super` in paths can only be used in start position
| ^^^^^ `super` in paths can only be used in start position
error[E0433]: failed to resolve. `self` in paths can only be used in start position
error[E0433]: failed to resolve: `self` in paths can only be used in start position
--> $DIR/absolute-paths-in-nested-use-groups.rs:18:5
|
LL | self::bar, //~ ERROR `self` in paths can only be used in start position

View File

@ -10,8 +10,8 @@
fn main() {
let foo = thing::len(Vec::new());
//~^ ERROR failed to resolve. Use of undeclared type or module `thing`
//~^ ERROR failed to resolve: use of undeclared type or module `thing`
let foo = foo::bar::baz();
//~^ ERROR failed to resolve. Use of undeclared type or module `foo`
//~^ ERROR failed to resolve: use of undeclared type or module `foo`
}

View File

@ -1,14 +1,14 @@
error[E0433]: failed to resolve. Use of undeclared type or module `thing`
error[E0433]: failed to resolve: use of undeclared type or module `thing`
--> $DIR/bad-module.rs:12:15
|
LL | let foo = thing::len(Vec::new());
| ^^^^^ Use of undeclared type or module `thing`
| ^^^^^ use of undeclared type or module `thing`
error[E0433]: failed to resolve. Use of undeclared type or module `foo`
error[E0433]: failed to resolve: use of undeclared type or module `foo`
--> $DIR/bad-module.rs:15:15
|
LL | let foo = foo::bar::baz();
| ^^^ Use of undeclared type or module `foo`
| ^^^ use of undeclared type or module `foo`
error: aborting due to 2 previous errors

View File

@ -14,5 +14,5 @@
mod existent {}
#[existent::nonexistent] //~ ERROR failed to resolve. Could not find `nonexistent` in `existent`
#[existent::nonexistent] //~ ERROR failed to resolve: could not find `nonexistent` in `existent`
fn main() {}

View File

@ -1,8 +1,8 @@
error[E0433]: failed to resolve. Could not find `nonexistent` in `existent`
error[E0433]: failed to resolve: could not find `nonexistent` in `existent`
--> $DIR/custom-attribute-multisegment.rs:17:13
|
LL | #[existent::nonexistent] //~ ERROR failed to resolve. Could not find `nonexistent` in `existent`
| ^^^^^^^^^^^ Could not find `nonexistent` in `existent`
LL | #[existent::nonexistent] //~ ERROR failed to resolve: could not find `nonexistent` in `existent`
| ^^^^^^^^^^^ could not find `nonexistent` in `existent`
error: aborting due to previous error

View File

@ -1,8 +1,8 @@
error[E0433]: failed to resolve. Use of undeclared type or module `HashMap`
error[E0433]: failed to resolve: use of undeclared type or module `HashMap`
--> $DIR/issue-31997-1.rs:30:19
|
LL | let mut map = HashMap::new();
| ^^^^^^^ Use of undeclared type or module `HashMap`
| ^^^^^^^ use of undeclared type or module `HashMap`
error: aborting due to previous error

View File

@ -1,4 +1,4 @@
error[E0433]: failed to resolve. `$crate` in paths can only be used in start position
error[E0433]: failed to resolve: `$crate` in paths can only be used in start position
--> $DIR/dollar-crate-is-keyword-2.rs:16:16
|
LL | use a::$crate::b; //~ ERROR `$crate` in paths can only be used in start position
@ -16,7 +16,7 @@ LL | use a::$crate; //~ ERROR unresolved import `a::$crate`
LL | m!();
| ----- in this macro invocation
error[E0433]: failed to resolve. `$crate` in paths can only be used in start position
error[E0433]: failed to resolve: `$crate` in paths can only be used in start position
--> $DIR/dollar-crate-is-keyword-2.rs:17:21
|
LL | type A = a::$crate; //~ ERROR `$crate` in paths can only be used in start position

View File

@ -11,7 +11,7 @@
type A0 = dyn;
//~^ ERROR cannot find type `dyn` in this scope
type A1 = dyn::dyn;
//~^ ERROR Use of undeclared type or module `dyn`
//~^ ERROR use of undeclared type or module `dyn`
type A2 = dyn<dyn, dyn>;
//~^ ERROR cannot find type `dyn` in this scope
//~| ERROR cannot find type `dyn` in this scope
@ -19,6 +19,6 @@ type A2 = dyn<dyn, dyn>;
type A3 = dyn<<dyn as dyn>::dyn>;
//~^ ERROR cannot find type `dyn` in this scope
//~| ERROR cannot find type `dyn` in this scope
//~| ERROR Use of undeclared type or module `dyn`
//~| ERROR use of undeclared type or module `dyn`
fn main() {}

View File

@ -1,14 +1,14 @@
error[E0433]: failed to resolve. Use of undeclared type or module `dyn`
error[E0433]: failed to resolve: use of undeclared type or module `dyn`
--> $DIR/dyn-trait-compatibility.rs:13:11
|
LL | type A1 = dyn::dyn;
| ^^^ Use of undeclared type or module `dyn`
| ^^^ use of undeclared type or module `dyn`
error[E0433]: failed to resolve. Use of undeclared type or module `dyn`
error[E0433]: failed to resolve: use of undeclared type or module `dyn`
--> $DIR/dyn-trait-compatibility.rs:19:23
|
LL | type A3 = dyn<<dyn as dyn>::dyn>;
| ^^^ Use of undeclared type or module `dyn`
| ^^^ use of undeclared type or module `dyn`
error[E0412]: cannot find type `dyn` in this scope
--> $DIR/dyn-trait-compatibility.rs:11:11

View File

@ -2,7 +2,7 @@ error[E0530]: match bindings cannot shadow tuple structs
--> $DIR/empty-struct-tuple-pat.rs:32:9
|
LL | struct Empty2();
| ---------------- a tuple struct `Empty2` is defined here
| ---------------- the tuple struct `Empty2` is defined here
...
LL | Empty2 => () //~ ERROR match bindings cannot shadow tuple structs
| ^^^^^^ cannot be named the same as a tuple struct
@ -11,7 +11,7 @@ error[E0530]: match bindings cannot shadow tuple structs
--> $DIR/empty-struct-tuple-pat.rs:35:9
|
LL | use empty_struct::*;
| --------------- a tuple struct `XEmpty6` is imported here
| --------------- the tuple struct `XEmpty6` is imported here
...
LL | XEmpty6 => () //~ ERROR match bindings cannot shadow tuple structs
| ^^^^^^^ cannot be named the same as a tuple struct

View File

@ -2,7 +2,7 @@ error[E0530]: let bindings cannot shadow tuple structs
--> $DIR/enum-in-scope.rs:14:9
|
LL | struct hello(isize);
| -------------------- a tuple struct `hello` is defined here
| -------------------- the tuple struct `hello` is defined here
...
LL | let hello = 0; //~ERROR let bindings cannot shadow tuple structs
| ^^^^^ cannot be named the same as a tuple struct

View File

@ -2,7 +2,7 @@ error[E0432]: unresolved import `something`
--> $DIR/E0432.rs:11:5
|
LL | use something::Foo; //~ ERROR E0432
| ^^^^^^^^^ Maybe a missing `extern crate something;`?
| ^^^^^^^^^ maybe a missing `extern crate something;`?
error: aborting due to previous error

View File

@ -1,8 +1,8 @@
error[E0433]: failed to resolve. Use of undeclared type or module `HashMap`
error[E0433]: failed to resolve: use of undeclared type or module `HashMap`
--> $DIR/E0433.rs:12:15
|
LL | let map = HashMap::new(); //~ ERROR E0433
| ^^^^^^^ Use of undeclared type or module `HashMap`
| ^^^^^^^ use of undeclared type or module `HashMap`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0530]: match bindings cannot shadow statics
--> $DIR/E0530.rs:16:9
|
LL | static TEST: i32 = 0;
| --------------------- a static `TEST` is defined here
| --------------------- the static `TEST` is defined here
...
LL | TEST => {} //~ ERROR E0530
| ^^^^ cannot be named the same as a static

View File

@ -1,20 +1,21 @@
error[E0659]: `foo` is ambiguous
error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
--> $DIR/E0659.rs:25:15
|
LL | collider::foo(); //~ ERROR E0659
| ^^^ ambiguous name
|
note: `foo` could refer to the name imported here
note: `foo` could refer to the function imported here
--> $DIR/E0659.rs:20:13
|
LL | pub use moon::*;
| ^^^^^^^
note: `foo` could also refer to the name imported here
= help: consider adding an explicit import of `foo` to disambiguate
note: `foo` could also refer to the function imported here
--> $DIR/E0659.rs:21:13
|
LL | pub use earth::*;
| ^^^^^^^^
= note: consider adding an explicit import of `foo` to disambiguate
= help: consider adding an explicit import of `foo` to disambiguate
error: aborting due to previous error

View File

@ -13,7 +13,7 @@
// want to change eventually.
mod foo {
pub fn bar() { foo::baz(); } //~ ERROR failed to resolve. Use of undeclared type or module `foo`
pub fn bar() { foo::baz(); } //~ ERROR failed to resolve: use of undeclared type or module `foo`
fn baz() { }
}

View File

@ -1,8 +1,8 @@
error[E0433]: failed to resolve. Use of undeclared type or module `foo`
error[E0433]: failed to resolve: use of undeclared type or module `foo`
--> $DIR/export-fully-qualified.rs:16:20
|
LL | pub fn bar() { foo::baz(); } //~ ERROR failed to resolve. Use of undeclared type or module `foo`
| ^^^ Use of undeclared type or module `foo`
LL | pub fn bar() { foo::baz(); } //~ ERROR failed to resolve: use of undeclared type or module `foo`
| ^^^ use of undeclared type or module `foo`
error: aborting due to previous error

View File

@ -9,7 +9,7 @@
// except according to those terms.
mod foo {
pub fn x() { bar::x(); } //~ ERROR failed to resolve. Use of undeclared type or module `bar`
pub fn x() { bar::x(); } //~ ERROR failed to resolve: use of undeclared type or module `bar`
}
mod bar {

View File

@ -1,8 +1,8 @@
error[E0433]: failed to resolve. Use of undeclared type or module `bar`
error[E0433]: failed to resolve: use of undeclared type or module `bar`
--> $DIR/export2.rs:12:18
|
LL | pub fn x() { bar::x(); } //~ ERROR failed to resolve. Use of undeclared type or module `bar`
| ^^^ Use of undeclared type or module `bar`
LL | pub fn x() { bar::x(); } //~ ERROR failed to resolve: use of undeclared type or module `bar`
| ^^^ use of undeclared type or module `bar`
error: aborting due to previous error

View File

@ -12,5 +12,5 @@
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
}

View File

@ -1,8 +1,9 @@
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`.

View File

@ -2,13 +2,13 @@ error[E0432]: unresolved import `core`
--> $DIR/feature-gate-extern_absolute_paths.rs:11:5
|
LL | use core::default; //~ ERROR unresolved import `core`
| ^^^^ Maybe a missing `extern crate core;`?
| ^^^^ maybe a missing `extern crate core;`?
error[E0433]: failed to resolve. Maybe a missing `extern crate core;`?
error[E0433]: failed to resolve: maybe a missing `extern crate core;`?
--> $DIR/feature-gate-extern_absolute_paths.rs:14:19
|
LL | let _: u8 = ::core::default::Default(); //~ ERROR failed to resolve
| ^^^^ Maybe a missing `extern crate core;`?
| ^^^^ maybe a missing `extern crate core;`?
error: aborting due to 2 previous errors

View File

@ -1,6 +1,6 @@
// edition:2018
#![feature(alloc)]
#![feature(alloc, underscore_imports)]
extern crate alloc;
@ -23,7 +23,7 @@ mod absolute {
}
mod import_in_scope {
use alloc;
use alloc as _;
//~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable
use alloc::boxed;
//~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable

View File

@ -1,7 +1,7 @@
error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #55599)
--> $DIR/feature-gate-extern_crate_item_prelude.rs:26:9
|
LL | use alloc;
LL | use alloc as _;
| ^^^^^
|
= help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable

View File

@ -8,15 +8,22 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// edition:2018
pub mod foo {
pub use bar::Bar;
//~^ ERROR unresolved import `bar`
pub use bar::Bar; //~ ERROR imports can only refer to extern crate names
pub mod bar {
pub struct Bar;
}
}
use inline; //~ ERROR imports can only refer to extern crate names
use Vec; //~ ERROR imports can only refer to extern crate names
use vec; //~ ERROR imports can only refer to extern crate names
fn main() {
let _ = foo::Bar;
}

View File

@ -1,9 +1,62 @@
error[E0432]: unresolved import `bar`
--> $DIR/feature-gate-uniform-paths.rs:12:13
error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
--> $DIR/feature-gate-uniform-paths.rs:14:13
|
LL | pub use bar::Bar;
| ^^^ Did you mean `self::bar`?
LL | pub use bar::Bar; //~ ERROR imports can only refer to extern crate names
| ^^^
LL |
LL | / pub mod bar {
LL | | pub struct Bar;
LL | | }
| |_____- not an extern crate passed with `--extern`
|
= help: add #![feature(uniform_paths)] to the crate attributes to enable
note: this import refers to the module defined here
--> $DIR/feature-gate-uniform-paths.rs:16:5
|
LL | / pub mod bar {
LL | | pub struct Bar;
LL | | }
| |_____^
error: aborting due to previous error
error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
--> $DIR/feature-gate-uniform-paths.rs:21:5
|
LL | use inline; //~ ERROR imports can only refer to extern crate names
| ^^^^^^ not an extern crate passed with `--extern`
|
= help: add #![feature(uniform_paths)] to the crate attributes to enable
note: this import refers to the built-in attribute imported here
--> $DIR/feature-gate-uniform-paths.rs:21:5
|
LL | use inline; //~ ERROR imports can only refer to extern crate names
| ^^^^^^
For more information about this error, try `rustc --explain E0432`.
error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
--> $DIR/feature-gate-uniform-paths.rs:23:5
|
LL | use Vec; //~ ERROR imports can only refer to extern crate names
| ^^^ not an extern crate passed with `--extern`
|
= help: add #![feature(uniform_paths)] to the crate attributes to enable
note: this import refers to the struct imported here
--> $DIR/feature-gate-uniform-paths.rs:23:5
|
LL | use Vec; //~ ERROR imports can only refer to extern crate names
| ^^^
error[E0658]: imports can only refer to extern crate names passed with `--extern` on stable channel (see issue #53130)
--> $DIR/feature-gate-uniform-paths.rs:25:5
|
LL | use vec; //~ ERROR imports can only refer to extern crate names
| ^^^ not an extern crate passed with `--extern`
|
= help: add #![feature(uniform_paths)] to the crate attributes to enable
note: this import refers to the macro imported here
--> $DIR/feature-gate-uniform-paths.rs:25:5
|
LL | use vec; //~ ERROR imports can only refer to extern crate names
| ^^^
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,11 +1,11 @@
error[E0433]: failed to resolve. Use of undeclared type or module `Vec`
error[E0433]: failed to resolve: use of undeclared type or module `Vec`
--> $DIR/no_implicit_prelude.rs:21:9
|
LL | fn f() { ::bar::m!(); }
| ------------ in this macro invocation
...
LL | Vec::new(); //~ ERROR failed to resolve
| ^^^ Use of undeclared type or module `Vec`
| ^^^ use of undeclared type or module `Vec`
error[E0599]: no method named `clone` found for type `()` in the current scope
--> $DIR/no_implicit_prelude.rs:22:12

View File

@ -9,7 +9,7 @@
// except according to those terms.
use baz::zed::bar; //~ ERROR unresolved import `baz::zed` [E0432]
//~^ Could not find `zed` in `baz`
//~^ could not find `zed` in `baz`
mod baz {}
mod zed {

View File

@ -2,7 +2,7 @@ error[E0432]: unresolved import `baz::zed`
--> $DIR/import2.rs:11:10
|
LL | use baz::zed::bar; //~ ERROR unresolved import `baz::zed` [E0432]
| ^^^ Could not find `zed` in `baz`
| ^^^ could not find `zed` in `baz`
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0432]: unresolved import `main`
--> $DIR/import3.rs:12:5
|
LL | use main::bar;
| ^^^^ Maybe a missing `extern crate main;`?
| ^^^^ maybe a missing `extern crate main;`?
error: aborting due to previous error

View File

@ -0,0 +1,9 @@
mod m1 {
pub fn f() {}
}
mod m2 {
pub fn f(_: u8) {}
}
pub use m1::*;
pub use m2::*;

View File

@ -12,77 +12,81 @@ help: you can use `as` to change the binding name of the import
LL | use a::foo as other_foo; //~ ERROR the name `foo` is defined multiple times
| ^^^^^^^^^^^^^^^^^^^
error[E0659]: `foo` is ambiguous
error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
--> $DIR/duplicate.rs:56:15
|
LL | use self::foo::bar; //~ ERROR `foo` is ambiguous
| ^^^ ambiguous name
|
note: `foo` could refer to the name imported here
note: `foo` could refer to the module imported here
--> $DIR/duplicate.rs:53:9
|
LL | use self::m1::*;
| ^^^^^^^^^^^
note: `foo` could also refer to the name imported here
= help: consider adding an explicit import of `foo` to disambiguate
note: `foo` could also refer to the module imported here
--> $DIR/duplicate.rs:54:9
|
LL | use self::m2::*;
| ^^^^^^^^^^^
= note: consider adding an explicit import of `foo` to disambiguate
= help: consider adding an explicit import of `foo` to disambiguate
error[E0659]: `foo` is ambiguous
error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
--> $DIR/duplicate.rs:45:8
|
LL | f::foo(); //~ ERROR `foo` is ambiguous
| ^^^ ambiguous name
|
note: `foo` could refer to the name imported here
note: `foo` could refer to the function imported here
--> $DIR/duplicate.rs:34:13
|
LL | pub use a::*;
| ^^^^
note: `foo` could also refer to the name imported here
= help: consider adding an explicit import of `foo` to disambiguate
note: `foo` could also refer to the function imported here
--> $DIR/duplicate.rs:35:13
|
LL | pub use b::*;
| ^^^^
= note: consider adding an explicit import of `foo` to disambiguate
= help: consider adding an explicit import of `foo` to disambiguate
error[E0659]: `foo` is ambiguous
error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
--> $DIR/duplicate.rs:46:8
|
LL | g::foo(); //~ ERROR `foo` is ambiguous
| ^^^ ambiguous name
|
note: `foo` could refer to the name imported here
note: `foo` could refer to the function imported here
--> $DIR/duplicate.rs:39:13
|
LL | pub use a::*;
| ^^^^
note: `foo` could also refer to the name imported here
= help: consider adding an explicit import of `foo` to disambiguate
note: `foo` could also refer to the unresolved item imported here
--> $DIR/duplicate.rs:40:13
|
LL | pub use f::*;
| ^^^^
= note: consider adding an explicit import of `foo` to disambiguate
= help: consider adding an explicit import of `foo` to disambiguate
error[E0659]: `foo` is ambiguous
error[E0659]: `foo` is ambiguous (glob import vs glob import in the same module)
--> $DIR/duplicate.rs:59:9
|
LL | foo::bar(); //~ ERROR `foo` is ambiguous
| ^^^ ambiguous name
|
note: `foo` could refer to the name imported here
note: `foo` could refer to the module imported here
--> $DIR/duplicate.rs:53:9
|
LL | use self::m1::*;
| ^^^^^^^^^^^
note: `foo` could also refer to the name imported here
= help: consider adding an explicit import of `foo` to disambiguate
note: `foo` could also refer to the module imported here
--> $DIR/duplicate.rs:54:9
|
LL | use self::m2::*;
| ^^^^^^^^^^^
= note: consider adding an explicit import of `foo` to disambiguate
= help: consider adding an explicit import of `foo` to disambiguate
error: aborting due to 5 previous errors

View File

@ -7,7 +7,7 @@ mod n {
mod m {
fn check() {
two_macros::m!(); //~ ERROR failed to resolve. Use of undeclared type or module `two_macros`
two_macros::m!(); //~ ERROR failed to resolve: use of undeclared type or module `two_macros`
}
}

View File

@ -7,11 +7,11 @@ LL | extern crate std as non_existent;
LL | define_std_as_non_existent!();
| ------------------------------ in this macro invocation
error[E0433]: failed to resolve. Use of undeclared type or module `two_macros`
error[E0433]: failed to resolve: use of undeclared type or module `two_macros`
--> $DIR/extern-prelude-extern-crate-fail.rs:10:9
|
LL | two_macros::m!(); //~ ERROR failed to resolve. Use of undeclared type or module `two_macros`
| ^^^^^^^^^^ Use of undeclared type or module `two_macros`
LL | two_macros::m!(); //~ ERROR failed to resolve: use of undeclared type or module `two_macros`
| ^^^^^^^^^^ use of undeclared type or module `two_macros`
error: aborting due to 2 previous errors

View File

@ -1,10 +1,11 @@
error[E0659]: `Vec` is ambiguous
error[E0659]: `Vec` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:15:9
|
LL | Vec::panic!(); //~ ERROR `Vec` is ambiguous
| ^^^ ambiguous name
|
note: `Vec` could refer to the name defined here
= note: `Vec` could refer to a struct from prelude
note: `Vec` could also refer to the extern crate imported here
--> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:7:9
|
LL | extern crate std as Vec;
@ -12,8 +13,6 @@ LL | extern crate std as Vec;
...
LL | define_vec!();
| -------------- in this macro invocation
note: `Vec` could also refer to the name defined here
= note: macro-expanded items do not shadow when used in a macro invocation path
error: aborting due to previous error

View File

@ -0,0 +1,7 @@
// aux-build:glob-conflict.rs
extern crate glob_conflict;
fn main() {
glob_conflict::f(); //~ ERROR cannot find function `f` in module `glob_conflict`
}

View File

@ -0,0 +1,9 @@
error[E0425]: cannot find function `f` in module `glob_conflict`
--> $DIR/glob-conflict-cross-crate.rs:6:20
|
LL | glob_conflict::f(); //~ ERROR cannot find function `f` in module `glob_conflict`
| ^ not found in `glob_conflict`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0425`.

View File

@ -1,48 +1,50 @@
error[E0659]: `env` is ambiguous
error[E0659]: `env` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
--> $DIR/glob-shadowing.rs:21:17
|
LL | let x = env!("PATH"); //~ ERROR `env` is ambiguous
| ^^^ ambiguous name
|
note: `env` could refer to the name imported here
= note: `env` could refer to a built-in macro
note: `env` could also refer to the macro imported here
--> $DIR/glob-shadowing.rs:19:9
|
LL | use m::*;
| ^^^^
= note: `env` is also a builtin macro
= note: consider adding an explicit import of `env` to disambiguate
= help: consider adding an explicit import of `env` to disambiguate
= help: or use `self::env` to refer to this macro unambiguously
error[E0659]: `env` is ambiguous
error[E0659]: `env` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
--> $DIR/glob-shadowing.rs:29:21
|
LL | let x = env!("PATH"); //~ ERROR `env` is ambiguous
| ^^^ ambiguous name
|
note: `env` could refer to the name imported here
= note: `env` could refer to a built-in macro
note: `env` could also refer to the macro imported here
--> $DIR/glob-shadowing.rs:27:13
|
LL | use m::*;
| ^^^^
= note: `env` is also a builtin macro
= note: consider adding an explicit import of `env` to disambiguate
= help: consider adding an explicit import of `env` to disambiguate
error[E0659]: `fenv` is ambiguous
error[E0659]: `fenv` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
--> $DIR/glob-shadowing.rs:39:21
|
LL | let x = fenv!(); //~ ERROR `fenv` is ambiguous
| ^^^^ ambiguous name
|
note: `fenv` could refer to the name imported here
note: `fenv` could refer to the macro imported here
--> $DIR/glob-shadowing.rs:37:13
|
LL | use m::*;
| ^^^^
note: `fenv` could also refer to the name defined here
= help: consider adding an explicit import of `fenv` to disambiguate
note: `fenv` could also refer to the macro defined here
--> $DIR/glob-shadowing.rs:35:5
|
LL | pub macro fenv($e: expr) { $e }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: consider adding an explicit import of `fenv` to disambiguate
= help: use `self::fenv` to refer to this macro unambiguously
error: aborting due to 3 previous errors

View File

@ -2,24 +2,25 @@ error[E0432]: unresolved import `nonexistent_module`
--> $DIR/issue-53269.rs:16:9
|
LL | use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_module`
| ^^^^^^^^^^^^^^^^^^ Maybe a missing `extern crate nonexistent_module;`?
| ^^^^^^^^^^^^^^^^^^ maybe a missing `extern crate nonexistent_module;`?
error[E0659]: `mac` is ambiguous
error[E0659]: `mac` is ambiguous (`macro_rules` vs non-`macro_rules` from other module)
--> $DIR/issue-53269.rs:18:5
|
LL | mac!(); //~ ERROR `mac` is ambiguous
| ^^^ ambiguous name
|
note: `mac` could refer to the name defined here
note: `mac` could refer to the macro defined here
--> $DIR/issue-53269.rs:13:1
|
LL | macro_rules! mac { () => () }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `mac` could also refer to the name imported here
note: `mac` could also refer to the unresolved item imported here
--> $DIR/issue-53269.rs:16:9
|
LL | use nonexistent_module::mac; //~ ERROR unresolved import `nonexistent_module`
| ^^^^^^^^^^^^^^^^^^^^^^^
= help: use `self::mac` to refer to this unresolved item unambiguously
error: aborting due to 2 previous errors

View File

@ -8,7 +8,7 @@ error[E0432]: unresolved import `non_existent`
--> $DIR/issue-55457.rs:2:5
|
LL | use non_existent::non_existent; //~ ERROR unresolved import `non_existent`
| ^^^^^^^^^^^^ Maybe a missing `extern crate non_existent;`?
| ^^^^^^^^^^^^ maybe a missing `extern crate non_existent;`?
error: cannot determine resolution for the derive macro `NonExistent`
--> $DIR/issue-55457.rs:5:10

View File

@ -0,0 +1,21 @@
mod m {
mod m1 {
pub struct S {}
}
mod m2 {
// Note this derive, it makes this struct macro-expanded,
// so it doesn't appear in time to participate in the initial resolution of `use m::S`,
// only in the later validation pass.
#[derive(Default)]
pub struct S {}
}
// Create a glob vs glob ambiguity
pub use self::m1::*;
pub use self::m2::*;
}
fn main() {
use m::S; //~ ERROR `S` is ambiguous
let s = S {};
}

View File

@ -0,0 +1,22 @@
error[E0659]: `S` is ambiguous (glob import vs glob import in the same module)
--> $DIR/issue-55884-1.rs:19:12
|
LL | use m::S; //~ ERROR `S` is ambiguous
| ^ ambiguous name
|
note: `S` could refer to the struct imported here
--> $DIR/issue-55884-1.rs:14:13
|
LL | pub use self::m1::*;
| ^^^^^^^^^^^
= help: consider adding an explicit import of `S` to disambiguate
note: `S` could also refer to the struct imported here
--> $DIR/issue-55884-1.rs:15:13
|
LL | pub use self::m2::*;
| ^^^^^^^^^^^
= help: consider adding an explicit import of `S` to disambiguate
error: aborting due to previous error
For more information about this error, try `rustc --explain E0659`.

View File

@ -0,0 +1,14 @@
mod options {
pub struct ParseOptions {}
}
mod parser {
pub use options::*;
// Private single import shadows public glob import, but arrives too late for initial
// resolution of `use parser::ParseOptions` because it depends on that resolution itself.
use ParseOptions;
}
pub use parser::ParseOptions; //~ ERROR struct `ParseOptions` is private
fn main() {}

View File

@ -0,0 +1,9 @@
error[E0603]: struct `ParseOptions` is private
--> $DIR/issue-55884-2.rs:12:17
|
LL | pub use parser::ParseOptions; //~ ERROR struct `ParseOptions` is private
| ^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0603`.

View File

@ -1,10 +1,10 @@
error[E0659]: `exported` is ambiguous
error[E0659]: `exported` is ambiguous (glob import vs macro-expanded name in the same module during import/macro resolution)
--> $DIR/local-modularized-tricky-fail-1.rs:38:1
|
LL | exported!(); //~ ERROR `exported` is ambiguous
| ^^^^^^^^ ambiguous name
|
note: `exported` could refer to the name defined here
note: `exported` could refer to the macro defined here
--> $DIR/local-modularized-tricky-fail-1.rs:15:5
|
LL | / macro_rules! exported {
@ -14,20 +14,21 @@ LL | | }
...
LL | define_exported!();
| ------------------- in this macro invocation
note: `exported` could also refer to the name imported here
note: `exported` could also refer to the macro imported here
--> $DIR/local-modularized-tricky-fail-1.rs:32:5
|
LL | use inner1::*;
| ^^^^^^^^^
= note: macro-expanded macros do not shadow
= help: consider adding an explicit import of `exported` to disambiguate
error[E0659]: `include` is ambiguous
error[E0659]: `include` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/local-modularized-tricky-fail-1.rs:56:1
|
LL | include!(); //~ ERROR `include` is ambiguous
| ^^^^^^^ ambiguous name
|
note: `include` could refer to the name defined here
= note: `include` could refer to a built-in macro
note: `include` could also refer to the macro defined here
--> $DIR/local-modularized-tricky-fail-1.rs:27:5
|
LL | / macro_rules! include {
@ -37,16 +38,16 @@ LL | | }
...
LL | define_include!();
| ------------------ in this macro invocation
= note: `include` is also a builtin macro
= note: macro-expanded macros do not shadow
= help: use `self::include` to refer to this macro unambiguously
error[E0659]: `panic` is ambiguous
error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/local-modularized-tricky-fail-1.rs:45:5
|
LL | panic!(); //~ ERROR `panic` is ambiguous
| ^^^^^ ambiguous name
|
note: `panic` could refer to the name defined here
= note: `panic` could refer to a macro from prelude
note: `panic` could also refer to the macro defined here
--> $DIR/local-modularized-tricky-fail-1.rs:21:5
|
LL | / macro_rules! panic {
@ -56,16 +57,16 @@ LL | | }
...
LL | define_panic!();
| ---------------- in this macro invocation
= note: `panic` is also a builtin macro
= note: macro-expanded macros do not shadow
= help: use `self::panic` to refer to this macro unambiguously
error[E0659]: `panic` is ambiguous
error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> <::std::macros::panic macros>:1:13
|
LL | ( ) => ( { panic ! ( "explicit panic" ) } ) ; ( $ msg : expr ) => (
| ^^^^^ ambiguous name
|
note: `panic` could refer to the name defined here
= note: `panic` could refer to a macro from prelude
note: `panic` could also refer to the macro defined here
--> $DIR/local-modularized-tricky-fail-1.rs:21:5
|
LL | / macro_rules! panic {
@ -75,8 +76,7 @@ LL | | }
...
LL | define_panic!();
| ---------------- in this macro invocation
= note: `panic` is also a builtin macro
= note: macro-expanded macros do not shadow
= help: use `self::panic` to refer to this macro unambiguously
error: aborting due to 4 previous errors

View File

@ -1,40 +1,40 @@
error[E0659]: `bar` is ambiguous
error[E0659]: `bar` is ambiguous (glob import vs macro-expanded name in the same module during import/macro resolution)
--> $DIR/macro-paths.rs:23:5
|
LL | bar::m! { //~ ERROR ambiguous
| ^^^ ambiguous name
|
note: `bar` could refer to the name defined here
note: `bar` could refer to the module defined here
--> $DIR/macro-paths.rs:24:9
|
LL | mod bar { pub use two_macros::m; }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `bar` could also refer to the name imported here
note: `bar` could also refer to the module imported here
--> $DIR/macro-paths.rs:22:9
|
LL | use foo::*;
| ^^^^^^
= note: macro-expanded items do not shadow when used in a macro invocation path
= help: consider adding an explicit import of `bar` to disambiguate
error[E0659]: `baz` is ambiguous
error[E0659]: `baz` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/macro-paths.rs:33:5
|
LL | baz::m! { //~ ERROR ambiguous
| ^^^ ambiguous name
|
note: `baz` could refer to the name defined here
note: `baz` could refer to the module defined here
--> $DIR/macro-paths.rs:34:9
|
LL | mod baz { pub use two_macros::m; }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `baz` could also refer to the name defined here
note: `baz` could also refer to the module defined here
--> $DIR/macro-paths.rs:28:1
|
LL | / pub mod baz {
LL | | pub use two_macros::m;
LL | | }
| |_^
= note: macro-expanded items do not shadow when used in a macro invocation path
= help: use `self::baz` to refer to this module unambiguously
error: aborting due to 2 previous errors

View File

@ -1,38 +1,38 @@
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (glob import vs macro-expanded name in the same module during import/macro resolution)
--> $DIR/macros.rs:26:5
|
LL | m! { //~ ERROR ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name imported here
note: `m` could refer to the macro imported here
--> $DIR/macros.rs:27:13
|
LL | use foo::m;
| ^^^^^^
note: `m` could also refer to the name imported here
note: `m` could also refer to the macro imported here
--> $DIR/macros.rs:25:9
|
LL | use two_macros::*;
| ^^^^^^^^^^^^^
= note: macro-expanded macro imports do not shadow
= help: consider adding an explicit import of `m` to disambiguate
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/macros.rs:39:9
|
LL | m! { //~ ERROR ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name imported here
note: `m` could refer to the macro imported here
--> $DIR/macros.rs:40:17
|
LL | use two_macros::n as m;
| ^^^^^^^^^^^^^^^^^^
note: `m` could also refer to the name imported here
note: `m` could also refer to the macro imported here
--> $DIR/macros.rs:32:9
|
LL | use two_macros::m;
| ^^^^^^^^^^^^^
= note: macro-expanded macro imports do not shadow
= help: use `self::m` to refer to this macro unambiguously
error: aborting due to 2 previous errors

View File

@ -1,20 +1,21 @@
error[E0659]: `Foo` is ambiguous
error[E0659]: `Foo` is ambiguous (glob import vs glob import in the same module)
--> $DIR/rfc-1560-warning-cycle.rs:19:17
|
LL | fn f(_: Foo) {} //~ ERROR `Foo` is ambiguous
| ^^^ ambiguous name
|
note: `Foo` could refer to the name imported here
note: `Foo` could refer to the struct imported here
--> $DIR/rfc-1560-warning-cycle.rs:17:13
|
LL | use *;
| ^
note: `Foo` could also refer to the name imported here
= help: consider adding an explicit import of `Foo` to disambiguate
note: `Foo` could also refer to the struct imported here
--> $DIR/rfc-1560-warning-cycle.rs:18:13
|
LL | use bar::*;
| ^^^^^^
= note: consider adding an explicit import of `Foo` to disambiguate
= help: consider adding an explicit import of `Foo` to disambiguate
error: aborting due to previous error

View File

@ -1,38 +1,40 @@
error[E0659]: `panic` is ambiguous
error[E0659]: `panic` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
--> $DIR/shadow_builtin_macros.rs:25:14
|
LL | fn f() { panic!(); } //~ ERROR ambiguous
| ^^^^^ ambiguous name
|
note: `panic` could refer to the name imported here
= note: `panic` could refer to a macro from prelude
note: `panic` could also refer to the macro imported here
--> $DIR/shadow_builtin_macros.rs:24:9
|
LL | use foo::*;
| ^^^^^^
= note: `panic` is also a builtin macro
= note: consider adding an explicit import of `panic` to disambiguate
= help: consider adding an explicit import of `panic` to disambiguate
= help: or use `self::panic` to refer to this macro unambiguously
error[E0659]: `panic` is ambiguous
error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/shadow_builtin_macros.rs:30:14
|
LL | fn f() { panic!(); } //~ ERROR ambiguous
| ^^^^^ ambiguous name
|
note: `panic` could refer to the name imported here
= note: `panic` could refer to a macro from prelude
note: `panic` could also refer to the macro imported here
--> $DIR/shadow_builtin_macros.rs:29:26
|
LL | ::two_macros::m!(use foo::panic;);
| ^^^^^^^^^^
= note: `panic` is also a builtin macro
= note: macro-expanded macro imports do not shadow
= help: use `self::panic` to refer to this macro unambiguously
error[E0659]: `panic` is ambiguous
error[E0659]: `panic` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/shadow_builtin_macros.rs:43:5
|
LL | panic!(); //~ ERROR `panic` is ambiguous
| ^^^^^ ambiguous name
|
note: `panic` could refer to the name defined here
= note: `panic` could refer to a macro from prelude
note: `panic` could also refer to the macro defined here
--> $DIR/shadow_builtin_macros.rs:40:9
|
LL | macro_rules! panic { () => {} }
@ -40,26 +42,25 @@ LL | macro_rules! panic { () => {} }
LL | } }
LL | m!();
| ----- in this macro invocation
= note: `panic` is also a builtin macro
= note: macro-expanded macros do not shadow
error[E0659]: `n` is ambiguous
error[E0659]: `n` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
--> $DIR/shadow_builtin_macros.rs:59:5
|
LL | n!(); //~ ERROR ambiguous
| ^ ambiguous name
|
note: `n` could refer to the name imported here
note: `n` could refer to the macro imported here
--> $DIR/shadow_builtin_macros.rs:58:9
|
LL | use bar::*;
| ^^^^^^
note: `n` could also refer to the name imported here
= help: consider adding an explicit import of `n` to disambiguate
= help: or use `self::n` to refer to this macro unambiguously
note: `n` could also refer to the macro imported here
--> $DIR/shadow_builtin_macros.rs:46:13
|
LL | #[macro_use(n)]
| ^
= note: consider adding an explicit import of `n` to disambiguate
error: aborting due to 4 previous errors

View File

@ -2,7 +2,7 @@ error[E0530]: match bindings cannot shadow statics
--> $DIR/issue-16149.rs:17:9
|
LL | static externalValue: isize;
| ---------------------------- a static `externalValue` is defined here
| ---------------------------- the static `externalValue` is defined here
...
LL | externalValue => true,
| ^^^^^^^^^^^^^ cannot be named the same as a static

View File

@ -11,6 +11,6 @@
// Testing that we don't fail abnormally after hitting the errors
use unresolved::*; //~ ERROR unresolved import `unresolved` [E0432]
//~^ Maybe a missing `extern crate unresolved;`?
//~^ maybe a missing `extern crate unresolved;`?
fn main() {}

View File

@ -2,7 +2,7 @@ error[E0432]: unresolved import `unresolved`
--> $DIR/issue-1697.rs:13:5
|
LL | use unresolved::*; //~ ERROR unresolved import `unresolved` [E0432]
| ^^^^^^^^^^ Maybe a missing `extern crate unresolved;`?
| ^^^^^^^^^^ maybe a missing `extern crate unresolved;`?
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0530]: match bindings cannot shadow statics
--> $DIR/issue-17718-patterns.rs:17:9
|
LL | static A1: usize = 1;
| --------------------- a static `A1` is defined here
| --------------------- the static `A1` is defined here
...
LL | A1 => {} //~ ERROR: match bindings cannot shadow statics
| ^^ cannot be named the same as a static
@ -11,7 +11,7 @@ error[E0530]: match bindings cannot shadow statics
--> $DIR/issue-17718-patterns.rs:18:9
|
LL | static mut A2: usize = 1;
| ------------------------- a static `A2` is defined here
| ------------------------- the static `A2` is defined here
...
LL | A2 => {} //~ ERROR: match bindings cannot shadow statics
| ^^ cannot be named the same as a static

View File

@ -2,7 +2,7 @@ error[E0530]: function parameters cannot shadow statics
--> $DIR/issue-23716.rs:13:8
|
LL | static foo: i32 = 0;
| -------------------- a static `foo` is defined here
| -------------------- the static `foo` is defined here
LL |
LL | fn bar(foo: i32) {}
| ^^^ cannot be named the same as a static
@ -11,7 +11,7 @@ error[E0530]: function parameters cannot shadow statics
--> $DIR/issue-23716.rs:23:13
|
LL | use self::submod::answer;
| -------------------- a static `answer` is imported here
| -------------------- the static `answer` is imported here
LL |
LL | fn question(answer: i32) {}
| ^^^^^^ cannot be named the same as a static

View File

@ -8,7 +8,7 @@ error[E0530]: match bindings cannot shadow constants
--> $DIR/issue-27033.rs:17:9
|
LL | const C: u8 = 1;
| ---------------- a constant `C` is defined here
| ---------------- the constant `C` is defined here
LL | match 1 {
LL | C @ 2 => { //~ ERROR match bindings cannot shadow constant
| ^ cannot be named the same as a constant

View File

@ -11,10 +11,10 @@
type Alias = ();
use Alias::*;
//~^ ERROR unresolved import `Alias` [E0432]
//~| Not a module `Alias`
//~| not a module `Alias`
use std::io::Result::*;
//~^ ERROR unresolved import `std::io::Result` [E0432]
//~| Not a module `Result`
//~| not a module `Result`
trait T {}
use T::*; //~ ERROR items in traits are not importable

View File

@ -8,13 +8,13 @@ error[E0432]: unresolved import `Alias`
--> $DIR/issue-30560.rs:12:5
|
LL | use Alias::*;
| ^^^^^ Not a module `Alias`
| ^^^^^ not a module `Alias`
error[E0432]: unresolved import `std::io::Result`
--> $DIR/issue-30560.rs:15:14
|
LL | use std::io::Result::*;
| ^^^^^^ Not a module `Result`
| ^^^^^^ not a module `Result`
error: aborting due to 3 previous errors

View File

@ -11,6 +11,6 @@
fn main() {
match 0 {
aaa::bbb(_) => ()
//~^ ERROR failed to resolve. Use of undeclared type or module `aaa`
//~^ ERROR failed to resolve: use of undeclared type or module `aaa`
};
}

View File

@ -1,8 +1,8 @@
error[E0433]: failed to resolve. Use of undeclared type or module `aaa`
error[E0433]: failed to resolve: use of undeclared type or module `aaa`
--> $DIR/issue-33293.rs:13:9
|
LL | aaa::bbb(_) => ()
| ^^^ Use of undeclared type or module `aaa`
| ^^^ use of undeclared type or module `aaa`
error: aborting due to previous error

View File

@ -2,19 +2,19 @@ error[E0432]: unresolved import `abc`
--> $DIR/issue-33464.rs:13:5
|
LL | use abc::one_el;
| ^^^ Maybe a missing `extern crate abc;`?
| ^^^ maybe a missing `extern crate abc;`?
error[E0432]: unresolved import `abc`
--> $DIR/issue-33464.rs:15:5
|
LL | use abc::{a, bbb, cccccc};
| ^^^ Maybe a missing `extern crate abc;`?
| ^^^ maybe a missing `extern crate abc;`?
error[E0432]: unresolved import `a_very_long_name`
--> $DIR/issue-33464.rs:17:5
|
LL | use a_very_long_name::{el, el2};
| ^^^^^^^^^^^^^^^^ Maybe a missing `extern crate a_very_long_name;`?
| ^^^^^^^^^^^^^^^^ maybe a missing `extern crate a_very_long_name;`?
error: aborting due to 3 previous errors

View File

@ -2,7 +2,7 @@ error[E0530]: match bindings cannot shadow constants
--> $DIR/issue-34047.rs:15:13
|
LL | const C: u8 = 0;
| ---------------- a constant `C` is defined here
| ---------------- the constant `C` is defined here
...
LL | mut C => {} //~ ERROR match bindings cannot shadow constants
| ^ cannot be named the same as a constant

View File

@ -2,7 +2,7 @@ error[E0432]: unresolved import `issue_36881_aux`
--> $DIR/issue-36881.rs:16:9
|
LL | use issue_36881_aux::Foo; //~ ERROR unresolved import
| ^^^^^^^^^^^^^^^ Maybe a missing `extern crate issue_36881_aux;`?
| ^^^^^^^^^^^^^^^ maybe a missing `extern crate issue_36881_aux;`?
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0432]: unresolved import `libc`
--> $DIR/issue-37887.rs:13:9
|
LL | use libc::*; //~ ERROR unresolved import
| ^^^^ Maybe a missing `extern crate libc;`?
| ^^^^ maybe a missing `extern crate libc;`?
error[E0658]: use of unstable library feature 'libc': use `libc` from crates.io (see issue #27783)
--> $DIR/issue-37887.rs:12:5

View File

@ -10,6 +10,6 @@
fn main() {
let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() };
//~^ ERROR failed to resolve. Could not find `imp` in `sys` [E0433]
//~^ ERROR failed to resolve: could not find `imp` in `sys` [E0433]
//~^^ ERROR module `sys` is private [E0603]
}

View File

@ -1,8 +1,8 @@
error[E0433]: failed to resolve. Could not find `imp` in `sys`
error[E0433]: failed to resolve: could not find `imp` in `sys`
--> $DIR/issue-38857.rs:12:23
|
LL | let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() };
| ^^^ Could not find `imp` in `sys`
| ^^^ could not find `imp` in `sys`
error[E0603]: module `sys` is private
--> $DIR/issue-38857.rs:12:18

View File

@ -9,5 +9,5 @@
// except according to those terms.
fn main() {
let super = 22; //~ ERROR failed to resolve. There are too many initial `super`s
let super = 22; //~ ERROR failed to resolve: there are too many initial `super`s
}

View File

@ -1,8 +1,8 @@
error[E0433]: failed to resolve. There are too many initial `super`s.
error[E0433]: failed to resolve: there are too many initial `super`s.
--> $DIR/keyword-super-as-identifier.rs:12:9
|
LL | let super = 22; //~ ERROR failed to resolve. There are too many initial `super`s
| ^^^^^ There are too many initial `super`s.
LL | let super = 22; //~ ERROR failed to resolve: there are too many initial `super`s
| ^^^^^ there are too many initial `super`s.
error: aborting due to previous error

View File

@ -9,5 +9,5 @@
// except according to those terms.
fn main() {
let super: isize; //~ ERROR failed to resolve. There are too many initial `super`s
let super: isize; //~ ERROR failed to resolve: there are too many initial `super`s
}

View File

@ -1,8 +1,8 @@
error[E0433]: failed to resolve. There are too many initial `super`s.
error[E0433]: failed to resolve: there are too many initial `super`s.
--> $DIR/keyword-super.rs:12:9
|
LL | let super: isize; //~ ERROR failed to resolve. There are too many initial `super`s
| ^^^^^ There are too many initial `super`s.
LL | let super: isize; //~ ERROR failed to resolve: there are too many initial `super`s
| ^^^^^ there are too many initial `super`s.
error: aborting due to previous error

View File

@ -1,32 +1,32 @@
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (`macro_rules` vs non-`macro_rules` from other module)
--> $DIR/ambiguity-legacy-vs-modern.rs:31:9
|
LL | m!() //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/ambiguity-legacy-vs-modern.rs:26:5
|
LL | macro_rules! m { () => (()) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/ambiguity-legacy-vs-modern.rs:29:9
|
LL | macro m() { 0 }
| ^^^^^^^^^^^^^^^
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (`macro_rules` vs non-`macro_rules` from other module)
--> $DIR/ambiguity-legacy-vs-modern.rs:43:5
|
LL | m!() //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/ambiguity-legacy-vs-modern.rs:40:9
|
LL | macro_rules! m { () => (()) }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/ambiguity-legacy-vs-modern.rs:36:5
|
LL | macro m() { 0 }

View File

@ -25,6 +25,6 @@ test!(b,
#[qux]
fn main() {
a::bar();
//~^ ERROR failed to resolve. Use of undeclared type or module `a`
//~^ ERROR failed to resolve: use of undeclared type or module `a`
b::bar();
}

View File

@ -1,8 +1,8 @@
error[E0433]: failed to resolve. Use of undeclared type or module `a`
error[E0433]: failed to resolve: use of undeclared type or module `a`
--> $DIR/macro-inner-attributes.rs:27:5
|
LL | a::bar();
| ^ Use of undeclared type or module `a`
| ^ use of undeclared type or module `a`
error: aborting due to previous error

View File

@ -12,8 +12,8 @@
mod m {
fn check() {
Vec::clone!(); //~ ERROR failed to resolve. Not a module `Vec`
u8::clone!(); //~ ERROR failed to resolve. Not a module `u8`
Vec::clone!(); //~ ERROR failed to resolve: not a module `Vec`
u8::clone!(); //~ ERROR failed to resolve: not a module `u8`
}
}

View File

@ -1,14 +1,14 @@
error[E0433]: failed to resolve. Not a module `Vec`
error[E0433]: failed to resolve: not a module `Vec`
--> $DIR/macro-path-prelude-fail-1.rs:15:9
|
LL | Vec::clone!(); //~ ERROR failed to resolve. Not a module `Vec`
| ^^^ Not a module `Vec`
LL | Vec::clone!(); //~ ERROR failed to resolve: not a module `Vec`
| ^^^ not a module `Vec`
error[E0433]: failed to resolve. Not a module `u8`
error[E0433]: failed to resolve: not a module `u8`
--> $DIR/macro-path-prelude-fail-1.rs:16:9
|
LL | u8::clone!(); //~ ERROR failed to resolve. Not a module `u8`
| ^^ Not a module `u8`
LL | u8::clone!(); //~ ERROR failed to resolve: not a module `u8`
| ^^ not a module `u8`
error: aborting due to 2 previous errors

View File

@ -10,7 +10,7 @@
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
}
}

View File

@ -1,8 +1,9 @@
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`.

View File

@ -1,16 +1,17 @@
error[E0659]: `std` is ambiguous
error[E0659]: `std` is ambiguous (glob import vs any other name from outer scope during import/macro resolution)
--> $DIR/macro-path-prelude-shadowing.rs:39:9
|
LL | std::panic!(); //~ ERROR `std` is ambiguous
| ^^^ ambiguous name
|
note: `std` could refer to the name imported here
= note: `std` could refer to a built-in extern crate
note: `std` could also refer to the module imported here
--> $DIR/macro-path-prelude-shadowing.rs:37:9
|
LL | use m2::*; // glob-import user-defined `std`
| ^^^^^
note: `std` could also refer to the name defined here
= note: consider adding an explicit import of `std` to disambiguate
= help: consider adding an explicit import of `std` to disambiguate
= help: or use `self::std` to refer to this module unambiguously
error: aborting due to previous error

View File

@ -9,13 +9,13 @@ LL | m1!();
|
= note: macro-expanded `#[macro_use]`s may not shadow existing macros (see RFC 1560)
error[E0659]: `foo` is ambiguous
error[E0659]: `foo` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/macro-shadowing.rs:27:1
|
LL | foo!(); //~ ERROR `foo` is ambiguous
| ^^^ ambiguous name
|
note: `foo` could refer to the name defined here
note: `foo` could refer to the macro defined here
--> $DIR/macro-shadowing.rs:20:5
|
LL | macro_rules! foo { () => {} }
@ -23,12 +23,11 @@ LL | macro_rules! foo { () => {} }
...
LL | m1!();
| ------ in this macro invocation
note: `foo` could also refer to the name defined here
note: `foo` could also refer to the macro defined here
--> $DIR/macro-shadowing.rs:15:1
|
LL | macro_rules! foo { () => {} }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: macro-expanded macros do not shadow
error: aborting due to 2 previous errors

View File

@ -1,8 +1,8 @@
error[E0433]: failed to resolve. Use of undeclared type or module `m`
error[E0433]: failed to resolve: use of undeclared type or module `m`
--> $DIR/macro_path_as_generic_bound.rs:17:6
|
LL | foo!(m::m2::A); //~ ERROR failed to resolve
| ^ Use of undeclared type or module `m`
| ^ use of undeclared type or module `m`
error: aborting due to previous error

View File

@ -1,10 +1,10 @@
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-legacy.rs:101:13
|
LL | m!(); //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:88:9
|
LL | macro_rules! m { () => { Right } }
@ -12,7 +12,7 @@ LL | macro_rules! m { () => { Right } }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:97:9
|
LL | macro_rules! m { () => {} }
@ -20,15 +20,14 @@ LL | macro_rules! m { () => {} }
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-legacy.rs:139:42
|
LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:88:9
|
LL | macro_rules! m { () => { Right } }
@ -36,7 +35,7 @@ LL | macro_rules! m { () => { Right } }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:135:9
|
LL | macro_rules! m { () => {} }
@ -44,15 +43,14 @@ LL | macro_rules! m { () => {} }
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-legacy.rs:148:9
|
LL | m!(); //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:88:9
|
LL | macro_rules! m { () => { Right } }
@ -60,7 +58,7 @@ LL | macro_rules! m { () => { Right } }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:144:9
|
LL | macro_rules! m { () => {} }
@ -68,15 +66,14 @@ LL | macro_rules! m { () => {} }
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-legacy.rs:164:9
|
LL | m!(); //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:88:9
|
LL | macro_rules! m { () => { Right } }
@ -84,7 +81,7 @@ LL | macro_rules! m { () => { Right } }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:85:9
|
LL | macro_rules! m { () => { Wrong } }
@ -92,15 +89,14 @@ LL | macro_rules! m { () => { Wrong } }
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-legacy.rs:180:13
|
LL | m!(); //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:88:9
|
LL | macro_rules! m { () => { Right } }
@ -108,7 +104,7 @@ LL | macro_rules! m { () => { Right } }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:85:9
|
LL | macro_rules! m { () => { Wrong } }
@ -116,15 +112,14 @@ LL | macro_rules! m { () => { Wrong } }
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-legacy.rs:218:42
|
LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:88:9
|
LL | macro_rules! m { () => { Right } }
@ -132,7 +127,7 @@ LL | macro_rules! m { () => { Right } }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:85:9
|
LL | macro_rules! m { () => { Wrong } }
@ -140,15 +135,14 @@ LL | macro_rules! m { () => { Wrong } }
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-legacy.rs:232:9
|
LL | m!(); //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:88:9
|
LL | macro_rules! m { () => { Right } }
@ -156,7 +150,7 @@ LL | macro_rules! m { () => { Right } }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:227:13
|
LL | macro_rules! m { () => {} }
@ -164,15 +158,14 @@ LL | macro_rules! m { () => {} }
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-legacy.rs:262:42
|
LL | macro_rules! gen_invoc { () => { m!() } } //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:88:9
|
LL | macro_rules! m { () => { Right } }
@ -180,7 +173,7 @@ LL | macro_rules! m { () => { Right } }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-legacy.rs:257:13
|
LL | macro_rules! m { () => {} }
@ -188,7 +181,6 @@ LL | macro_rules! m { () => {} }
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error: aborting due to 8 previous errors

View File

@ -1,10 +1,10 @@
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-modern.rs:106:17
|
LL | m!(); //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-modern.rs:91:9
|
LL | macro m() { Right }
@ -12,7 +12,7 @@ LL | macro m() { Right }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-modern.rs:101:9
|
LL | macro m() {}
@ -20,15 +20,14 @@ LL | macro m() {}
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-modern.rs:149:33
|
LL | macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-modern.rs:91:9
|
LL | macro m() { Right }
@ -36,7 +35,7 @@ LL | macro m() { Right }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-modern.rs:145:9
|
LL | macro m() {}
@ -44,15 +43,14 @@ LL | macro m() {}
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-modern.rs:158:13
|
LL | m!(); //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-modern.rs:91:9
|
LL | macro m() { Right }
@ -60,7 +58,7 @@ LL | macro m() { Right }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-modern.rs:155:9
|
LL | macro m() {}
@ -68,15 +66,14 @@ LL | macro m() {}
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-modern.rs:174:13
|
LL | m!(); //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-modern.rs:91:9
|
LL | macro m() { Right }
@ -84,7 +81,7 @@ LL | macro m() { Right }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-modern.rs:87:9
|
LL | macro m() { Wrong }
@ -92,15 +89,14 @@ LL | macro m() { Wrong }
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-modern.rs:192:17
|
LL | m!(); //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-modern.rs:91:9
|
LL | macro m() { Right }
@ -108,7 +104,7 @@ LL | macro m() { Right }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-modern.rs:87:9
|
LL | macro m() { Wrong }
@ -116,15 +112,14 @@ LL | macro m() { Wrong }
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error[E0659]: `m` is ambiguous
error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution)
--> $DIR/restricted-shadowing-modern.rs:235:33
|
LL | macro gen_invoc() { m!() } //~ ERROR `m` is ambiguous
| ^ ambiguous name
|
note: `m` could refer to the name defined here
note: `m` could refer to the macro defined here
--> $DIR/restricted-shadowing-modern.rs:91:9
|
LL | macro m() { Right }
@ -132,7 +127,7 @@ LL | macro m() { Right }
...
LL | include!();
| ----------- in this macro invocation
note: `m` could also refer to the name defined here
note: `m` could also refer to the macro defined here
--> $DIR/restricted-shadowing-modern.rs:87:9
|
LL | macro m() { Wrong }
@ -140,7 +135,6 @@ LL | macro m() { Wrong }
...
LL | include!();
| ----------- in this macro invocation
= note: macro-expanded macros do not shadow
error: aborting due to 6 previous errors

Some files were not shown because too many files have changed in this diff Show More