Skip to content

Commit eb679ee

Browse files
Do not feed anon const a type that references generics that it does not have
1 parent dea1661 commit eb679ee

File tree

4 files changed

+77
-9
lines changed

4 files changed

+77
-9
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2294,18 +2294,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22942294
{
22952295
let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args);
22962296

2297+
// FIXME(generic_const_parameter_types): Ideally we remove these errors below when
2298+
// we have the ability to intermix typeck of anon const const args with the parent
2299+
// bodies typeck.
2300+
22972301
// We must error if the instantiated type has any inference variables as we will
22982302
// use this type to feed the `type_of` and query results must not contain inference
22992303
// variables otherwise we will ICE.
2300-
//
2301-
// We also error if the type contains any regions as effectively any region will wind
2302-
// up as a region variable in mir borrowck. It would also be somewhat concerning if
2303-
// hir typeck was using equality but mir borrowck wound up using subtyping as that could
2304-
// result in a non-infer in hir typeck but a region variable in borrowck.
2305-
//
2306-
// FIXME(generic_const_parameter_types): Ideally we remove these errors one day when
2307-
// we have the ability to intermix typeck of anon const const args with the parent
2308-
// bodies typeck.
23092304
if tcx.features().generic_const_parameter_types()
23102305
&& (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions())
23112306
{
@@ -2316,6 +2311,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23162311
tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
23172312
return ty::Const::new_error(tcx, e);
23182313
}
2314+
// We also error if the type contains any regions as effectively any region will wind
2315+
// up as a region variable in mir borrowck. It would also be somewhat concerning if
2316+
// hir typeck was using equality but mir borrowck wound up using subtyping as that could
2317+
// result in a non-infer in hir typeck but a region variable in borrowck.
23192318
if anon_const_type.has_non_region_infer() {
23202319
let e = tcx.dcx().span_err(
23212320
const_arg.span(),
@@ -2324,6 +2323,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
23242323
tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
23252324
return ty::Const::new_error(tcx, e);
23262325
}
2326+
// We error when the type contains unsubstituted generics since we do not currently
2327+
// give the anon const any of the generics from the parent.
2328+
if anon_const_type.has_non_region_param() {
2329+
let e = tcx.dcx().span_err(
2330+
const_arg.span(),
2331+
"anonymous constants referencing generics are not yet supported",
2332+
);
2333+
tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
2334+
return ty::Const::new_error(tcx, e);
2335+
}
23272336

23282337
tcx.feed_anon_const_type(
23292338
anon.def_id,
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
warning: the feature `generic_const_parameter_types` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/references-parent-generics.rs:3:27
3+
|
4+
LL | #![cfg_attr(feat, feature(generic_const_parameter_types))]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #137626 <https://github.com/rust-lang/rust/issues/137626> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
error: `Self` is forbidden as the type of a const generic parameter
11+
--> $DIR/references-parent-generics.rs:7:25
12+
|
13+
LL | type Assoc<const N: Self>;
14+
| ^^^^
15+
|
16+
= note: the only supported types are integers, `bool`, and `char`
17+
18+
error: anonymous constants referencing generics are not yet supported
19+
--> $DIR/references-parent-generics.rs:14:21
20+
|
21+
LL | let x: T::Assoc<3>;
22+
| ^
23+
24+
error: aborting due to 2 previous errors; 1 warning emitted
25+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: `Self` is forbidden as the type of a const generic parameter
2+
--> $DIR/references-parent-generics.rs:7:25
3+
|
4+
LL | type Assoc<const N: Self>;
5+
| ^^^^
6+
|
7+
= note: the only supported types are integers, `bool`, and `char`
8+
9+
error: anonymous constants referencing generics are not yet supported
10+
--> $DIR/references-parent-generics.rs:14:21
11+
|
12+
LL | let x: T::Assoc<3>;
13+
| ^
14+
15+
error: aborting due to 2 previous errors
16+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ revisions: feat nofeat
2+
3+
#![cfg_attr(feat, feature(generic_const_parameter_types))]
4+
//[feat]~^ WARN the feature `generic_const_parameter_types` is incomplete
5+
6+
trait Foo {
7+
type Assoc<const N: Self>;
8+
//~^ ERROR `Self` is forbidden as the type of a const generic parameter
9+
}
10+
11+
fn foo<T: Foo>() {
12+
// We used to end up feeding the type of this anon const to be `T`, but the anon const
13+
// doesn't inherit the generics of `foo`, which led to index oob errors.
14+
let x: T::Assoc<3>;
15+
//~^ ERROR anonymous constants referencing generics are not yet supported
16+
}
17+
18+
fn main() {}

0 commit comments

Comments
 (0)