mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-03 04:04:06 +00:00
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:
commit
7e82eda000
@ -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)]
|
||||
|
@ -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",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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())?;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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),
|
||||
};
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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(¬e_msg);
|
||||
} else {
|
||||
err.span_note(b.span, ¬e_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(¬e);
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
})
|
||||
|
@ -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(¬e_msg);
|
||||
} else {
|
||||
err.span_note(binding.span, ¬e_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),
|
||||
})
|
||||
});
|
||||
};
|
||||
|
@ -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(),
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
13
src/test/ui-fulldeps/custom-derive/derive-in-mod.rs
Normal file
13
src/test/ui-fulldeps/custom-derive/derive-in-mod.rs
Normal 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() {}
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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`
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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() { }
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
2
src/test/ui/extern/extern-macro.rs
vendored
2
src/test/ui/extern/extern-macro.rs
vendored
@ -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
|
||||
}
|
||||
|
7
src/test/ui/extern/extern-macro.stderr
vendored
7
src/test/ui/extern/extern-macro.stderr
vendored
@ -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`.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
9
src/test/ui/imports/auxiliary/glob-conflict.rs
Normal file
9
src/test/ui/imports/auxiliary/glob-conflict.rs
Normal file
@ -0,0 +1,9 @@
|
||||
mod m1 {
|
||||
pub fn f() {}
|
||||
}
|
||||
mod m2 {
|
||||
pub fn f(_: u8) {}
|
||||
}
|
||||
|
||||
pub use m1::*;
|
||||
pub use m2::*;
|
@ -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
|
||||
|
||||
|
@ -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`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
7
src/test/ui/imports/glob-conflict-cross-crate.rs
Normal file
7
src/test/ui/imports/glob-conflict-cross-crate.rs
Normal 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`
|
||||
}
|
9
src/test/ui/imports/glob-conflict-cross-crate.stderr
Normal file
9
src/test/ui/imports/glob-conflict-cross-crate.stderr
Normal 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`.
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
21
src/test/ui/imports/issue-55884-1.rs
Normal file
21
src/test/ui/imports/issue-55884-1.rs
Normal 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 {};
|
||||
}
|
22
src/test/ui/imports/issue-55884-1.stderr
Normal file
22
src/test/ui/imports/issue-55884-1.stderr
Normal 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`.
|
14
src/test/ui/imports/issue-55884-2.rs
Normal file
14
src/test/ui/imports/issue-55884-2.rs
Normal 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() {}
|
9
src/test/ui/imports/issue-55884-2.stderr
Normal file
9
src/test/ui/imports/issue-55884-2.stderr
Normal 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`.
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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() {}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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`
|
||||
};
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 }
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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`.
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user