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
|
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::ImportDirective;
|
||||||
use resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport};
|
use resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport};
|
||||||
use {Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, ToNameBinding};
|
use {Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, ToNameBinding};
|
||||||
use {PerNS, Resolver, ResolverArenas};
|
use {ModuleOrUniformRoot, PerNS, Resolver, ResolverArenas};
|
||||||
use Namespace::{self, TypeNS, ValueNS, MacroNS};
|
use Namespace::{self, TypeNS, ValueNS, MacroNS};
|
||||||
use {resolve_error, resolve_struct_error, ResolutionError};
|
use {resolve_error, resolve_struct_error, ResolutionError};
|
||||||
|
|
||||||
|
@ -175,7 +175,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
ModuleKind::Def(_, name) => name,
|
ModuleKind::Def(_, name) => name,
|
||||||
ModuleKind::Block(..) => unreachable!(),
|
ModuleKind::Block(..) => unreachable!(),
|
||||||
};
|
};
|
||||||
source.name = crate_name;
|
// 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() {
|
if rename.is_none() {
|
||||||
ident.name = crate_name;
|
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 {
|
let subclass = SingleImport {
|
||||||
target: ident,
|
target: ident,
|
||||||
source,
|
source,
|
||||||
|
@ -299,7 +310,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
root_id: item.id,
|
root_id: item.id,
|
||||||
id: item.id,
|
id: item.id,
|
||||||
parent,
|
parent,
|
||||||
imported_module: Cell::new(Some(module)),
|
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
|
||||||
subclass: ImportDirectiveSubclass::ExternCrate(orig_name),
|
subclass: ImportDirectiveSubclass::ExternCrate(orig_name),
|
||||||
root_span: item.span,
|
root_span: item.span,
|
||||||
span: item.span,
|
span: item.span,
|
||||||
|
@ -701,7 +712,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
root_id: item.id,
|
root_id: item.id,
|
||||||
id: item.id,
|
id: item.id,
|
||||||
parent: graph_root,
|
parent: graph_root,
|
||||||
imported_module: Cell::new(Some(module)),
|
imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))),
|
||||||
subclass: ImportDirectiveSubclass::MacroUse,
|
subclass: ImportDirectiveSubclass::MacroUse,
|
||||||
root_span: span,
|
root_span: span,
|
||||||
span,
|
span,
|
||||||
|
@ -721,7 +732,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
} else {
|
} else {
|
||||||
for (name, span) in legacy_imports.imports {
|
for (name, span) in legacy_imports.imports {
|
||||||
let ident = Ident::with_empty_ctxt(name);
|
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 {
|
if let Ok(binding) = result {
|
||||||
let directive = macro_use_directive(span);
|
let directive = macro_use_directive(span);
|
||||||
self.potentially_unused_imports.push(directive);
|
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)]
|
#[derive(Clone, Debug)]
|
||||||
enum PathResult<'a> {
|
enum PathResult<'a> {
|
||||||
Module(Module<'a>),
|
Module(ModuleOrUniformRoot<'a>),
|
||||||
NonModule(PathResolution),
|
NonModule(PathResolution),
|
||||||
Indeterminate,
|
Indeterminate,
|
||||||
Failed(Span, String, bool /* is the error from the last segment? */),
|
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 hir::Path { ref segments, span, ref mut def } = *path;
|
||||||
let path: Vec<_> = segments.iter().map(|seg| seg.ident).collect();
|
let path: Vec<_> = segments.iter().map(|seg| seg.ident).collect();
|
||||||
// FIXME (Manishearth): Intra doc links won't get warned of epoch changes
|
// FIXME (Manishearth): Intra doc links won't get warned of epoch changes
|
||||||
match self.resolve_path(&path, Some(namespace), true, span, CrateLint::No) {
|
match self.resolve_path(None, &path, Some(namespace), true, span, CrateLint::No) {
|
||||||
PathResult::Module(module) => *def = module.def().unwrap(),
|
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
|
||||||
|
*def = module.def().unwrap(),
|
||||||
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
|
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 =>
|
||||||
*def = path_res.base_def(),
|
*def = path_res.base_def(),
|
||||||
PathResult::NonModule(..) => match self.resolve_path(
|
PathResult::NonModule(..) => match self.resolve_path(
|
||||||
|
None,
|
||||||
&path,
|
&path,
|
||||||
None,
|
None,
|
||||||
true,
|
true,
|
||||||
|
@ -1599,6 +1612,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
|
PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) |
|
||||||
PathResult::Indeterminate => unreachable!(),
|
PathResult::Indeterminate => unreachable!(),
|
||||||
PathResult::Failed(span, msg, _) => {
|
PathResult::Failed(span, msg, _) => {
|
||||||
error_callback(self, span, ResolutionError::FailedToResolve(&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(
|
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 {
|
if let Ok(binding) = item {
|
||||||
// The ident resolves to an 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;
|
let orig_current_module = self.current_module;
|
||||||
self.current_module = module; // Lexical resolutions can never be a privacy error.
|
self.current_module = module; // Lexical resolutions can never be a privacy error.
|
||||||
let result = self.resolve_ident_in_module_unadjusted(
|
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;
|
self.current_module = orig_current_module;
|
||||||
|
|
||||||
|
@ -1954,8 +1978,14 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||||
return Some(LexicalScopeBinding::Item(binding));
|
return Some(LexicalScopeBinding::Item(binding));
|
||||||
}
|
}
|
||||||
if let Some(prelude) = self.prelude {
|
if let Some(prelude) = self.prelude {
|
||||||
if let Ok(binding) = self.resolve_ident_in_module_unadjusted(prelude, ident, ns,
|
if let Ok(binding) = self.resolve_ident_in_module_unadjusted(
|
||||||
false, false, path_span) {
|
ModuleOrUniformRoot::Module(prelude),
|
||||||
|
ident,
|
||||||
|
ns,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
path_span,
|
||||||
|
) {
|
||||||
return Some(LexicalScopeBinding::Item(binding));
|
return Some(LexicalScopeBinding::Item(binding));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2013,7 +2043,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_ident_in_module(&mut self,
|
fn resolve_ident_in_module(&mut self,
|
||||||
module: Module<'a>,
|
module: ModuleOrUniformRoot<'a>,
|
||||||
mut ident: Ident,
|
mut ident: Ident,
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
record_used: bool,
|
record_used: bool,
|
||||||
|
@ -2021,8 +2051,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||||
-> Result<&'a NameBinding<'a>, Determinacy> {
|
-> Result<&'a NameBinding<'a>, Determinacy> {
|
||||||
ident.span = ident.span.modern();
|
ident.span = ident.span.modern();
|
||||||
let orig_current_module = self.current_module;
|
let orig_current_module = self.current_module;
|
||||||
if let Some(def) = ident.span.adjust(module.expansion) {
|
if let ModuleOrUniformRoot::Module(module) = module {
|
||||||
self.current_module = self.macro_def_scope(def);
|
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(
|
let result = self.resolve_ident_in_module_unadjusted(
|
||||||
module, ident, ns, false, record_used, span,
|
module, ident, ns, false, record_used, span,
|
||||||
|
@ -2410,13 +2442,16 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||||
if def != Def::Err {
|
if def != Def::Err {
|
||||||
new_id = Some(def.def_id());
|
new_id = Some(def.def_id());
|
||||||
let span = trait_ref.path.span;
|
let span = trait_ref.path.span;
|
||||||
if let PathResult::Module(module) = self.resolve_path(
|
if let PathResult::Module(ModuleOrUniformRoot::Module(module)) =
|
||||||
&path,
|
self.resolve_path(
|
||||||
None,
|
None,
|
||||||
false,
|
&path,
|
||||||
span,
|
None,
|
||||||
CrateLint::SimplePath(trait_ref.ref_id),
|
false,
|
||||||
) {
|
span,
|
||||||
|
CrateLint::SimplePath(trait_ref.ref_id),
|
||||||
|
)
|
||||||
|
{
|
||||||
new_val = Some((module, trait_ref.clone()));
|
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
|
// If there is a TraitRef in scope for an impl, then the method must be in the
|
||||||
// trait.
|
// trait.
|
||||||
if let Some((module, _)) = self.current_trait_ref {
|
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;
|
let path = &self.current_trait_ref.as_ref().unwrap().1.path;
|
||||||
resolve_error(self, span, err(ident.name, &path_names_to_string(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())
|
(String::new(), "the crate root".to_string())
|
||||||
} else {
|
} else {
|
||||||
let mod_path = &path[..path.len() - 1];
|
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) {
|
false, span, CrateLint::No) {
|
||||||
PathResult::Module(module) => module.def(),
|
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
|
||||||
|
module.def(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}.map_or(String::new(), |def| format!("{} ", def.kind_name()));
|
}.map_or(String::new(), |def| format!("{} ", def.kind_name()));
|
||||||
(mod_prefix, format!("`{}`", names_to_string(mod_path)))
|
(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(
|
let result = match self.resolve_path(
|
||||||
|
None,
|
||||||
&path,
|
&path,
|
||||||
Some(ns),
|
Some(ns),
|
||||||
true,
|
true,
|
||||||
|
@ -3326,7 +3369,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||||
crate_lint,
|
crate_lint,
|
||||||
) {
|
) {
|
||||||
PathResult::NonModule(path_res) => path_res,
|
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())
|
PathResolution::new(module.def().unwrap())
|
||||||
}
|
}
|
||||||
// In `a(::assoc_item)*` `a` cannot be a module. If `a` does resolve to a module we
|
// 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.
|
// Such behavior is required for backward compatibility.
|
||||||
// The same fallback is used when `a` resolves to nothing.
|
// 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) &&
|
if (ns == TypeNS || path.len() > 1) &&
|
||||||
self.primitive_type_table.primitive_types
|
self.primitive_type_table.primitive_types
|
||||||
.contains_key(&path[0].name) => {
|
.contains_key(&path[0].name) => {
|
||||||
let prim = self.primitive_type_table.primitive_types[&path[0].name];
|
let prim = self.primitive_type_table.primitive_types[&path[0].name];
|
||||||
PathResolution::with_unresolved_segments(Def::PrimTy(prim), path.len() - 1)
|
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) => {
|
PathResult::Failed(span, msg, false) => {
|
||||||
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
||||||
err_path_resolution()
|
err_path_resolution()
|
||||||
}
|
}
|
||||||
|
PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) |
|
||||||
PathResult::Failed(..) => return None,
|
PathResult::Failed(..) => return None,
|
||||||
PathResult::Indeterminate => bug!("indetermined path result in resolve_qpath"),
|
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() {
|
path[0].name != keywords::DollarCrate.name() {
|
||||||
let unqualified_result = {
|
let unqualified_result = {
|
||||||
match self.resolve_path(
|
match self.resolve_path(
|
||||||
|
None,
|
||||||
&[*path.last().unwrap()],
|
&[*path.last().unwrap()],
|
||||||
Some(ns),
|
Some(ns),
|
||||||
false,
|
false,
|
||||||
|
@ -3369,7 +3416,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||||
CrateLint::No,
|
CrateLint::No,
|
||||||
) {
|
) {
|
||||||
PathResult::NonModule(path_res) => path_res.base_def(),
|
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),
|
_ => return Some(result),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -3384,13 +3432,14 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||||
|
|
||||||
fn resolve_path(
|
fn resolve_path(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
base_module: Option<ModuleOrUniformRoot<'a>>,
|
||||||
path: &[Ident],
|
path: &[Ident],
|
||||||
opt_ns: Option<Namespace>, // `None` indicates a module path
|
opt_ns: Option<Namespace>, // `None` indicates a module path
|
||||||
record_used: bool,
|
record_used: bool,
|
||||||
path_span: Span,
|
path_span: Span,
|
||||||
crate_lint: CrateLint,
|
crate_lint: CrateLint,
|
||||||
) -> PathResult<'a> {
|
) -> PathResult<'a> {
|
||||||
let mut module = None;
|
let mut module = base_module;
|
||||||
let mut allow_super = true;
|
let mut allow_super = true;
|
||||||
let mut second_binding = None;
|
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() {
|
if i == 0 && ns == TypeNS && name == keywords::SelfValue.name() {
|
||||||
let mut ctxt = ident.span.ctxt().modern();
|
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
|
continue
|
||||||
} else if allow_super && ns == TypeNS && name == keywords::Super.name() {
|
} else if allow_super && ns == TypeNS && name == keywords::Super.name() {
|
||||||
let mut ctxt = ident.span.ctxt().modern();
|
let mut ctxt = ident.span.ctxt().modern();
|
||||||
let self_module = match i {
|
let self_module_parent = match i {
|
||||||
0 => self.resolve_self(&mut ctxt, self.current_module),
|
0 => self.resolve_self(&mut ctxt, self.current_module).parent,
|
||||||
_ => module.unwrap(),
|
_ => match module {
|
||||||
|
Some(ModuleOrUniformRoot::Module(module)) => module.parent,
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
if let Some(parent) = self_module.parent {
|
if let Some(parent) = self_module_parent {
|
||||||
module = Some(self.resolve_self(&mut ctxt, parent));
|
module = Some(ModuleOrUniformRoot::Module(
|
||||||
|
self.resolve_self(&mut ctxt, parent)));
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
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);
|
return PathResult::Failed(ident.span, msg, false);
|
||||||
}
|
}
|
||||||
} else if i == 0 && ns == TypeNS && name == keywords::Extern.name() {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
allow_super = false;
|
allow_super = false;
|
||||||
|
|
||||||
if ns == TypeNS {
|
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()) ||
|
if (i == 0 && name == keywords::CrateRoot.name()) ||
|
||||||
(i == 0 && name == keywords::Crate.name()) ||
|
(i == 0 && name == keywords::Crate.name()) ||
|
||||||
(i == 0 && name == keywords::DollarCrate.name()) ||
|
(i == 0 && name == keywords::DollarCrate.name()) ||
|
||||||
(i == 1 && name == keywords::Crate.name() &&
|
(i == 1 && name == keywords::Crate.name() &&
|
||||||
path[0].name == keywords::CrateRoot.name()) {
|
path[0].name == keywords::CrateRoot.name()) {
|
||||||
// `::a::b`, `crate::a::b`, `::crate::a::b` or `$crate::a::b`
|
// `::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
|
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 def = binding.def();
|
||||||
let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(def);
|
let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(def);
|
||||||
if let Some(next_module) = binding.module() {
|
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() {
|
} else if def == Def::ToolMod && i + 1 != path.len() {
|
||||||
let def = Def::NonMacroAttr(NonMacroAttrKind::Tool);
|
let def = Def::NonMacroAttr(NonMacroAttrKind::Tool);
|
||||||
return PathResult::NonModule(PathResolution::new(def));
|
return PathResult::NonModule(PathResolution::new(def));
|
||||||
|
@ -3537,14 +3585,18 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||||
}
|
}
|
||||||
Err(Undetermined) => return PathResult::Indeterminate,
|
Err(Undetermined) => return PathResult::Indeterminate,
|
||||||
Err(Determined) => {
|
Err(Determined) => {
|
||||||
if let Some(module) = module {
|
if let Some(ModuleOrUniformRoot::Module(module)) = module {
|
||||||
if opt_ns.is_some() && !module.is_normal() {
|
if opt_ns.is_some() && !module.is_normal() {
|
||||||
return PathResult::NonModule(PathResolution::with_unresolved_segments(
|
return PathResult::NonModule(PathResolution::with_unresolved_segments(
|
||||||
module.def().unwrap(), path.len() - i
|
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 is_mod = |def| match def { Def::Mod(..) => true, _ => false };
|
||||||
let mut candidates =
|
let mut candidates =
|
||||||
self.lookup_import_candidates(name, TypeNS, is_mod);
|
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);
|
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(
|
fn lint_if_path_starts_with_module(
|
||||||
|
@ -3578,6 +3633,17 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||||
path_span: Span,
|
path_span: Span,
|
||||||
second_binding: Option<&NameBinding>,
|
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 {
|
let (diag_id, diag_span) = match crate_lint {
|
||||||
CrateLint::No => return,
|
CrateLint::No => return,
|
||||||
CrateLint::SimplePath(id) => (id, path_span),
|
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
|
let diag = lint::builtin::BuiltinLintDiagnostics
|
||||||
::AbsPathWithModule(span);
|
::AbsPathWithModule(diag_span);
|
||||||
self.session.buffer_lint_with_diagnostic(
|
self.session.buffer_lint_with_diagnostic(
|
||||||
lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
|
||||||
id, span,
|
diag_id, diag_span,
|
||||||
"absolute paths must start with `self`, `super`, \
|
"absolute paths must start with `self`, `super`, \
|
||||||
`crate`, or an external crate name in the 2018 edition",
|
`crate`, or an external crate name in the 2018 edition",
|
||||||
diag);
|
diag);
|
||||||
|
@ -3782,8 +3835,13 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||||
|
|
||||||
// Look for associated items in the current trait.
|
// Look for associated items in the current trait.
|
||||||
if let Some((module, _)) = self.current_trait_ref {
|
if let Some((module, _)) = self.current_trait_ref {
|
||||||
if let Ok(binding) =
|
if let Ok(binding) = self.resolve_ident_in_module(
|
||||||
self.resolve_ident_in_module(module, ident, ns, false, module.span) {
|
ModuleOrUniformRoot::Module(module),
|
||||||
|
ident,
|
||||||
|
ns,
|
||||||
|
false,
|
||||||
|
module.span,
|
||||||
|
) {
|
||||||
let def = binding.def();
|
let def = binding.def();
|
||||||
if filter_fn(def) {
|
if filter_fn(def) {
|
||||||
return Some(if self.has_self.contains(&def.def_id()) {
|
return Some(if self.has_self.contains(&def.def_id()) {
|
||||||
|
@ -3855,9 +3913,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||||
} else {
|
} else {
|
||||||
// Search in module.
|
// Search in module.
|
||||||
let mod_path = &path[..path.len() - 1];
|
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) {
|
false, span, CrateLint::No) {
|
||||||
add_module_candidates(module, &mut names);
|
if let ModuleOrUniformRoot::Module(module) = module {
|
||||||
|
add_module_candidates(module, &mut names);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4096,7 +4156,13 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
|
||||||
let mut found_traits = Vec::new();
|
let mut found_traits = Vec::new();
|
||||||
// Look for the current trait.
|
// Look for the current trait.
|
||||||
if let Some((module, _)) = self.current_trait_ref {
|
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();
|
let def_id = module.def_id().unwrap();
|
||||||
found_traits.push(TraitCandidate { def_id: def_id, import_id: None });
|
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() {
|
if ident.span.glob_adjust(module.expansion, binding.span.ctxt().modern()).is_none() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if self.resolve_ident_in_module_unadjusted(module, ident, ns, false, false, module.span)
|
if self.resolve_ident_in_module_unadjusted(
|
||||||
.is_ok() {
|
ModuleOrUniformRoot::Module(module),
|
||||||
|
ident,
|
||||||
|
ns,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
module.span,
|
||||||
|
).is_ok() {
|
||||||
let import_id = match binding.kind {
|
let import_id = match binding.kind {
|
||||||
NameBindingKind::Import { directive, .. } => {
|
NameBindingKind::Import { directive, .. } => {
|
||||||
self.maybe_unused_trait_imports.insert(directive.id);
|
self.maybe_unused_trait_imports.insert(directive.id);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
use {AmbiguityError, CrateLint, Resolver, ResolutionError, is_known_tool, resolve_error};
|
use {AmbiguityError, CrateLint, Resolver, ResolutionError, is_known_tool, resolve_error};
|
||||||
use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding};
|
use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding};
|
||||||
|
use ModuleOrUniformRoot;
|
||||||
use Namespace::{self, TypeNS, MacroNS};
|
use Namespace::{self, TypeNS, MacroNS};
|
||||||
use build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport};
|
use build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport};
|
||||||
use resolve_imports::ImportResolver;
|
use resolve_imports::ImportResolver;
|
||||||
|
@ -538,7 +539,8 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
return Err(Determinacy::Determined);
|
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() {
|
PathResult::NonModule(path_res) => match path_res.base_def() {
|
||||||
Def::Err => Err(Determinacy::Determined),
|
Def::Err => Err(Determinacy::Determined),
|
||||||
def @ _ => {
|
def @ _ => {
|
||||||
|
@ -655,7 +657,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
WhereToResolve::Module(module) => {
|
WhereToResolve::Module(module) => {
|
||||||
let orig_current_module = mem::replace(&mut self.current_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(
|
||||||
module, ident, ns, true, record_used, path_span,
|
ModuleOrUniformRoot::Module(module),
|
||||||
|
ident,
|
||||||
|
ns,
|
||||||
|
true,
|
||||||
|
record_used,
|
||||||
|
path_span,
|
||||||
);
|
);
|
||||||
self.current_module = orig_current_module;
|
self.current_module = orig_current_module;
|
||||||
binding.map(MacroBinding::Modern)
|
binding.map(MacroBinding::Modern)
|
||||||
|
@ -715,9 +722,14 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
let mut result = Err(Determinacy::Determined);
|
let mut result = Err(Determinacy::Determined);
|
||||||
if use_prelude {
|
if use_prelude {
|
||||||
if let Some(prelude) = self.prelude {
|
if let Some(prelude) = self.prelude {
|
||||||
if let Ok(binding) =
|
if let Ok(binding) = self.resolve_ident_in_module_unadjusted(
|
||||||
self.resolve_ident_in_module_unadjusted(prelude, ident, ns,
|
ModuleOrUniformRoot::Module(prelude),
|
||||||
false, false, path_span) {
|
ident,
|
||||||
|
ns,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
path_span,
|
||||||
|
) {
|
||||||
result = Ok(MacroBinding::Global(binding));
|
result = Ok(MacroBinding::Global(binding));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -893,7 +905,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
|
||||||
pub fn finalize_current_module_macro_resolutions(&mut self) {
|
pub fn finalize_current_module_macro_resolutions(&mut self) {
|
||||||
let module = self.current_module;
|
let module = self.current_module;
|
||||||
for &(ref path, span) in module.macro_resolutions.borrow().iter() {
|
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::NonModule(_) => {},
|
||||||
PathResult::Failed(span, msg, _) => {
|
PathResult::Failed(span, msg, _) => {
|
||||||
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
use self::ImportDirectiveSubclass::*;
|
use self::ImportDirectiveSubclass::*;
|
||||||
|
|
||||||
use {AmbiguityError, CrateLint, Module, PerNS};
|
use {AmbiguityError, CrateLint, Module, ModuleOrUniformRoot, PerNS};
|
||||||
use Namespace::{self, TypeNS, MacroNS};
|
use Namespace::{self, TypeNS, MacroNS};
|
||||||
use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
|
use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
|
||||||
use Resolver;
|
use Resolver;
|
||||||
|
@ -85,7 +85,8 @@ pub struct ImportDirective<'a> {
|
||||||
|
|
||||||
pub parent: Module<'a>,
|
pub parent: Module<'a>,
|
||||||
pub module_path: Vec<Ident>,
|
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 subclass: ImportDirectiveSubclass<'a>,
|
||||||
pub vis: Cell<ty::Visibility>,
|
pub vis: Cell<ty::Visibility>,
|
||||||
pub expansion: Mark,
|
pub expansion: Mark,
|
||||||
|
@ -133,13 +134,38 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
|
||||||
/// Attempts to resolve `ident` in namespaces `ns` of `module`.
|
/// Attempts to resolve `ident` in namespaces `ns` of `module`.
|
||||||
/// Invariant: if `record_used` is `Some`, expansion and import resolution must be complete.
|
/// Invariant: if `record_used` is `Some`, expansion and import resolution must be complete.
|
||||||
pub fn resolve_ident_in_module_unadjusted(&mut self,
|
pub fn resolve_ident_in_module_unadjusted(&mut self,
|
||||||
module: Module<'a>,
|
module: ModuleOrUniformRoot<'a>,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
ns: Namespace,
|
ns: Namespace,
|
||||||
restricted_shadowing: bool,
|
restricted_shadowing: bool,
|
||||||
record_used: bool,
|
record_used: bool,
|
||||||
path_span: Span)
|
path_span: Span)
|
||||||
-> Result<&'a NameBinding<'a>, Determinacy> {
|
-> 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);
|
self.populate_module_if_necessary(module);
|
||||||
|
|
||||||
let resolution = self.resolution(module, ident, ns)
|
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()) {
|
if !self.is_accessible(glob_import.vis.get()) {
|
||||||
continue
|
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());
|
let (orig_current_module, mut ident) = (self.current_module, ident.modern());
|
||||||
match ident.span.glob_adjust(module.expansion, glob_import.span.ctxt().modern()) {
|
match ident.span.glob_adjust(module.expansion, glob_import.span.ctxt().modern()) {
|
||||||
Some(Some(def)) => self.current_module = self.macro_def_scope(def),
|
Some(Some(def)) => self.current_module = self.macro_def_scope(def),
|
||||||
|
@ -268,7 +298,12 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
|
||||||
None => continue,
|
None => continue,
|
||||||
};
|
};
|
||||||
let result = self.resolve_ident_in_module_unadjusted(
|
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;
|
self.current_module = orig_current_module;
|
||||||
match result {
|
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
|
// For better failure detection, pretend that the import will not define any names
|
||||||
// while resolving its module path.
|
// while resolving its module path.
|
||||||
directive.vis.set(ty::Visibility::Invisible);
|
directive.vis.set(ty::Visibility::Invisible);
|
||||||
let result = self.resolve_path(&directive.module_path[..], None, false,
|
let result = self.resolve_path(
|
||||||
directive.span, directive.crate_lint());
|
Some(ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name())),
|
||||||
|
&directive.module_path[..],
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
directive.span,
|
||||||
|
directive.crate_lint(),
|
||||||
|
);
|
||||||
directive.vis.set(vis);
|
directive.vis.set(vis);
|
||||||
|
|
||||||
match result {
|
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)> {
|
fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Span, String)> {
|
||||||
self.current_module = directive.parent;
|
self.current_module = directive.parent;
|
||||||
let ImportDirective { ref module_path, span, .. } = *directive;
|
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(
|
let module_result = self.resolve_path(
|
||||||
|
Some(ModuleOrUniformRoot::UniformRoot(keywords::Invalid.name())),
|
||||||
&module_path,
|
&module_path,
|
||||||
None,
|
None,
|
||||||
true,
|
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]) &&
|
if !self_path.is_empty() && !is_special(self_path[0]) &&
|
||||||
!(self_path.len() > 1 && is_special(self_path[1])) {
|
!(self_path.len() > 1 && is_special(self_path[1])) {
|
||||||
self_path[0].name = keywords::SelfValue.name();
|
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));
|
span, CrateLint::No));
|
||||||
}
|
}
|
||||||
return if let Some(PathResult::Module(..)) = self_result {
|
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 {
|
let (ident, result, type_ns_only) = match directive.subclass {
|
||||||
SingleImport { source, ref result, type_ns_only, .. } => (source, result, type_ns_only),
|
SingleImport { source, ref result, type_ns_only, .. } => (source, result, type_ns_only),
|
||||||
GlobImport { .. } 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 } => {
|
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()));
|
||||||
|
}
|
||||||
|
}
|
||||||
if !is_prelude &&
|
if !is_prelude &&
|
||||||
max_vis.get() != ty::Visibility::Invisible && // Allow empty globs.
|
max_vis.get() != ty::Visibility::Invisible && // Allow empty globs.
|
||||||
!max_vis.get().is_at_least(directive.vis.get(), &*self) {
|
!max_vis.get().is_at_least(directive.vis.get(), &*self) {
|
||||||
|
@ -770,8 +758,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
||||||
if let Ok(binding) = result[ns].get() {
|
if let Ok(binding) = result[ns].get() {
|
||||||
all_ns_err = false;
|
all_ns_err = false;
|
||||||
if this.record_use(ident, ns, binding, directive.span) {
|
if this.record_use(ident, ns, binding, directive.span) {
|
||||||
this.resolution(module, ident, ns).borrow_mut().binding =
|
if let ModuleOrUniformRoot::Module(module) = module {
|
||||||
Some(this.dummy_binding);
|
this.resolution(module, ident, ns).borrow_mut().binding =
|
||||||
|
Some(this.dummy_binding);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -786,8 +776,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
||||||
});
|
});
|
||||||
|
|
||||||
return if all_ns_failed {
|
return if all_ns_failed {
|
||||||
let resolutions = module.resolutions.borrow();
|
let resolutions = match module {
|
||||||
let names = resolutions.iter().filter_map(|(&(ref i, _), resolution)| {
|
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
|
if *i == ident { return None; } // Never suggest the same name
|
||||||
match *resolution.borrow() {
|
match *resolution.borrow() {
|
||||||
NameResolution { binding: Some(name_binding), .. } => {
|
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),
|
Some(name) => format!(". Did you mean to use `{}`?", name),
|
||||||
None => "".to_owned(),
|
None => "".to_owned(),
|
||||||
};
|
};
|
||||||
let module_str = module_to_string(module);
|
let msg = match module {
|
||||||
let msg = if let Some(module_str) = module_str {
|
ModuleOrUniformRoot::Module(module) => {
|
||||||
format!("no `{}` in `{}`{}", ident, module_str, lev_suggestion)
|
let module_str = module_to_string(module);
|
||||||
} else {
|
if let Some(module_str) = module_str {
|
||||||
format!("no `{}` in the root{}", ident, lev_suggestion)
|
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))
|
Some((span, msg))
|
||||||
} else {
|
} else {
|
||||||
|
@ -868,26 +876,20 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if warn_if_binding_comes_from_local_crate {
|
if module_path.len() <= 1 {
|
||||||
let mut warned = false;
|
// 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| {
|
self.per_ns(|this, ns| {
|
||||||
let binding = match result[ns].get().ok() {
|
if let Ok(binding) = result[ns].get() {
|
||||||
Some(b) => b,
|
this.lint_if_path_starts_with_module(
|
||||||
None => return
|
directive.crate_lint(),
|
||||||
};
|
&full_path,
|
||||||
if let NameBindingKind::Import { directive: d, .. } = binding.kind {
|
directive.span,
|
||||||
if let ImportDirectiveSubclass::ExternCrate(..) = d.subclass {
|
Some(binding),
|
||||||
return
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if warned {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
warned = true;
|
|
||||||
this.lint_path_starts_with_module(
|
|
||||||
directive.root_id,
|
|
||||||
directive.root_span,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -904,7 +906,15 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) {
|
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);
|
self.populate_module_if_necessary(module);
|
||||||
|
|
||||||
if let Some(Def::Trait(_)) = module.def() {
|
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 mut err = self.session.struct_span_err(binding.span, &msg);
|
||||||
|
|
||||||
let imported_module = directive.imported_module.get()
|
let imported_module = match directive.imported_module.get() {
|
||||||
.expect("module should exist");
|
Some(ModuleOrUniformRoot::Module(module)) => module,
|
||||||
|
_ => bug!("module should exist"),
|
||||||
|
};
|
||||||
let resolutions = imported_module.parent.expect("parent should exist")
|
let resolutions = imported_module.parent.expect("parent should exist")
|
||||||
.resolutions.borrow();
|
.resolutions.borrow();
|
||||||
let enum_path_segment_index = directive.module_path.len() - 1;
|
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.
|
// or starts with something like `self`/`super`/`$crate`/etc.
|
||||||
pub fn make_root(&self) -> Option<PathSegment> {
|
pub fn make_root(&self) -> Option<PathSegment> {
|
||||||
if let Some(ident) = self.segments.get(0).map(|seg| seg.ident) {
|
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;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,11 @@
|
||||||
|
|
||||||
macro_rules! m {
|
macro_rules! m {
|
||||||
() => {
|
() => {
|
||||||
struct $crate {} //~ ERROR expected identifier, found reserved identifier `$crate`
|
// 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
|
use $crate; // OK
|
||||||
//~^ WARN `$crate` may not be imported
|
//~^ WARN `$crate` may not be imported
|
||||||
|
|
|
@ -9,15 +9,14 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// aux-build:import_crate_var.rs
|
// 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)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
#[macro_use] extern crate import_crate_var;
|
#[macro_use] extern crate import_crate_var;
|
||||||
|
|
||||||
#[rustc_error]
|
#[rustc_error]
|
||||||
fn main() {
|
fn main() { //~ ERROR compilation successful
|
||||||
m!();
|
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)]
|
#![feature(extern_in_paths)]
|
||||||
|
|
||||||
fn main() {
|
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
|
// aux-build:xcrate.rs
|
||||||
// edition:2018
|
// edition:2018
|
||||||
|
|
||||||
use crate; //~ ERROR unresolved import `crate`
|
use crate; //~ ERROR crate root imports need to be explicitly named: `use crate as name;`
|
||||||
//~^ NOTE crate root imports need to be explicitly named: `use crate as name;`
|
use *; //~ ERROR cannot glob-import all possible crates
|
||||||
use *; //~ ERROR unresolved import `*`
|
|
||||||
//~^ NOTE cannot glob-import all possible crates
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let s = ::xcrate; //~ ERROR expected value, found module `xcrate`
|
let s = ::xcrate; //~ ERROR expected value, found module `xcrate`
|
||||||
|
|
|
@ -14,8 +14,7 @@
|
||||||
|
|
||||||
use extern; //~ ERROR unresolved import `extern`
|
use extern; //~ ERROR unresolved import `extern`
|
||||||
//~^ NOTE no `extern` in the root
|
//~^ NOTE no `extern` in the root
|
||||||
use extern::*; //~ ERROR unresolved import `extern::*`
|
use extern::*; //~ ERROR cannot glob-import all possible crates
|
||||||
//~^ NOTE cannot glob-import all possible crates
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let s = extern::xcrate; //~ ERROR expected value, found module `extern::xcrate`
|
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