Skip to content

Commit a8b3dfd

Browse files
committed
Suppress lint type_alias_bounds for ty aliases containing const projections under GCE
1 parent 63a54d9 commit a8b3dfd

File tree

3 files changed

+144
-0
lines changed

3 files changed

+144
-0
lines changed

compiler/rustc_lint/src/builtin.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,16 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
14371437
return;
14381438
}
14391439

1440+
1441+
// FIXME(generic_const_exprs): Revisit this before stabilization.
1442+
// See also `tests/ui/const-generics/generic_const_exprs/type-alias-bounds.rs`.
1443+
let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
1444+
if ty.has_type_flags(ty::TypeFlags::HAS_CT_PROJECTION)
1445+
&& cx.tcx.features().generic_const_exprs
1446+
{
1447+
return;
1448+
}
1449+
14401450
// NOTE(inherent_associated_types): While we currently do take some bounds in type
14411451
// aliases into consideration during IAT *selection*, we don't perform full use+def
14421452
// site wfchecking for such type aliases. Therefore TAB should still trigger.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
error[E0277]: the trait bound `String: Copy` is not satisfied
2+
--> $DIR/type-alias-bounds.rs:23:12
3+
|
4+
LL | let _: AliasConstUnused<String>;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
6+
|
7+
note: required by a bound in `ct_unused_0::AliasConstUnused`
8+
--> $DIR/type-alias-bounds.rs:20:30
9+
|
10+
LL | type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>);
11+
| ^^^^ required by this bound in `AliasConstUnused`
12+
13+
error[E0277]: the trait bound `String: Copy` is not satisfied
14+
--> $DIR/type-alias-bounds.rs:31:12
15+
|
16+
LL | let _: AliasConstUnused;
17+
| ^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
18+
|
19+
note: required by a bound in `ct_unused_1::AliasConstUnused`
20+
--> $DIR/type-alias-bounds.rs:29:41
21+
|
22+
LL | type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
23+
| ^^^^ required by this bound in `AliasConstUnused`
24+
25+
error[E0277]: the trait bound `String: Copy` is not satisfied
26+
--> $DIR/type-alias-bounds.rs:39:12
27+
|
28+
LL | let _: AliasFnUnused<String>;
29+
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
30+
|
31+
note: required by a bound in `AliasFnUnused`
32+
--> $DIR/type-alias-bounds.rs:36:27
33+
|
34+
LL | type AliasFnUnused<T: Copy> = (T, I32<{ code() }>);
35+
| ^^^^ required by this bound in `AliasFnUnused`
36+
37+
error[E0277]: the trait bound `String: Copy` is not satisfied
38+
--> $DIR/type-alias-bounds.rs:57:12
39+
|
40+
LL | let _: AliasAssocConstUsed<String>;
41+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
42+
|
43+
note: required by a bound in `AliasAssocConstUsed`
44+
--> $DIR/type-alias-bounds.rs:55:41
45+
|
46+
LL | type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>;
47+
| ^^^^ required by this bound in `AliasAssocConstUsed`
48+
49+
error[E0277]: the trait bound `String: Copy` is not satisfied
50+
--> $DIR/type-alias-bounds.rs:65:12
51+
|
52+
LL | let _: AliasFnUsed<String>;
53+
| ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
54+
|
55+
note: required by a bound in `AliasFnUsed`
56+
--> $DIR/type-alias-bounds.rs:62:33
57+
|
58+
LL | type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>;
59+
| ^^^^ required by this bound in `AliasFnUsed`
60+
61+
error: aborting due to 5 previous errors
62+
63+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//@ revisions: pos neg
2+
//@[pos] check-pass
3+
4+
#![feature(generic_const_exprs)]
5+
#![feature(trivial_bounds)] // only used in test case `ct_unused_1`
6+
#![allow(incomplete_features)]
7+
8+
// FIXME(generic_const_exprs): Revisit this before stabilization.
9+
// Check that we don't emit the lint `type_alias_bounds` for (eager) type aliases
10+
// whose RHS contains a const projection (aka uneval'ed const).
11+
// Since anon consts inherit the parent generics and predicates and we effectively
12+
// check them before and after instantiaton for well-formedness, the type alias
13+
// bounds are in every sense "enforced".
14+
// Note that the test cases whose name ends in "unused" just demonstrate that this
15+
// holds even if the const projections don't "visibly" capture any generics and/or
16+
// predicates.
17+
#![deny(type_alias_bounds)]
18+
19+
fn ct_unused_0() {
20+
type AliasConstUnused<T: Copy> = (T, I32<{ DATA }>);
21+
const DATA: i32 = 0;
22+
#[cfg(neg)]
23+
let _: AliasConstUnused<String>;
24+
//[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
25+
}
26+
27+
fn ct_unused_1() {
28+
#[allow(trivial_bounds)]
29+
type AliasConstUnused where String: Copy = I32<{ 0; 0 }>;
30+
#[cfg(neg)]
31+
let _: AliasConstUnused;
32+
//[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
33+
}
34+
35+
fn fn_unused() {
36+
type AliasFnUnused<T: Copy> = (T, I32<{ code() }>);
37+
const fn code() -> i32 { 0 }
38+
#[cfg(neg)]
39+
let _: AliasFnUnused<String>;
40+
//[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
41+
}
42+
43+
trait Trait {
44+
type Proj;
45+
const DATA: i32;
46+
}
47+
48+
impl Trait for String {
49+
type Proj = i32;
50+
const DATA: i32 = 0;
51+
}
52+
53+
// Regression test for issue #94398.
54+
fn assoc_ct_used() {
55+
type AliasAssocConstUsed<T: Trait + Copy> = I32<{ T::DATA }>;
56+
#[cfg(neg)]
57+
let _: AliasAssocConstUsed<String>;
58+
//[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
59+
}
60+
61+
fn fn_used() {
62+
type AliasFnUsed<T: Trait + Copy> = I32<{ code::<T>() }>;
63+
const fn code<T: Trait>() -> i32 { T::DATA }
64+
#[cfg(neg)]
65+
let _: AliasFnUsed<String>;
66+
//[neg]~^ ERROR the trait bound `String: Copy` is not satisfied
67+
}
68+
69+
struct I32<const N: i32>;
70+
71+
fn main() {}

0 commit comments

Comments
 (0)