@@ -254,9 +254,16 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
254254 LangItem :: TransmuteTrait ,
255255 ) {
256256 // Recompute the safe transmute reason and use that for the error reporting
257+ let ( report_obligation, report_pred) =
258+ self . select_transmute_obligation_for_reporting (
259+ & obligation,
260+ main_trait_predicate,
261+ root_obligation,
262+ ) ;
263+
257264 match self . get_safe_transmute_error_and_reason (
258- obligation . clone ( ) ,
259- main_trait_predicate ,
265+ report_obligation ,
266+ report_pred ,
260267 span,
261268 ) {
262269 GetSafeTransmuteErrorAndReason :: Silent => {
@@ -2793,6 +2800,51 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
27932800 } )
27942801 }
27952802
2803+ fn select_transmute_obligation_for_reporting (
2804+ & self ,
2805+ obligation : & PredicateObligation < ' tcx > ,
2806+ trait_predicate : ty:: PolyTraitPredicate < ' tcx > ,
2807+ root_obligation : & PredicateObligation < ' tcx > ,
2808+ ) -> ( PredicateObligation < ' tcx > , ty:: PolyTraitPredicate < ' tcx > ) {
2809+ let ocx = ObligationCtxt :: new ( self ) ;
2810+ let normalized_predicate = self . tcx . erase_and_anonymize_regions (
2811+ self . tcx . instantiate_bound_regions_with_erased ( trait_predicate) ,
2812+ ) ;
2813+ let trait_ref = normalized_predicate. trait_ref ;
2814+
2815+ let Ok ( assume) = ocx. structurally_normalize_const (
2816+ & obligation. cause ,
2817+ obligation. param_env ,
2818+ trait_ref. args . const_at ( 2 ) ,
2819+ ) else {
2820+ return ( obligation. clone ( ) , trait_predicate) ;
2821+ } ;
2822+
2823+ let Some ( assume) = rustc_transmute:: Assume :: from_const ( self . tcx , assume) else {
2824+ return ( obligation. clone ( ) , trait_predicate) ;
2825+ } ;
2826+
2827+ let is_normalized_yes = matches ! (
2828+ rustc_transmute:: TransmuteTypeEnv :: new( self . tcx) . is_transmutable(
2829+ trait_ref. args. type_at( 1 ) ,
2830+ trait_ref. args. type_at( 0 ) ,
2831+ assume,
2832+ ) ,
2833+ rustc_transmute:: Answer :: Yes ,
2834+ ) ;
2835+
2836+ // If the normalized check unexpectedly passes, fall back to root obligation for reporting.
2837+ if is_normalized_yes
2838+ && let ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( root_pred) ) =
2839+ root_obligation. predicate . kind ( ) . skip_binder ( )
2840+ && root_pred. def_id ( ) == trait_predicate. def_id ( )
2841+ {
2842+ return ( root_obligation. clone ( ) , root_obligation. predicate . kind ( ) . rebind ( root_pred) ) ;
2843+ }
2844+
2845+ ( obligation. clone ( ) , trait_predicate)
2846+ }
2847+
27962848 fn get_safe_transmute_error_and_reason (
27972849 & self ,
27982850 obligation : PredicateObligation < ' tcx > ,
0 commit comments