From 6b7e7265590a74f0cf03bb1669e5e032ee388635 Mon Sep 17 00:00:00 2001 From: qaijuang <237468078+qaijuang@users.noreply.github.com> Date: Fri, 15 May 2026 09:31:55 -0400 Subject: [PATCH 1/2] Add regression test for impossible dyn Sized predicate --- tests/ui/const_prop/issue-102553.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/ui/const_prop/issue-102553.rs b/tests/ui/const_prop/issue-102553.rs index 2b04619e23b51..6d7abc0dba5c1 100644 --- a/tests/ui/const_prop/issue-102553.rs +++ b/tests/ui/const_prop/issue-102553.rs @@ -1,5 +1,5 @@ -//@ compile-flags: --crate-type=lib -//@ check-pass +//@ compile-flags: --crate-type=lib -Zmir-opt-level=3 +//@ build-pass pub trait Widget { fn boxed<'w>(self) -> Box + 'w> @@ -22,3 +22,21 @@ impl Widget for dyn WidgetDyn + '_ { Box::new(self) } } + +// Regression test for https://github.com/rust-lang/rust/issues/156051. +trait WidgetSize { + fn size<'w>(self) -> usize + where + Self: Sized + 'w; +} + +trait WidgetSizeDyn {} + +impl WidgetSize for dyn WidgetSizeDyn + '_ { + fn size<'w>(self) -> usize + where + Self: Sized + 'w, + { + core::mem::size_of::() + } +} From 3b6dffefc6fe6dd0ffc628d0e843406235dd47b4 Mon Sep 17 00:00:00 2001 From: qaijuang <237468078+qaijuang@users.noreply.github.com> Date: Fri, 15 May 2026 09:34:03 -0400 Subject: [PATCH 2/2] Consider structurally impossible Sized predicates --- .../src/impossible_predicates.rs | 43 ++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_mir_transform/src/impossible_predicates.rs b/compiler/rustc_mir_transform/src/impossible_predicates.rs index 88486f6baddad..e7c8345f80d07 100644 --- a/compiler/rustc_mir_transform/src/impossible_predicates.rs +++ b/compiler/rustc_mir_transform/src/impossible_predicates.rs @@ -27,7 +27,7 @@ //! it's usually never invoked in this way. use rustc_middle::mir::{Body, START_BLOCK, TerminatorKind}; -use rustc_middle::ty::{TyCtxt, TypeFlags, TypeVisitableExt, Unnormalized}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFlags, TypeVisitableExt, Unnormalized}; use rustc_span::def_id::DefId; use rustc_trait_selection::traits; use tracing::trace; @@ -36,9 +36,48 @@ use crate::pass_manager::MirPass; pub(crate) struct ImpossiblePredicates; -fn has_impossible_predicates(tcx: TyCtxt<'_>, def_id: DefId) -> bool { +fn is_structurally_unsized<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { + match ty.kind() { + ty::Str | ty::Slice(_) | ty::Dynamic(_, _) | ty::Foreign(_) => true, + ty::Tuple(tys) => tys.last().is_some_and(|ty| is_structurally_unsized(tcx, *ty)), + ty::Adt(def, args) => { + def.sizedness_constraint(tcx, ty::SizedTraitKind::Sized).is_some_and(|ty| { + is_structurally_unsized(tcx, ty.instantiate(tcx, args).skip_norm_wip()) + }) + } + _ => false, + } +} + +fn has_structurally_impossible_sized_predicate<'tcx>( + tcx: TyCtxt<'tcx>, + sized_trait: DefId, + predicate: ty::Clause<'tcx>, +) -> bool { + let Some(trait_predicate) = predicate.as_trait_clause() else { + return false; + }; + let trait_predicate = trait_predicate.skip_binder(); + + trait_predicate.polarity == ty::PredicatePolarity::Positive + && trait_predicate.def_id() == sized_trait + && is_structurally_unsized(tcx, trait_predicate.self_ty()) +} + +fn has_impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool { let predicates = tcx.predicates_of(def_id).instantiate_identity(tcx); tracing::trace!(?predicates); + + // Some `Sized` predicates that mention local generics are still impossible + // for every instantiation, e.g. `dyn Trait: Sized`. + if let Some(sized_trait) = tcx.lang_items().sized_trait() { + if predicates.predicates.iter().copied().map(Unnormalized::skip_norm_wip).any(|predicate| { + has_structurally_impossible_sized_predicate(tcx, sized_trait, predicate) + }) { + return true; + } + } + let predicates = predicates.predicates.into_iter().map(Unnormalized::skip_norm_wip).filter(|p| { !p.has_type_flags(