[beta] Don't look for non-type-level assoc consts when checking trait object types

This commit is contained in:
León Orell Valerian Liehr
2026-03-11 19:39:47 +01:00
parent 94a8e826a5
commit bdc1b3ffa8
10 changed files with 82 additions and 15 deletions
@@ -230,8 +230,9 @@ pub(super) fn lower_trait_object_ty(
ordered_associated_items.extend(
tcx.associated_items(pred.trait_ref.def_id)
.in_definition_order()
// Only associated types & consts can possibly be constrained via a binding.
.filter(|item| item.is_type() || item.is_const())
// Only associated types & type consts can possibly be
// constrained in a trait object type via a binding.
.filter(|item| item.is_type() || item.is_type_const(tcx))
// Traits with RPITITs are simply not dyn compatible (for now).
.filter(|item| !item.is_impl_trait_in_trait())
.map(|item| (item.def_id, trait_ref)),
+2 -2
View File
@@ -137,8 +137,8 @@ pub fn as_def_kind(&self) -> DefKind {
self.kind.as_def_kind()
}
pub fn is_const(&self) -> bool {
matches!(self.kind, ty::AssocKind::Const { .. })
pub fn is_type_const(&self, tcx: TyCtxt<'_>) -> bool {
matches!(self.kind, ty::AssocKind::Const { .. }) && tcx.is_rhs_type_const(self.def_id)
}
pub fn is_fn(&self) -> bool {
+1 -1
View File
@@ -724,7 +724,7 @@ pub fn new_dynamic(
.map(|principal| {
tcx.associated_items(principal.def_id())
.in_definition_order()
.filter(|item| item.is_type() || item.is_const())
.filter(|item| item.is_type() || item.is_type_const(tcx))
.filter(|item| !item.is_impl_trait_in_trait())
.filter(|item| !tcx.generics_require_sized_self(item.def_id))
.count()
@@ -239,7 +239,7 @@ fn trait_object_ty<'tcx>(tcx: TyCtxt<'tcx>, poly_trait_ref: ty::PolyTraitRef<'tc
.flat_map(|super_poly_trait_ref| {
tcx.associated_items(super_poly_trait_ref.def_id())
.in_definition_order()
.filter(|item| item.is_type() || item.is_const())
.filter(|item| item.is_type() || item.is_type_const(tcx))
.filter(|item| !tcx.generics_require_sized_self(item.def_id))
.map(move |assoc_item| {
super_poly_trait_ref.map_bound(|super_trait_ref| {
@@ -7,6 +7,8 @@ trait Trait {
impl dyn Trait {
//~^ ERROR the trait `Trait` is not dyn compatible [E0038]
const fn n() -> usize { Self::N }
//~^ ERROR the trait `Trait` is not dyn compatible [E0038]
//~| ERROR the trait `Trait` is not dyn compatible [E0038]
}
fn main() {}
@@ -1,8 +1,8 @@
error[E0038]: the trait `Trait` is not dyn compatible
--> $DIR/associated-const-in-trait.rs:7:10
--> $DIR/associated-const-in-trait.rs:7:6
|
LL | impl dyn Trait {
| ^^^^^ `Trait` is not dyn compatible
| ^^^^^^^^^ `Trait` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
@@ -14,6 +14,38 @@ LL | const N: usize;
| ^ ...because it contains associated const `N`
= help: consider moving `N` to another trait
error: aborting due to 1 previous error
error[E0038]: the trait `Trait` is not dyn compatible
--> $DIR/associated-const-in-trait.rs:9:29
|
LL | const fn n() -> usize { Self::N }
| ^^^^ `Trait` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/associated-const-in-trait.rs:4:11
|
LL | trait Trait {
| ----- this trait is not dyn compatible...
LL | const N: usize;
| ^ ...because it contains associated const `N`
= help: consider moving `N` to another trait
error[E0038]: the trait `Trait` is not dyn compatible
--> $DIR/associated-const-in-trait.rs:9:29
|
LL | const fn n() -> usize { Self::N }
| ^^^^^^^ `Trait` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/associated-const-in-trait.rs:4:11
|
LL | trait Trait {
| ----- this trait is not dyn compatible...
LL | const N: usize;
| ^ ...because it contains associated const `N`
= help: consider moving `N` to another trait
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0038`.
+2 -2
View File
@@ -1,8 +1,8 @@
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/issue-48027.rs:6:10
--> $DIR/issue-48027.rs:6:6
|
LL | impl dyn Bar {}
| ^^^ `Bar` is not dyn compatible
| ^^^^^^^ `Bar` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
@@ -1,8 +1,8 @@
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/associated-consts.rs:8:35
--> $DIR/associated-consts.rs:8:31
|
LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
| ^^^ `Bar` is not dyn compatible
| ^^^^^^^ `Bar` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
+27
View File
@@ -0,0 +1,27 @@
// Demonstrate that we don't check the definition site of (eager) type aliases for well-formedness.
//
// Listed below are ill-formed type system entities which we don't reject since they appear inside
// the definition of (eager) type aliases. These type aliases are intentionally not referenced from
// anywhere to prevent the eagerly expanded / instantiated aliased types from getting wfchecked
// since that's not what we're testing here.
//@ check-pass
type UnsatTraitBound0 = [str]; // `str: Sized` unsatisfied
type UnsatTraitBound1<T = Vec<str>> = T; // `str: Sized` unsatisfied
type UnsatOutlivesBound<'a> = &'static &'a (); // `'a: 'static` unsatisfied
type Diverging = [(); panic!()]; // `panic!()` diverging
type DynIncompat0 = dyn Sized; // `Sized` axiomatically dyn incompatible
// issue: <https://github.com/rust-lang/rust/issues/153731>
type DynIncompat1 = dyn HasAssocConst; // dyn incompatible due to (non-type-level) assoc const
// * dyn incompatible due to GAT
// * `'a: 'static`, `String: Copy` and `[u8]: Sized` unsatisfied, `loop {}` diverging
type Several<'a> = dyn HasGenericAssocType<Type<'a, String, { loop {} }> = [u8]>;
trait HasAssocConst { const N: usize; }
trait HasGenericAssocType { type Type<'a: 'static, T: Copy, const N: usize>; }
fn main() {}
+7 -2
View File
@@ -1,8 +1,8 @@
error[E0038]: the trait `T` is not dyn compatible
--> $DIR/issue-87495.rs:4:29
--> $DIR/issue-87495.rs:4:25
|
LL | const CONST: (bool, dyn T);
| ^ `T` is not dyn compatible
| ^^^^^ `T` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
@@ -13,6 +13,11 @@ LL | trait T {
LL | const CONST: (bool, dyn T);
| ^^^^^ ...because it contains associated const `CONST`
= help: consider moving `CONST` to another trait
help: you might have meant to use `Self` to refer to the implementing type
|
LL - const CONST: (bool, dyn T);
LL + const CONST: (bool, Self);
|
error: aborting due to 1 previous error