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