about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-10-20 20:26:24 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2018-10-24 00:14:50 +0300
commitfaefc83a7a1ca31c4f32feca4f8b0b0b99b9831b (patch)
treec648a98d9efc0643a482656434d537e29f99af62
parent0f625ac48dc3b834c35796496c600a96e053227e (diff)
downloadrust-faefc83a7a1ca31c4f32feca4f8b0b0b99b9831b.tar.gz
rust-faefc83a7a1ca31c4f32feca4f8b0b0b99b9831b.zip
Feature gate extern prelude additions from `extern crate` items
Fix rustdoc and fulldeps tests
-rw-r--r--src/librustc_resolve/lib.rs12
-rw-r--r--src/librustc_resolve/macros.rs3
-rw-r--r--src/librustc_resolve/resolve_imports.rs11
-rw-r--r--src/librustdoc/core.rs4
-rw-r--r--src/libsyntax/feature_gate.rs3
-rw-r--r--src/test/ui-fulldeps/proc-macro/extern-prelude-extern-crate-proc-macro.rs2
-rw-r--r--src/test/ui-fulldeps/resolve-error.stderr2
-rw-r--r--src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.rs39
-rw-r--r--src/test/ui/feature-gates/feature-gate-extern_crate_item_prelude.stderr67
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-cfg.rs1
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-pass.rs2
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.rs2
-rw-r--r--src/test/ui/imports/extern-prelude-extern-crate-restricted-shadowing.stderr4
13 files changed, 143 insertions, 9 deletions
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::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy};
 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 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
 
         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 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
         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 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
                 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 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
                     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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
         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 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
                             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 @@ declare_features! (
 
     // 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<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() {}
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<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`.
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;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^