diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index ec9a15d9f2b44..61fa78b1d5751 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -455,6 +455,9 @@ declare_features! ( // Parentheses in patterns (active, pattern_parentheses, "1.26.0", None, None), + + // `use path as _;` and `extern crate c as _;` + (active, underscore_imports, "1.26.0", Some(48216), None), ); declare_features! ( @@ -1436,9 +1439,24 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } + fn visit_use_tree(&mut self, use_tree: &'a ast::UseTree, id: NodeId, _nested: bool) { + if let ast::UseTreeKind::Simple(ident) = use_tree.kind { + if ident.name == "_" { + gate_feature_post!(&self, underscore_imports, use_tree.span, + "renaming imports with `_` is unstable"); + } + } + + visit::walk_use_tree(self, use_tree, id); + } + fn visit_item(&mut self, i: &'a ast::Item) { match i.node { ast::ItemKind::ExternCrate(_) => { + if i.ident.name == "_" { + gate_feature_post!(&self, underscore_imports, i.span, + "renaming extern crates with `_` is unstable"); + } if let Some(attr) = attr::find_by_name(&i.attrs[..], "macro_reexport") { gate_feature_post!(&self, macro_reexport, attr.span, "macros re-exports are experimental \ diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index bd0ca0e670487..2506a7f72d22b 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -7040,7 +7040,11 @@ impl<'a> Parser<'a> { fn parse_rename(&mut self) -> PResult<'a, Option> { if self.eat_keyword(keywords::As) { - self.parse_ident().map(Some) + if self.eat(&token::Underscore) { + Ok(Some(Ident::with_empty_ctxt(Symbol::gensym("_")))) + } else { + self.parse_ident().map(Some) + } } else { Ok(None) } diff --git a/src/test/ui/feature-gate-underscore-imports.rs b/src/test/ui/feature-gate-underscore-imports.rs new file mode 100644 index 0000000000000..ceb8afe124a8c --- /dev/null +++ b/src/test/ui/feature-gate-underscore-imports.rs @@ -0,0 +1,14 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate std as _; //~ ERROR renaming extern crates with `_` is unstable +use std::vec as _; //~ ERROR renaming imports with `_` is unstable + +fn main() {} diff --git a/src/test/ui/feature-gate-underscore-imports.stderr b/src/test/ui/feature-gate-underscore-imports.stderr new file mode 100644 index 0000000000000..2eea95260d5e5 --- /dev/null +++ b/src/test/ui/feature-gate-underscore-imports.stderr @@ -0,0 +1,19 @@ +error[E0658]: renaming extern crates with `_` is unstable (see issue #48216) + --> $DIR/feature-gate-underscore-imports.rs:11:1 + | +LL | extern crate std as _; //~ ERROR renaming extern crates with `_` is unstable + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(underscore_imports)] to the crate attributes to enable + +error[E0658]: renaming imports with `_` is unstable (see issue #48216) + --> $DIR/feature-gate-underscore-imports.rs:12:5 + | +LL | use std::vec as _; //~ ERROR renaming imports with `_` is unstable + | ^^^^^^^^^^^^^ + | + = help: add #![feature(underscore_imports)] to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.rs b/src/test/ui/rfc-2166-underscore-imports/basic.rs new file mode 100644 index 0000000000000..06651a71d0c00 --- /dev/null +++ b/src/test/ui/rfc-2166-underscore-imports/basic.rs @@ -0,0 +1,67 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// must-compile-successfully + +#![feature(underscore_imports)] +#![warn(unused_imports, unused_extern_crates)] + +struct S; + +mod m { + pub trait Tr1 { + fn tr1_is_in_scope(&self) {} + } + pub trait Tr2 { + fn tr2_is_in_scope(&self) {} + } + + impl Tr1 for ::S {} + impl Tr2 for ::S {} +} + +mod unused { + use m::Tr1 as _; //~ WARN unused import + use S as _; //~ WARN unused import + extern crate core as _; //~ WARN unused extern crate +} + +mod outer { + mod middle { + pub use m::Tr1 as _; + pub use m::Tr2 as _; // OK, no name conflict + struct Tr1; // OK, no name conflict + fn check() { + // Both traits are in scope + ::S.tr1_is_in_scope(); + ::S.tr2_is_in_scope(); + } + + mod inner { + // `_` imports are fetched by glob imports + use super::*; + fn check() { + // Both traits are in scope + ::S.tr1_is_in_scope(); + ::S.tr2_is_in_scope(); + } + } + } + + // `_` imports are fetched by glob imports + use self::middle::*; + fn check() { + // Both traits are in scope + ::S.tr1_is_in_scope(); + ::S.tr2_is_in_scope(); + } +} + +fn main() {} diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.stderr b/src/test/ui/rfc-2166-underscore-imports/basic.stderr new file mode 100644 index 0000000000000..4530d0fa604aa --- /dev/null +++ b/src/test/ui/rfc-2166-underscore-imports/basic.stderr @@ -0,0 +1,30 @@ +warning: unused import: `m::Tr1 as _` + --> $DIR/basic.rs:31:9 + | +LL | use m::Tr1 as _; //~ WARN unused import + | ^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/basic.rs:14:9 + | +LL | #![warn(unused_imports, unused_extern_crates)] + | ^^^^^^^^^^^^^^ + +warning: unused import: `S as _` + --> $DIR/basic.rs:32:9 + | +LL | use S as _; //~ WARN unused import + | ^^^^^^ + +warning: unused extern crate + --> $DIR/basic.rs:33:5 + | +LL | extern crate core as _; //~ WARN unused extern crate + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/basic.rs:14:25 + | +LL | #![warn(unused_imports, unused_extern_crates)] + | ^^^^^^^^^^^^^^^^^^^^ +