@@ -65,6 +65,11 @@ pub struct ImplCandidate<'tcx> {
65
65
pub similarity : CandidateSimilarity ,
66
66
}
67
67
68
+ enum GetSafeTransmuteErrorAndReason {
69
+ Silent ,
70
+ Error { err_msg : String , safe_transmute_explanation : String } ,
71
+ }
72
+
68
73
pub trait InferCtxtExt < ' tcx > {
69
74
/// Given some node representing a fn-like thing in the HIR map,
70
75
/// returns a span and `ArgKind` information that describes the
@@ -724,11 +729,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
724
729
== self . tcx . lang_items ( ) . transmute_trait ( )
725
730
{
726
731
// Recompute the safe transmute reason and use that for the error reporting
727
- self . get_safe_transmute_error_and_reason (
732
+ match self . get_safe_transmute_error_and_reason (
728
733
obligation. clone ( ) ,
729
734
trait_ref,
730
735
span,
731
- )
736
+ ) {
737
+ GetSafeTransmuteErrorAndReason :: Silent => return ,
738
+ GetSafeTransmuteErrorAndReason :: Error {
739
+ err_msg,
740
+ safe_transmute_explanation,
741
+ } => ( err_msg, Some ( safe_transmute_explanation) ) ,
742
+ }
732
743
} else {
733
744
( err_msg, None )
734
745
} ;
@@ -1292,7 +1303,7 @@ trait InferCtxtPrivExt<'tcx> {
1292
1303
obligation : PredicateObligation < ' tcx > ,
1293
1304
trait_ref : ty:: PolyTraitRef < ' tcx > ,
1294
1305
span : Span ,
1295
- ) -> ( String , Option < String > ) ;
1306
+ ) -> GetSafeTransmuteErrorAndReason ;
1296
1307
1297
1308
fn add_tuple_trait_message (
1298
1309
& self ,
@@ -2738,7 +2749,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2738
2749
obligation : PredicateObligation < ' tcx > ,
2739
2750
trait_ref : ty:: PolyTraitRef < ' tcx > ,
2740
2751
span : Span ,
2741
- ) -> ( String , Option < String > ) {
2752
+ ) -> GetSafeTransmuteErrorAndReason {
2753
+ use rustc_transmute:: Answer ;
2754
+
2742
2755
// Erase regions because layout code doesn't particularly care about regions.
2743
2756
let trait_ref = self . tcx . erase_regions ( self . tcx . erase_late_bound_regions ( trait_ref) ) ;
2744
2757
@@ -2758,13 +2771,13 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2758
2771
scope,
2759
2772
assume,
2760
2773
) {
2761
- Err ( reason) => {
2774
+ Answer :: No ( reason) => {
2762
2775
let dst = trait_ref. substs . type_at ( 0 ) ;
2763
2776
let src = trait_ref. substs . type_at ( 1 ) ;
2764
- let custom_err_msg = format ! (
2777
+ let err_msg = format ! (
2765
2778
"`{src}` cannot be safely transmuted into `{dst}` in the defining scope of `{scope}`"
2766
2779
) ;
2767
- let reason_msg = match reason {
2780
+ let safe_transmute_explanation = match reason {
2768
2781
rustc_transmute:: Reason :: SrcIsUnspecified => {
2769
2782
format ! ( "`{src}` does not have a well-specified layout" )
2770
2783
}
@@ -2794,11 +2807,21 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
2794
2807
rustc_transmute:: Reason :: DstIsMoreUnique => {
2795
2808
format ! ( "`{src}` is a shared reference, but `{dst}` is a unique reference" )
2796
2809
}
2810
+ // Already reported by rustc
2811
+ rustc_transmute:: Reason :: TypeError => {
2812
+ return GetSafeTransmuteErrorAndReason :: Silent ;
2813
+ }
2814
+ rustc_transmute:: Reason :: SrcLayoutUnknown => {
2815
+ format ! ( "`{src}` has an unknown layout" )
2816
+ }
2817
+ rustc_transmute:: Reason :: DstLayoutUnknown => {
2818
+ format ! ( "`{dst}` has an unknown layout" )
2819
+ }
2797
2820
} ;
2798
- ( custom_err_msg , Some ( reason_msg ) )
2821
+ GetSafeTransmuteErrorAndReason :: Error { err_msg , safe_transmute_explanation }
2799
2822
}
2800
2823
// Should never get a Yes at this point! We already ran it before, and did not get a Yes.
2801
- Ok ( None ) => span_bug ! (
2824
+ Answer :: Yes => span_bug ! (
2802
2825
span,
2803
2826
"Inconsistent rustc_transmute::is_transmutable(...) result, got Yes" ,
2804
2827
) ,
0 commit comments