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;
@@ -286,99 +285,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
286
285
) -> Result < PredicateObligations < ' tcx > , SelectionError < ' tcx > > {
287
286
use rustc_transmute:: { Answer , Assume , Condition } ;
288
287
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
-
376
288
/// Flatten the `Condition` tree into a conjunction of obligations.
377
289
#[ instrument( level = "debug" , skip( tcx, obligation) ) ]
378
290
fn flatten_answer_tree < ' tcx > (
379
291
tcx : TyCtxt < ' tcx > ,
380
292
obligation : & PolyTraitObligation < ' tcx > ,
381
- cond : Condition < rustc_transmute :: layout :: rustc :: Ref < ' tcx > > ,
293
+ cond : Condition < Region < ' tcx > , Ty < ' tcx > > ,
382
294
assume : Assume ,
383
295
) -> PredicateObligations < ' tcx > {
384
296
match cond {
@@ -388,13 +300,50 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
388
300
. into_iter ( )
389
301
. flat_map ( |cond| flatten_answer_tree ( tcx, obligation, cond, assume) )
390
302
. 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
+ }
398
347
}
399
348
}
400
349
0 commit comments