From a8b3dfd25336dc12f17da23a0ed7004a4ebee234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Fri, 14 Jun 2024 16:18:32 +0200 Subject: [PATCH] Suppress lint type_alias_bounds for ty aliases containing const projections under GCE --- compiler/rustc_lint/src/builtin.rs | 10 +++ .../type-alias-bounds.neg.stderr | 63 ++++++++++++++++ .../generic_const_exprs/type-alias-bounds.rs | 71 +++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr create mode 100644 tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 40b336cd5ea..90555007607 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1437,6 +1437,16 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds { return; } + + // FIXME(generic_const_exprs): Revisit this before stabilization. + // See also `tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs`. + let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); + if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION) + && cx.tcx.features().generic_const_exprs + { + return; + } + // NOTE(inherent_associated_types): While we currently do take some bounds in type // aliases into consideration during IAT *selection*, we don't perform full use+def // site wfchecking for such type aliases. Therefore TAB should still trigger. diff --git a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr new file mode 100644 index 00000000000..fa12dd14753 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.neg.stderr @@ -0,0 +1,63 @@ +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-alias-bounds.rs:23:12 + | +LL | let _: AliasConstUnused; + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `ct_unused_0::AliasConstUnused` + --> $DIR/type-alias-bounds.rs:20:30 + | +LL | type AliasConstUnused = (T, I32<{ DATA }>); + | ^^^^ required by this bound in `AliasConstUnused` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-alias-bounds.rs:31:12 + | +LL | let _: AliasConstUnused; + | ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `ct_unused_1::AliasConstUnused` + --> $DIR/type-alias-bounds.rs:29:41 + | +LL | type AliasConstUnused where String: Copy = I32<{ 0; 0 }>; + | ^^^^ required by this bound in `AliasConstUnused` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-alias-bounds.rs:39:12 + | +LL | let _: AliasFnUnused; + | ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `AliasFnUnused` + --> $DIR/type-alias-bounds.rs:36:27 + | +LL | type AliasFnUnused = (T, I32<{ code() }>); + | ^^^^ required by this bound in `AliasFnUnused` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-alias-bounds.rs:57:12 + | +LL | let _: AliasAssocConstUsed; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `AliasAssocConstUsed` + --> $DIR/type-alias-bounds.rs:55:41 + | +LL | type AliasAssocConstUsed = I32<{ T::DATA }>; + | ^^^^ required by this bound in `AliasAssocConstUsed` + +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/type-alias-bounds.rs:65:12 + | +LL | let _: AliasFnUsed; + | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | +note: required by a bound in `AliasFnUsed` + --> $DIR/type-alias-bounds.rs:62:33 + | +LL | type AliasFnUsed = I32<{ code::() }>; + | ^^^^ required by this bound in `AliasFnUsed` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs new file mode 100644 index 00000000000..f16e646129c --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs @@ -0,0 +1,71 @@ +//@ revisions: pos neg +//@[pos] check-pass + +#![feature(generic_const_exprs)] +#![feature(trivial_bounds)] // only used in test case `ct_unused_1` +#![allow(incomplete_features)] + +// FIXME(generic_const_exprs): Revisit this before stabilization. +// Check that we don't emit the lint `type_alias_bounds` for (eager) type aliases +// whose RHS contains a const projection (aka uneval'ed const). +// Since anon consts inherit the parent generics and predicates and we effectively +// check them before and after instantiaton for well-formedness, the type alias +// bounds are in every sense "enforced". +// Note that the test cases whose name ends in "unused" just demonstrate that this +// holds even if the const projections don't "visibly" capture any generics and/or +// predicates. +#![deny(type_alias_bounds)] + +fn ct_unused_0() { + type AliasConstUnused = (T, I32<{ DATA }>); + const DATA: i32 = 0; + #[cfg(neg)] + let _: AliasConstUnused; + //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied +} + +fn ct_unused_1() { + #[allow(trivial_bounds)] + type AliasConstUnused where String: Copy = I32<{ 0; 0 }>; + #[cfg(neg)] + let _: AliasConstUnused; + //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied +} + +fn fn_unused() { + type AliasFnUnused = (T, I32<{ code() }>); + const fn code() -> i32 { 0 } + #[cfg(neg)] + let _: AliasFnUnused; + //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied +} + +trait Trait { + type Proj; + const DATA: i32; +} + +impl Trait for String { + type Proj = i32; + const DATA: i32 = 0; +} + +// Regression test for issue #94398. +fn assoc_ct_used() { + type AliasAssocConstUsed = I32<{ T::DATA }>; + #[cfg(neg)] + let _: AliasAssocConstUsed; + //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied +} + +fn fn_used() { + type AliasFnUsed = I32<{ code::() }>; + const fn code() -> i32 { T::DATA } + #[cfg(neg)] + let _: AliasFnUsed; + //[neg]~^ ERROR the trait bound `String: Copy` is not satisfied +} + +struct I32; + +fn main() {}