From faefc83a7a1ca31c4f32feca4f8b0b0b99b9831b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 20 Oct 2018 20:26:24 +0300 Subject: [PATCH] Feature gate extern prelude additions from `extern crate` items Fix rustdoc and fulldeps tests --- src/librustc_resolve/lib.rs | 12 +++- src/librustc_resolve/macros.rs | 3 +- src/librustc_resolve/resolve_imports.rs | 11 ++- src/librustdoc/core.rs | 4 +- src/libsyntax/feature_gate.rs | 3 + .../extern-prelude-extern-crate-proc-macro.rs | 2 + src/test/ui-fulldeps/resolve-error.stderr | 2 +- .../feature-gate-extern_crate_item_prelude.rs | 39 +++++++++++ ...ture-gate-extern_crate_item_prelude.stderr | 67 +++++++++++++++++++ .../extern-prelude-extern-crate-cfg.rs | 1 + .../extern-prelude-extern-crate-pass.rs | 2 + ...elude-extern-crate-restricted-shadowing.rs | 2 + ...e-extern-crate-restricted-shadowing.stderr | 4 +- 13 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs create mode 100644 src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 67dc749cb00..2c21067bd58 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -58,6 +58,7 @@ 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; @@ -1971,7 +1972,7 @@ fn resolve_ident_in_lexical_scope(&mut self, 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)); } } @@ -4820,10 +4821,17 @@ fn report_conflict<'b>(&mut self, 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 { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 2f7e300b8ff..3345e01a929 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -693,7 +693,8 @@ struct Flags: u8 { 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())); } } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index a3aa50fe027..6c73f1bd0f8 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -222,7 +222,7 @@ pub fn resolve_ident_in_module_unadjusted(&mut self, 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); @@ -742,7 +742,7 @@ struct UniformPathsCanaryResults<'a> { 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 @@ -1023,6 +1023,13 @@ fn finalize_import(&mut self, directive: &'b ImportDirective<'b>) -> Option<(Spa 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); + } + } } }); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 49f13df64d6..8f9c3fa4b7f 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -476,7 +476,9 @@ pub fn run_core(search_paths: SearchPaths, 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()), diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index d0f407aa924..2cd4fd92bc8 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -501,6 +501,9 @@ pub fn walk_feature_fields(&self, mut f: F) // 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! ( diff --git a/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs b/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs index 25a2a376147..e320ad97135 100644 --- a/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs +++ b/src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs @@ -1,6 +1,8 @@ // compile-pass // edition:2018 +#![feature(extern_crate_item_prelude)] + extern crate proc_macro; use proc_macro::TokenStream; // OK diff --git a/src/test/ui-fulldeps/resolve-error.stderr b/src/test/ui-fulldeps/resolve-error.stderr index 278409c688a..59ca668d485 100644 --- a/src/test/ui-fulldeps/resolve-error.stderr +++ b/src/test/ui-fulldeps/resolve-error.stderr @@ -20,7 +20,7 @@ error: cannot find derive macro `attr_proc_macra` in this scope --> $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 diff --git a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs b/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs new file mode 100644 index 00000000000..eb7c52c3d0f --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs @@ -0,0 +1,39 @@ +// 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; + //~^ 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; + //~^ 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() {} diff --git a/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr b/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr new file mode 100644 index 00000000000..4dec8a35bca --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr @@ -0,0 +1,67 @@ +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; + | ^^^^^ + | + = 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; + | ^^^^^ + | + = 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`. diff --git a/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs b/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs index 6117e5f6f3c..c48a65798b6 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-cfg.rs @@ -1,6 +1,7 @@ // compile-pass // compile-flags:--cfg my_feature +#![feature(extern_crate_item_prelude)] #![no_std] #[cfg(my_feature)] diff --git a/src/test/ui/imports/extern-prelude-extern-crate-pass.rs b/src/test/ui/imports/extern-prelude-extern-crate-pass.rs index bb4cf6ca99c..8c147dfd04a 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-pass.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-pass.rs @@ -1,6 +1,8 @@ // compile-pass // aux-build:two_macros.rs +#![feature(extern_crate_item_prelude)] + extern crate two_macros; mod m { diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs index 3eefaf1267e..732f1c4de2f 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs +++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs @@ -1,5 +1,7 @@ // aux-build:two_macros.rs +#![feature(extern_crate_item_prelude)] + macro_rules! define_vec { () => { extern crate std as Vec; diff --git a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr index 6a28d74a343..6c832e70e49 100644 --- a/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr +++ b/src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr @@ -1,11 +1,11 @@ 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; | ^^^^^^^^^^^^^^^^^^^^^^^^ -- 2.44.0