99
1010use std:: ops:: ControlFlow ;
1111
12- use rustc_ast:: Mutability ;
1312use rustc_data_structures:: stack:: ensure_sufficient_stack;
1413use rustc_hir:: lang_items:: LangItem ;
1514use rustc_infer:: infer:: { DefineOpaqueTypes , HigherRankedType , InferOk } ;
1615use rustc_infer:: traits:: ObligationCauseCode ;
1716use rustc_middle:: traits:: { BuiltinImplSource , SignatureMismatchData } ;
18- use rustc_middle:: ty:: { self , GenericArgsRef , Ty , TyCtxt , Upcast , elaborate} ;
17+ use rustc_middle:: ty:: { self , GenericArgsRef , Region , Ty , TyCtxt , Upcast , elaborate} ;
1918use rustc_middle:: { bug, span_bug} ;
2019use rustc_span:: def_id:: DefId ;
2120use thin_vec:: thin_vec;
@@ -286,99 +285,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
286285 ) -> Result < PredicateObligations < ' tcx > , SelectionError < ' tcx > > {
287286 use rustc_transmute:: { Answer , Assume , Condition } ;
288287
289- /// Generate sub-obligations for reference-to-reference transmutations.
290- fn reference_obligations < ' tcx > (
291- tcx : TyCtxt < ' tcx > ,
292- obligation : & PolyTraitObligation < ' tcx > ,
293- ( src_lifetime, src_ty, src_mut) : ( ty:: Region < ' tcx > , Ty < ' tcx > , Mutability ) ,
294- ( dst_lifetime, dst_ty, dst_mut) : ( ty:: Region < ' tcx > , Ty < ' tcx > , Mutability ) ,
295- assume : Assume ,
296- ) -> PredicateObligations < ' tcx > {
297- let make_transmute_obl = |src, dst| {
298- let transmute_trait = obligation. predicate . def_id ( ) ;
299- let assume = obligation. predicate . skip_binder ( ) . trait_ref . args . const_at ( 2 ) ;
300- let trait_ref = ty:: TraitRef :: new (
301- tcx,
302- transmute_trait,
303- [
304- ty:: GenericArg :: from ( dst) ,
305- ty:: GenericArg :: from ( src) ,
306- ty:: GenericArg :: from ( assume) ,
307- ] ,
308- ) ;
309- Obligation :: with_depth (
310- tcx,
311- obligation. cause . clone ( ) ,
312- obligation. recursion_depth + 1 ,
313- obligation. param_env ,
314- trait_ref,
315- )
316- } ;
317-
318- let make_freeze_obl = |ty| {
319- let trait_ref = ty:: TraitRef :: new (
320- tcx,
321- tcx. require_lang_item ( LangItem :: Freeze , obligation. cause . span ) ,
322- [ ty:: GenericArg :: from ( ty) ] ,
323- ) ;
324- Obligation :: with_depth (
325- tcx,
326- obligation. cause . clone ( ) ,
327- obligation. recursion_depth + 1 ,
328- obligation. param_env ,
329- trait_ref,
330- )
331- } ;
332-
333- let make_outlives_obl = |target, region| {
334- let outlives = ty:: OutlivesPredicate ( target, region) ;
335- Obligation :: with_depth (
336- tcx,
337- obligation. cause . clone ( ) ,
338- obligation. recursion_depth + 1 ,
339- obligation. param_env ,
340- outlives,
341- )
342- } ;
343-
344- // Given a transmutation from `&'a (mut) Src` and `&'dst (mut) Dst`,
345- // it is always the case that `Src` must be transmutable into `Dst`,
346- // and that that `'src` must outlive `'dst`.
347- let mut obls = PredicateObligations :: with_capacity ( 1 ) ;
348- obls. push ( make_transmute_obl ( src_ty, dst_ty) ) ;
349- if !assume. lifetimes {
350- obls. push ( make_outlives_obl ( src_lifetime, dst_lifetime) ) ;
351- }
352-
353- // Given a transmutation from `&Src`, both `Src` and `Dst` must be
354- // `Freeze`, otherwise, using the transmuted value could lead to
355- // data races.
356- if src_mut == Mutability :: Not {
357- obls. extend ( [ make_freeze_obl ( src_ty) , make_freeze_obl ( dst_ty) ] )
358- }
359-
360- // Given a transmutation into `&'dst mut Dst`, it also must be the
361- // case that `Dst` is transmutable into `Src`. For example,
362- // transmuting bool -> u8 is OK as long as you can't update that u8
363- // to be > 1, because you could later transmute the u8 back to a
364- // bool and get undefined behavior. It also must be the case that
365- // `'dst` lives exactly as long as `'src`.
366- if dst_mut == Mutability :: Mut {
367- obls. push ( make_transmute_obl ( dst_ty, src_ty) ) ;
368- if !assume. lifetimes {
369- obls. push ( make_outlives_obl ( dst_lifetime, src_lifetime) ) ;
370- }
371- }
372-
373- obls
374- }
375-
376288 /// Flatten the `Condition` tree into a conjunction of obligations.
377289 #[ instrument( level = "debug" , skip( tcx, obligation) ) ]
378290 fn flatten_answer_tree < ' tcx > (
379291 tcx : TyCtxt < ' tcx > ,
380292 obligation : & PolyTraitObligation < ' tcx > ,
381- cond : Condition < rustc_transmute :: layout :: rustc :: Ref < ' tcx > > ,
293+ cond : Condition < Region < ' tcx > , Ty < ' tcx > > ,
382294 assume : Assume ,
383295 ) -> PredicateObligations < ' tcx > {
384296 match cond {
@@ -388,13 +300,50 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
388300 . into_iter ( )
389301 . flat_map ( |cond| flatten_answer_tree ( tcx, obligation, cond, assume) )
390302 . collect ( ) ,
391- Condition :: IfTransmutable { src, dst } => reference_obligations (
392- tcx,
393- obligation,
394- ( src. lifetime , src. ty , src. mutability ) ,
395- ( dst. lifetime , dst. ty , dst. mutability ) ,
396- assume,
397- ) ,
303+ Condition :: Immutable { ty } => {
304+ let trait_ref = ty:: TraitRef :: new (
305+ tcx,
306+ tcx. require_lang_item ( LangItem :: Freeze , obligation. cause . span ) ,
307+ [ ty:: GenericArg :: from ( ty) ] ,
308+ ) ;
309+ thin_vec ! [ Obligation :: with_depth(
310+ tcx,
311+ obligation. cause. clone( ) ,
312+ obligation. recursion_depth + 1 ,
313+ obligation. param_env,
314+ trait_ref,
315+ ) ]
316+ }
317+ Condition :: Outlives { long, short } => {
318+ let outlives = ty:: OutlivesPredicate ( long, short) ;
319+ thin_vec ! [ Obligation :: with_depth(
320+ tcx,
321+ obligation. cause. clone( ) ,
322+ obligation. recursion_depth + 1 ,
323+ obligation. param_env,
324+ outlives,
325+ ) ]
326+ }
327+ Condition :: Transmutable { src, dst } => {
328+ let transmute_trait = obligation. predicate . def_id ( ) ;
329+ let assume = obligation. predicate . skip_binder ( ) . trait_ref . args . const_at ( 2 ) ;
330+ let trait_ref = ty:: TraitRef :: new (
331+ tcx,
332+ transmute_trait,
333+ [
334+ ty:: GenericArg :: from ( dst) ,
335+ ty:: GenericArg :: from ( src) ,
336+ ty:: GenericArg :: from ( assume) ,
337+ ] ,
338+ ) ;
339+ thin_vec ! [ Obligation :: with_depth(
340+ tcx,
341+ obligation. cause. clone( ) ,
342+ obligation. recursion_depth + 1 ,
343+ obligation. param_env,
344+ trait_ref,
345+ ) ]
346+ }
398347 }
399348 }
400349
0 commit comments