Skip to content

Commit bdc1b3f

Browse files
committed
[beta] Don't look for non-type-level assoc consts when checking trait object types
1 parent 94a8e82 commit bdc1b3f

10 files changed

Lines changed: 82 additions & 15 deletions

File tree

compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_trait.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
230230
ordered_associated_items.extend(
231231
tcx.associated_items(pred.trait_ref.def_id)
232232
.in_definition_order()
233-
// Only associated types & consts can possibly be constrained via a binding.
234-
.filter(|item| item.is_type() || item.is_const())
233+
// Only associated types & type consts can possibly be
234+
// constrained in a trait object type via a binding.
235+
.filter(|item| item.is_type() || item.is_type_const(tcx))
235236
// Traits with RPITITs are simply not dyn compatible (for now).
236237
.filter(|item| !item.is_impl_trait_in_trait())
237238
.map(|item| (item.def_id, trait_ref)),

compiler/rustc_middle/src/ty/assoc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@ impl AssocItem {
137137
self.kind.as_def_kind()
138138
}
139139

140-
pub fn is_const(&self) -> bool {
141-
matches!(self.kind, ty::AssocKind::Const { .. })
140+
pub fn is_type_const(&self, tcx: TyCtxt<'_>) -> bool {
141+
matches!(self.kind, ty::AssocKind::Const { .. }) && tcx.is_rhs_type_const(self.def_id)
142142
}
143143

144144
pub fn is_fn(&self) -> bool {

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ impl<'tcx> Ty<'tcx> {
724724
.map(|principal| {
725725
tcx.associated_items(principal.def_id())
726726
.in_definition_order()
727-
.filter(|item| item.is_type() || item.is_const())
727+
.filter(|item| item.is_type() || item.is_type_const(tcx))
728728
.filter(|item| !item.is_impl_trait_in_trait())
729729
.filter(|item| !tcx.generics_require_sized_self(item.def_id))
730730
.count()

compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
239239
.flat_map(|super_poly_trait_ref| {
240240
tcx.associated_items(super_poly_trait_ref.def_id())
241241
.in_definition_order()
242-
.filter(|item| item.is_type() || item.is_const())
242+
.filter(|item| item.is_type() || item.is_type_const(tcx))
243243
.filter(|item| !tcx.generics_require_sized_self(item.def_id))
244244
.map(move |assoc_item| {
245245
super_poly_trait_ref.map_bound(|super_trait_ref| {

tests/ui/associated-consts/associated-const-in-trait.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ trait Trait {
77
impl dyn Trait {
88
//~^ ERROR the trait `Trait` is not dyn compatible [E0038]
99
const fn n() -> usize { Self::N }
10+
//~^ ERROR the trait `Trait` is not dyn compatible [E0038]
11+
//~| ERROR the trait `Trait` is not dyn compatible [E0038]
1012
}
1113

1214
fn main() {}

tests/ui/associated-consts/associated-const-in-trait.stderr

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0038]: the trait `Trait` is not dyn compatible
2-
--> $DIR/associated-const-in-trait.rs:7:10
2+
--> $DIR/associated-const-in-trait.rs:7:6
33
|
44
LL | impl dyn Trait {
5-
| ^^^^^ `Trait` is not dyn compatible
5+
| ^^^^^^^^^ `Trait` is not dyn compatible
66
|
77
note: for a trait to be dyn compatible it needs to allow building a vtable
88
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
@@ -14,6 +14,38 @@ LL | const N: usize;
1414
| ^ ...because it contains associated const `N`
1515
= help: consider moving `N` to another trait
1616

17-
error: aborting due to 1 previous error
17+
error[E0038]: the trait `Trait` is not dyn compatible
18+
--> $DIR/associated-const-in-trait.rs:9:29
19+
|
20+
LL | const fn n() -> usize { Self::N }
21+
| ^^^^ `Trait` is not dyn compatible
22+
|
23+
note: for a trait to be dyn compatible it needs to allow building a vtable
24+
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
25+
--> $DIR/associated-const-in-trait.rs:4:11
26+
|
27+
LL | trait Trait {
28+
| ----- this trait is not dyn compatible...
29+
LL | const N: usize;
30+
| ^ ...because it contains associated const `N`
31+
= help: consider moving `N` to another trait
32+
33+
error[E0038]: the trait `Trait` is not dyn compatible
34+
--> $DIR/associated-const-in-trait.rs:9:29
35+
|
36+
LL | const fn n() -> usize { Self::N }
37+
| ^^^^^^^ `Trait` is not dyn compatible
38+
|
39+
note: for a trait to be dyn compatible it needs to allow building a vtable
40+
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
41+
--> $DIR/associated-const-in-trait.rs:4:11
42+
|
43+
LL | trait Trait {
44+
| ----- this trait is not dyn compatible...
45+
LL | const N: usize;
46+
| ^ ...because it contains associated const `N`
47+
= help: consider moving `N` to another trait
48+
49+
error: aborting due to 3 previous errors
1850

1951
For more information about this error, try `rustc --explain E0038`.

tests/ui/associated-item/issue-48027.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0038]: the trait `Bar` is not dyn compatible
2-
--> $DIR/issue-48027.rs:6:10
2+
--> $DIR/issue-48027.rs:6:6
33
|
44
LL | impl dyn Bar {}
5-
| ^^^ `Bar` is not dyn compatible
5+
| ^^^^^^^ `Bar` is not dyn compatible
66
|
77
note: for a trait to be dyn compatible it needs to allow building a vtable
88
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>

tests/ui/dyn-compatibility/associated-consts.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0038]: the trait `Bar` is not dyn compatible
2-
--> $DIR/associated-consts.rs:8:35
2+
--> $DIR/associated-consts.rs:8:31
33
|
44
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
5-
| ^^^ `Bar` is not dyn compatible
5+
| ^^^^^^^ `Bar` is not dyn compatible
66
|
77
note: for a trait to be dyn compatible it needs to allow building a vtable
88
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Demonstrate that we don't check the definition site of (eager) type aliases for well-formedness.
2+
//
3+
// Listed below are ill-formed type system entities which we don't reject since they appear inside
4+
// the definition of (eager) type aliases. These type aliases are intentionally not referenced from
5+
// anywhere to prevent the eagerly expanded / instantiated aliased types from getting wfchecked
6+
// since that's not what we're testing here.
7+
8+
//@ check-pass
9+
10+
type UnsatTraitBound0 = [str]; // `str: Sized` unsatisfied
11+
type UnsatTraitBound1<T = Vec<str>> = T; // `str: Sized` unsatisfied
12+
type UnsatOutlivesBound<'a> = &'static &'a (); // `'a: 'static` unsatisfied
13+
14+
type Diverging = [(); panic!()]; // `panic!()` diverging
15+
16+
type DynIncompat0 = dyn Sized; // `Sized` axiomatically dyn incompatible
17+
// issue: <https://github.com/rust-lang/rust/issues/153731>
18+
type DynIncompat1 = dyn HasAssocConst; // dyn incompatible due to (non-type-level) assoc const
19+
20+
// * dyn incompatible due to GAT
21+
// * `'a: 'static`, `String: Copy` and `[u8]: Sized` unsatisfied, `loop {}` diverging
22+
type Several<'a> = dyn HasGenericAssocType<Type<'a, String, { loop {} }> = [u8]>;
23+
24+
trait HasAssocConst { const N: usize; }
25+
trait HasGenericAssocType { type Type<'a: 'static, T: Copy, const N: usize>; }
26+
27+
fn main() {}

tests/ui/wf/issue-87495.stderr

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0038]: the trait `T` is not dyn compatible
2-
--> $DIR/issue-87495.rs:4:29
2+
--> $DIR/issue-87495.rs:4:25
33
|
44
LL | const CONST: (bool, dyn T);
5-
| ^ `T` is not dyn compatible
5+
| ^^^^^ `T` is not dyn compatible
66
|
77
note: for a trait to be dyn compatible it needs to allow building a vtable
88
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
@@ -13,6 +13,11 @@ LL | trait T {
1313
LL | const CONST: (bool, dyn T);
1414
| ^^^^^ ...because it contains associated const `CONST`
1515
= help: consider moving `CONST` to another trait
16+
help: you might have meant to use `Self` to refer to the implementing type
17+
|
18+
LL - const CONST: (bool, dyn T);
19+
LL + const CONST: (bool, Self);
20+
|
1621

1722
error: aborting due to 1 previous error
1823

0 commit comments

Comments
 (0)