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 dd6c40bfbb8dc..5f91f1d7b3e1f 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 7ecd8c734d322..0000000000000 --- a/tests/crashes/137865.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ known-bug: #137865 -trait Foo { - type Assoc; - 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 0000000000000..29171c8006afb --- /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 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; + | ^^^^ + | + = 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 0000000000000..64b413188144d --- /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; + | ^^^^ + | + = 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 0000000000000..21994eb83b42c --- /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; + //~^ ERROR `Self` is forbidden as the type of a const generic parameter +} + +fn 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() {}