about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2025-03-09 18:23:17 +0000
committerMichael Goulet <michael@errs.io>2025-03-09 20:03:13 +0000
commited6dfddfeb345e0fe94ef735a54d6290d278a6b8 (patch)
tree68a397bf114c960a9777cb9632efc2a80e8261c7
parent385970f0c1fd0c09bac426b02f38300c0b1ba9a2 (diff)
downloadrust-ed6dfddfeb345e0fe94ef735a54d6290d278a6b8.tar.gz
rust-ed6dfddfeb345e0fe94ef735a54d6290d278a6b8.zip
Do not feed anon const a type that references generics that it does not have
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs25
-rw-r--r--tests/crashes/137865.rs5
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr25
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr16
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs18
5 files changed, 76 insertions, 13 deletions
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index dd6c40bfbb8..5f91f1d7b3e 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -2294,18 +2294,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         {
             let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args);
 
-            // We must error if the instantiated type has any inference variables as we will
-            // use this type to feed the `type_of` and query results must not contain inference
-            // variables otherwise we will ICE.
-            //
+            // FIXME(generic_const_parameter_types): Ideally we remove these errors below when
+            // we have the ability to intermix typeck of anon const const args with the parent
+            // bodies typeck.
+
             // We also error if the type contains any regions as effectively any region will wind
             // up as a region variable in mir borrowck. It would also be somewhat concerning if
             // hir typeck was using equality but mir borrowck wound up using subtyping as that could
             // result in a non-infer in hir typeck but a region variable in borrowck.
-            //
-            // FIXME(generic_const_parameter_types): Ideally we remove these errors one day when
-            // we have the ability to intermix typeck of anon const const args with the parent
-            // bodies typeck.
             if tcx.features().generic_const_parameter_types()
                 && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions())
             {
@@ -2316,6 +2312,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
                 return ty::Const::new_error(tcx, e);
             }
+            // We must error if the instantiated type has any inference variables as we will
+            // use this type to feed the `type_of` and query results must not contain inference
+            // variables otherwise we will ICE.
             if anon_const_type.has_non_region_infer() {
                 let e = tcx.dcx().span_err(
                     const_arg.span(),
@@ -2324,6 +2323,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
                 return ty::Const::new_error(tcx, e);
             }
+            // We error when the type contains unsubstituted generics since we do not currently
+            // give the anon const any of the generics from the parent.
+            if anon_const_type.has_non_region_param() {
+                let e = tcx.dcx().span_err(
+                    const_arg.span(),
+                    "anonymous constants referencing generics are not yet supported",
+                );
+                tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
+                return ty::Const::new_error(tcx, e);
+            }
 
             tcx.feed_anon_const_type(
                 anon.def_id,
diff --git a/tests/crashes/137865.rs b/tests/crashes/137865.rs
deleted file mode 100644
index 7ecd8c734d3..00000000000
--- a/tests/crashes/137865.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//@ known-bug: #137865
-trait Foo {
-    type Assoc<const N: Self>;
-    fn foo() -> Self::Assoc<3>;
-}
diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr
new file mode 100644
index 00000000000..29171c8006a
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.feat.stderr
@@ -0,0 +1,25 @@
+warning: the feature `generic_const_parameter_types` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/references-parent-generics.rs:3:27
+   |
+LL | #![cfg_attr(feat, feature(generic_const_parameter_types))]
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #137626 <https://github.com/rust-lang/rust/issues/137626> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: `Self` is forbidden as the type of a const generic parameter
+  --> $DIR/references-parent-generics.rs:7:25
+   |
+LL |     type Assoc<const N: Self>;
+   |                         ^^^^
+   |
+   = note: the only supported types are integers, `bool`, and `char`
+
+error: anonymous constants referencing generics are not yet supported
+  --> $DIR/references-parent-generics.rs:14:21
+   |
+LL |     let x: T::Assoc<3>;
+   |                     ^
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr
new file mode 100644
index 00000000000..64b41318814
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.nofeat.stderr
@@ -0,0 +1,16 @@
+error: `Self` is forbidden as the type of a const generic parameter
+  --> $DIR/references-parent-generics.rs:7:25
+   |
+LL |     type Assoc<const N: Self>;
+   |                         ^^^^
+   |
+   = note: the only supported types are integers, `bool`, and `char`
+
+error: anonymous constants referencing generics are not yet supported
+  --> $DIR/references-parent-generics.rs:14:21
+   |
+LL |     let x: T::Assoc<3>;
+   |                     ^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs
new file mode 100644
index 00000000000..21994eb83b4
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/references-parent-generics.rs
@@ -0,0 +1,18 @@
+//@ revisions: feat nofeat
+
+#![cfg_attr(feat, feature(generic_const_parameter_types))]
+//[feat]~^ WARN the feature `generic_const_parameter_types` is incomplete
+
+trait Foo {
+    type Assoc<const N: Self>;
+    //~^ ERROR `Self` is forbidden as the type of a const generic parameter
+}
+
+fn foo<T: Foo>() {
+    // We used to end up feeding the type of this anon const to be `T`, but the anon const
+    // doesn't inherit the generics of `foo`, which led to index oob errors.
+    let x: T::Assoc<3>;
+    //~^ ERROR anonymous constants referencing generics are not yet supported
+}
+
+fn main() {}