diff options
| author | Jacob Pratt <jacob@jhpratt.dev> | 2025-08-21 01:12:21 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-21 01:12:21 -0400 |
| commit | 64c43edffedaee7c06c024ea7fc3f84f73cac81f (patch) | |
| tree | f4b8dd9cede27b9088b0496723bcd00d25816089 /compiler/rustc_trait_selection | |
| parent | 803456aeffe837096d9dcc1640a62d19b6c443eb (diff) | |
| parent | e57e5f02b8fa3272d1ec4f75a0ab66dfed9b9b9b (diff) | |
| download | rust-64c43edffedaee7c06c024ea7fc3f84f73cac81f.tar.gz rust-64c43edffedaee7c06c024ea7fc3f84f73cac81f.zip | |
Rollup merge of #145627 - compiler-errors:const-supertrait-dyn-compat, r=fee1-dead
Unconditionally-const supertraits are considered not dyn compatible Let's save some space in the design of const traits by making `dyn Trait` where `trait Trait: const Super` not dyn compatible. Such a trait cannot satisfy `dyn Trait: Trait`; we could in the future make this dyn compatible but *NOT* implement `Trait`, but that's a bit weird and seems like it needs to be independently justified moving forward. Fixes https://github.com/rust-lang/rust/issues/145198 r? fee1-dead
Diffstat (limited to 'compiler/rustc_trait_selection')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs index ea1eed95723..4b493c95d59 100644 --- a/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs +++ b/compiler/rustc_trait_selection/src/traits/dyn_compatibility.rs @@ -106,6 +106,10 @@ fn dyn_compatibility_violations_for_trait( if !spans.is_empty() { violations.push(DynCompatibilityViolation::SupertraitNonLifetimeBinder(spans)); } + let spans = super_predicates_are_unconditionally_const(tcx, trait_def_id); + if !spans.is_empty() { + violations.push(DynCompatibilityViolation::SupertraitConst(spans)); + } violations } @@ -247,16 +251,31 @@ fn super_predicates_have_non_lifetime_binders( tcx: TyCtxt<'_>, trait_def_id: DefId, ) -> SmallVec<[Span; 1]> { - // If non_lifetime_binders is disabled, then exit early - if !tcx.features().non_lifetime_binders() { - return SmallVec::new(); - } tcx.explicit_super_predicates_of(trait_def_id) .iter_identity_copied() .filter_map(|(pred, span)| pred.has_non_region_bound_vars().then_some(span)) .collect() } +/// Checks for `const Trait` supertraits. We're okay with `[const] Trait`, +/// supertraits since for a non-const instantiation of that trait, the +/// conditionally-const supertrait is also not required to be const. +fn super_predicates_are_unconditionally_const( + tcx: TyCtxt<'_>, + trait_def_id: DefId, +) -> SmallVec<[Span; 1]> { + tcx.explicit_super_predicates_of(trait_def_id) + .iter_identity_copied() + .filter_map(|(pred, span)| { + if let ty::ClauseKind::HostEffect(_) = pred.kind().skip_binder() { + Some(span) + } else { + None + } + }) + .collect() +} + fn trait_has_sized_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> bool { tcx.generics_require_sized_self(trait_def_id) } |
