use syntax::ext::base::SyntaxExtension;
use syntax::ext::base::Determinacy::{self, Determined, Undetermined};
use syntax::ext::base::MacroKind;
+use syntax::feature_gate::{emit_feature_err, GateIssue};
use syntax::symbol::{Symbol, keywords};
use syntax::util::lev_distance::find_best_match_for_name;
if !module.no_implicit_prelude {
if ns == TypeNS {
- if let Some(binding) = self.extern_prelude_get(ident, !record_used) {
+ if let Some(binding) = self.extern_prelude_get(ident, !record_used, false) {
return Some(LexicalScopeBinding::Item(binding));
}
}
self.name_already_seen.insert(name, span);
}
- fn extern_prelude_get(&mut self, ident: Ident, speculative: bool)
+ fn extern_prelude_get(&mut self, ident: Ident, speculative: bool, skip_feature_gate: bool)
-> Option<&'a NameBinding<'a>> {
self.extern_prelude.get(&ident.modern()).cloned().and_then(|entry| {
if let Some(binding) = entry.extern_crate_item {
+ if !speculative && !skip_feature_gate && entry.introduced_by_item &&
+ !self.session.features_untracked().extern_crate_item_prelude {
+ emit_feature_err(&self.session.parse_sess, "extern_crate_item_prelude",
+ ident.span, GateIssue::Language,
+ "use of extern prelude names introduced \
+ with `extern crate` items is unstable");
+ }
Some(binding)
} else {
let crate_id = if !speculative {
WhereToResolve::ExternPrelude => {
let mut result = Err(Determinacy::Determined);
if use_prelude {
- if let Some(binding) = self.extern_prelude_get(ident, !record_used) {
+ if let Some(binding) = self.extern_prelude_get(ident, !record_used,
+ innermost_result.is_some()) {
result = Ok((binding, Flags::PRELUDE, Flags::empty()));
}
}
ns == TypeNS &&
!ident.is_path_segment_keyword()
{
- if let Some(binding) = self.extern_prelude_get(ident, !record_used) {
+ if let Some(binding) = self.extern_prelude_get(ident, !record_used, false) {
let module = self.get_module(binding.def().def_id());
self.populate_module_if_necessary(module);
return Ok(binding);
for ((span, _, ns), results) in uniform_paths_canaries {
let name = results.name;
let external_crate = if ns == TypeNS {
- self.extern_prelude_get(Ident::with_empty_ctxt(name), true)
+ self.extern_prelude_get(Ident::with_empty_ctxt(name), true, false)
.map(|binding| binding.def())
} else {
None
Some(this.dummy_binding);
}
}
+ if record_used && ns == TypeNS {
+ if let ModuleOrUniformRoot::UniformRoot(..) = module {
+ // Make sure single-segment import is resolved non-speculatively
+ // at least once to report the feature error.
+ this.extern_prelude_get(ident, false, false);
+ }
+ }
}
});
trait_map: resolver.trait_map.clone(),
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports.clone(),
maybe_unused_extern_crates: resolver.maybe_unused_extern_crates.clone(),
- extern_prelude: resolver.extern_prelude.clone(),
+ extern_prelude: resolver.extern_prelude.iter().map(|(ident, entry)| {
+ (ident.name, entry.introduced_by_item)
+ }).collect(),
};
let analysis = ty::CrateAnalysis {
access_levels: Lrc::new(AccessLevels::default()),
// Allows `const _: TYPE = VALUE`
(active, underscore_const_names, "1.31.0", Some(54912), None),
+
+ // `extern crate foo as bar;` puts `bar` into extern prelude.
+ (active, extern_crate_item_prelude, "1.31.0", Some(54658), None),
);
declare_features! (
// compile-pass
// edition:2018
+#![feature(extern_crate_item_prelude)]
+
extern crate proc_macro;
use proc_macro::TokenStream; // OK
--> $DIR/resolve-error.rs:54:10
|
LL | #[derive(attr_proc_macra)]
- | ^^^^^^^^^^^^^^^
+ | ^^^^^^^^^^^^^^^ help: try: `attr_proc_macro`
error: cannot find macro `FooWithLongNama!` in this scope
--> $DIR/resolve-error.rs:59:5
--- /dev/null
+// edition:2018
+
+#![feature(alloc)]
+
+extern crate alloc;
+
+mod in_scope {
+ fn check() {
+ let v = alloc::vec![0];
+ //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable
+ type A = alloc::boxed::Box<u8>;
+ //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable
+ }
+}
+
+mod absolute {
+ fn check() {
+ let v = ::alloc::vec![0];
+ //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable
+ type A = ::alloc::boxed::Box<u8>;
+ //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable
+ }
+}
+
+mod import_in_scope {
+ use alloc;
+ //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable
+ use alloc::boxed;
+ //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable
+}
+
+mod import_absolute {
+ use ::alloc;
+ //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable
+ use ::alloc::boxed;
+ //~^ ERROR use of extern prelude names introduced with `extern crate` items is unstable
+}
+
+fn main() {}
--- /dev/null
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+ --> $DIR/feature-gate-extern_crate_item_prelude.rs:26:9
+ |
+LL | use alloc;
+ | ^^^^^
+ |
+ = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
+
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+ --> $DIR/feature-gate-extern_crate_item_prelude.rs:28:9
+ |
+LL | use alloc::boxed;
+ | ^^^^^
+ |
+ = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
+
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+ --> $DIR/feature-gate-extern_crate_item_prelude.rs:33:11
+ |
+LL | use ::alloc;
+ | ^^^^^
+ |
+ = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
+
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+ --> $DIR/feature-gate-extern_crate_item_prelude.rs:35:11
+ |
+LL | use ::alloc::boxed;
+ | ^^^^^
+ |
+ = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
+
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+ --> $DIR/feature-gate-extern_crate_item_prelude.rs:9:17
+ |
+LL | let v = alloc::vec![0];
+ | ^^^^^
+ |
+ = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
+
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+ --> $DIR/feature-gate-extern_crate_item_prelude.rs:11:18
+ |
+LL | type A = alloc::boxed::Box<u8>;
+ | ^^^^^
+ |
+ = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
+
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+ --> $DIR/feature-gate-extern_crate_item_prelude.rs:18:19
+ |
+LL | let v = ::alloc::vec![0];
+ | ^^^^^
+ |
+ = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
+
+error[E0658]: use of extern prelude names introduced with `extern crate` items is unstable (see issue #54658)
+ --> $DIR/feature-gate-extern_crate_item_prelude.rs:20:20
+ |
+LL | type A = ::alloc::boxed::Box<u8>;
+ | ^^^^^
+ |
+ = help: add #![feature(extern_crate_item_prelude)] to the crate attributes to enable
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
// compile-pass
// compile-flags:--cfg my_feature
+#![feature(extern_crate_item_prelude)]
#![no_std]
#[cfg(my_feature)]
// compile-pass
// aux-build:two_macros.rs
+#![feature(extern_crate_item_prelude)]
+
extern crate two_macros;
mod m {
// aux-build:two_macros.rs
+#![feature(extern_crate_item_prelude)]
+
macro_rules! define_vec {
() => {
extern crate std as Vec;
error[E0659]: `Vec` is ambiguous
- --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:13:9
+ --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:15:9
|
LL | Vec::panic!(); //~ ERROR `Vec` is ambiguous
| ^^^ ambiguous name
|
note: `Vec` could refer to the name defined here
- --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:5:9
+ --> $DIR/extern-prelude-extern-crate-restricted-shadowing.rs:7:9
|
LL | extern crate std as Vec;
| ^^^^^^^^^^^^^^^^^^^^^^^^