diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 6ac212af68e..e172f9d71ff 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1166,20 +1166,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - if !self.session.features_untracked().const_generics_defaults { - if let GenericParamKind::Const { default: Some(ref default), .. } = param.kind { - let mut err = self.err_handler().struct_span_err( - default.value.span, - "default values for const generic parameters are unstable", - ); - err.help( - "add `#![feature(const_generics_defaults)]` \ - to the crate attributes to enable", - ); - err.emit(); - break; - } - } } validate_generic_param_order( diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 6a9d6d2ed12..435f32535b6 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -619,6 +619,10 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { extended_key_value_attributes, "arbitrary expressions in key-value attributes are unstable" ); + gate_all!( + const_generics_defaults, + "default values for const generic parameters are experimental" + ); if sess.parse_sess.span_diagnostic.err_count() == 0 { // Errors for `destructuring_assignment` can get quite noisy, especially where `_` is // involved, so we only emit errors where there are no other parsing errors. diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index ff84dba4177..42a13376863 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -5,7 +5,7 @@ use rustc_ast::{ self as ast, Attribute, GenericBounds, GenericParam, GenericParamKind, WhereClause, }; use rustc_errors::PResult; -use rustc_span::symbol::kw; +use rustc_span::symbol::{kw, sym}; impl<'a> Parser<'a> { /// Parses bounds of a lifetime parameter `BOUND + BOUND + BOUND`, possibly with trailing `+`. @@ -56,8 +56,19 @@ impl<'a> Parser<'a> { self.expect(&token::Colon)?; let ty = self.parse_ty()?; - // Parse optional const generics default value. - let default = if self.eat(&token::Eq) { Some(self.parse_const_arg()?) } else { None }; + // Parse optional const generics default value, taking care of feature gating the spans + // with the unstable syntax mechanism. + let default = if self.eat(&token::Eq) { + // The gated span goes from the `=` to the end of the const argument that follows (and + // which could be a block expression). + let start = self.prev_token.span; + let const_arg = self.parse_const_arg()?; + let span = start.to(const_arg.value.span); + self.sess.gated_spans.gate(sym::const_generics_defaults, span); + Some(const_arg) + } else { + None + }; Ok(GenericParam { ident, diff --git a/src/test/ui/const-generics/min_const_generics/default_function_param.rs b/src/test/ui/const-generics/min_const_generics/default_function_param.rs index 425c5eb9e7c..5b0a42a4556 100644 --- a/src/test/ui/const-generics/min_const_generics/default_function_param.rs +++ b/src/test/ui/const-generics/min_const_generics/default_function_param.rs @@ -1,4 +1,4 @@ fn foo() {} -//~^ ERROR default values for const generic parameters are unstable +//~^ ERROR default values for const generic parameters are experimental fn main() {} diff --git a/src/test/ui/const-generics/min_const_generics/default_function_param.stderr b/src/test/ui/const-generics/min_const_generics/default_function_param.stderr index 3d2fac78d7c..31b5ad5123e 100644 --- a/src/test/ui/const-generics/min_const_generics/default_function_param.stderr +++ b/src/test/ui/const-generics/min_const_generics/default_function_param.stderr @@ -1,10 +1,12 @@ -error: default values for const generic parameters are unstable - --> $DIR/default_function_param.rs:1:28 +error[E0658]: default values for const generic parameters are experimental + --> $DIR/default_function_param.rs:1:26 | LL | fn foo() {} - | ^ + | ^^^ | + = note: see issue #44580 for more information = help: add `#![feature(const_generics_defaults)]` 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/const-generics/min_const_generics/default_trait_param.rs b/src/test/ui/const-generics/min_const_generics/default_trait_param.rs index c6d91ef97a0..14bac473ed9 100644 --- a/src/test/ui/const-generics/min_const_generics/default_trait_param.rs +++ b/src/test/ui/const-generics/min_const_generics/default_trait_param.rs @@ -1,4 +1,4 @@ trait Foo {} -//~^ ERROR default values for const generic parameters are unstable +//~^ ERROR default values for const generic parameters are experimental fn main() {} diff --git a/src/test/ui/const-generics/min_const_generics/default_trait_param.stderr b/src/test/ui/const-generics/min_const_generics/default_trait_param.stderr index b727fdd807b..5617b35ad01 100644 --- a/src/test/ui/const-generics/min_const_generics/default_trait_param.stderr +++ b/src/test/ui/const-generics/min_const_generics/default_trait_param.stderr @@ -1,10 +1,12 @@ -error: default values for const generic parameters are unstable - --> $DIR/default_trait_param.rs:1:30 +error[E0658]: default values for const generic parameters are experimental + --> $DIR/default_trait_param.rs:1:28 | LL | trait Foo {} - | ^^^^ + | ^^^^^^ | + = note: see issue #44580 for more information = help: add `#![feature(const_generics_defaults)]` 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/feature-gates/feature-gate-const_generics_defaults.rs b/src/test/ui/feature-gates/feature-gate-const_generics_defaults.rs index 90959e7a365..5b5ccc88873 100644 --- a/src/test/ui/feature-gates/feature-gate-const_generics_defaults.rs +++ b/src/test/ui/feature-gates/feature-gate-const_generics_defaults.rs @@ -1,7 +1,9 @@ +#[cfg(FALSE)] struct A; -//~^ ERROR default values for const generic parameters are unstable +//~^ ERROR default values for const generic parameters are experimental -fn foo() {} -//~^ ERROR default values for const generic parameters are unstable +#[cfg(FALSE)] +fn foo() {} +//~^ ERROR default values for const generic parameters are experimental fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-const_generics_defaults.stderr b/src/test/ui/feature-gates/feature-gate-const_generics_defaults.stderr index 00d564772d2..e2b48d793fd 100644 --- a/src/test/ui/feature-gates/feature-gate-const_generics_defaults.stderr +++ b/src/test/ui/feature-gates/feature-gate-const_generics_defaults.stderr @@ -1,18 +1,21 @@ -error: default values for const generic parameters are unstable - --> $DIR/feature-gate-const_generics_defaults.rs:1:27 +error[E0658]: default values for const generic parameters are experimental + --> $DIR/feature-gate-const_generics_defaults.rs:2:25 | LL | struct A; - | ^ + | ^^^ | + = note: see issue #44580 for more information = help: add `#![feature(const_generics_defaults)]` to the crate attributes to enable -error: default values for const generic parameters are unstable - --> $DIR/feature-gate-const_generics_defaults.rs:4:22 +error[E0658]: default values for const generic parameters are experimental + --> $DIR/feature-gate-const_generics_defaults.rs:6:22 | -LL | fn foo() {} - | ^ +LL | fn foo() {} + | ^^^^^^^ | + = note: see issue #44580 for more information = help: add `#![feature(const_generics_defaults)]` to the crate attributes to enable error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0658`.