9
9
10
10
use std:: ops:: ControlFlow ;
11
11
12
- use rustc_ast:: Mutability ;
13
12
use rustc_data_structures:: stack:: ensure_sufficient_stack;
14
13
use rustc_hir:: lang_items:: LangItem ;
15
14
use rustc_infer:: infer:: { DefineOpaqueTypes , HigherRankedType , InferOk } ;
16
15
use rustc_infer:: traits:: ObligationCauseCode ;
17
16
use 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} ;
19
18
use rustc_middle:: { bug, span_bug} ;
20
19
use rustc_span:: def_id:: DefId ;
21
20
use thin_vec:: thin_vec;
@@ -291,99 +290,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
291
290
) -> Result < PredicateObligations < ' tcx > , SelectionError < ' tcx > > {
292
291
use rustc_transmute:: { Answer , Assume , Condition } ;
293
292
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
-
381
293
/// Flatten the `Condition` tree into a conjunction of obligations.
382
294
#[ instrument( level = "debug" , skip( tcx, obligation) ) ]
383
295
fn flatten_answer_tree < ' tcx > (
384
296
tcx : TyCtxt < ' tcx > ,
385
297
obligation : & PolyTraitObligation < ' tcx > ,
386
- cond : Condition < rustc_transmute :: layout :: rustc :: Ref < ' tcx > > ,
298
+ cond : Condition < Region < ' tcx > , Ty < ' tcx > > ,
387
299
assume : Assume ,
388
300
) -> PredicateObligations < ' tcx > {
389
301
match cond {
@@ -393,13 +305,50 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
393
305
. into_iter ( )
394
306
. flat_map ( |cond| flatten_answer_tree ( tcx, obligation, cond, assume) )
395
307
. 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
+ }
403
352
}
404
353
}
405
354
0 commit comments