@@ -48,6 +48,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
4848 ImplSource :: Builtin ( data)
4949 }
5050
51+ TransmutabilityCandidate => {
52+ let data = self . confirm_transmutability_candidate ( obligation) ?;
53+ ImplSource :: Builtin ( data)
54+ }
55+
5156 ParamCandidate ( param) => {
5257 let obligations =
5358 self . confirm_param_candidate ( obligation, param. map_bound ( |t| t. trait_ref ) ) ;
@@ -267,6 +272,53 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
267272 ImplSourceBuiltinData { nested : obligations }
268273 }
269274
275+ fn confirm_transmutability_candidate (
276+ & mut self ,
277+ obligation : & TraitObligation < ' tcx > ,
278+ ) -> Result < ImplSourceBuiltinData < PredicateObligation < ' tcx > > , SelectionError < ' tcx > > {
279+ debug ! ( ?obligation, "confirm_transmutability_candidate" ) ;
280+
281+ let predicate = obligation. predicate ;
282+
283+ let type_at = |i| predicate. map_bound ( |p| p. trait_ref . substs . type_at ( i) ) ;
284+ let bool_at = |i| {
285+ predicate
286+ . skip_binder ( )
287+ . trait_ref
288+ . substs
289+ . const_at ( i)
290+ . try_eval_bool ( self . tcx ( ) , obligation. param_env )
291+ . unwrap ( )
292+ } ;
293+
294+ let src_and_dst = predicate. map_bound ( |p| rustc_transmute:: Types {
295+ src : p. trait_ref . substs . type_at ( 1 ) ,
296+ dst : p. trait_ref . substs . type_at ( 0 ) ,
297+ } ) ;
298+
299+ let scope = type_at ( 2 ) . skip_binder ( ) ;
300+
301+ let assume = rustc_transmute:: Assume {
302+ alignment : bool_at ( 3 ) ,
303+ lifetimes : bool_at ( 4 ) ,
304+ validity : bool_at ( 5 ) ,
305+ visibility : bool_at ( 6 ) ,
306+ } ;
307+
308+ let cause = obligation. cause . clone ( ) ;
309+
310+ let mut transmute_env = rustc_transmute:: TransmuteTypeEnv :: new ( self . infcx ) ;
311+
312+ let maybe_transmutable = transmute_env. is_transmutable ( cause, src_and_dst, scope, assume) ;
313+
314+ use rustc_transmute:: Answer ;
315+
316+ match maybe_transmutable {
317+ Answer :: Yes => Ok ( ImplSourceBuiltinData { nested : vec ! [ ] } ) ,
318+ _ => Err ( Unimplemented ) ,
319+ }
320+ }
321+
270322 /// This handles the case where an `auto trait Foo` impl is being used.
271323 /// The idea is that the impl applies to `X : Foo` if the following conditions are met:
272324 ///
0 commit comments