From fab6d8ae8c14cf3b4a53b7a716ce4809be35ffaf Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 5 Feb 2025 11:45:50 +0000 Subject: [PATCH] Prevent generic pattern types from being used in libstd --- compiler/rustc_feature/src/unstable.rs | 2 + compiler/rustc_span/src/symbol.rs | 1 + .../rustc_trait_selection/src/traits/wf.rs | 44 ++++++++++++++++- .../pattern_types/assoc_const.default.stderr | 49 +++++++++++++++++-- tests/ui/type/pattern_types/assoc_const.rs | 8 ++- tests/ui/type/pattern_types/const_generics.rs | 4 +- tests/ui/type/pattern_types/transmute.rs | 4 +- 7 files changed, 101 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 784063b0e31a3..8aaa2d4439256 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -507,6 +507,8 @@ declare_features! ( (incomplete, generic_const_exprs, "1.56.0", Some(76560)), /// Allows generic parameters and where-clauses on free & associated const items. (incomplete, generic_const_items, "1.73.0", Some(113521)), + /// Allows any generic constants being used as pattern type range ends + (incomplete, generic_pattern_types, "CURRENT_RUSTC_VERSION", Some(136574)), /// Allows registering static items globally, possibly across crates, to iterate over at runtime. (unstable, global_registration, "1.80.0", Some(125119)), /// Allows using guards in patterns. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 75a472d896fc4..621d150281ca4 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1013,6 +1013,7 @@ symbols! { generic_const_exprs, generic_const_items, generic_param_attrs, + generic_pattern_types, get_context, global_alloc_ty, global_allocator, diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 96051ad0aa54f..c27bd269b0d9f 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -8,8 +8,9 @@ use rustc_middle::ty::{ self, GenericArg, GenericArgKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; -use rustc_span::Span; +use rustc_session::parse::feature_err; use rustc_span::def_id::{DefId, LocalDefId}; +use rustc_span::{Span, sym}; use tracing::{debug, instrument, trace}; use crate::infer::InferCtxt; @@ -704,8 +705,47 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { )); } - ty::Pat(subty, _) => { + ty::Pat(subty, pat) => { self.require_sized(subty, ObligationCauseCode::Misc); + match *pat { + ty::PatternKind::Range { start, end, include_end: _ } => { + let mut check = |c| { + let cause = self.cause(ObligationCauseCode::Misc); + self.out.push(traits::Obligation::with_depth( + tcx, + cause.clone(), + self.recursion_depth, + self.param_env, + ty::Binder::dummy(ty::PredicateKind::Clause( + ty::ClauseKind::ConstArgHasType(c, subty), + )), + )); + if !tcx.features().generic_pattern_types() { + if c.has_param() { + if self.span.is_dummy() { + self.tcx().dcx().delayed_bug( + "feature error should be reported elsewhere, too", + ); + } else { + feature_err( + &self.tcx().sess, + sym::generic_pattern_types, + self.span, + "wraparound pattern type ranges cause monomorphization time errors", + ) + .emit(); + } + } + } + }; + if let Some(start) = start { + check(start) + } + if let Some(end) = end { + check(end) + } + } + } } ty::Tuple(tys) => { diff --git a/tests/ui/type/pattern_types/assoc_const.default.stderr b/tests/ui/type/pattern_types/assoc_const.default.stderr index abda40e468162..c5d9691a02918 100644 --- a/tests/ui/type/pattern_types/assoc_const.default.stderr +++ b/tests/ui/type/pattern_types/assoc_const.default.stderr @@ -1,3 +1,24 @@ +error[E0658]: wraparound pattern type ranges cause monomorphization time errors + --> $DIR/assoc_const.rs:17:19 + | +LL | fn foo(_: pattern_type!(u32 is ::START..=::END)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #136574 for more information + = help: add `#![feature(generic_pattern_types)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: wraparound pattern type ranges cause monomorphization time errors + --> $DIR/assoc_const.rs:17:19 + | +LL | fn foo(_: pattern_type!(u32 is ::START..=::END)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #136574 for more information + = help: add `#![feature(generic_pattern_types)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: constant expression depends on a generic parameter --> $DIR/assoc_const.rs:17:19 | @@ -15,8 +36,29 @@ LL | fn foo(_: pattern_type!(u32 is ::START..=::END) = note: this may fail depending on what value the parameter takes = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +error[E0658]: wraparound pattern type ranges cause monomorphization time errors + --> $DIR/assoc_const.rs:22:19 + | +LL | fn bar(_: pattern_type!(u32 is T::START..=T::END)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #136574 for more information + = help: add `#![feature(generic_pattern_types)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: wraparound pattern type ranges cause monomorphization time errors + --> $DIR/assoc_const.rs:22:19 + | +LL | fn bar(_: pattern_type!(u32 is T::START..=T::END)) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #136574 for more information + = help: add `#![feature(generic_pattern_types)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + error: constant expression depends on a generic parameter - --> $DIR/assoc_const.rs:20:19 + --> $DIR/assoc_const.rs:22:19 | LL | fn bar(_: pattern_type!(u32 is T::START..=T::END)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -24,7 +66,7 @@ LL | fn bar(_: pattern_type!(u32 is T::START..=T::END)) {} = note: this may fail depending on what value the parameter takes error: constant expression depends on a generic parameter - --> $DIR/assoc_const.rs:20:19 + --> $DIR/assoc_const.rs:22:19 | LL | fn bar(_: pattern_type!(u32 is T::START..=T::END)) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,5 +74,6 @@ LL | fn bar(_: pattern_type!(u32 is T::START..=T::END)) {} = note: this may fail depending on what value the parameter takes = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` -error: aborting due to 4 previous errors +error: aborting due to 8 previous errors +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/type/pattern_types/assoc_const.rs b/tests/ui/type/pattern_types/assoc_const.rs index af0f7e4cbf32f..87886587d5153 100644 --- a/tests/ui/type/pattern_types/assoc_const.rs +++ b/tests/ui/type/pattern_types/assoc_const.rs @@ -1,8 +1,8 @@ #![feature(pattern_types)] #![feature(pattern_type_macro)] -#![cfg_attr(const_arg, feature(generic_const_exprs))] +#![cfg_attr(const_arg, feature(generic_const_exprs, generic_pattern_types))] #![expect(incomplete_features)] - +// gate-test-generic_pattern_types line to the test file. //@ revisions: default const_arg //@[const_arg] check-pass @@ -17,8 +17,12 @@ trait Foo { fn foo(_: pattern_type!(u32 is ::START..=::END)) {} //[default]~^ ERROR: constant expression depends on a generic parameter //[default]~| ERROR: constant expression depends on a generic parameter +//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors +//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors fn bar(_: pattern_type!(u32 is T::START..=T::END)) {} //[default]~^ ERROR: constant expression depends on a generic parameter //[default]~| ERROR: constant expression depends on a generic parameter +//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors +//[default]~| ERROR: wraparound pattern type ranges cause monomorphization time errors fn main() {} diff --git a/tests/ui/type/pattern_types/const_generics.rs b/tests/ui/type/pattern_types/const_generics.rs index 5cef0dc030552..79d46c010d733 100644 --- a/tests/ui/type/pattern_types/const_generics.rs +++ b/tests/ui/type/pattern_types/const_generics.rs @@ -1,7 +1,7 @@ //@ check-pass -#![feature(pattern_types)] -#![feature(pattern_type_macro)] +#![feature(pattern_types, generic_pattern_types, pattern_type_macro)] +#![expect(incomplete_features)] use std::pat::pattern_type; diff --git a/tests/ui/type/pattern_types/transmute.rs b/tests/ui/type/pattern_types/transmute.rs index cb76b2b938dc6..43dd62a19e706 100644 --- a/tests/ui/type/pattern_types/transmute.rs +++ b/tests/ui/type/pattern_types/transmute.rs @@ -1,5 +1,5 @@ -#![feature(pattern_types)] -#![feature(pattern_type_macro)] +#![feature(pattern_types, pattern_type_macro, generic_pattern_types)] +#![expect(incomplete_features)] use std::pat::pattern_type;