diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b86b92fb29e60..84122688c83d2 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -499,6 +499,9 @@ declare_features! ( // #[cfg_attr(predicate, multiple, attributes, here)] (active, cfg_attr_multi, "1.31.0", Some(54881), None), + + // Allows `const _: TYPE = VALUE` + (active, underscore_const_names, "1.31.0", Some(54912), None), ); declare_features! ( @@ -1583,6 +1586,13 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } + ast::ItemKind::Const(_,_) => { + if i.ident.name == "_" { + gate_feature_post!(&self, underscore_const_names, i.span, + "naming constants with `_` is unstable"); + } + } + ast::ItemKind::ForeignMod(ref foreign_module) => { self.check_abi(foreign_module.abi, i.span); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index b5896f37c00b8..c7089a295fc3d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6346,7 +6346,13 @@ impl<'a> Parser<'a> { } fn parse_item_const(&mut self, m: Option) -> PResult<'a, ItemInfo> { - let id = self.parse_ident()?; + let id = match self.token { + token::Ident(ident, false) if ident.name == keywords::Underscore.name() => { + self.bump(); // `_` + ident.gensym() + }, + _ => self.parse_ident()?, + }; self.expect(&token::Colon)?; let ty = self.parse_ty()?; self.expect(&token::Eq)?; diff --git a/src/test/ui/feature-gate-underscore_const_names.rs b/src/test/ui/feature-gate-underscore_const_names.rs new file mode 100644 index 0000000000000..b283e28651487 --- /dev/null +++ b/src/test/ui/feature-gate-underscore_const_names.rs @@ -0,0 +1,24 @@ +// Copyright 2012-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. +#![feature(const_let)] + +trait Trt {} +struct Str {} + +impl Trt for Str {} + +const _ : () = { + use std::marker::PhantomData; + struct ImplementsTrait(PhantomData); + let _ = ImplementsTrait::(PhantomData); + () +}; + +fn main() {} diff --git a/src/test/ui/feature-gate-underscore_const_names.stderr b/src/test/ui/feature-gate-underscore_const_names.stderr new file mode 100644 index 0000000000000..ab90ef8f11f7c --- /dev/null +++ b/src/test/ui/feature-gate-underscore_const_names.stderr @@ -0,0 +1,16 @@ +error[E0658]: naming constants with `_` is unstable (see issue #54912) + --> $DIR/feature-gate-underscore_const_names.rs:17:1 + | +LL | / const _ : () = { +LL | | use std::marker::PhantomData; +LL | | struct ImplementsTrait(PhantomData); +LL | | let _ = ImplementsTrait::(PhantomData); +LL | | () +LL | | }; + | |__^ + | + = help: add #![feature(underscore_const_names)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/underscore_const_names.rs b/src/test/ui/underscore_const_names.rs new file mode 100644 index 0000000000000..8d31fd0b1e93d --- /dev/null +++ b/src/test/ui/underscore_const_names.rs @@ -0,0 +1,43 @@ +// Copyright 2012-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. + +// compile-pass + +#![feature(const_let)] +#![feature(underscore_const_names)] + +trait Trt {} +struct Str {} +impl Trt for Str {} + +macro_rules! check_impl { + ($struct:ident,$trait:ident) => { + const _ : () = { + use std::marker::PhantomData; + struct ImplementsTrait(PhantomData); + let _ = ImplementsTrait::<$struct>(PhantomData); + () + }; + } +} + +#[deny(unused)] +const _ : () = (); + +const _ : i32 = 42; +const _ : Str = Str{}; + +check_impl!(Str, Trt); +check_impl!(Str, Trt); + +fn main() { + check_impl!(Str, Trt); + check_impl!(Str, Trt); +}