Skip to content

Do not feed anon const a type that references generics that it does not have #138256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
{
Expand All @@ -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(),
Expand All @@ -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,
Expand Down
5 changes: 0 additions & 5 deletions tests/crashes/137865.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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() {}
Loading