about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2025-02-11 02:53:44 +0100
committerGitHub <noreply@github.com>2025-02-11 02:53:44 +0100
commitc92aae90e4bcdcc6978e3c3ca9f01777220b356c (patch)
tree8249c12b94f32008532edaa1dfa43a0326b70762
parent66573926f28be9116de08f5b707fd62bb6ef94df (diff)
parentfab6d8ae8c14cf3b4a53b7a716ce4809be35ffaf (diff)
downloadrust-c92aae90e4bcdcc6978e3c3ca9f01777220b356c.tar.gz
rust-c92aae90e4bcdcc6978e3c3ca9f01777220b356c.zip
Rollup merge of #136584 - oli-obk:pattern-types-generic, r=BoxyUwU
Prevent generic pattern types from being used in libstd

Pattern types should follow the same rules that patterns follow. So a pattern type range must not wrap and not be empty. While we reject such invalid ranges at layout computation time, that only happens during monomorphization in the case of const generics. This is the exact same issue as other const generic math has, and since there's no solution there yet, I put these pattern types behind a separate incomplete feature.

These are not necessary for the pattern types MVP (replacing the layout range attributes in libcore and rustc).

cc #136574 (new tracking issue for the `generic_pattern_types` feature gate)

r? ``@lcnr``

cc ``@scottmcm`` ``@joshtriplett``
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs44
-rw-r--r--tests/ui/type/pattern_types/assoc_const.default.stderr49
-rw-r--r--tests/ui/type/pattern_types/assoc_const.rs8
-rw-r--r--tests/ui/type/pattern_types/const_generics.rs4
-rw-r--r--tests/ui/type/pattern_types/transmute.rs4
7 files changed, 101 insertions, 11 deletions
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 3a2e810dc6a..a4c5e4800eb 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -513,6 +513,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 16015776697..bb59b4c40bd 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1026,6 +1026,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 96051ad0aa5..c27bd269b0d 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<TyCtxt<'tcx>> 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 abda40e4681..c5d9691a029 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<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #136574 <https://github.com/rust-lang/rust/issues/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<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::END)) {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #136574 <https://github.com/rust-lang/rust/issues/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<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::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<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #136574 <https://github.com/rust-lang/rust/issues/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<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #136574 <https://github.com/rust-lang/rust/issues/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<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +66,7 @@ LL | fn bar<T: Foo>(_: 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<T: Foo>(_: pattern_type!(u32 is T::START..=T::END)) {}
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,5 +74,6 @@ LL | fn bar<T: Foo>(_: 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 af0f7e4cbf3..87886587d51 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<T: Foo>(_: pattern_type!(u32 is <T as Foo>::START..=<T as Foo>::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<T: Foo>(_: 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 5cef0dc0305..79d46c010d7 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 cb76b2b938d..43dd62a19e7 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;