@@ -2247,124 +2247,143 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
22472247 span : Span ,
22482248 ) -> GetSafeTransmuteErrorAndReason {
22492249 use rustc_transmute:: Answer ;
2250+ self . probe ( |_| {
2251+ // We don't assemble a transmutability candidate for types that are generic
2252+ // and we should have ambiguity for types that still have non-region infer.
2253+ if obligation. predicate . has_non_region_param ( ) || obligation. has_non_region_infer ( ) {
2254+ return GetSafeTransmuteErrorAndReason :: Default ;
2255+ }
22502256
2251- // We don't assemble a transmutability candidate for types that are generic
2252- // and we should have ambiguity for types that still have non-region infer.
2253- if obligation. predicate . has_non_region_param ( ) || obligation. has_non_region_infer ( ) {
2254- return GetSafeTransmuteErrorAndReason :: Default ;
2255- }
2257+ // Erase regions because layout code doesn't particularly care about regions.
2258+ let trait_ref =
2259+ self . tcx . erase_regions ( self . tcx . instantiate_bound_regions_with_erased ( trait_ref) ) ;
22562260
2257- // Erase regions because layout code doesn't particularly care about regions.
2258- let trait_ref =
2259- self . tcx . erase_regions ( self . tcx . instantiate_bound_regions_with_erased ( trait_ref) ) ;
2261+ let src_and_dst = rustc_transmute:: Types {
2262+ dst : trait_ref. args . type_at ( 0 ) ,
2263+ src : trait_ref. args . type_at ( 1 ) ,
2264+ } ;
22602265
2261- let src_and_dst = rustc_transmute:: Types {
2262- dst : trait_ref. args . type_at ( 0 ) ,
2263- src : trait_ref. args . type_at ( 1 ) ,
2264- } ;
2265- let Some ( assume) = rustc_transmute:: Assume :: from_const (
2266- self . infcx . tcx ,
2267- obligation. param_env ,
2268- trait_ref. args . const_at ( 2 ) ,
2269- ) else {
2270- self . dcx ( ) . span_delayed_bug (
2271- span,
2272- "Unable to construct rustc_transmute::Assume where it was previously possible" ,
2273- ) ;
2274- return GetSafeTransmuteErrorAndReason :: Silent ;
2275- } ;
2266+ let ocx = ObligationCtxt :: new ( self ) ;
2267+ let Ok ( assume) = ocx. structurally_normalize_const (
2268+ & obligation. cause ,
2269+ obligation. param_env ,
2270+ trait_ref. args . const_at ( 2 ) ,
2271+ ) else {
2272+ self . dcx ( ) . span_delayed_bug (
2273+ span,
2274+ "Unable to construct rustc_transmute::Assume where it was previously possible" ,
2275+ ) ;
2276+ return GetSafeTransmuteErrorAndReason :: Silent ;
2277+ } ;
22762278
2277- let dst = trait_ref. args . type_at ( 0 ) ;
2278- let src = trait_ref. args . type_at ( 1 ) ;
2279+ let Some ( assume) =
2280+ rustc_transmute:: Assume :: from_const ( self . infcx . tcx , obligation. param_env , assume)
2281+ else {
2282+ self . dcx ( ) . span_delayed_bug (
2283+ span,
2284+ "Unable to construct rustc_transmute::Assume where it was previously possible" ,
2285+ ) ;
2286+ return GetSafeTransmuteErrorAndReason :: Silent ;
2287+ } ;
22792288
2280- let err_msg = format ! ( "`{src}` cannot be safely transmuted into `{dst}`" ) ;
2289+ let dst = trait_ref. args . type_at ( 0 ) ;
2290+ let src = trait_ref. args . type_at ( 1 ) ;
2291+ let err_msg = format ! ( "`{src}` cannot be safely transmuted into `{dst}`" ) ;
22812292
2282- match rustc_transmute:: TransmuteTypeEnv :: new ( self . infcx ) . is_transmutable (
2283- obligation. cause ,
2284- src_and_dst,
2285- assume,
2286- ) {
2287- Answer :: No ( reason) => {
2288- let safe_transmute_explanation = match reason {
2289- rustc_transmute:: Reason :: SrcIsNotYetSupported => {
2290- format ! ( "analyzing the transmutability of `{src}` is not yet supported" )
2291- }
2293+ match rustc_transmute:: TransmuteTypeEnv :: new ( self . infcx ) . is_transmutable (
2294+ obligation. cause ,
2295+ src_and_dst,
2296+ assume,
2297+ ) {
2298+ Answer :: No ( reason) => {
2299+ let safe_transmute_explanation = match reason {
2300+ rustc_transmute:: Reason :: SrcIsNotYetSupported => {
2301+ format ! ( "analyzing the transmutability of `{src}` is not yet supported" )
2302+ }
22922303
2293- rustc_transmute:: Reason :: DstIsNotYetSupported => {
2294- format ! ( "analyzing the transmutability of `{dst}` is not yet supported" )
2295- }
2304+ rustc_transmute:: Reason :: DstIsNotYetSupported => {
2305+ format ! ( "analyzing the transmutability of `{dst}` is not yet supported" )
2306+ }
22962307
2297- rustc_transmute:: Reason :: DstIsBitIncompatible => {
2298- format ! ( "at least one value of `{src}` isn't a bit-valid value of `{dst}`" )
2299- }
2308+ rustc_transmute:: Reason :: DstIsBitIncompatible => {
2309+ format ! (
2310+ "at least one value of `{src}` isn't a bit-valid value of `{dst}`"
2311+ )
2312+ }
23002313
2301- rustc_transmute:: Reason :: DstUninhabited => {
2302- format ! ( "`{dst}` is uninhabited" )
2303- }
2314+ rustc_transmute:: Reason :: DstUninhabited => {
2315+ format ! ( "`{dst}` is uninhabited" )
2316+ }
23042317
2305- rustc_transmute:: Reason :: DstMayHaveSafetyInvariants => {
2306- format ! ( "`{dst}` may carry safety invariants" )
2307- }
2308- rustc_transmute:: Reason :: DstIsTooBig => {
2309- format ! ( "the size of `{src}` is smaller than the size of `{dst}`" )
2310- }
2311- rustc_transmute:: Reason :: DstRefIsTooBig { src, dst } => {
2312- let src_size = src. size ;
2313- let dst_size = dst. size ;
2314- format ! (
2315- "the referent size of `{src}` ({src_size} bytes) is smaller than that of `{dst}` ({dst_size} bytes)"
2316- )
2317- }
2318- rustc_transmute:: Reason :: SrcSizeOverflow => {
2319- format ! (
2320- "values of the type `{src}` are too big for the target architecture"
2321- )
2322- }
2323- rustc_transmute:: Reason :: DstSizeOverflow => {
2324- format ! (
2325- "values of the type `{dst}` are too big for the target architecture"
2326- )
2327- }
2328- rustc_transmute:: Reason :: DstHasStricterAlignment {
2329- src_min_align,
2330- dst_min_align,
2331- } => {
2332- format ! (
2333- "the minimum alignment of `{src}` ({src_min_align}) should be greater than that of `{dst}` ({dst_min_align})"
2334- )
2335- }
2336- rustc_transmute:: Reason :: DstIsMoreUnique => {
2337- format ! ( "`{src}` is a shared reference, but `{dst}` is a unique reference" )
2338- }
2339- // Already reported by rustc
2340- rustc_transmute:: Reason :: TypeError => {
2341- return GetSafeTransmuteErrorAndReason :: Silent ;
2342- }
2343- rustc_transmute:: Reason :: SrcLayoutUnknown => {
2344- format ! ( "`{src}` has an unknown layout" )
2345- }
2346- rustc_transmute:: Reason :: DstLayoutUnknown => {
2347- format ! ( "`{dst}` has an unknown layout" )
2318+ rustc_transmute:: Reason :: DstMayHaveSafetyInvariants => {
2319+ format ! ( "`{dst}` may carry safety invariants" )
2320+ }
2321+ rustc_transmute:: Reason :: DstIsTooBig => {
2322+ format ! ( "the size of `{src}` is smaller than the size of `{dst}`" )
2323+ }
2324+ rustc_transmute:: Reason :: DstRefIsTooBig { src, dst } => {
2325+ let src_size = src. size ;
2326+ let dst_size = dst. size ;
2327+ format ! (
2328+ "the referent size of `{src}` ({src_size} bytes) \
2329+ is smaller than that of `{dst}` ({dst_size} bytes)"
2330+ )
2331+ }
2332+ rustc_transmute:: Reason :: SrcSizeOverflow => {
2333+ format ! (
2334+ "values of the type `{src}` are too big for the target architecture"
2335+ )
2336+ }
2337+ rustc_transmute:: Reason :: DstSizeOverflow => {
2338+ format ! (
2339+ "values of the type `{dst}` are too big for the target architecture"
2340+ )
2341+ }
2342+ rustc_transmute:: Reason :: DstHasStricterAlignment {
2343+ src_min_align,
2344+ dst_min_align,
2345+ } => {
2346+ format ! (
2347+ "the minimum alignment of `{src}` ({src_min_align}) should \
2348+ be greater than that of `{dst}` ({dst_min_align})"
2349+ )
2350+ }
2351+ rustc_transmute:: Reason :: DstIsMoreUnique => {
2352+ format ! (
2353+ "`{src}` is a shared reference, but `{dst}` is a unique reference"
2354+ )
2355+ }
2356+ // Already reported by rustc
2357+ rustc_transmute:: Reason :: TypeError => {
2358+ return GetSafeTransmuteErrorAndReason :: Silent ;
2359+ }
2360+ rustc_transmute:: Reason :: SrcLayoutUnknown => {
2361+ format ! ( "`{src}` has an unknown layout" )
2362+ }
2363+ rustc_transmute:: Reason :: DstLayoutUnknown => {
2364+ format ! ( "`{dst}` has an unknown layout" )
2365+ }
2366+ } ;
2367+ GetSafeTransmuteErrorAndReason :: Error {
2368+ err_msg,
2369+ safe_transmute_explanation : Some ( safe_transmute_explanation) ,
23482370 }
2349- } ;
2350- GetSafeTransmuteErrorAndReason :: Error {
2351- err_msg,
2352- safe_transmute_explanation : Some ( safe_transmute_explanation) ,
23532371 }
2372+ // Should never get a Yes at this point! We already ran it before, and did not get a Yes.
2373+ Answer :: Yes => span_bug ! (
2374+ span,
2375+ "Inconsistent rustc_transmute::is_transmutable(...) result, got Yes" ,
2376+ ) ,
2377+ // Reached when a different obligation (namely `Freeze`) causes the
2378+ // transmutability analysis to fail. In this case, silence the
2379+ // transmutability error message in favor of that more specific
2380+ // error.
2381+ Answer :: If ( _) => GetSafeTransmuteErrorAndReason :: Error {
2382+ err_msg,
2383+ safe_transmute_explanation : None ,
2384+ } ,
23542385 }
2355- // Should never get a Yes at this point! We already ran it before, and did not get a Yes.
2356- Answer :: Yes => span_bug ! (
2357- span,
2358- "Inconsistent rustc_transmute::is_transmutable(...) result, got Yes" ,
2359- ) ,
2360- // Reached when a different obligation (namely `Freeze`) causes the
2361- // transmutability analysis to fail. In this case, silence the
2362- // transmutability error message in favor of that more specific
2363- // error.
2364- Answer :: If ( _) => {
2365- GetSafeTransmuteErrorAndReason :: Error { err_msg, safe_transmute_explanation : None }
2366- }
2367- }
2386+ } )
23682387 }
23692388
23702389 /// For effects predicates such as `<u32 as Add>::Effects: Compat<host>`, pretend that the
0 commit comments