rustc_resolve: fix special-case for one-segment import paths.
This commit is contained in:
parent
cd47831bf0
commit
f9b1176eef
17 changed files with 433 additions and 238 deletions
|
@ -1139,32 +1139,4 @@ impl<'a> CrateLoader<'a> {
|
|||
|
||||
cnum
|
||||
}
|
||||
|
||||
pub fn process_use_extern(
|
||||
&mut self,
|
||||
name: Symbol,
|
||||
span: Span,
|
||||
id: ast::NodeId,
|
||||
definitions: &Definitions,
|
||||
) -> CrateNum {
|
||||
let cnum = self.resolve_crate(
|
||||
&None, name, name, None, None, span, PathKind::Crate, DepKind::Explicit
|
||||
).0;
|
||||
|
||||
let def_id = definitions.opt_local_def_id(id).unwrap();
|
||||
let path_len = definitions.def_path(def_id.index).data.len();
|
||||
|
||||
self.update_extern_crate(
|
||||
cnum,
|
||||
ExternCrate {
|
||||
src: ExternCrateSource::Use,
|
||||
span,
|
||||
path_len,
|
||||
direct: true,
|
||||
},
|
||||
&mut FxHashSet(),
|
||||
);
|
||||
|
||||
cnum
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ use macros::{InvocationData, LegacyScope};
|
|||
use resolve_imports::ImportDirective;
|
||||
use resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport};
|
||||
use {Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, ToNameBinding};
|
||||
use {PerNS, Resolver, ResolverArenas};
|
||||
use {ModuleOrUniformRoot, PerNS, Resolver, ResolverArenas};
|
||||
use Namespace::{self, TypeNS, ValueNS, MacroNS};
|
||||
use {resolve_error, resolve_struct_error, ResolutionError};
|
||||
|
||||
|
@ -175,7 +175,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
|||
ModuleKind::Def(_, name) => name,
|
||||
ModuleKind::Block(..) => unreachable!(),
|
||||
};
|
||||
// HACK(eddyb) unclear how good this is, but keeping `$crate`
|
||||
// in `source` breaks `src/test/compile-fail/import-crate-var.rs`,
|
||||
// while the current crate doesn't have a valid `crate_name`.
|
||||
if crate_name != keywords::Invalid.name() {
|
||||
source.name = crate_name;
|
||||
}
|
||||
if rename.is_none() {
|
||||
ident.name = crate_name;
|
||||
}
|
||||
|
@ -187,6 +192,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
|||
}
|
||||
}
|
||||
|
||||
if ident.name == keywords::Crate.name() {
|
||||
self.session.span_err(ident.span,
|
||||
"crate root imports need to be explicitly named: \
|
||||
`use crate as name;`");
|
||||
}
|
||||
|
||||
let subclass = SingleImport {
|
||||
target: ident,
|
||||
source,
|
||||
|
@ -299,7 +310,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
|||
root_id: item.id,
|
||||
id: item.id,
|
||||
parent,
|
||||
imported_module: Cell::new(Some(module)),
|
||||
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
|
||||
subclass: ImportDirectiveSubclass::ExternCrate(orig_name),
|
||||
root_span: item.span,
|
||||
span: item.span,
|
||||
|
@ -701,7 +712,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
|||
root_id: item.id,
|
||||
id: item.id,
|
||||
parent: graph_root,
|
||||
imported_module: Cell::new(Some(module)),
|
||||
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
|
||||
subclass: ImportDirectiveSubclass::MacroUse,
|
||||
root_span: span,
|
||||
span,
|
||||
|
@ -721,7 +732,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
|||
} else {
|
||||
for (name, span) in legacy_imports.imports {
|
||||
let ident = Ident::with_empty_ctxt(name);
|
||||
let result = self.resolve_ident_in_module(module, ident, MacroNS, false, span);
|
||||
let result = self.resolve_ident_in_module(
|
||||
ModuleOrUniformRoot::Module(module),
|
||||
ident,
|
||||
MacroNS,
|
||||
false,
|
||||
span,
|
||||
);
|
||||
if let Ok(binding) = result {
|
||||
let directive = macro_use_directive(span);
|
||||
self.potentially_unused_imports.push(directive);
|
||||
|
|
|
@ -953,9 +953,20 @@ impl<'a> LexicalScopeBinding<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub 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),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum PathResult<'a> {
|
||||
Module(Module<'a>),
|
||||
Module(ModuleOrUniformRoot<'a>),
|
||||
NonModule(PathResolution),
|
||||
Indeterminate,
|
||||
Failed(Span, String, bool /* is the error from the last segment? */),
|
||||
|
@ -1583,11 +1594,13 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
|
|||
let hir::Path { ref segments, span, ref mut def } = *path;
|
||||
let path: Vec<_> = segments.iter().map(|seg| seg.ident).collect();
|
||||
// FIXME (Manishearth): Intra doc links won't get warned of epoch changes
|
||||
match self.resolve_path(&path, Some(namespace), true, span, CrateLint::No) {
|
||||
PathResult::Module(module) => *def = module.def().unwrap(),
|
||||
match self.resolve_path(None, &path, Some(namespace), true, span, CrateLint::No) {
|
||||
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
|
||||
*def = module.def().unwrap(),
|
||||
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
|
||||
*def = path_res.base_def(),
|
||||
PathResult::NonModule(..) => match self.resolve_path(
|
||||
None,
|
||||
&path,
|
||||
None,
|
||||
true,
|
||||
|
@ -1599,6 +1612,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
|
|||
}
|
||||
_ => {}
|
||||
},
|
||||
PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) |
|
||||
PathResult::Indeterminate => unreachable!(),
|
||||
PathResult::Failed(span, msg, _) => {
|
||||
error_callback(self, span, ResolutionError::FailedToResolve(&msg));
|
||||
|
@ -1881,7 +1895,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
};
|
||||
|
||||
let item = self.resolve_ident_in_module_unadjusted(
|
||||
module, ident, ns, false, record_used, path_span,
|
||||
ModuleOrUniformRoot::Module(module),
|
||||
ident,
|
||||
ns,
|
||||
false,
|
||||
record_used,
|
||||
path_span,
|
||||
);
|
||||
if let Ok(binding) = item {
|
||||
// The ident resolves to an item.
|
||||
|
@ -1906,7 +1925,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
let orig_current_module = self.current_module;
|
||||
self.current_module = module; // Lexical resolutions can never be a privacy error.
|
||||
let result = self.resolve_ident_in_module_unadjusted(
|
||||
module, ident, ns, false, record_used, path_span,
|
||||
ModuleOrUniformRoot::Module(module),
|
||||
ident,
|
||||
ns,
|
||||
false,
|
||||
record_used,
|
||||
path_span,
|
||||
);
|
||||
self.current_module = orig_current_module;
|
||||
|
||||
|
@ -1954,8 +1978,14 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
return Some(LexicalScopeBinding::Item(binding));
|
||||
}
|
||||
if let Some(prelude) = self.prelude {
|
||||
if let Ok(binding) = self.resolve_ident_in_module_unadjusted(prelude, ident, ns,
|
||||
false, false, path_span) {
|
||||
if let Ok(binding) = self.resolve_ident_in_module_unadjusted(
|
||||
ModuleOrUniformRoot::Module(prelude),
|
||||
ident,
|
||||
ns,
|
||||
false,
|
||||
false,
|
||||
path_span,
|
||||
) {
|
||||
return Some(LexicalScopeBinding::Item(binding));
|
||||
}
|
||||
}
|
||||
|
@ -2013,7 +2043,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
}
|
||||
|
||||
fn resolve_ident_in_module(&mut self,
|
||||
module: Module<'a>,
|
||||
module: ModuleOrUniformRoot<'a>,
|
||||
mut ident: Ident,
|
||||
ns: Namespace,
|
||||
record_used: bool,
|
||||
|
@ -2021,9 +2051,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
-> 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);
|
||||
}
|
||||
}
|
||||
let result = self.resolve_ident_in_module_unadjusted(
|
||||
module, ident, ns, false, record_used, span,
|
||||
);
|
||||
|
@ -2410,13 +2442,16 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
if def != Def::Err {
|
||||
new_id = Some(def.def_id());
|
||||
let span = trait_ref.path.span;
|
||||
if let PathResult::Module(module) = self.resolve_path(
|
||||
if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
|
||||
self.resolve_path(
|
||||
None,
|
||||
&path,
|
||||
None,
|
||||
false,
|
||||
span,
|
||||
CrateLint::SimplePath(trait_ref.ref_id),
|
||||
) {
|
||||
)
|
||||
{
|
||||
new_val = Some((module, trait_ref.clone()));
|
||||
}
|
||||
}
|
||||
|
@ -2533,7 +2568,13 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
// If there is a TraitRef in scope for an impl, then the method must be in the
|
||||
// trait.
|
||||
if let Some((module, _)) = self.current_trait_ref {
|
||||
if self.resolve_ident_in_module(module, ident, ns, false, span).is_err() {
|
||||
if self.resolve_ident_in_module(
|
||||
ModuleOrUniformRoot::Module(module),
|
||||
ident,
|
||||
ns,
|
||||
false,
|
||||
span,
|
||||
).is_err() {
|
||||
let path = &self.current_trait_ref.as_ref().unwrap().1.path;
|
||||
resolve_error(self, span, err(ident.name, &path_names_to_string(path)));
|
||||
}
|
||||
|
@ -2908,9 +2949,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
(String::new(), "the crate root".to_string())
|
||||
} else {
|
||||
let mod_path = &path[..path.len() - 1];
|
||||
let mod_prefix = match this.resolve_path(mod_path, Some(TypeNS),
|
||||
let mod_prefix = match this.resolve_path(None, mod_path, Some(TypeNS),
|
||||
false, span, CrateLint::No) {
|
||||
PathResult::Module(module) => module.def(),
|
||||
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
|
||||
module.def(),
|
||||
_ => None,
|
||||
}.map_or(String::new(), |def| format!("{} ", def.kind_name()));
|
||||
(mod_prefix, format!("`{}`", names_to_string(mod_path)))
|
||||
|
@ -3319,6 +3361,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
}
|
||||
|
||||
let result = match self.resolve_path(
|
||||
None,
|
||||
&path,
|
||||
Some(ns),
|
||||
true,
|
||||
|
@ -3326,7 +3369,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
crate_lint,
|
||||
) {
|
||||
PathResult::NonModule(path_res) => path_res,
|
||||
PathResult::Module(module) if !module.is_normal() => {
|
||||
PathResult::Module(ModuleOrUniformRoot::Module(module)) if !module.is_normal() => {
|
||||
PathResolution::new(module.def().unwrap())
|
||||
}
|
||||
// In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we
|
||||
|
@ -3341,18 +3384,21 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
//
|
||||
// Such behavior is required for backward compatibility.
|
||||
// The same fallback is used when `a` resolves to nothing.
|
||||
PathResult::Module(..) | PathResult::Failed(..)
|
||||
PathResult::Module(ModuleOrUniformRoot::Module(_)) |
|
||||
PathResult::Failed(..)
|
||||
if (ns == TypeNS || path.len() > 1) &&
|
||||
self.primitive_type_table.primitive_types
|
||||
.contains_key(&path[0].name) => {
|
||||
let prim = self.primitive_type_table.primitive_types[&path[0].name];
|
||||
PathResolution::with_unresolved_segments(Def::PrimTy(prim), path.len() - 1)
|
||||
}
|
||||
PathResult::Module(module) => PathResolution::new(module.def().unwrap()),
|
||||
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
|
||||
PathResolution::new(module.def().unwrap()),
|
||||
PathResult::Failed(span, msg, false) => {
|
||||
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
||||
err_path_resolution()
|
||||
}
|
||||
PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) |
|
||||
PathResult::Failed(..) => return None,
|
||||
PathResult::Indeterminate => bug!("indetermined path result in resolve_qpath"),
|
||||
};
|
||||
|
@ -3362,6 +3408,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
path[0].name != keywords::DollarCrate.name() {
|
||||
let unqualified_result = {
|
||||
match self.resolve_path(
|
||||
None,
|
||||
&[*path.last().unwrap()],
|
||||
Some(ns),
|
||||
false,
|
||||
|
@ -3369,7 +3416,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
CrateLint::No,
|
||||
) {
|
||||
PathResult::NonModule(path_res) => path_res.base_def(),
|
||||
PathResult::Module(module) => module.def().unwrap(),
|
||||
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
|
||||
module.def().unwrap(),
|
||||
_ => return Some(result),
|
||||
}
|
||||
};
|
||||
|
@ -3384,13 +3432,14 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
|
||||
fn resolve_path(
|
||||
&mut self,
|
||||
base_module: Option<ModuleOrUniformRoot<'a>>,
|
||||
path: &[Ident],
|
||||
opt_ns: Option<Namespace>, // `None` indicates a module path
|
||||
record_used: bool,
|
||||
path_span: Span,
|
||||
crate_lint: CrateLint,
|
||||
) -> PathResult<'a> {
|
||||
let mut module = None;
|
||||
let mut module = base_module;
|
||||
let mut allow_super = true;
|
||||
let mut second_binding = None;
|
||||
|
||||
|
@ -3412,49 +3461,48 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
|
||||
if i == 0 && ns == TypeNS && name == keywords::SelfValue.name() {
|
||||
let mut ctxt = ident.span.ctxt().modern();
|
||||
module = Some(self.resolve_self(&mut ctxt, self.current_module));
|
||||
module = Some(ModuleOrUniformRoot::Module(
|
||||
self.resolve_self(&mut ctxt, self.current_module)));
|
||||
continue
|
||||
} else if allow_super && ns == TypeNS && name == keywords::Super.name() {
|
||||
let mut ctxt = ident.span.ctxt().modern();
|
||||
let self_module = match i {
|
||||
0 => self.resolve_self(&mut ctxt, self.current_module),
|
||||
_ => module.unwrap(),
|
||||
let self_module_parent = match i {
|
||||
0 => self.resolve_self(&mut ctxt, self.current_module).parent,
|
||||
_ => match module {
|
||||
Some(ModuleOrUniformRoot::Module(module)) => module.parent,
|
||||
_ => None,
|
||||
},
|
||||
};
|
||||
if let Some(parent) = self_module.parent {
|
||||
module = Some(self.resolve_self(&mut ctxt, parent));
|
||||
if let Some(parent) = self_module_parent {
|
||||
module = Some(ModuleOrUniformRoot::Module(
|
||||
self.resolve_self(&mut ctxt, parent)));
|
||||
continue
|
||||
} else {
|
||||
let msg = "There are too many initial `super`s.".to_string();
|
||||
return PathResult::Failed(ident.span, msg, false);
|
||||
}
|
||||
} else if i == 0 && ns == TypeNS && name == keywords::Extern.name() {
|
||||
continue;
|
||||
}
|
||||
allow_super = false;
|
||||
|
||||
if ns == TypeNS {
|
||||
if i == 0 {
|
||||
if name == keywords::Extern.name() ||
|
||||
name == keywords::CrateRoot.name() &&
|
||||
self.session.features_untracked().extern_absolute_paths &&
|
||||
self.session.rust_2018() {
|
||||
module = Some(ModuleOrUniformRoot::UniformRoot(name));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (i == 0 && name == keywords::CrateRoot.name()) ||
|
||||
(i == 0 && name == keywords::Crate.name()) ||
|
||||
(i == 0 && name == keywords::DollarCrate.name()) ||
|
||||
(i == 1 && name == keywords::Crate.name() &&
|
||||
path[0].name == keywords::CrateRoot.name()) {
|
||||
// `::a::b`, `crate::a::b`, `::crate::a::b` or `$crate::a::b`
|
||||
module = Some(self.resolve_crate_root(ident));
|
||||
module = Some(ModuleOrUniformRoot::Module(
|
||||
self.resolve_crate_root(ident)));
|
||||
continue
|
||||
} else if i == 1 && !ident.is_path_segment_keyword() {
|
||||
let prev_name = path[0].name;
|
||||
if prev_name == keywords::Extern.name() ||
|
||||
prev_name == keywords::CrateRoot.name() &&
|
||||
self.session.features_untracked().extern_absolute_paths &&
|
||||
self.session.rust_2018() {
|
||||
// `::extern_crate::a::b`
|
||||
let crate_id = self.crate_loader.process_path_extern(name, ident.span);
|
||||
let crate_root =
|
||||
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
|
||||
self.populate_module_if_necessary(crate_root);
|
||||
module = Some(crate_root);
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3513,7 +3561,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
let def = binding.def();
|
||||
let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(def);
|
||||
if let Some(next_module) = binding.module() {
|
||||
module = Some(next_module);
|
||||
module = Some(ModuleOrUniformRoot::Module(next_module));
|
||||
} else if def == Def::ToolMod && i + 1 != path.len() {
|
||||
let def = Def::NonMacroAttr(NonMacroAttrKind::Tool);
|
||||
return PathResult::NonModule(PathResolution::new(def));
|
||||
|
@ -3537,14 +3585,18 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
}
|
||||
Err(Undetermined) => return PathResult::Indeterminate,
|
||||
Err(Determined) => {
|
||||
if let Some(module) = module {
|
||||
if let Some(ModuleOrUniformRoot::Module(module)) = module {
|
||||
if opt_ns.is_some() && !module.is_normal() {
|
||||
return PathResult::NonModule(PathResolution::with_unresolved_segments(
|
||||
module.def().unwrap(), path.len() - i
|
||||
));
|
||||
}
|
||||
}
|
||||
let msg = if module.and_then(ModuleData::def) == self.graph_root.def() {
|
||||
let module_def = match module {
|
||||
Some(ModuleOrUniformRoot::Module(module)) => module.def(),
|
||||
_ => None,
|
||||
};
|
||||
let msg = if module_def == self.graph_root.def() {
|
||||
let is_mod = |def| match def { Def::Mod(..) => true, _ => false };
|
||||
let mut candidates =
|
||||
self.lookup_import_candidates(name, TypeNS, is_mod);
|
||||
|
@ -3568,7 +3620,10 @@ 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(self.graph_root))
|
||||
PathResult::Module(module.unwrap_or_else(|| {
|
||||
span_bug!(path_span, "resolve_path: empty(?) path {:?} has no module", path);
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
fn lint_if_path_starts_with_module(
|
||||
|
@ -3578,6 +3633,17 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
path_span: Span,
|
||||
second_binding: Option<&NameBinding>,
|
||||
) {
|
||||
// In the 2018 edition this lint is a hard error, so nothing to do
|
||||
if self.session.rust_2018() {
|
||||
return
|
||||
}
|
||||
|
||||
// In the 2015 edition there's no use in emitting lints unless the
|
||||
// crate's already enabled the feature that we're going to suggest
|
||||
if !self.session.features_untracked().crate_in_paths {
|
||||
return
|
||||
}
|
||||
|
||||
let (diag_id, diag_span) = match crate_lint {
|
||||
CrateLint::No => return,
|
||||
CrateLint::SimplePath(id) => (id, path_span),
|
||||
|
@ -3620,24 +3686,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
}
|
||||
}
|
||||
|
||||
self.lint_path_starts_with_module(diag_id, diag_span);
|
||||
}
|
||||
|
||||
fn lint_path_starts_with_module(&self, id: NodeId, span: Span) {
|
||||
// In the 2018 edition this lint is a hard error, so nothing to do
|
||||
if self.session.rust_2018() {
|
||||
return
|
||||
}
|
||||
// In the 2015 edition there's no use in emitting lints unless the
|
||||
// crate's already enabled the feature that we're going to suggest
|
||||
if !self.session.features_untracked().crate_in_paths {
|
||||
return
|
||||
}
|
||||
let diag = lint::builtin::BuiltinLintDiagnostics
|
||||
::AbsPathWithModule(span);
|
||||
::AbsPathWithModule(diag_span);
|
||||
self.session.buffer_lint_with_diagnostic(
|
||||
lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
||||
id, span,
|
||||
diag_id, diag_span,
|
||||
"absolute paths must start with `self`, `super`, \
|
||||
`crate`, or an external crate name in the 2018 edition",
|
||||
diag);
|
||||
|
@ -3782,8 +3835,13 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
|
||||
// Look for associated items in the current trait.
|
||||
if let Some((module, _)) = self.current_trait_ref {
|
||||
if let Ok(binding) =
|
||||
self.resolve_ident_in_module(module, ident, ns, false, module.span) {
|
||||
if let Ok(binding) = self.resolve_ident_in_module(
|
||||
ModuleOrUniformRoot::Module(module),
|
||||
ident,
|
||||
ns,
|
||||
false,
|
||||
module.span,
|
||||
) {
|
||||
let def = binding.def();
|
||||
if filter_fn(def) {
|
||||
return Some(if self.has_self.contains(&def.def_id()) {
|
||||
|
@ -3855,11 +3913,13 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
} else {
|
||||
// Search in module.
|
||||
let mod_path = &path[..path.len() - 1];
|
||||
if let PathResult::Module(module) = self.resolve_path(mod_path, Some(TypeNS),
|
||||
if let PathResult::Module(module) = self.resolve_path(None, mod_path, Some(TypeNS),
|
||||
false, span, CrateLint::No) {
|
||||
if let ModuleOrUniformRoot::Module(module) = module {
|
||||
add_module_candidates(module, &mut names);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let name = path[path.len() - 1].name;
|
||||
// Make sure error reporting is deterministic.
|
||||
|
@ -4096,7 +4156,13 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
let mut found_traits = Vec::new();
|
||||
// Look for the current trait.
|
||||
if let Some((module, _)) = self.current_trait_ref {
|
||||
if self.resolve_ident_in_module(module, ident, ns, false, module.span).is_ok() {
|
||||
if self.resolve_ident_in_module(
|
||||
ModuleOrUniformRoot::Module(module),
|
||||
ident,
|
||||
ns,
|
||||
false,
|
||||
module.span,
|
||||
).is_ok() {
|
||||
let def_id = module.def_id().unwrap();
|
||||
found_traits.push(TraitCandidate { def_id: def_id, import_id: None });
|
||||
}
|
||||
|
@ -4144,8 +4210,14 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
|||
if ident.span.glob_adjust(module.expansion, binding.span.ctxt().modern()).is_none() {
|
||||
continue
|
||||
}
|
||||
if self.resolve_ident_in_module_unadjusted(module, ident, ns, false, false, module.span)
|
||||
.is_ok() {
|
||||
if self.resolve_ident_in_module_unadjusted(
|
||||
ModuleOrUniformRoot::Module(module),
|
||||
ident,
|
||||
ns,
|
||||
false,
|
||||
false,
|
||||
module.span,
|
||||
).is_ok() {
|
||||
let import_id = match binding.kind {
|
||||
NameBindingKind::Import { directive, .. } => {
|
||||
self.maybe_unused_trait_imports.insert(directive.id);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
use {AmbiguityError, CrateLint, Resolver, ResolutionError, is_known_tool, resolve_error};
|
||||
use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding};
|
||||
use ModuleOrUniformRoot;
|
||||
use Namespace::{self, TypeNS, MacroNS};
|
||||
use build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport};
|
||||
use resolve_imports::ImportResolver;
|
||||
|
@ -538,7 +539,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
|||
return Err(Determinacy::Determined);
|
||||
}
|
||||
|
||||
let def = match self.resolve_path(&path, Some(MacroNS), false, span, CrateLint::No) {
|
||||
let res = self.resolve_path(None, &path, Some(MacroNS), false, span, CrateLint::No);
|
||||
let def = match res {
|
||||
PathResult::NonModule(path_res) => match path_res.base_def() {
|
||||
Def::Err => Err(Determinacy::Determined),
|
||||
def @ _ => {
|
||||
|
@ -655,7 +657,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
|||
WhereToResolve::Module(module) => {
|
||||
let orig_current_module = mem::replace(&mut self.current_module, module);
|
||||
let binding = self.resolve_ident_in_module_unadjusted(
|
||||
module, ident, ns, true, record_used, path_span,
|
||||
ModuleOrUniformRoot::Module(module),
|
||||
ident,
|
||||
ns,
|
||||
true,
|
||||
record_used,
|
||||
path_span,
|
||||
);
|
||||
self.current_module = orig_current_module;
|
||||
binding.map(MacroBinding::Modern)
|
||||
|
@ -715,9 +722,14 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
|||
let mut result = Err(Determinacy::Determined);
|
||||
if use_prelude {
|
||||
if let Some(prelude) = self.prelude {
|
||||
if let Ok(binding) =
|
||||
self.resolve_ident_in_module_unadjusted(prelude, ident, ns,
|
||||
false, false, path_span) {
|
||||
if let Ok(binding) = self.resolve_ident_in_module_unadjusted(
|
||||
ModuleOrUniformRoot::Module(prelude),
|
||||
ident,
|
||||
ns,
|
||||
false,
|
||||
false,
|
||||
path_span,
|
||||
) {
|
||||
result = Ok(MacroBinding::Global(binding));
|
||||
}
|
||||
}
|
||||
|
@ -893,7 +905,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
|||
pub fn finalize_current_module_macro_resolutions(&mut self) {
|
||||
let module = self.current_module;
|
||||
for &(ref path, span) in module.macro_resolutions.borrow().iter() {
|
||||
match self.resolve_path(&path, Some(MacroNS), true, span, CrateLint::No) {
|
||||
match self.resolve_path(None, &path, Some(MacroNS), true, span, CrateLint::No) {
|
||||
PathResult::NonModule(_) => {},
|
||||
PathResult::Failed(span, msg, _) => {
|
||||
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
use self::ImportDirectiveSubclass::*;
|
||||
|
||||
use {AmbiguityError, CrateLint, Module, PerNS};
|
||||
use {AmbiguityError, CrateLint, Module, ModuleOrUniformRoot, PerNS};
|
||||
use Namespace::{self, TypeNS, MacroNS};
|
||||
use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
|
||||
use Resolver;
|
||||
|
@ -85,7 +85,8 @@ pub struct ImportDirective<'a> {
|
|||
|
||||
pub parent: Module<'a>,
|
||||
pub module_path: Vec<Ident>,
|
||||
pub imported_module: Cell<Option<Module<'a>>>, // the resolution of `module_path`
|
||||
/// The resolution of `module_path`.
|
||||
pub imported_module: Cell<Option<ModuleOrUniformRoot<'a>>>,
|
||||
pub subclass: ImportDirectiveSubclass<'a>,
|
||||
pub vis: Cell<ty::Visibility>,
|
||||
pub expansion: Mark,
|
||||
|
@ -133,13 +134,38 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
|
|||
/// 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: Module<'a>,
|
||||
module: ModuleOrUniformRoot<'a>,
|
||||
ident: Ident,
|
||||
ns: Namespace,
|
||||
restricted_shadowing: bool,
|
||||
record_used: bool,
|
||||
path_span: Span)
|
||||
-> Result<&'a NameBinding<'a>, Determinacy> {
|
||||
let module = match module {
|
||||
ModuleOrUniformRoot::Module(module) => module,
|
||||
ModuleOrUniformRoot::UniformRoot(root) => {
|
||||
let crate_root = if
|
||||
root != keywords::Extern.name() &&
|
||||
(
|
||||
ident.name == keywords::Crate.name() ||
|
||||
ident.name == keywords::DollarCrate.name()
|
||||
)
|
||||
{
|
||||
self.resolve_crate_root(ident)
|
||||
} else if !ident.is_path_segment_keyword() {
|
||||
let crate_id =
|
||||
self.crate_loader.process_path_extern(ident.name, ident.span);
|
||||
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
|
||||
} 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);
|
||||
}
|
||||
};
|
||||
|
||||
self.populate_module_if_necessary(module);
|
||||
|
||||
let resolution = self.resolution(module, ident, ns)
|
||||
|
@ -260,7 +286,11 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
|
|||
if !self.is_accessible(glob_import.vis.get()) {
|
||||
continue
|
||||
}
|
||||
let module = unwrap_or!(glob_import.imported_module.get(), return Err(Undetermined));
|
||||
let module = match glob_import.imported_module.get() {
|
||||
Some(ModuleOrUniformRoot::Module(module)) => module,
|
||||
Some(ModuleOrUniformRoot::UniformRoot(_)) => continue,
|
||||
None => return Err(Undetermined),
|
||||
};
|
||||
let (orig_current_module, mut ident) = (self.current_module, ident.modern());
|
||||
match ident.span.glob_adjust(module.expansion, glob_import.span.ctxt().modern()) {
|
||||
Some(Some(def)) => self.current_module = self.macro_def_scope(def),
|
||||
|
@ -268,7 +298,12 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
|
|||
None => continue,
|
||||
};
|
||||
let result = self.resolve_ident_in_module_unadjusted(
|
||||
module, ident, ns, false, false, path_span,
|
||||
ModuleOrUniformRoot::Module(module),
|
||||
ident,
|
||||
ns,
|
||||
false,
|
||||
false,
|
||||
path_span,
|
||||
);
|
||||
self.current_module = orig_current_module;
|
||||
match result {
|
||||
|
@ -576,8 +611,14 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
// 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(&directive.module_path[..], None, false,
|
||||
directive.span, directive.crate_lint());
|
||||
let result = self.resolve_path(
|
||||
Some(ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name())),
|
||||
&directive.module_path[..],
|
||||
None,
|
||||
false,
|
||||
directive.span,
|
||||
directive.crate_lint(),
|
||||
);
|
||||
directive.vis.set(vis);
|
||||
|
||||
match result {
|
||||
|
@ -644,77 +685,9 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Span, String)> {
|
||||
self.current_module = directive.parent;
|
||||
let ImportDirective { ref module_path, span, .. } = *directive;
|
||||
let mut warn_if_binding_comes_from_local_crate = false;
|
||||
|
||||
// FIXME: Last path segment is treated specially in import resolution, so extern crate
|
||||
// mode for absolute paths needs some special support for single-segment imports.
|
||||
if module_path.len() == 1 && (module_path[0].name == keywords::CrateRoot.name() ||
|
||||
module_path[0].name == keywords::Extern.name()) {
|
||||
let is_extern = module_path[0].name == keywords::Extern.name() ||
|
||||
(self.session.features_untracked().extern_absolute_paths &&
|
||||
self.session.rust_2018());
|
||||
match directive.subclass {
|
||||
GlobImport { .. } if is_extern => {
|
||||
return Some((directive.span,
|
||||
"cannot glob-import all possible crates".to_string()));
|
||||
}
|
||||
GlobImport { .. } if self.session.features_untracked().extern_absolute_paths => {
|
||||
self.lint_path_starts_with_module(
|
||||
directive.root_id,
|
||||
directive.root_span,
|
||||
);
|
||||
}
|
||||
SingleImport { source, target, .. } => {
|
||||
let crate_root = if source.name == keywords::Crate.name() &&
|
||||
module_path[0].name != keywords::Extern.name() {
|
||||
if target.name == keywords::Crate.name() {
|
||||
return Some((directive.span,
|
||||
"crate root imports need to be explicitly named: \
|
||||
`use crate as name;`".to_string()));
|
||||
} else {
|
||||
Some(self.resolve_crate_root(source))
|
||||
}
|
||||
} else if is_extern && !source.is_path_segment_keyword() {
|
||||
let crate_id =
|
||||
self.resolver.crate_loader.process_use_extern(
|
||||
source.name,
|
||||
directive.span,
|
||||
directive.id,
|
||||
&self.resolver.definitions,
|
||||
);
|
||||
let crate_root =
|
||||
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
|
||||
self.populate_module_if_necessary(crate_root);
|
||||
Some(crate_root)
|
||||
} else {
|
||||
warn_if_binding_comes_from_local_crate = true;
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(crate_root) = crate_root {
|
||||
let binding = (crate_root, ty::Visibility::Public, directive.span,
|
||||
directive.expansion).to_name_binding(self.arenas);
|
||||
let binding = self.arenas.alloc_name_binding(NameBinding {
|
||||
kind: NameBindingKind::Import {
|
||||
binding,
|
||||
directive,
|
||||
used: Cell::new(false),
|
||||
},
|
||||
vis: directive.vis.get(),
|
||||
span: directive.span,
|
||||
expansion: directive.expansion,
|
||||
});
|
||||
let _ = self.try_define(directive.parent, target, TypeNS, binding);
|
||||
let import = self.import_map.entry(directive.id).or_default();
|
||||
import[TypeNS] = Some(PathResolution::new(binding.def()));
|
||||
return None;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let module_result = self.resolve_path(
|
||||
Some(ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name())),
|
||||
&module_path,
|
||||
None,
|
||||
true,
|
||||
|
@ -734,7 +707,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
if !self_path.is_empty() && !is_special(self_path[0]) &&
|
||||
!(self_path.len() > 1 && is_special(self_path[1])) {
|
||||
self_path[0].name = keywords::SelfValue.name();
|
||||
self_result = Some(self.resolve_path(&self_path, None, false,
|
||||
self_result = Some(self.resolve_path(None, &self_path, None, false,
|
||||
span, CrateLint::No));
|
||||
}
|
||||
return if let Some(PathResult::Module(..)) = self_result {
|
||||
|
@ -748,12 +721,27 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
|
||||
let (ident, result, type_ns_only) = match directive.subclass {
|
||||
SingleImport { source, ref result, type_ns_only, .. } => (source, result, type_ns_only),
|
||||
GlobImport { .. } if module.def_id() == directive.parent.def_id() => {
|
||||
GlobImport { is_prelude, ref max_vis } => {
|
||||
if 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();
|
||||
full_path.push(keywords::Invalid.ident());
|
||||
self.lint_if_path_starts_with_module(
|
||||
directive.crate_lint(),
|
||||
&full_path,
|
||||
directive.span,
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
if let ModuleOrUniformRoot::Module(module) = module {
|
||||
if module.def_id() == directive.parent.def_id() {
|
||||
// Importing a module into itself is not allowed.
|
||||
return Some((directive.span,
|
||||
"Cannot glob-import a module into itself.".to_string()));
|
||||
}
|
||||
GlobImport { is_prelude, ref max_vis } => {
|
||||
}
|
||||
if !is_prelude &&
|
||||
max_vis.get() != ty::Visibility::Invisible && // Allow empty globs.
|
||||
!max_vis.get().is_at_least(directive.vis.get(), &*self) {
|
||||
|
@ -770,10 +758,12 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
if let Ok(binding) = result[ns].get() {
|
||||
all_ns_err = false;
|
||||
if this.record_use(ident, ns, binding, directive.span) {
|
||||
if let ModuleOrUniformRoot::Module(module) = module {
|
||||
this.resolution(module, ident, ns).borrow_mut().binding =
|
||||
Some(this.dummy_binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if all_ns_err {
|
||||
|
@ -786,8 +776,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
});
|
||||
|
||||
return if all_ns_failed {
|
||||
let resolutions = module.resolutions.borrow();
|
||||
let names = resolutions.iter().filter_map(|(&(ref i, _), resolution)| {
|
||||
let resolutions = match module {
|
||||
ModuleOrUniformRoot::Module(module) =>
|
||||
Some(module.resolutions.borrow()),
|
||||
ModuleOrUniformRoot::UniformRoot(_) => None,
|
||||
};
|
||||
let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
|
||||
let names = resolutions.filter_map(|(&(ref i, _), resolution)| {
|
||||
if *i == ident { return None; } // Never suggest the same name
|
||||
match *resolution.borrow() {
|
||||
NameResolution { binding: Some(name_binding), .. } => {
|
||||
|
@ -813,11 +808,24 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
Some(name) => format!(". Did you mean to use `{}`?", name),
|
||||
None => "".to_owned(),
|
||||
};
|
||||
let msg = match module {
|
||||
ModuleOrUniformRoot::Module(module) => {
|
||||
let module_str = module_to_string(module);
|
||||
let msg = if let Some(module_str) = module_str {
|
||||
if let Some(module_str) = module_str {
|
||||
format!("no `{}` in `{}`{}", ident, module_str, lev_suggestion)
|
||||
} else {
|
||||
format!("no `{}` in the root{}", ident, lev_suggestion)
|
||||
}
|
||||
}
|
||||
ModuleOrUniformRoot::UniformRoot(_) => {
|
||||
if !ident.is_path_segment_keyword() {
|
||||
format!("no `{}` external crate{}", ident, lev_suggestion)
|
||||
} else {
|
||||
// HACK(eddyb) this shows up for `self` & `super`, which
|
||||
// should work instead - for now keep the same error message.
|
||||
format!("no `{}` in the root{}", ident, lev_suggestion)
|
||||
}
|
||||
}
|
||||
};
|
||||
Some((span, msg))
|
||||
} else {
|
||||
|
@ -868,26 +876,20 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
}
|
||||
}
|
||||
|
||||
if warn_if_binding_comes_from_local_crate {
|
||||
let mut warned = false;
|
||||
if 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();
|
||||
full_path.push(ident);
|
||||
self.per_ns(|this, ns| {
|
||||
let binding = match result[ns].get().ok() {
|
||||
Some(b) => b,
|
||||
None => return
|
||||
};
|
||||
if let NameBindingKind::Import { directive: d, .. } = binding.kind {
|
||||
if let ImportDirectiveSubclass::ExternCrate(..) = d.subclass {
|
||||
return
|
||||
}
|
||||
}
|
||||
if warned {
|
||||
return
|
||||
}
|
||||
warned = true;
|
||||
this.lint_path_starts_with_module(
|
||||
directive.root_id,
|
||||
directive.root_span,
|
||||
if let Ok(binding) = result[ns].get() {
|
||||
this.lint_if_path_starts_with_module(
|
||||
directive.crate_lint(),
|
||||
&full_path,
|
||||
directive.span,
|
||||
Some(binding),
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -904,7 +906,15 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
}
|
||||
|
||||
fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) {
|
||||
let module = directive.imported_module.get().unwrap();
|
||||
let module = match directive.imported_module.get().unwrap() {
|
||||
ModuleOrUniformRoot::Module(module) => module,
|
||||
ModuleOrUniformRoot::UniformRoot(_) => {
|
||||
self.session.span_err(directive.span,
|
||||
"cannot glob-import all possible crates");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
self.populate_module_if_necessary(module);
|
||||
|
||||
if let Some(Def::Trait(_)) = module.def() {
|
||||
|
@ -1026,8 +1036,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
|||
};
|
||||
let mut err = self.session.struct_span_err(binding.span, &msg);
|
||||
|
||||
let imported_module = directive.imported_module.get()
|
||||
.expect("module should exist");
|
||||
let imported_module = match directive.imported_module.get() {
|
||||
Some(ModuleOrUniformRoot::Module(module)) => module,
|
||||
_ => bug!("module should exist"),
|
||||
};
|
||||
let resolutions = imported_module.parent.expect("parent should exist")
|
||||
.resolutions.borrow();
|
||||
let enum_path_segment_index = directive.module_path.len() - 1;
|
||||
|
|
|
@ -101,7 +101,7 @@ impl Path {
|
|||
// or starts with something like `self`/`super`/`$crate`/etc.
|
||||
pub fn make_root(&self) -> Option<PathSegment> {
|
||||
if let Some(ident) = self.segments.get(0).map(|seg| seg.ident) {
|
||||
if ident.is_path_segment_keyword() && ident.name != keywords::Crate.name() {
|
||||
if ident.is_path_segment_keyword() {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
|
||||
macro_rules! m {
|
||||
() => {
|
||||
// Avoid having more than one `$crate`-named item in the same module,
|
||||
// as even though they error, they still parse as `$crate` and conflict.
|
||||
mod foo {
|
||||
struct $crate {} //~ ERROR expected identifier, found reserved identifier `$crate`
|
||||
}
|
||||
|
||||
use $crate; // OK
|
||||
//~^ WARN `$crate` may not be imported
|
||||
|
|
|
@ -9,15 +9,14 @@
|
|||
// except according to those terms.
|
||||
|
||||
// aux-build:import_crate_var.rs
|
||||
// error-pattern: `$crate` may not be imported
|
||||
// error-pattern: `use $crate;` was erroneously allowed and will become a hard error
|
||||
// error-pattern: compilation successful
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[macro_use] extern crate import_crate_var;
|
||||
|
||||
#[rustc_error]
|
||||
fn main() {
|
||||
fn main() { //~ ERROR compilation successful
|
||||
m!();
|
||||
//~^ WARN `$crate` may not be imported
|
||||
//~| NOTE `use $crate;` was erroneously allowed and will become a hard error
|
||||
}
|
||||
|
|
|
@ -11,5 +11,5 @@
|
|||
#![feature(extern_in_paths)]
|
||||
|
||||
fn main() {
|
||||
let extern = 0; //~ ERROR expected unit struct/variant or constant, found module `extern`
|
||||
let extern = 0; //~ ERROR cannot find unit struct/variant or constant `extern` in this scope
|
||||
}
|
||||
|
|
|
@ -11,10 +11,8 @@
|
|||
// aux-build:xcrate.rs
|
||||
// edition:2018
|
||||
|
||||
use crate; //~ ERROR unresolved import `crate`
|
||||
//~^ NOTE crate root imports need to be explicitly named: `use crate as name;`
|
||||
use *; //~ ERROR unresolved import `*`
|
||||
//~^ NOTE cannot glob-import all possible crates
|
||||
use crate; //~ ERROR crate root imports need to be explicitly named: `use crate as name;`
|
||||
use *; //~ ERROR cannot glob-import all possible crates
|
||||
|
||||
fn main() {
|
||||
let s = ::xcrate; //~ ERROR expected value, found module `xcrate`
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
|
||||
use extern; //~ ERROR unresolved import `extern`
|
||||
//~^ NOTE no `extern` in the root
|
||||
use extern::*; //~ ERROR unresolved import `extern::*`
|
||||
//~^ NOTE cannot glob-import all possible crates
|
||||
use extern::*; //~ ERROR cannot glob-import all possible crates
|
||||
|
||||
fn main() {
|
||||
let s = extern::xcrate; //~ ERROR expected value, found module `extern::xcrate`
|
||||
|
|
15
src/test/run-pass/issue-52140/auxiliary/some_crate.rs
Normal file
15
src/test/run-pass/issue-52140/auxiliary/some_crate.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub fn hello() {
|
||||
println!("Hello, world!");
|
||||
}
|
21
src/test/run-pass/issue-52140/main.rs
Normal file
21
src/test/run-pass/issue-52140/main.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:some_crate.rs
|
||||
// edition:2018
|
||||
|
||||
mod foo {
|
||||
pub use some_crate;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
::some_crate::hello();
|
||||
foo::some_crate::hello();
|
||||
}
|
15
src/test/run-pass/issue-52141/auxiliary/some_crate.rs
Normal file
15
src/test/run-pass/issue-52141/auxiliary/some_crate.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub fn hello() {
|
||||
println!("Hello, world!");
|
||||
}
|
24
src/test/run-pass/issue-52141/main.rs
Normal file
24
src/test/run-pass/issue-52141/main.rs
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:some_crate.rs
|
||||
// edition:2018
|
||||
|
||||
use some_crate as some_name;
|
||||
|
||||
mod foo {
|
||||
pub use crate::some_name::*;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
::some_crate::hello();
|
||||
some_name::hello();
|
||||
foo::hello();
|
||||
}
|
13
src/test/run-pass/issue-52705/auxiliary/png.rs
Normal file
13
src/test/run-pass/issue-52705/auxiliary/png.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub struct DecodingError;
|
22
src/test/run-pass/issue-52705/main.rs
Normal file
22
src/test/run-pass/issue-52705/main.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:png.rs
|
||||
// edition:2018
|
||||
|
||||
mod png {
|
||||
use png as png_ext;
|
||||
|
||||
fn foo() -> png_ext::DecodingError { unimplemented!() }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue