diff --git a/src/librustc_ast/ast.rs b/src/librustc_ast/ast.rs index 9337b27e5e9f0..3d26259174701 100644 --- a/src/librustc_ast/ast.rs +++ b/src/librustc_ast/ast.rs @@ -1052,6 +1052,30 @@ impl Expr { } } + /// Is this expr either `N`, or `{ N }`. + /// + /// If this is not the case, name resolution does not resolve `N` when using + /// `feature(min_const_generics)` as more complex expressions are not supported. + pub fn is_potential_trivial_const_param(&self) -> bool { + let this = if let ExprKind::Block(ref block, None) = self.kind { + if block.stmts.len() == 1 { + if let StmtKind::Expr(ref expr) = block.stmts[0].kind { expr } else { self } + } else { + self + } + } else { + self + }; + + if let ExprKind::Path(None, ref path) = this.kind { + if path.segments.len() == 1 && path.segments[0].args.is_none() { + return true; + } + } + + false + } + pub fn to_bound(&self) -> Option { match &self.kind { ExprKind::Path(None, path) => Some(GenericBound::Trait( diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index daf3e23d6a123..0e98c047c2fcf 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -776,7 +776,13 @@ fn validate_generic_param_order<'a>( span, &format!( "reorder the parameters: lifetimes, then types{}", - if sess.features_untracked().const_generics { ", then consts" } else { "" }, + if sess.features_untracked().const_generics + || sess.features_untracked().min_const_generics + { + ", then consts" + } else { + "" + }, ), ordered_params.clone(), Applicability::MachineApplicable, diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 22eaca4f071e2..8dcd445721a1e 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -526,12 +526,13 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_generic_param(&mut self, param: &'a GenericParam) { if let GenericParamKind::Const { .. } = param.kind { - gate_feature_post!( + gate_feature_fn!( &self, - const_generics, + |x: &Features| x.const_generics || x.min_const_generics, param.ident.span, + sym::min_const_generics, "const generics are unstable" - ) + ); } visit::walk_generic_param(self, param) } diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 7e42f219ce284..077f6cf3ca484 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -579,6 +579,9 @@ declare_features! ( /// Allows calling `transmute` in const fn (active, const_fn_transmute, "1.46.0", Some(53605), None), + /// The smallest useful subset of `const_generics`. + (active, min_const_generics, "1.46.0", Some(74878), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- diff --git a/src/librustc_middle/ty/context.rs b/src/librustc_middle/ty/context.rs index 6cbf5db8373a0..16f5e9a42d373 100644 --- a/src/librustc_middle/ty/context.rs +++ b/src/librustc_middle/ty/context.rs @@ -1380,7 +1380,9 @@ impl<'tcx> TyCtxt<'tcx> { /// we still evaluate them eagerly. #[inline] pub fn lazy_normalization(self) -> bool { - self.features().const_generics || self.features().lazy_normalization_consts + let features = self.features(); + // Note: We do not enable lazy normalization for `features.min_const_generics`. + features.const_generics || features.lazy_normalization_consts } #[inline] diff --git a/src/librustc_parse/parser/generics.rs b/src/librustc_parse/parser/generics.rs index 47794746126da..be72ed6dffb7c 100644 --- a/src/librustc_parse/parser/generics.rs +++ b/src/librustc_parse/parser/generics.rs @@ -54,7 +54,7 @@ impl<'a> Parser<'a> { self.expect(&token::Colon)?; let ty = self.parse_ty()?; - self.sess.gated_spans.gate(sym::const_generics, const_span.to(self.prev_token.span)); + self.sess.gated_spans.gate(sym::min_const_generics, const_span.to(self.prev_token.span)); Ok(GenericParam { ident, diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index a6b5b0ff3017a..9502be728de06 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -466,6 +466,23 @@ impl<'a> Resolver<'a> { ); err } + ResolutionError::ParamInNonTrivialAnonConst(name) => { + let mut err = self.session.struct_span_err( + span, + "generic parameters must not be used inside of non trivial constant values", + ); + err.span_label( + span, + &format!( + "non-trivial anonymous constants must not depend on the parameter `{}`", + name + ), + ); + err.help( + &format!("it is currently only allowed to use either `{0}` or `{{ {0} }}` as generic constants", name) + ); + err + } ResolutionError::SelfInTyParamDefault => { let mut err = struct_span_err!( self.session, diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index 44ff420909541..b5fc69f9f310e 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -111,7 +111,7 @@ crate enum RibKind<'a> { ItemRibKind(HasGenericParams), /// We're in a constant item. Can't refer to dynamic stuff. - ConstantItemRibKind, + ConstantItemRibKind(bool), /// We passed through a module. ModuleRibKind(Module<'a>), @@ -137,7 +137,7 @@ impl RibKind<'_> { NormalRibKind | ClosureOrAsyncRibKind | FnItemRibKind - | ConstantItemRibKind + | ConstantItemRibKind(_) | ModuleRibKind(_) | MacroDefinition(_) | ConstParamTyRibKind => false, @@ -426,7 +426,7 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { } fn visit_anon_const(&mut self, constant: &'ast AnonConst) { debug!("visit_anon_const {:?}", constant); - self.with_constant_rib(|this| { + self.with_constant_rib(constant.value.is_potential_trivial_const_param(), |this| { visit::walk_anon_const(this, constant); }); } @@ -628,7 +628,7 @@ impl<'a, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { if !check_ns(TypeNS) && check_ns(ValueNS) { // This must be equivalent to `visit_anon_const`, but we cannot call it // directly due to visitor lifetimes so we have to copy-paste some code. - self.with_constant_rib(|this| { + self.with_constant_rib(true, |this| { this.smart_resolve_path( ty.id, qself.as_ref(), @@ -829,7 +829,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { | ClosureOrAsyncRibKind | FnItemRibKind | ItemRibKind(..) - | ConstantItemRibKind + | ConstantItemRibKind(_) | ModuleRibKind(..) | ForwardTyParamBanRibKind | ConstParamTyRibKind => { @@ -948,7 +948,14 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // Only impose the restrictions of `ConstRibKind` for an // actual constant expression in a provided default. if let Some(expr) = default { - this.with_constant_rib(|this| this.visit_expr(expr)); + // We allow arbitrary const expressions inside of associated consts, + // even if they are potentially not const evaluatable. + // + // Type parameters can already be used and as associated consts are + // not used as part of the type system, this is far less surprising. + this.with_constant_rib(true, |this| { + this.visit_expr(expr) + }); } } AssocItemKind::Fn(_, _, generics, _) => { @@ -989,7 +996,9 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.with_item_rib(HasGenericParams::No, |this| { this.visit_ty(ty); if let Some(expr) = expr { - this.with_constant_rib(|this| this.visit_expr(expr)); + this.with_constant_rib(expr.is_potential_trivial_const_param(), |this| { + this.visit_expr(expr) + }); } }); } @@ -1086,11 +1095,11 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f)) } - fn with_constant_rib(&mut self, f: impl FnOnce(&mut Self)) { + fn with_constant_rib(&mut self, trivial: bool, f: impl FnOnce(&mut Self)) { debug!("with_constant_rib"); - self.with_rib(ValueNS, ConstantItemRibKind, |this| { - this.with_rib(TypeNS, ConstantItemRibKind, |this| { - this.with_label_rib(ConstantItemRibKind, f); + self.with_rib(ValueNS, ConstantItemRibKind(trivial), |this| { + this.with_rib(TypeNS, ConstantItemRibKind(trivial), |this| { + this.with_label_rib(ConstantItemRibKind(trivial), f); }) }); } @@ -1220,7 +1229,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { for item in impl_items { use crate::ResolutionError::*; match &item.kind { - AssocItemKind::Const(..) => { + AssocItemKind::Const(_default, _ty, _expr) => { debug!("resolve_implementation AssocItemKind::Const",); // If this is a trait impl, ensure the const // exists in trait @@ -1231,7 +1240,12 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { |n, s| ConstNotMemberOfTrait(n, s), ); - this.with_constant_rib(|this| { + // We allow arbitrary const expressions inside of associated consts, + // even if they are potentially not const evaluatable. + // + // Type parameters can already be used and as associated consts are + // not used as part of the type system, this is far less surprising. + this.with_constant_rib(true, |this| { visit::walk_assoc_item(this, item, AssocCtxt::Impl) }); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 234fcd789eee4..1425efcb54d1f 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -218,6 +218,10 @@ enum ResolutionError<'a> { ParamInTyOfConstParam(Symbol), /// constant values inside of type parameter defaults must not depend on generic parameters. ParamInAnonConstInTyDefault(Symbol), + /// generic parameters must not be used inside of non trivial constant values. + /// + /// This error is only emitted when using `min_const_generics`. + ParamInNonTrivialAnonConst(Symbol), /// Error E0735: type parameters with a default cannot use `Self` SelfInTyParamDefault, /// Error E0767: use of unreachable label @@ -2507,7 +2511,7 @@ impl<'a> Resolver<'a> { res_err = Some(CannotCaptureDynamicEnvironmentInFnItem); } } - ConstantItemRibKind => { + ConstantItemRibKind(_) => { // Still doesn't deal with upvars if record_used { self.report_error(span, AttemptToUseNonConstantValueInConstant); @@ -2546,7 +2550,18 @@ impl<'a> Resolver<'a> { in_ty_param_default = true; continue; } - ConstantItemRibKind => { + ConstantItemRibKind(trivial) => { + // HACK(min_const_generics): We currently only allow `N` or `{ N }`. + if !trivial && self.session.features_untracked().min_const_generics { + if record_used { + self.report_error( + span, + ResolutionError::ParamInNonTrivialAnonConst(rib_ident.name), + ); + } + return Res::Err; + } + if in_ty_param_default { if record_used { self.report_error( @@ -2612,7 +2627,18 @@ impl<'a> Resolver<'a> { in_ty_param_default = true; continue; } - ConstantItemRibKind => { + ConstantItemRibKind(trivial) => { + // HACK(min_const_generics): We currently only allow `N` or `{ N }`. + if !trivial && self.session.features_untracked().min_const_generics { + if record_used { + self.report_error( + span, + ResolutionError::ParamInNonTrivialAnonConst(rib_ident.name), + ); + } + return Res::Err; + } + if in_ty_param_default { if record_used { self.report_error( diff --git a/src/librustc_span/symbol.rs b/src/librustc_span/symbol.rs index 98776a0478237..5203bfdb3b7ce 100644 --- a/src/librustc_span/symbol.rs +++ b/src/librustc_span/symbol.rs @@ -672,6 +672,7 @@ symbols! { min_align_of, min_align_of_val, min_const_fn, + min_const_generics, min_const_unsafe_fn, min_specialization, minnumf32, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 97df065500a16..bab8db46a9d89 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1238,6 +1238,9 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { // HACK(eddyb) this provides the correct generics when // `feature(const_generics)` is enabled, so that const expressions // used with const generics, e.g. `Foo<{N+1}>`, can work at all. + // + // Note that we do not supply the parent generics when using + // `feature(min_const_generics)`. Some(parent_def_id.to_def_id()) } else { let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs index 8c9cd50a17d6a..17444c6d0ac95 100644 --- a/src/librustc_typeck/collect/type_of.rs +++ b/src/librustc_typeck/collect/type_of.rs @@ -326,21 +326,39 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { GenericParamKind::Type { default: Some(ref ty), .. } => icx.to_ty(ty), GenericParamKind::Const { ty: ref hir_ty, .. } => { let ty = icx.to_ty(hir_ty); - let err = match ty.peel_refs().kind { - ty::FnPtr(_) => Some("function pointers"), - ty::RawPtr(_) => Some("raw pointers"), - _ => None, + let err_ty_str; + let err = if tcx.features().min_const_generics { + match ty.kind { + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None, + ty::FnPtr(_) => Some("function pointers"), + ty::RawPtr(_) => Some("raw pointers"), + _ => { + err_ty_str = format!("`{}`", ty); + Some(err_ty_str.as_str()) + } + } + } else { + match ty.peel_refs().kind { + ty::FnPtr(_) => Some("function pointers"), + ty::RawPtr(_) => Some("raw pointers"), + _ => None, + } }; if let Some(unsupported_type) = err { - tcx.sess - .struct_span_err( - hir_ty.span, - &format!( - "using {} as const generic parameters is forbidden", - unsupported_type - ), - ) - .emit(); + let mut err = tcx.sess.struct_span_err( + hir_ty.span, + &format!( + "using {} as const generic parameters is forbidden", + unsupported_type + ), + ); + + if tcx.features().min_const_generics { + err.note("the only supported types are integers, `bool` and `char`") + .note("more complex types are supported with `#[feature(const_generics)]`").emit() + } else { + err.emit(); + } }; if traits::search_for_structural_match_violation(param.hir_id, param.span, tcx, ty) .is_some() diff --git a/src/test/ui/const-generics/const-param-in-trait-ungated.stderr b/src/test/ui/const-generics/const-param-in-trait-ungated.stderr index bdae6bc362c47..d53a4ac2d4c23 100644 --- a/src/test/ui/const-generics/const-param-in-trait-ungated.stderr +++ b/src/test/ui/const-generics/const-param-in-trait-ungated.stderr @@ -4,8 +4,8 @@ error[E0658]: const generics are unstable LL | trait Trait {} | ^ | - = note: see issue #44580 for more information - = help: add `#![feature(const_generics)]` to the crate attributes to enable + = note: see issue #74878 for more information + = help: add `#![feature(min_const_generics)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr index 616f0fa8f1af0..5d379ff083ca7 100644 --- a/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr +++ b/src/test/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr @@ -10,8 +10,8 @@ error[E0658]: const generics are unstable LL | struct B(PhantomData<[T; N]>); | ^ | - = note: see issue #44580 for more information - = help: add `#![feature(const_generics)]` to the crate attributes to enable + = note: see issue #74878 for more information + = help: add `#![feature(min_const_generics)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/defaults/wrong-order.stderr b/src/test/ui/const-generics/defaults/wrong-order.full.stderr similarity index 78% rename from src/test/ui/const-generics/defaults/wrong-order.stderr rename to src/test/ui/const-generics/defaults/wrong-order.full.stderr index 283f6656121c3..c51028d5b2001 100644 --- a/src/test/ui/const-generics/defaults/wrong-order.stderr +++ b/src/test/ui/const-generics/defaults/wrong-order.full.stderr @@ -1,5 +1,5 @@ error: type parameters with a default must be trailing - --> $DIR/wrong-order.rs:3:10 + --> $DIR/wrong-order.rs:5:10 | LL | struct A { | ^ @@ -7,10 +7,10 @@ LL | struct A { = note: using type defaults and const parameters in the same parameter list is currently not permitted warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/wrong-order.rs:1:12 + --> $DIR/wrong-order.rs:2:27 | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ +LL | #![cfg_attr(full, feature(const_generics))] + | ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information diff --git a/src/test/ui/const-generics/defaults/wrong-order.min.stderr b/src/test/ui/const-generics/defaults/wrong-order.min.stderr new file mode 100644 index 0000000000000..29a46367004d4 --- /dev/null +++ b/src/test/ui/const-generics/defaults/wrong-order.min.stderr @@ -0,0 +1,10 @@ +error: type parameters with a default must be trailing + --> $DIR/wrong-order.rs:5:10 + | +LL | struct A { + | ^ + | + = note: using type defaults and const parameters in the same parameter list is currently not permitted + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/defaults/wrong-order.rs b/src/test/ui/const-generics/defaults/wrong-order.rs index 7f17c6358b7b6..cb36d456f3887 100644 --- a/src/test/ui/const-generics/defaults/wrong-order.rs +++ b/src/test/ui/const-generics/defaults/wrong-order.rs @@ -1,4 +1,6 @@ -#![feature(const_generics)] //~ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete +#![cfg_attr(min, feature(min_const_generics))] struct A { //~^ ERROR type parameters with a default must be trailing diff --git a/src/test/ui/const-generics/issues/issue-56445.stderr b/src/test/ui/const-generics/issues/issue-56445.full.stderr similarity index 84% rename from src/test/ui/const-generics/issues/issue-56445.stderr rename to src/test/ui/const-generics/issues/issue-56445.full.stderr index fba638b0b2b97..d853ec5015ed2 100644 --- a/src/test/ui/const-generics/issues/issue-56445.stderr +++ b/src/test/ui/const-generics/issues/issue-56445.full.stderr @@ -1,8 +1,8 @@ warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-56445.rs:3:12 + --> $DIR/issue-56445.rs:3:27 | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ +LL | #![cfg_attr(full, feature(const_generics))] + | ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information diff --git a/src/test/ui/const-generics/issues/issue-56445.min.stderr b/src/test/ui/const-generics/issues/issue-56445.min.stderr new file mode 100644 index 0000000000000..ca35ee5b2905d --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-56445.min.stderr @@ -0,0 +1,20 @@ +error[E0771]: use of non-static lifetime `'a` in const generic + --> $DIR/issue-56445.rs:9:26 + | +LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); + | ^^ + | + = note: for more information, see issue #74052 + +error: using `&'static str` as const generic parameters is forbidden + --> $DIR/issue-56445.rs:9:25 + | +LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); + | ^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0771`. diff --git a/src/test/ui/const-generics/issues/issue-56445.rs b/src/test/ui/const-generics/issues/issue-56445.rs index 26441512e3fbd..174eb16abfc5f 100644 --- a/src/test/ui/const-generics/issues/issue-56445.rs +++ b/src/test/ui/const-generics/issues/issue-56445.rs @@ -1,12 +1,13 @@ // Regression test for https://github.com/rust-lang/rust/issues/56445#issuecomment-518402995. - -#![feature(const_generics)] -//~^ WARN: the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete +#![cfg_attr(min, feature(min_const_generics))] #![crate_type = "lib"] use std::marker::PhantomData; struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); //~^ ERROR: use of non-static lifetime `'a` in const generic +//[min]~| ERROR: using `&'static str` as const impl Bug<'_, ""> {} diff --git a/src/test/ui/const-generics/issues/issue-60263.stderr b/src/test/ui/const-generics/issues/issue-60263.stderr index 7b50c442d2f41..aeef296f38526 100644 --- a/src/test/ui/const-generics/issues/issue-60263.stderr +++ b/src/test/ui/const-generics/issues/issue-60263.stderr @@ -4,8 +4,8 @@ error[E0658]: const generics are unstable LL | struct B; | ^ | - = note: see issue #44580 for more information - = help: add `#![feature(const_generics)]` to the crate attributes to enable + = note: see issue #74878 for more information + = help: add `#![feature(min_const_generics)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/const-generics/issues/issue-61336-1.stderr b/src/test/ui/const-generics/issues/issue-60818-struct-constructors.full.stderr similarity index 67% rename from src/test/ui/const-generics/issues/issue-61336-1.stderr rename to src/test/ui/const-generics/issues/issue-60818-struct-constructors.full.stderr index b2c69d57c40b7..c03b7252a3c85 100644 --- a/src/test/ui/const-generics/issues/issue-61336-1.stderr +++ b/src/test/ui/const-generics/issues/issue-60818-struct-constructors.full.stderr @@ -1,8 +1,8 @@ warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-61336-1.rs:1:12 + --> $DIR/issue-60818-struct-constructors.rs:3:27 | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ +LL | #![cfg_attr(full, feature(const_generics))] + | ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information diff --git a/src/test/ui/const-generics/issues/issue-60818-struct-constructors.rs b/src/test/ui/const-generics/issues/issue-60818-struct-constructors.rs index 26d74ffb254ce..ae2b0520fb1c1 100644 --- a/src/test/ui/const-generics/issues/issue-60818-struct-constructors.rs +++ b/src/test/ui/const-generics/issues/issue-60818-struct-constructors.rs @@ -1,7 +1,7 @@ // check-pass - -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete +#![cfg_attr(min, feature(min_const_generics))] struct Generic; diff --git a/src/test/ui/const-generics/issues/issue-60818-struct-constructors.stderr b/src/test/ui/const-generics/issues/issue-61336-1.full.stderr similarity index 70% rename from src/test/ui/const-generics/issues/issue-60818-struct-constructors.stderr rename to src/test/ui/const-generics/issues/issue-61336-1.full.stderr index 94a2b673a51ec..f18728eabbb43 100644 --- a/src/test/ui/const-generics/issues/issue-60818-struct-constructors.stderr +++ b/src/test/ui/const-generics/issues/issue-61336-1.full.stderr @@ -1,8 +1,8 @@ warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-60818-struct-constructors.rs:3:12 + --> $DIR/issue-61336-1.rs:3:27 | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ +LL | #![cfg_attr(full, feature(const_generics))] + | ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information diff --git a/src/test/ui/const-generics/issues/issue-61336-1.rs b/src/test/ui/const-generics/issues/issue-61336-1.rs index 2135c868bbc70..201c0d039d98f 100644 --- a/src/test/ui/const-generics/issues/issue-61336-1.rs +++ b/src/test/ui/const-generics/issues/issue-61336-1.rs @@ -1,7 +1,7 @@ -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete - // build-pass +// revisions: full min +#![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete +#![cfg_attr(min, feature(min_const_generics))] fn f(x: T) -> [T; N] { [x; N] diff --git a/src/test/ui/const-generics/issues/issue-61336-2.stderr b/src/test/ui/const-generics/issues/issue-61336-2.full.stderr similarity index 83% rename from src/test/ui/const-generics/issues/issue-61336-2.stderr rename to src/test/ui/const-generics/issues/issue-61336-2.full.stderr index 5f3395223f95d..d21cd9df054c1 100644 --- a/src/test/ui/const-generics/issues/issue-61336-2.stderr +++ b/src/test/ui/const-generics/issues/issue-61336-2.full.stderr @@ -1,14 +1,14 @@ warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-61336-2.rs:1:12 + --> $DIR/issue-61336-2.rs:2:27 | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ +LL | #![cfg_attr(full, feature(const_generics))] + | ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/issue-61336-2.rs:9:5 + --> $DIR/issue-61336-2.rs:10:5 | LL | [x; { N }] | ^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` diff --git a/src/test/ui/const-generics/issues/issue-61336-2.min.stderr b/src/test/ui/const-generics/issues/issue-61336-2.min.stderr new file mode 100644 index 0000000000000..29ab7b1305e38 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-61336-2.min.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied + --> $DIR/issue-61336-2.rs:10:5 + | +LL | [x; { N }] + | ^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | + = note: the `Copy` trait is required because the repeated element will be copied +help: consider restricting type parameter `T` + | +LL | fn g(x: T) -> [T; N] { + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/issues/issue-61336-2.rs b/src/test/ui/const-generics/issues/issue-61336-2.rs index 52969056f00a5..25b9271105e24 100644 --- a/src/test/ui/const-generics/issues/issue-61336-2.rs +++ b/src/test/ui/const-generics/issues/issue-61336-2.rs @@ -1,5 +1,6 @@ -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete +#![cfg_attr(min, feature(min_const_generics))] fn f(x: T) -> [T; N] { [x; { N }] diff --git a/src/test/ui/const-generics/issues/issue-61336.full.stderr b/src/test/ui/const-generics/issues/issue-61336.full.stderr new file mode 100644 index 0000000000000..d1b5d5eb9417f --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-61336.full.stderr @@ -0,0 +1,24 @@ +warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-61336.rs:2:27 + | +LL | #![cfg_attr(full, feature(const_generics))] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #44580 for more information + +error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied + --> $DIR/issue-61336.rs:10:5 + | +LL | [x; N] + | ^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | + = note: the `Copy` trait is required because the repeated element will be copied +help: consider restricting type parameter `T` + | +LL | fn g(x: T) -> [T; N] { + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/issues/issue-61336.min.stderr b/src/test/ui/const-generics/issues/issue-61336.min.stderr new file mode 100644 index 0000000000000..bced8bbd82ff6 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-61336.min.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied + --> $DIR/issue-61336.rs:10:5 + | +LL | [x; N] + | ^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | + = note: the `Copy` trait is required because the repeated element will be copied +help: consider restricting type parameter `T` + | +LL | fn g(x: T) -> [T; N] { + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/issues/issue-61336.rs b/src/test/ui/const-generics/issues/issue-61336.rs index eb0f309762764..fb55542a1c993 100644 --- a/src/test/ui/const-generics/issues/issue-61336.rs +++ b/src/test/ui/const-generics/issues/issue-61336.rs @@ -1,5 +1,6 @@ -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete +#![cfg_attr(min, feature(min_const_generics))] fn f(x: T) -> [T; N] { [x; N] diff --git a/src/test/ui/const-generics/issues/issue-61432.stderr b/src/test/ui/const-generics/issues/issue-61422.full.stderr similarity index 70% rename from src/test/ui/const-generics/issues/issue-61432.stderr rename to src/test/ui/const-generics/issues/issue-61422.full.stderr index 1d547b1b6c98e..ac6c378295d31 100644 --- a/src/test/ui/const-generics/issues/issue-61432.stderr +++ b/src/test/ui/const-generics/issues/issue-61422.full.stderr @@ -1,8 +1,8 @@ warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-61432.rs:3:12 + --> $DIR/issue-61422.rs:3:27 | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ +LL | #![cfg_attr(full, feature(const_generics))] + | ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information diff --git a/src/test/ui/const-generics/issues/issue-61422.rs b/src/test/ui/const-generics/issues/issue-61422.rs index 7e7ef6867ed07..649f8b4255b12 100644 --- a/src/test/ui/const-generics/issues/issue-61422.rs +++ b/src/test/ui/const-generics/issues/issue-61422.rs @@ -1,7 +1,7 @@ // check-pass - -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete +#![cfg_attr(min, feature(min_const_generics))] use std::mem; diff --git a/src/test/ui/const-generics/issues/issue-61422.stderr b/src/test/ui/const-generics/issues/issue-61432.full.stderr similarity index 70% rename from src/test/ui/const-generics/issues/issue-61422.stderr rename to src/test/ui/const-generics/issues/issue-61432.full.stderr index 69bbaada69187..82b36de45a2aa 100644 --- a/src/test/ui/const-generics/issues/issue-61422.stderr +++ b/src/test/ui/const-generics/issues/issue-61432.full.stderr @@ -1,8 +1,8 @@ warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-61422.rs:3:12 + --> $DIR/issue-61432.rs:3:27 | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ +LL | #![cfg_attr(full, feature(const_generics))] + | ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information diff --git a/src/test/ui/const-generics/issues/issue-61432.rs b/src/test/ui/const-generics/issues/issue-61432.rs index 0440468e9e622..91a4794099c07 100644 --- a/src/test/ui/const-generics/issues/issue-61432.rs +++ b/src/test/ui/const-generics/issues/issue-61432.rs @@ -1,7 +1,7 @@ // run-pass - -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete +#![cfg_attr(min, feature(min_const_generics))] fn promote() { // works: diff --git a/src/test/ui/const-generics/issues/issue-61747.stderr b/src/test/ui/const-generics/issues/issue-61747.full.stderr similarity index 77% rename from src/test/ui/const-generics/issues/issue-61747.stderr rename to src/test/ui/const-generics/issues/issue-61747.full.stderr index 2685d9fdf167c..3ccce5675fcba 100644 --- a/src/test/ui/const-generics/issues/issue-61747.stderr +++ b/src/test/ui/const-generics/issues/issue-61747.full.stderr @@ -1,14 +1,14 @@ warning: the feature `const_generics` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-61747.rs:1:12 + --> $DIR/issue-61747.rs:2:27 | -LL | #![feature(const_generics)] - | ^^^^^^^^^^^^^^ +LL | #![cfg_attr(full, feature(const_generics))] + | ^^^^^^^^^^^^^^ | = note: `#[warn(incomplete_features)]` on by default = note: see issue #44580 for more information error: constant expression depends on a generic parameter - --> $DIR/issue-61747.rs:7:23 + --> $DIR/issue-61747.rs:8:23 | LL | fn successor() -> Const<{C + 1}> { | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/const-generics/issues/issue-61747.min.stderr b/src/test/ui/const-generics/issues/issue-61747.min.stderr new file mode 100644 index 0000000000000..2061b6c55bb7b --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-61747.min.stderr @@ -0,0 +1,10 @@ +error: generic parameters must not be used inside of non trivial constant values + --> $DIR/issue-61747.rs:8:30 + | +LL | fn successor() -> Const<{C + 1}> { + | ^ non-trivial anonymous constants must not depend on the parameter `C` + | + = help: it is currently only allowed to use either `C` or `{ C }` as generic constants + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issues/issue-61747.rs b/src/test/ui/const-generics/issues/issue-61747.rs index cc671163e85a1..4e5cde17f39a9 100644 --- a/src/test/ui/const-generics/issues/issue-61747.rs +++ b/src/test/ui/const-generics/issues/issue-61747.rs @@ -1,11 +1,13 @@ -#![feature(const_generics)] -//~^ WARN the feature `const_generics` is incomplete +// revisions: full min +#![cfg_attr(full, feature(const_generics))] //[full]~WARN the feature `const_generics` is incomplete +#![cfg_attr(min, feature(min_const_generics))] struct Const; impl Const<{C}> { fn successor() -> Const<{C + 1}> { - //~^ ERROR constant expression depends on a generic parameter + //[full]~^ ERROR constant expression depends on a generic parameter + //[min]~^^ ERROR generic parameters must not be used Const } } diff --git a/src/test/ui/const-generics/min_const_generics/assoc_const.rs b/src/test/ui/const-generics/min_const_generics/assoc_const.rs new file mode 100644 index 0000000000000..fa75613d9ddc1 --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/assoc_const.rs @@ -0,0 +1,18 @@ +// check-pass +#![feature(min_const_generics)] + +struct Foo; + +impl Foo { + const VALUE: usize = N * 2; +} + +trait Bar { + const ASSOC: usize; +} + +impl Bar for Foo { + const ASSOC: usize = N * 3; +} + +fn main() {} diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.rs b/src/test/ui/const-generics/min_const_generics/complex-expression.rs new file mode 100644 index 0000000000000..f9cb0d2829d6e --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/complex-expression.rs @@ -0,0 +1,29 @@ +#![feature(min_const_generics)] + +fn test() {} + +fn ok() -> [u8; M] { + [0; { M }] +} + +struct Break0([u8; { N + 1 }]); +//~^ ERROR generic parameters must not be used inside of non trivial constant values + +struct Break1([u8; { { N } }]); +//~^ ERROR generic parameters must not be used inside of non trivial constant values + +fn break2() { + let _: [u8; N + 1]; + //~^ ERROR generic parameters must not be used inside of non trivial constant values +} + +fn break3() { + let _ = [0; N + 1]; + //~^ ERROR generic parameters must not be used inside of non trivial constant values +} + +trait Foo { + const ASSOC: usize; +} + +fn main() {} diff --git a/src/test/ui/const-generics/min_const_generics/complex-expression.stderr b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr new file mode 100644 index 0000000000000..baed8d13f00f1 --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/complex-expression.stderr @@ -0,0 +1,34 @@ +error: generic parameters must not be used inside of non trivial constant values + --> $DIR/complex-expression.rs:9:38 + | +LL | struct Break0([u8; { N + 1 }]); + | ^ non-trivial anonymous constants must not depend on the parameter `N` + | + = help: it is currently only allowed to use either `N` or `{ N }` as generic constants + +error: generic parameters must not be used inside of non trivial constant values + --> $DIR/complex-expression.rs:12:40 + | +LL | struct Break1([u8; { { N } }]); + | ^ non-trivial anonymous constants must not depend on the parameter `N` + | + = help: it is currently only allowed to use either `N` or `{ N }` as generic constants + +error: generic parameters must not be used inside of non trivial constant values + --> $DIR/complex-expression.rs:16:17 + | +LL | let _: [u8; N + 1]; + | ^ non-trivial anonymous constants must not depend on the parameter `N` + | + = help: it is currently only allowed to use either `N` or `{ N }` as generic constants + +error: generic parameters must not be used inside of non trivial constant values + --> $DIR/complex-expression.rs:21:17 + | +LL | let _ = [0; N + 1]; + | ^ non-trivial anonymous constants must not depend on the parameter `N` + | + = help: it is currently only allowed to use either `N` or `{ N }` as generic constants + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/const-generics/min_const_generics/complex-types.rs b/src/test/ui/const-generics/min_const_generics/complex-types.rs new file mode 100644 index 0000000000000..a396fa83aa629 --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/complex-types.rs @@ -0,0 +1,18 @@ +#![feature(min_const_generics)] + +struct Foo; +//~^ ERROR using `[u8; 0]` as const generic parameters is forbidden + +struct Bar; +//~^ ERROR using `()` as const generic parameters is forbidden + +#[derive(PartialEq, Eq)] +struct No; + +struct Fez; +//~^ ERROR using `No` as const generic parameters is forbidden + +struct Faz; +//~^ ERROR using `&'static u8` as const generic parameters is forbidden + +fn main() {} diff --git a/src/test/ui/const-generics/min_const_generics/complex-types.stderr b/src/test/ui/const-generics/min_const_generics/complex-types.stderr new file mode 100644 index 0000000000000..835b1f1a3e867 --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/complex-types.stderr @@ -0,0 +1,38 @@ +error: using `[u8; 0]` as const generic parameters is forbidden + --> $DIR/complex-types.rs:3:21 + | +LL | struct Foo; + | ^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: using `()` as const generic parameters is forbidden + --> $DIR/complex-types.rs:6:21 + | +LL | struct Bar; + | ^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: using `No` as const generic parameters is forbidden + --> $DIR/complex-types.rs:12:21 + | +LL | struct Fez; + | ^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: using `&'static u8` as const generic parameters is forbidden + --> $DIR/complex-types.rs:15:21 + | +LL | struct Faz; + | ^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = note: more complex types are supported with `#[feature(const_generics)]` + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.rs b/src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.rs new file mode 100644 index 0000000000000..423deae460083 --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.rs @@ -0,0 +1,4 @@ +fn test() {} +//~^ ERROR const generics are unstable + +fn main() {} diff --git a/src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.stderr b/src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.stderr new file mode 100644 index 0000000000000..7f82a960da255 --- /dev/null +++ b/src/test/ui/const-generics/min_const_generics/feature-gate-min_const_generics.stderr @@ -0,0 +1,12 @@ +error[E0658]: const generics are unstable + --> $DIR/feature-gate-min_const_generics.rs:1:15 + | +LL | fn test() {} + | ^ + | + = note: see issue #74878 for more information + = help: add `#![feature(min_const_generics)]` 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/type-dependent/const-arg-in-const-arg.rs b/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs index ae50252facd25..3ccdd47261372 100644 --- a/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs +++ b/src/test/ui/const-generics/type-dependent/const-arg-in-const-arg.rs @@ -1,7 +1,8 @@ // run-pass -#![feature(const_generics)] +// revisions: full min +#![cfg_attr(full, feature(const_generics))] +#![cfg_attr(min, feature(min_const_generics))] #![allow(incomplete_features)] -#![feature(const_fn)] struct Foo; diff --git a/src/test/ui/feature-gates/feature-gate-const_generics-ptr.stderr b/src/test/ui/feature-gates/feature-gate-const_generics-ptr.stderr index b2c96d3810f98..eef465318a390 100644 --- a/src/test/ui/feature-gates/feature-gate-const_generics-ptr.stderr +++ b/src/test/ui/feature-gates/feature-gate-const_generics-ptr.stderr @@ -4,8 +4,8 @@ error[E0658]: const generics are unstable LL | struct ConstFn; | ^ | - = note: see issue #44580 for more information - = help: add `#![feature(const_generics)]` to the crate attributes to enable + = note: see issue #74878 for more information + = help: add `#![feature(min_const_generics)]` to the crate attributes to enable error[E0658]: const generics are unstable --> $DIR/feature-gate-const_generics-ptr.rs:5:23 @@ -13,8 +13,8 @@ error[E0658]: const generics are unstable LL | struct ConstPtr; | ^ | - = note: see issue #44580 for more information - = help: add `#![feature(const_generics)]` to the crate attributes to enable + = note: see issue #74878 for more information + = help: add `#![feature(min_const_generics)]` to the crate attributes to enable error: using function pointers as const generic parameters is forbidden --> $DIR/feature-gate-const_generics-ptr.rs:1:25 diff --git a/src/test/ui/feature-gates/feature-gate-const_generics.stderr b/src/test/ui/feature-gates/feature-gate-const_generics.stderr index 02aa1f5a4d843..f80362252f923 100644 --- a/src/test/ui/feature-gates/feature-gate-const_generics.stderr +++ b/src/test/ui/feature-gates/feature-gate-const_generics.stderr @@ -4,8 +4,8 @@ error[E0658]: const generics are unstable LL | fn foo() {} | ^ | - = note: see issue #44580 for more information - = help: add `#![feature(const_generics)]` to the crate attributes to enable + = note: see issue #74878 for more information + = help: add `#![feature(min_const_generics)]` to the crate attributes to enable error[E0658]: const generics are unstable --> $DIR/feature-gate-const_generics.rs:3:18 @@ -13,8 +13,8 @@ error[E0658]: const generics are unstable LL | struct Foo([(); X]); | ^ | - = note: see issue #44580 for more information - = help: add `#![feature(const_generics)]` to the crate attributes to enable + = note: see issue #74878 for more information + = help: add `#![feature(min_const_generics)]` to the crate attributes to enable error: aborting due to 2 previous errors