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;
@@ -291,99 +290,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
291290 ) -> Result < PredicateObligations < ' tcx > , SelectionError < ' tcx > > {
292291 use rustc_transmute:: { Answer , Assume , Condition } ;
293292
294- /// Generate sub-obligations for reference-to-reference transmutations.
295- fn reference_obligations < ' tcx > (
296- tcx : TyCtxt < ' tcx > ,
297- obligation : & PolyTraitObligation < ' tcx > ,
298- ( src_lifetime, src_ty, src_mut) : ( ty:: Region < ' tcx > , Ty < ' tcx > , Mutability ) ,
299- ( dst_lifetime, dst_ty, dst_mut) : ( ty:: Region < ' tcx > , Ty < ' tcx > , Mutability ) ,
300- assume : Assume ,
301- ) -> PredicateObligations < ' tcx > {
302- let make_transmute_obl = |src, dst| {
303- let transmute_trait = obligation. predicate . def_id ( ) ;
304- let assume = obligation. predicate . skip_binder ( ) . trait_ref . args . const_at ( 2 ) ;
305- let trait_ref = ty:: TraitRef :: new (
306- tcx,
307- transmute_trait,
308- [
309- ty:: GenericArg :: from ( dst) ,
310- ty:: GenericArg :: from ( src) ,
311- ty:: GenericArg :: from ( assume) ,
312- ] ,
313- ) ;
314- Obligation :: with_depth (
315- tcx,
316- obligation. cause . clone ( ) ,
317- obligation. recursion_depth + 1 ,
318- obligation. param_env ,
319- trait_ref,
320- )
321- } ;
322-
323- let make_freeze_obl = |ty| {
324- let trait_ref = ty:: TraitRef :: new (
325- tcx,
326- tcx. require_lang_item ( LangItem :: Freeze , None ) ,
327- [ ty:: GenericArg :: from ( ty) ] ,
328- ) ;
329- Obligation :: with_depth (
330- tcx,
331- obligation. cause . clone ( ) ,
332- obligation. recursion_depth + 1 ,
333- obligation. param_env ,
334- trait_ref,
335- )
336- } ;
337-
338- let make_outlives_obl = |target, region| {
339- let outlives = ty:: OutlivesPredicate ( target, region) ;
340- Obligation :: with_depth (
341- tcx,
342- obligation. cause . clone ( ) ,
343- obligation. recursion_depth + 1 ,
344- obligation. param_env ,
345- outlives,
346- )
347- } ;
348-
349- // Given a transmutation from `&'a (mut) Src` and `&'dst (mut) Dst`,
350- // it is always the case that `Src` must be transmutable into `Dst`,
351- // and that that `'src` must outlive `'dst`.
352- let mut obls = PredicateObligations :: with_capacity ( 1 ) ;
353- obls. push ( make_transmute_obl ( src_ty, dst_ty) ) ;
354- if !assume. lifetimes {
355- obls. push ( make_outlives_obl ( src_lifetime, dst_lifetime) ) ;
356- }
357-
358- // Given a transmutation from `&Src`, both `Src` and `Dst` must be
359- // `Freeze`, otherwise, using the transmuted value could lead to
360- // data races.
361- if src_mut == Mutability :: Not {
362- obls. extend ( [ make_freeze_obl ( src_ty) , make_freeze_obl ( dst_ty) ] )
363- }
364-
365- // Given a transmutation into `&'dst mut Dst`, it also must be the
366- // case that `Dst` is transmutable into `Src`. For example,
367- // transmuting bool -> u8 is OK as long as you can't update that u8
368- // to be > 1, because you could later transmute the u8 back to a
369- // bool and get undefined behavior. It also must be the case that
370- // `'dst` lives exactly as long as `'src`.
371- if dst_mut == Mutability :: Mut {
372- obls. push ( make_transmute_obl ( dst_ty, src_ty) ) ;
373- if !assume. lifetimes {
374- obls. push ( make_outlives_obl ( dst_lifetime, src_lifetime) ) ;
375- }
376- }
377-
378- obls
379- }
380-
381293 /// Flatten the `Condition` tree into a conjunction of obligations.
382294 #[ instrument( level = "debug" , skip( tcx, obligation) ) ]
383295 fn flatten_answer_tree < ' tcx > (
384296 tcx : TyCtxt < ' tcx > ,
385297 obligation : & PolyTraitObligation < ' tcx > ,
386- cond : Condition < rustc_transmute :: layout :: rustc :: Ref < ' tcx > > ,
298+ cond : Condition < Region < ' tcx > , Ty < ' tcx > > ,
387299 assume : Assume ,
388300 ) -> PredicateObligations < ' tcx > {
389301 match cond {
@@ -393,13 +305,50 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
393305 . into_iter ( )
394306 . flat_map ( |cond| flatten_answer_tree ( tcx, obligation, cond, assume) )
395307 . collect ( ) ,
396- Condition :: IfTransmutable { src, dst } => reference_obligations (
397- tcx,
398- obligation,
399- ( src. lifetime , src. ty , src. mutability ) ,
400- ( dst. lifetime , dst. ty , dst. mutability ) ,
401- assume,
402- ) ,
308+ Condition :: Immutable { ty } => {
309+ let trait_ref = ty:: TraitRef :: new (
310+ tcx,
311+ tcx. require_lang_item ( LangItem :: Freeze , None ) ,
312+ [ ty:: GenericArg :: from ( ty) ] ,
313+ ) ;
314+ thin_vec ! [ Obligation :: with_depth(
315+ tcx,
316+ obligation. cause. clone( ) ,
317+ obligation. recursion_depth + 1 ,
318+ obligation. param_env,
319+ trait_ref,
320+ ) ]
321+ }
322+ Condition :: Outlives { long, short } => {
323+ let outlives = ty:: OutlivesPredicate ( long, short) ;
324+ thin_vec ! [ Obligation :: with_depth(
325+ tcx,
326+ obligation. cause. clone( ) ,
327+ obligation. recursion_depth + 1 ,
328+ obligation. param_env,
329+ outlives,
330+ ) ]
331+ }
332+ Condition :: Transmutable { src, dst } => {
333+ let transmute_trait = obligation. predicate . def_id ( ) ;
334+ let assume = obligation. predicate . skip_binder ( ) . trait_ref . args . const_at ( 2 ) ;
335+ let trait_ref = ty:: TraitRef :: new (
336+ tcx,
337+ transmute_trait,
338+ [
339+ ty:: GenericArg :: from ( dst) ,
340+ ty:: GenericArg :: from ( src) ,
341+ ty:: GenericArg :: from ( assume) ,
342+ ] ,
343+ ) ;
344+ thin_vec ! [ Obligation :: with_depth(
345+ tcx,
346+ obligation. cause. clone( ) ,
347+ obligation. recursion_depth + 1 ,
348+ obligation. param_env,
349+ trait_ref,
350+ ) ]
351+ }
403352 }
404353 }
405354
0 commit comments