提交 e4ba1d41 编写于 作者: B bors

Auto merge of #54116 - eddyb:extern-prelude, r=petrochenkov

rustc_resolve: allow only core, std, meta and --extern in Rust 2018 paths.

As per https://github.com/rust-lang/rust/issues/53166#issuecomment-419265401:
* Rust 2018 imports can no longer refer to crates not in "extern prelude"
  * `::foo` won't load a crate named `foo` unless `foo` is in the "extern prelude"
  * `extern crate foo;`, however, remains unchanged (can load arbitrary crates)
* `--extern crate_name` is added (note the lack of `=path`) as an unstable option
  * adds `crate_name` to the "extern prelude" (see above)
  * crate is searched in sysroot & library paths, just like `extern crate crate_name`.
  * `Cargo` support will be added later
* `core`, `std` and ~~`proc_macro`~~ `meta` are *always* available in the extern prelude
  * warning for interaction with `no_std` / `no_core` will be added later
  * **EDIT**: `proc_macro` was replaced by `meta`, see https://github.com/rust-lang/rust/issues/53166#issuecomment-421137230
    * note that there is no crate named `meta` being added, so `use meta::...;` will fail, we're only whitelisting it so we can start producing `uniform_paths` compatibility errors

Fixes #54006 (as the example now requires `--extern alloc`, which is unstable).
Fixes #54253 (hit during fixing RLS).

r? @petrochenkov cc @aturon @alexcrichton @Centril @joshtriplett
......@@ -12,7 +12,7 @@ version = "0.0.0"
dependencies = [
"compiler_builtins 0.0.0",
"core 0.0.0",
"rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
......@@ -433,7 +433,7 @@ dependencies = [
name = "core"
version = "0.0.0"
dependencies = [
"rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
......@@ -475,7 +475,7 @@ dependencies = [
"crossbeam-epoch 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -1444,7 +1444,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
......@@ -1644,7 +1644,7 @@ dependencies = [
[[package]]
name = "rand"
version = "0.5.4"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -1767,6 +1767,7 @@ dependencies = [
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ordslice 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"racer 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rls-analysis 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -2191,7 +2192,7 @@ version = "0.0.0"
dependencies = [
"graphviz 0.0.0",
"log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_fs_util 0.0.0",
......@@ -2627,7 +2628,7 @@ dependencies = [
"panic_abort 0.0.0",
"panic_unwind 0.0.0",
"profiler_builtins 0.0.0",
"rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_asan 0.0.0",
"rustc_lsan 0.0.0",
"rustc_msan 0.0.0",
......@@ -2794,7 +2795,7 @@ version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
......@@ -3262,7 +3263,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
"checksum racer 2.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4bc3847329b20ff5ba56c298938c179ae9911af15c9c10553f683b65164533"
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
"checksum rand 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "12397506224b2f93e6664ffc4f664b29be8208e5157d3d90b44f09b5fae470ea"
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
"checksum rayon 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80e811e76f1dbf68abf87a759083d34600017fc4e10b6bd5ad84a700f9dba4b1"
"checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
......
......@@ -275,18 +275,18 @@ pub fn should_codegen(&self) -> bool {
// DO NOT switch BTreeMap or BTreeSet out for an unsorted container type! That
// would break dependency tracking for commandline arguments.
#[derive(Clone, Hash)]
pub struct Externs(BTreeMap<String, BTreeSet<String>>);
pub struct Externs(BTreeMap<String, BTreeSet<Option<String>>>);
impl Externs {
pub fn new(data: BTreeMap<String, BTreeSet<String>>) -> Externs {
pub fn new(data: BTreeMap<String, BTreeSet<Option<String>>>) -> Externs {
Externs(data)
}
pub fn get(&self, key: &str) -> Option<&BTreeSet<String>> {
pub fn get(&self, key: &str) -> Option<&BTreeSet<Option<String>>> {
self.0.get(key)
}
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<String>> {
pub fn iter<'a>(&'a self) -> BTreeMapIter<'a, String, BTreeSet<Option<String>>> {
self.0.iter()
}
}
......@@ -2169,6 +2169,8 @@ pub fn build_session_options_and_crate_config(
let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
let test = matches.opt_present("test");
let is_unstable_enabled = nightly_options::is_unstable_enabled(matches);
prints.extend(matches.opt_strs("print").into_iter().map(|s| match &*s {
"crate-name" => PrintRequest::CrateName,
"file-names" => PrintRequest::FileNames,
......@@ -2182,15 +2184,13 @@ pub fn build_session_options_and_crate_config(
"tls-models" => PrintRequest::TlsModels,
"native-static-libs" => PrintRequest::NativeStaticLibs,
"target-spec-json" => {
if nightly_options::is_unstable_enabled(matches) {
if is_unstable_enabled {
PrintRequest::TargetSpec
} else {
early_error(
error_format,
&format!(
"the `-Z unstable-options` flag must also be passed to \
enable the target-spec-json print option"
),
"the `-Z unstable-options` flag must also be passed to \
enable the target-spec-json print option",
);
}
}
......@@ -2220,18 +2220,19 @@ pub fn build_session_options_and_crate_config(
Some(s) => s,
None => early_error(error_format, "--extern value must not be empty"),
};
let location = match parts.next() {
Some(s) => s,
None => early_error(
let location = parts.next().map(|s| s.to_string());
if location.is_none() && !is_unstable_enabled {
early_error(
error_format,
"--extern value must be of the format `foo=bar`",
),
"the `-Z unstable-options` flag must also be passed to \
enable `--extern crate_name` without `=path`",
);
};
externs
.entry(name.to_string())
.or_default()
.insert(location.to_string());
.insert(location);
}
let crate_name = matches.opt_str("crate-name");
......@@ -2687,33 +2688,33 @@ fn test_externs_tracking_hash_different_construction_order() {
v1.externs = Externs::new(mk_map(vec![
(
String::from("a"),
mk_set(vec![String::from("b"), String::from("c")]),
mk_set(vec![Some(String::from("b")), Some(String::from("c"))]),
),
(
String::from("d"),
mk_set(vec![String::from("e"), String::from("f")]),
mk_set(vec![Some(String::from("e")), Some(String::from("f"))]),
),
]));
v2.externs = Externs::new(mk_map(vec![
(
String::from("d"),
mk_set(vec![String::from("e"), String::from("f")]),
mk_set(vec![Some(String::from("e")), Some(String::from("f"))]),
),
(
String::from("a"),
mk_set(vec![String::from("b"), String::from("c")]),
mk_set(vec![Some(String::from("b")), Some(String::from("c"))]),
),
]));
v3.externs = Externs::new(mk_map(vec![
(
String::from("a"),
mk_set(vec![String::from("b"), String::from("c")]),
mk_set(vec![Some(String::from("b")), Some(String::from("c"))]),
),
(
String::from("d"),
mk_set(vec![String::from("f"), String::from("e")]),
mk_set(vec![Some(String::from("f")), Some(String::from("e"))]),
),
]));
......
......@@ -1247,7 +1247,11 @@ pub fn create_and_enter<F, R>(s: &'tcx Session,
.collect(),
hir,
def_path_hash_to_def_id,
queries: query::Queries::new(providers, on_disk_query_result_cache),
queries: query::Queries::new(
providers,
extern_providers,
on_disk_query_result_cache,
),
rcache: Lock::new(FxHashMap()),
selection_cache: traits::SelectionCache::new(),
evaluation_cache: traits::EvaluationCache::new(),
......
......@@ -692,10 +692,12 @@ pub(super) fn get_query<Q: QueryDescription<'gcx>>(
impl<$tcx> Queries<$tcx> {
pub fn new(
providers: IndexVec<CrateNum, Providers<$tcx>>,
fallback_extern_providers: Providers<$tcx>,
on_disk_cache: OnDiskCache<'tcx>,
) -> Self {
Queries {
providers,
fallback_extern_providers: Box::new(fallback_extern_providers),
on_disk_cache,
$($name: Lock::new(QueryCache::new())),*
}
......@@ -818,7 +820,13 @@ fn to_dep_node(tcx: TyCtxt<'_, $tcx, '_>, key: &Self::Key) -> DepNode {
#[inline]
fn compute(tcx: TyCtxt<'_, 'tcx, '_>, key: Self::Key) -> Self::Value {
__query_compute::$name(move || {
let provider = tcx.queries.providers[key.query_crate()].$name;
let provider = tcx.queries.providers.get(key.query_crate())
// HACK(eddyb) it's possible crates may be loaded after
// the query engine is created, and because crate loading
// is not yet integrated with the query engine, such crates
// would be be missing appropriate entries in `providers`.
.unwrap_or(&tcx.queries.fallback_extern_providers)
.$name;
provider(tcx.global_tcx(), key)
})
}
......@@ -899,6 +907,7 @@ pub(crate) struct Queries<$tcx> {
pub(crate) on_disk_cache: OnDiskCache<'tcx>,
providers: IndexVec<CrateNum, Providers<$tcx>>,
fallback_extern_providers: Box<Providers<$tcx>>,
$($(#[$attr])* $name: Lock<QueryCache<$tcx, queries::$name<$tcx>>>,)*
}
......
......@@ -100,6 +100,18 @@ enum LoadResult {
Loaded(Library),
}
enum LoadError<'a> {
LocatorError(locator::Context<'a>),
}
impl<'a> LoadError<'a> {
fn report(self) -> ! {
match self {
LoadError::LocatorError(mut locate_ctxt) => locate_ctxt.report_errs(),
}
}
}
impl<'a> CrateLoader<'a> {
pub fn new(sess: &'a Session, cstore: &'a CStore, local_crate_name: &str) -> Self {
CrateLoader {
......@@ -132,7 +144,8 @@ fn existing_match(&self, name: Symbol, hash: Option<&Svh>, kind: PathKind)
// from the strings on the command line.
let source = &self.cstore.get_crate_data(cnum).source;
if let Some(locs) = self.sess.opts.externs.get(&*name.as_str()) {
let found = locs.iter().any(|l| {
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
let found = locs.iter().filter_map(|l| l.as_ref()).any(|l| {
let l = fs::canonicalize(l).ok();
source.dylib.as_ref().map(|p| &p.0) == l.as_ref() ||
source.rlib.as_ref().map(|p| &p.0) == l.as_ref()
......@@ -267,16 +280,17 @@ fn register_crate(&mut self,
(cnum, cmeta)
}
fn resolve_crate(&mut self,
root: &Option<CratePaths>,
ident: Symbol,
name: Symbol,
hash: Option<&Svh>,
extra_filename: Option<&str>,
span: Span,
path_kind: PathKind,
mut dep_kind: DepKind)
-> (CrateNum, Lrc<cstore::CrateMetadata>) {
fn resolve_crate<'b>(
&'b mut self,
root: &'b Option<CratePaths>,
ident: Symbol,
name: Symbol,
hash: Option<&'b Svh>,
extra_filename: Option<&'b str>,
span: Span,
path_kind: PathKind,
mut dep_kind: DepKind,
) -> Result<(CrateNum, Lrc<cstore::CrateMetadata>), LoadError<'b>> {
info!("resolving crate `extern crate {} as {}`", name, ident);
let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
LoadResult::Previous(cnum)
......@@ -320,7 +334,7 @@ fn resolve_crate(&mut self,
};
self.load(&mut proc_macro_locator)
}).unwrap_or_else(|| locate_ctxt.report_errs())
}).ok_or_else(move || LoadError::LocatorError(locate_ctxt))?
};
match result {
......@@ -332,10 +346,10 @@ fn resolve_crate(&mut self,
data.dep_kind.with_lock(|data_dep_kind| {
*data_dep_kind = cmp::max(*data_dep_kind, dep_kind);
});
(cnum, data)
Ok((cnum, data))
}
LoadResult::Loaded(library) => {
self.register_crate(root, ident, span, library, dep_kind)
Ok(self.register_crate(root, ident, span, library, dep_kind))
}
}
}
......@@ -440,7 +454,7 @@ fn resolve_crate_deps(&mut self,
let (local_cnum, ..) = self.resolve_crate(
root, dep.name, dep.name, Some(&dep.hash), Some(&dep.extra_filename), span,
PathKind::Dependency, dep_kind,
);
).unwrap_or_else(|err| err.report());
local_cnum
})).collect()
}
......@@ -694,7 +708,8 @@ fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
let dep_kind = DepKind::Implicit;
let (cnum, data) =
self.resolve_crate(&None, name, name, None, None, DUMMY_SP, PathKind::Crate, dep_kind);
self.resolve_crate(&None, name, name, None, None, DUMMY_SP, PathKind::Crate, dep_kind)
.unwrap_or_else(|err| err.report());
// Sanity check the loaded crate to ensure it is indeed a panic runtime
// and the panic strategy is indeed what we thought it was.
......@@ -802,7 +817,8 @@ fn inject_sanitizer_runtime(&mut self) {
let dep_kind = DepKind::Explicit;
let (_, data) =
self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP,
PathKind::Crate, dep_kind);
PathKind::Crate, dep_kind)
.unwrap_or_else(|err| err.report());
// Sanity check the loaded crate to ensure it is indeed a sanitizer runtime
if !data.root.sanitizer_runtime {
......@@ -825,7 +841,8 @@ fn inject_profiler_runtime(&mut self) {
let dep_kind = DepKind::Implicit;
let (_, data) =
self.resolve_crate(&None, symbol, symbol, None, None, DUMMY_SP,
PathKind::Crate, dep_kind);
PathKind::Crate, dep_kind)
.unwrap_or_else(|err| err.report());
// Sanity check the loaded crate to ensure it is indeed a profiler runtime
if !data.root.profiler_runtime {
......@@ -945,7 +962,8 @@ fn inject_allocator_crate(&mut self, krate: &ast::Crate) {
None,
DUMMY_SP,
PathKind::Crate,
DepKind::Implicit);
DepKind::Implicit)
.unwrap_or_else(|err| err.report());
self.sess.injected_allocator.set(Some(cnum));
data
})
......@@ -1102,7 +1120,7 @@ pub fn process_extern_crate(
let (cnum, ..) = self.resolve_crate(
&None, item.ident.name, orig_name, None, None,
item.span, PathKind::Crate, dep_kind,
);
).unwrap_or_else(|err| err.report());
let def_id = definitions.opt_local_def_id(item.id).unwrap();
let path_len = definitions.def_path(def_id.index).data.len();
......@@ -1130,7 +1148,7 @@ pub fn process_path_extern(
) -> CrateNum {
let cnum = self.resolve_crate(
&None, name, name, None, None, span, PathKind::Crate, DepKind::Explicit
).0;
).unwrap_or_else(|err| err.report()).0;
self.update_extern_crate(
cnum,
......@@ -1146,4 +1164,28 @@ pub fn process_path_extern(
cnum
}
pub fn maybe_process_path_extern(
&mut self,
name: Symbol,
span: Span,
) -> Option<CrateNum> {
let cnum = self.resolve_crate(
&None, name, name, None, None, span, PathKind::Crate, DepKind::Explicit
).ok()?.0;
self.update_extern_crate(
cnum,
ExternCrate {
src: ExternCrateSource::Path,
span,
// to have the least priority in `update_extern_crate`
path_len: usize::max_value(),
direct: true,
},
&mut FxHashSet(),
);
Some(cnum)
}
}
......@@ -438,7 +438,12 @@ fn find_library_crate(&mut self,
if self.hash.is_none() {
self.should_match_name = false;
if let Some(s) = self.sess.opts.externs.get(&self.crate_name.as_str()) {
return self.find_commandline_library(s.iter());
// Only use `--extern crate_name=path` here, not `--extern crate_name`.
if s.iter().any(|l| l.is_some()) {
return self.find_commandline_library(
s.iter().filter_map(|l| l.as_ref()),
);
}
}
self.should_match_name = true;
}
......
......@@ -1674,13 +1674,14 @@ pub fn new(session: &'a Session,
let mut extern_prelude: FxHashSet<Name> =
session.opts.externs.iter().map(|kv| Symbol::intern(kv.0)).collect();
if !attr::contains_name(&krate.attrs, "no_core") {
if !attr::contains_name(&krate.attrs, "no_std") {
extern_prelude.insert(Symbol::intern("std"));
} else {
extern_prelude.insert(Symbol::intern("core"));
}
}
// HACK(eddyb) this ignore the `no_{core,std}` attributes.
// FIXME(eddyb) warn (elsewhere) if core/std is used with `no_{core,std}`.
// if !attr::contains_name(&krate.attrs, "no_core") {
// if !attr::contains_name(&krate.attrs, "no_std") {
extern_prelude.insert(Symbol::intern("core"));
extern_prelude.insert(Symbol::intern("std"));
extern_prelude.insert(Symbol::intern("meta"));
let mut invocations = FxHashMap();
invocations.insert(Mark::root(),
......@@ -1982,7 +1983,9 @@ fn resolve_ident_in_lexical_scope(&mut self,
"access to extern crates through prelude is experimental").emit();
}
let crate_root = self.load_extern_prelude_crate_if_needed(ident);
let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
self.populate_module_if_necessary(&crate_root);
let binding = (crate_root, ty::Visibility::Public,
ident.span, Mark::root()).to_name_binding(self.arenas);
......@@ -2010,13 +2013,6 @@ fn resolve_ident_in_lexical_scope(&mut self,
None
}
fn load_extern_prelude_crate_if_needed(&mut self, ident: Ident) -> Module<'a> {
let crate_id = self.crate_loader.process_path_extern(ident.name, ident.span);
let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
self.populate_module_if_necessary(&crate_root);
crate_root
}
fn hygienic_lexical_parent(&mut self, module: Module<'a>, span: &mut Span)
-> Option<Module<'a>> {
if !module.expansion.is_descendant_of(span.ctxt().outer()) {
......@@ -4427,15 +4423,24 @@ fn lookup_import_candidates<FilterFn>(&mut self,
if self.session.features_untracked().extern_prelude {
let extern_prelude_names = self.extern_prelude.clone();
for &krate_name in extern_prelude_names.iter() {
let krate_ident = Ident::with_empty_ctxt(krate_name);
let external_prelude_module = self.load_extern_prelude_crate_if_needed(krate_ident);
for &name in extern_prelude_names.iter() {
let ident = Ident::with_empty_ctxt(name);
match self.crate_loader.maybe_process_path_extern(name, ident.span) {
Some(crate_id) => {
let crate_root = self.get_module(DefId {
krate: crate_id,
index: CRATE_DEF_INDEX,
});
self.populate_module_if_necessary(&crate_root);
suggestions.extend(
self.lookup_import_candidates_from_module(
lookup_name, namespace, external_prelude_module, krate_ident, &filter_fn
)
);
suggestions.extend(
self.lookup_import_candidates_from_module(
lookup_name, namespace, crate_root, ident, &filter_fn
)
);
}
None => {}
}
}
}
......
......@@ -196,7 +196,11 @@ pub fn resolve_ident_in_module_unadjusted(&mut self,
}
// Fall back to resolving to an external crate.
if !(ns == TypeNS && self.extern_prelude.contains(&ident.name)) {
if !(
ns == TypeNS &&
!ident.is_path_segment_keyword() &&
self.extern_prelude.contains(&ident.name)
) {
// ... unless the crate name is not in the `extern_prelude`.
return binding;
}
......@@ -211,7 +215,11 @@ pub fn resolve_ident_in_module_unadjusted(&mut self,
)
{
self.resolve_crate_root(ident)
} else if ns == TypeNS && !ident.is_path_segment_keyword() {
} else if
ns == TypeNS &&
!ident.is_path_segment_keyword() &&
self.extern_prelude.contains(&ident.name)
{
let crate_id =
self.crate_loader.process_path_extern(ident.name, ident.span);
self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
......@@ -738,7 +746,7 @@ struct UniformPathsCanaryResults<'a> {
// Currently imports can't resolve in non-module scopes,
// we only have canaries in them for future-proofing.
if external_crate.is_none() && results.module_scope.is_none() {
return;
continue;
}
{
......@@ -753,7 +761,7 @@ struct UniformPathsCanaryResults<'a> {
let possible_resultions =
1 + all_results.filter(|&def| def != first).count();
if possible_resultions <= 1 {
return;
continue;
}
}
......
......@@ -609,16 +609,19 @@ fn acquire_input<R, F>(input: PathBuf,
/// Extracts `--extern CRATE=PATH` arguments from `matches` and
/// returns a map mapping crate names to their paths or else an
/// error message.
// FIXME(eddyb) This shouldn't be duplicated with `rustc::session`.
fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
let mut externs: BTreeMap<_, BTreeSet<_>> = BTreeMap::new();
for arg in &matches.opt_strs("extern") {
let mut parts = arg.splitn(2, '=');
let name = parts.next().ok_or("--extern value must not be empty".to_string())?;
let location = parts.next()
.ok_or("--extern value must be of the format `foo=bar`"
.to_string())?;
let location = parts.next().map(|s| s.to_string());
if location.is_none() && !nightly_options::is_unstable_enabled(matches) {
return Err("the `-Z unstable-options` flag must also be passed to \
enable `--extern crate_name` without `=path`".to_string());
}
let name = name.to_string();
externs.entry(name).or_default().insert(location.to_string());
externs.entry(name).or_default().insert(location);
}
Ok(Externs::new(externs))
}
......
......@@ -81,7 +81,7 @@
// to be used by rustc to compile tests in libtest
pub mod test {
pub use {assert_test_result, filter_tests, parse_opts, run_test, test_main, test_main_static,
Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, RunIgnored, ShouldPanic,
Bencher, DynTestFn, DynTestName, Metric, MetricMap, Options, ShouldPanic,
StaticBenchFn, StaticTestFn, StaticTestName, TestDesc, TestDescAndFn, TestName,
TestOpts, TestResult, TrFailed, TrFailedMsg, TrIgnored, TrOk};
}
......@@ -349,19 +349,12 @@ pub enum OutputFormat {
Json,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum RunIgnored {
Yes,
No,
Only,
}
#[derive(Debug)]
pub struct TestOpts {
pub list: bool,
pub filter: Option<String>,
pub filter_exact: bool,
pub run_ignored: RunIgnored,
pub run_ignored: bool,
pub run_tests: bool,
pub bench_benchmarks: bool,
pub logfile: Option<PathBuf>,
......@@ -380,7 +373,7 @@ fn new() -> TestOpts {
list: false,
filter: None,
filter_exact: false,
run_ignored: RunIgnored::No,
run_ignored: false,
run_tests: false,
bench_benchmarks: false,
logfile: None,
......@@ -399,8 +392,7 @@ fn new() -> TestOpts {
fn optgroups() -> getopts::Options {
let mut opts = getopts::Options::new();
opts.optflag("", "include-ignored", "Run ignored and not ignored tests")
.optflag("", "ignored", "Run only ignored tests")
opts.optflag("", "ignored", "Run ignored tests")
.optflag("", "test", "Run tests and not benchmarks")
.optflag("", "bench", "Run benchmarks instead of tests")
.optflag("", "list", "List all tests and benchmarks")
......@@ -499,8 +491,8 @@ fn usage(binary: &str, options: &getopts::Options) {
contain: #[should_panic(expected = "foo")].
#[ignore] - When applied to a function which is already attributed as a
test, then the test runner will ignore these tests during
normal test runs. Running with --ignored or --include-ignored will run
these tests."#,
normal test runs. Running with --ignored will run these
tests."#,
usage = options.usage(&message)
);
}
......@@ -553,21 +545,7 @@ pub fn parse_opts(args: &[String]) -> Option<OptRes> {
None
};
let include_ignored = matches.opt_present("include-ignored");
if !allow_unstable && include_ignored {
return Some(Err(
"The \"include-ignored\" flag is only accepted on the nightly compiler".into()
));
}
let run_ignored = match (include_ignored, matches.opt_present("ignored")) {
(true, true) => return Some(Err(
"the options --include-ignored and --ignored are mutually exclusive".into()
)),
(true, false) => RunIgnored::Yes,
(false, true) => RunIgnored::Only,
(false, false) => RunIgnored::No,
};
let run_ignored = matches.opt_present("ignored");
let quiet = matches.opt_present("quiet");
let exact = matches.opt_present("exact");
let list = matches.opt_present("list");
......@@ -1319,36 +1297,55 @@ fn num_cpus() -> usize {
pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescAndFn> {
let mut filtered = tests;
let matches_filter = |test: &TestDescAndFn, filter: &str| {
let test_name = test.desc.name.as_slice();
match opts.filter_exact {
true => test_name == filter,
false => test_name.contains(filter),
}
};
// Remove tests that don't match the test filter
if let Some(ref filter) = opts.filter {
filtered.retain(|test| matches_filter(test, filter));
}
filtered = match opts.filter {
None => filtered,
Some(ref filter) => filtered
.into_iter()
.filter(|test| {
if opts.filter_exact {
test.desc.name.as_slice() == &filter[..]
} else {
test.desc.name.as_slice().contains(&filter[..])
}
})
.collect(),
};
// Skip tests that match any of the skip filters
filtered.retain(|test| {
!opts.skip.iter().any(|sf| matches_filter(test, sf))
});
// maybe unignore tests
match opts.run_ignored {
RunIgnored::Yes => {
filtered.iter_mut().for_each(|test| test.desc.ignore = false);
},
RunIgnored::Only => {
filtered.retain(|test| test.desc.ignore);
filtered.iter_mut().for_each(|test| test.desc.ignore = false);
filtered = filtered
.into_iter()
.filter(|t| {
!opts.skip.iter().any(|sf| {
if opts.filter_exact {
t.desc.name.as_slice() == &sf[..]
} else {
t.desc.name.as_slice().contains(&sf[..])
}
})
})
.collect();
// Maybe pull out the ignored test and unignore them
filtered = if !opts.run_ignored {
filtered
} else {
fn filter(test: TestDescAndFn) -> Option<TestDescAndFn> {
if test.desc.ignore {
let TestDescAndFn { desc, testfn } = test;
Some(TestDescAndFn {
desc: TestDesc {
ignore: false,
..desc
},
testfn,
})
} else {
None
}
}
RunIgnored::No => {}
}
filtered.into_iter().filter_map(filter).collect()
};
// Sort the tests alphabetically
filtered.sort_by(|t1, t2| t1.desc.name.as_slice().cmp(t2.desc.name.as_slice()));
......@@ -1737,37 +1734,13 @@ pub fn run_once<F>(f: F)
#[cfg(test)]
mod tests {
use test::{filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, RunIgnored,
ShouldPanic, StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed,
TrFailedMsg, TrIgnored, TrOk};
use test::{filter_tests, parse_opts, run_test, DynTestFn, DynTestName, MetricMap, ShouldPanic,
StaticTestName, TestDesc, TestDescAndFn, TestOpts, TrFailed, TrFailedMsg,
TrIgnored, TrOk};
use std::sync::mpsc::channel;
use bench;
use Bencher;
fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
vec![
TestDescAndFn {
desc: TestDesc {
name: StaticTestName("1"),
ignore: true,
should_panic: ShouldPanic::No,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move || {})),
},
TestDescAndFn {
desc: TestDesc {
name: StaticTestName("2"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move || {})),
},
]
}
#[test]
pub fn do_not_run_ignored_tests() {
fn f() {
......@@ -1893,20 +1866,11 @@ fn parse_ignored_flag() {
"filter".to_string(),
"--ignored".to_string(),
];
let opts = parse_opts(&args).unwrap().unwrap();
assert_eq!(opts.run_ignored, RunIgnored::Only);
}
#[test]
fn parse_include_ignored_flag() {
let args = vec![
"progname".to_string(),
"filter".to_string(),
"-Zunstable-options".to_string(),
"--include-ignored".to_string(),
];
let opts = parse_opts(&args).unwrap().unwrap();
assert_eq!(opts.run_ignored, RunIgnored::Yes);
let opts = match parse_opts(&args) {
Some(Ok(o)) => o,
_ => panic!("Malformed arg in parse_ignored_flag"),
};
assert!((opts.run_ignored));
}
#[test]
......@@ -1916,9 +1880,28 @@ pub fn filter_for_ignored_option() {
let mut opts = TestOpts::new();
opts.run_tests = true;
opts.run_ignored = RunIgnored::Only;
opts.run_ignored = true;
let tests = one_ignored_one_unignored_test();
let tests = vec![
TestDescAndFn {
desc: TestDesc {
name: StaticTestName("1"),
ignore: true,
should_panic: ShouldPanic::No,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move || {})),
},
TestDescAndFn {
desc: TestDesc {
name: StaticTestName("2"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
},
testfn: DynTestFn(Box::new(move || {})),
},
];
let filtered = filter_tests(&opts, tests);
assert_eq!(filtered.len(), 1);
......@@ -1926,23 +1909,6 @@ pub fn filter_for_ignored_option() {
assert!(!filtered[0].desc.ignore);
}
#[test]
pub fn run_include_ignored_option() {
// When we "--include-ignored" tests, the ignore flag should be set to false on
// all tests and no test filtered out
let mut opts = TestOpts::new();
opts.run_tests = true;
opts.run_ignored = RunIgnored::Yes;
let tests = one_ignored_one_unignored_test();
let filtered = filter_tests(&opts, tests);
assert_eq!(filtered.len(), 2);
assert!(!filtered[0].desc.ignore);
assert!(!filtered[1].desc.ignore);
}
#[test]
pub fn exact_filter_match() {
fn tests() -> Vec<TestDescAndFn> {
......@@ -2050,9 +2016,7 @@ pub fn sort_tests() {
"test::ignored_tests_result_in_ignored".to_string(),
"test::first_free_arg_should_be_a_filter".to_string(),
"test::parse_ignored_flag".to_string(),
"test::parse_include_ignored_flag".to_string(),
"test::filter_for_ignored_option".to_string(),
"test::run_include_ignored_option".to_string(),
"test::sort_tests".to_string(),
];
let tests = {
......@@ -2083,8 +2047,6 @@ fn testfn() {}
"test::first_free_arg_should_be_a_filter".to_string(),
"test::ignored_tests_result_in_ignored".to_string(),
"test::parse_ignored_flag".to_string(),
"test::parse_include_ignored_flag".to_string(),
"test::run_include_ignored_option".to_string(),
"test::sort_tests".to_string(),
];
......
-include ../tools.mk
all: extern_absolute_paths.rs extern_in_paths.rs krate2
$(RUSTC) extern_absolute_paths.rs -Zsave-analysis --edition=2018
$(RUSTC) extern_absolute_paths.rs -Zsave-analysis --edition=2018 \
-Z unstable-options --extern krate2
cat $(TMPDIR)/save-analysis/extern_absolute_paths.json | "$(PYTHON)" validate_json.py
$(RUSTC) extern_in_paths.rs -Zsave-analysis --edition=2018
$(RUSTC) extern_in_paths.rs -Zsave-analysis --edition=2018 \
-Z unstable-options --extern krate2
cat $(TMPDIR)/save-analysis/extern_in_paths.json | "$(PYTHON)" validate_json.py
krate2: krate2.rs
......
......@@ -10,6 +10,7 @@
// edition:2018
// aux-build:issue-52489.rs
// compile-flags:--extern issue_52489
use issue_52489;
//~^ ERROR use of unstable library feature 'issue_52489_unstable'
......
error[E0658]: use of unstable library feature 'issue_52489_unstable'
--> $DIR/issue-52489.rs:14:5
--> $DIR/issue-52489.rs:15:5
|
LL | use issue_52489;
| ^^^^^^^^^^^
......
// 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.
// edition:2018
// Tests that `meta` is whitelisted, even if the crate doesn't exist
// yet (i.e. it causes a different error than `not-whitelisted.rs`).
use meta; //~ ERROR can't find crate for `meta`
fn main() {}
error[E0463]: can't find crate for `meta`
--> $DIR/meta.rs:15:5
|
LL | use meta; //~ ERROR can't find crate for `meta`
| ^^^^ can't find crate
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
......@@ -10,6 +10,6 @@
// edition:2018
use xcrate::S; //~ ERROR can't find crate for `xcrate`
use xcrate::S; //~ ERROR unresolved import `xcrate`
fn main() {}
error[E0463]: can't find crate for `xcrate`
error[E0432]: unresolved import `xcrate`
--> $DIR/non-existent-1.rs:13:5
|
LL | use xcrate::S; //~ ERROR can't find crate for `xcrate`
| ^^^^^^ can't find crate
LL | use xcrate::S; //~ ERROR unresolved import `xcrate`
| ^^^^^^ Could not find `xcrate` in `{{root}}`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
For more information about this error, try `rustc --explain E0432`.
......@@ -11,5 +11,6 @@
// edition:2018
fn main() {
let s = ::xcrate::S; //~ ERROR can't find crate for `xcrate`
let s = ::xcrate::S;
//~^ ERROR failed to resolve. Could not find `xcrate` in `{{root}}`
}
error[E0463]: can't find crate for `xcrate`
error[E0433]: failed to resolve. Could not find `xcrate` in `{{root}}`
--> $DIR/non-existent-2.rs:14:15
|
LL | let s = ::xcrate::S; //~ ERROR can't find crate for `xcrate`
| ^^^^^^ can't find crate
LL | let s = ::xcrate::S;
| ^^^^^^ Could not find `xcrate` in `{{root}}`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
For more information about this error, try `rustc --explain E0433`.
......@@ -10,6 +10,6 @@
// edition:2018
use ycrate; //~ ERROR can't find crate for `ycrate`
use ycrate; //~ ERROR unresolved import `ycrate`
fn main() {}
error[E0463]: can't find crate for `ycrate`
error[E0432]: unresolved import `ycrate`
--> $DIR/non-existent-3.rs:13:5
|
LL | use ycrate; //~ ERROR can't find crate for `ycrate`
| ^^^^^^ can't find crate
LL | use ycrate; //~ ERROR unresolved import `ycrate`
| ^^^^^^ no `ycrate` external crate
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
For more information about this error, try `rustc --explain E0432`.
// 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.
// edition:2018
// Tests that arbitrary crates (other than `core`, `std` and `meta`)
// aren't allowed without `--extern`, even if they're in the sysroot.
use alloc; //~ ERROR unresolved import `alloc`
use test; //~ ERROR unresolved import `test`
use proc_macro; //~ ERROR unresolved import `proc_macro`
fn main() {}
error[E0432]: unresolved import `alloc`
--> $DIR/not-whitelisted.rs:15:5
|
LL | use alloc; //~ ERROR unresolved import `alloc`
| ^^^^^ no `alloc` external crate
error[E0432]: unresolved import `test`
--> $DIR/not-whitelisted.rs:16:5
|
LL | use test; //~ ERROR unresolved import `test`
| ^^^^ no `test` external crate
error[E0432]: unresolved import `proc_macro`
--> $DIR/not-whitelisted.rs:17:5
|
LL | use proc_macro; //~ ERROR unresolved import `proc_macro`
| ^^^^^^^^^^ no `proc_macro` external crate
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0432`.
......@@ -9,6 +9,7 @@
// except according to those terms.
// aux-build:xcrate.rs
// compile-flags:--extern xcrate
// edition:2018
use crate; //~ ERROR crate root imports need to be explicitly named: `use crate as name;`
......
error: crate root imports need to be explicitly named: `use crate as name;`
--> $DIR/single-segment.rs:14:5
--> $DIR/single-segment.rs:15:5
|
LL | use crate; //~ ERROR crate root imports need to be explicitly named: `use crate as name;`
| ^^^^^
error: cannot glob-import all possible crates
--> $DIR/single-segment.rs:15:5
--> $DIR/single-segment.rs:16:5
|
LL | use *; //~ ERROR cannot glob-import all possible crates
| ^
error[E0423]: expected value, found module `xcrate`
--> $DIR/single-segment.rs:18:13
--> $DIR/single-segment.rs:19:13
|
LL | let s = ::xcrate; //~ ERROR expected value, found module `xcrate`
| ^^^^^^^^ not a value
......
......@@ -10,6 +10,6 @@
#![feature(extern_in_paths)]
use extern::xcrate::S; //~ ERROR can't find crate for `xcrate`
use extern::xcrate::S; //~ ERROR unresolved import `extern::xcrate`
fn main() {}
error[E0463]: can't find crate for `xcrate`
error[E0432]: unresolved import `extern::xcrate`
--> $DIR/non-existent-1.rs:13:13
|
LL | use extern::xcrate::S; //~ ERROR can't find crate for `xcrate`
| ^^^^^^ can't find crate
LL | use extern::xcrate::S; //~ ERROR unresolved import `extern::xcrate`
| ^^^^^^ Could not find `xcrate` in `extern`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
For more information about this error, try `rustc --explain E0432`.
......@@ -11,5 +11,6 @@
#![feature(extern_in_paths)]
fn main() {
let s = extern::xcrate::S; //~ ERROR can't find crate for `xcrate`
let s = extern::xcrate::S;
//~^ ERROR failed to resolve. Could not find `xcrate` in `extern`
}
error[E0463]: can't find crate for `xcrate`
error[E0433]: failed to resolve. Could not find `xcrate` in `extern`
--> $DIR/non-existent-2.rs:14:21
|
LL | let s = extern::xcrate::S; //~ ERROR can't find crate for `xcrate`
| ^^^^^^ can't find crate
LL | let s = extern::xcrate::S;
| ^^^^^^ Could not find `xcrate` in `extern`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
For more information about this error, try `rustc --explain E0433`.
......@@ -10,6 +10,6 @@
#![feature(extern_in_paths)]
use extern::ycrate; //~ ERROR can't find crate for `ycrate`
use extern::ycrate; //~ ERROR unresolved import `extern::ycrate`
fn main() {}
error[E0463]: can't find crate for `ycrate`
--> $DIR/non-existent-3.rs:13:13
error[E0432]: unresolved import `extern::ycrate`
--> $DIR/non-existent-3.rs:13:5
|
LL | use extern::ycrate; //~ ERROR can't find crate for `ycrate`
| ^^^^^^ can't find crate
LL | use extern::ycrate; //~ ERROR unresolved import `extern::ycrate`
| ^^^^^^^^^^^^^^ no `ycrate` external crate
error: aborting due to previous error
For more information about this error, try `rustc --explain E0463`.
For more information about this error, try `rustc --explain E0432`.
......@@ -9,6 +9,7 @@
// except according to those terms.
// aux-build:xcrate.rs
// compile-flags:--extern xcrate
#![feature(extern_in_paths)]
......
error: cannot glob-import all possible crates
--> $DIR/single-segment.rs:17:5
--> $DIR/single-segment.rs:18:5
|
LL | use extern::*; //~ ERROR cannot glob-import all possible crates
| ^^^^^^^^^
error[E0432]: unresolved import `extern`
--> $DIR/single-segment.rs:15:5
--> $DIR/single-segment.rs:16:5
|
LL | use extern; //~ ERROR unresolved import `extern`
| ^^^^^^ no `extern` in the root
error[E0423]: expected value, found module `extern::xcrate`
--> $DIR/single-segment.rs:20:13
--> $DIR/single-segment.rs:21:13
|
LL | let s = extern::xcrate; //~ ERROR expected value, found module `extern::xcrate`
| ^^^^^^^^^^^^^^ not a value
......
......@@ -10,6 +10,7 @@
// run-pass
// aux-build:some_crate.rs
// compile-flags:--extern some_crate
// edition:2018
mod foo {
......
......@@ -10,6 +10,7 @@
// run-pass
// aux-build:some_crate.rs
// compile-flags:--extern some_crate
// edition:2018
use some_crate as some_name;
......
......@@ -10,6 +10,7 @@
// run-pass
// aux-build:png2.rs
// compile-flags:--extern png2
// edition:2018
mod png {
......
......@@ -10,6 +10,7 @@
// run-pass
// aux-build:xcrate.rs
// compile-flags:--extern xcrate
// edition:2018
use xcrate::Z;
......
......@@ -10,6 +10,7 @@
// run-pass
// aux-build:xcrate.rs
// compile-flags:--extern xcrate
#![feature(extern_in_paths)]
......
// 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.
// run-pass
// edition:2018
// Tests that `core` and `std` are always available.
use core::iter;
use std::io;
// FIXME(eddyb) Add a `meta` crate to the distribution.
// use meta;
fn main() {
for _ in iter::once(()) {
io::stdout();
}
}
......@@ -37,7 +37,7 @@ fn main() {
{
// Test that having `std_io` in a module scope and a non-module
// scope is allowed, when both resolve to the same definition.
use std::io as std_io;
use ::std::io as std_io;
use std_io::stdout;
stdout();
}
......
......@@ -10,6 +10,7 @@
// aux-build:edition-lint-paths.rs
// run-rustfix
// compile-flags:--extern edition_lint_paths
// edition:2018
// The "normal case". Ideally we would remove the `extern crate` here,
......
......@@ -10,6 +10,7 @@
// aux-build:edition-lint-paths.rs
// run-rustfix
// compile-flags:--extern edition_lint_paths
// edition:2018
// The "normal case". Ideally we would remove the `extern crate` here,
......
error: unused extern crate
--> $DIR/extern-crate-idiomatic-in-2018.rs:21:1
--> $DIR/extern-crate-idiomatic-in-2018.rs:22:1
|
LL | extern crate edition_lint_paths;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
|
note: lint level defined here
--> $DIR/extern-crate-idiomatic-in-2018.rs:18:9
--> $DIR/extern-crate-idiomatic-in-2018.rs:19:9
|
LL | #![deny(rust_2018_idioms)]
| ^^^^^^^^^^^^^^^^
= note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)]
error: `extern crate` is not idiomatic in the new edition
--> $DIR/extern-crate-idiomatic-in-2018.rs:24:1
--> $DIR/extern-crate-idiomatic-in-2018.rs:25:1
|
LL | extern crate edition_lint_paths as bar;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
......
......@@ -10,6 +10,7 @@
// run-pass
// aux-build:edition-lint-paths.rs
// compile-flags:--extern edition_lint_paths
// run-rustfix
// The "normal case". Ideally we would remove the `extern crate` here,
......
......@@ -10,6 +10,7 @@
// run-pass
// aux-build:edition-lint-paths.rs
// compile-flags:--extern edition_lint_paths
// run-rustfix
// The "normal case". Ideally we would remove the `extern crate` here,
......
// 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.
// edition:2018
#![no_std]
#![crate_type = "lib"]
use alloc::vec;
//~^ ERROR unresolved import `alloc`
pub fn foo() {
let mut xs = vec![];
//~^ ERROR cannot determine resolution for the macro `vec`
xs.push(0);
}
error[E0432]: unresolved import `alloc`
--> $DIR/issue-54006.rs:16:5
|
LL | use alloc::vec;
| ^^^^^ Could not find `alloc` in `{{root}}`
error: cannot determine resolution for the macro `vec`
--> $DIR/issue-54006.rs:20:18
|
LL | let mut xs = vec![];
| ^^^
|
= note: import resolution is stuck, try simplifying macro imports
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0432`.
......@@ -12,6 +12,7 @@
// edition:2018
// compile-pass
// aux-build:remove-extern-crate.rs
// compile-flags:--extern remove_extern_crate
#![warn(rust_2018_idioms)]
......
......@@ -12,6 +12,7 @@
// edition:2018
// compile-pass
// aux-build:remove-extern-crate.rs
// compile-flags:--extern remove_extern_crate
#![warn(rust_2018_idioms)]
......
warning: unused extern crate
--> $DIR/remove-extern-crate.rs:18:1
--> $DIR/remove-extern-crate.rs:19:1
|
LL | extern crate core;
| ^^^^^^^^^^^^^^^^^^ help: remove it
|
note: lint level defined here
--> $DIR/remove-extern-crate.rs:16:9
--> $DIR/remove-extern-crate.rs:17:9
|
LL | #![warn(rust_2018_idioms)]
| ^^^^^^^^^^^^^^^^
= note: #[warn(unused_extern_crates)] implied by #[warn(rust_2018_idioms)]
warning: `extern crate` is not idiomatic in the new edition
--> $DIR/remove-extern-crate.rs:19:1
--> $DIR/remove-extern-crate.rs:20:1
|
LL | extern crate core as another_name;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
warning: `extern crate` is not idiomatic in the new edition
--> $DIR/remove-extern-crate.rs:32:5
--> $DIR/remove-extern-crate.rs:33:5
|
LL | extern crate core;
| ^^^^^^^^^^^^^^^^^^ help: convert it to a `use`
......
// 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.
// edition:2018
// Dummy import to introduce `uniform_paths` canaries.
use std;
// fn version() -> &'static str {""}
mod foo {
// Error wasn't reported, despite `version` being commented out above.
use crate::version; //~ ERROR unresolved import `crate::version`
fn bar() {
version();
}
}
fn main() {}
error[E0432]: unresolved import `crate::version`
--> $DIR/issue-54253.rs:20:9
|
LL | use crate::version; //~ ERROR unresolved import `crate::version`
| ^^^^^^^^^^^^^^ no `version` in the root
error: aborting due to previous error
For more information about this error, try `rustc --explain E0432`.
// 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.
// edition:2018
#![feature(uniform_paths)]
// Dummy import to introduce `uniform_paths` canaries.
use std;
// fn version() -> &'static str {""}
mod foo {
// Error wasn't reported, despite `version` being commented out above.
use crate::version; //~ ERROR unresolved import `crate::version`
fn bar() {
version();
}
}
fn main() {}
error[E0432]: unresolved import `crate::version`
--> $DIR/issue-54253.rs:22:9
|
LL | use crate::version; //~ ERROR unresolved import `crate::version`
| ^^^^^^^^^^^^^^ no `version` in the root
error: aborting due to previous error
For more information about this error, try `rustc --explain E0432`.
Subproject commit daa922393c7417dcee930a880c80668cda3e308a
Subproject commit 183639b70bacf457920694d78a19cefe3565e1c0
Subproject commit fa922de1e5e1f02b576b7a5aa6ded16935693ec5
Subproject commit 2b21611d38a16a775f55ea102d8f442dfc51cf6d
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册