@@ -320,51 +320,70 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
320
320
}
321
321
322
322
pub fn write_cvalue ( self , fx : & mut FunctionCx < ' a , ' tcx , impl Backend > , from : CValue < ' tcx > ) {
323
+ use rustc:: hir:: Mutability :: * ;
324
+
323
325
let from_ty = from. layout ( ) . ty ;
324
326
let to_ty = self . layout ( ) . ty ;
325
- match ( & from_ty. sty , & to_ty. sty ) {
326
- ( ty:: Ref ( _, t, src_mut) , ty:: Ref ( _, u, dest_mut) )
327
- if ( if * dest_mut != crate :: rustc:: hir:: Mutability :: MutImmutable
328
- && src_mut != dest_mut
329
- {
330
- false
331
- } else if t != u {
332
- false
333
- } else {
334
- true
335
- } ) =>
336
- {
337
- // &mut T -> &T is allowed
338
- // &'a T -> &'b T is allowed
339
- }
340
- ( ty:: FnPtr ( _) , ty:: FnPtr ( _) ) => {
341
- let from_sig = fx. tcx . normalize_erasing_late_bound_regions (
342
- ParamEnv :: reveal_all ( ) ,
343
- & from_ty. fn_sig ( fx. tcx ) ,
344
- ) ;
345
- let to_sig = fx. tcx . normalize_erasing_late_bound_regions (
346
- ParamEnv :: reveal_all ( ) ,
347
- & to_ty. fn_sig ( fx. tcx ) ,
348
- ) ;
349
- assert_eq ! (
350
- from_sig, to_sig,
351
- "Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n \n {:#?}" ,
352
- from_sig, to_sig, fx,
353
- ) ;
354
- // fn(&T) -> for<'l> fn(&'l T) is allowed
355
- }
356
- _ => {
357
- assert_eq ! (
358
- from_ty,
359
- to_ty,
360
- "Can't write value with incompatible type {:?} to place with type {:?}\n \n {:#?}" ,
361
- from_ty. sty,
362
- to_ty. sty,
363
- fx,
364
- ) ;
327
+
328
+ fn assert_assignable < ' a , ' tcx : ' a > ( fx : & FunctionCx < ' a , ' tcx , impl Backend > , from_ty : Ty < ' tcx > , to_ty : Ty < ' tcx > ) {
329
+ match ( & from_ty. sty , & to_ty. sty ) {
330
+ ( ty:: Ref ( _, t, MutImmutable ) , ty:: Ref ( _, u, MutImmutable ) )
331
+ | ( ty:: Ref ( _, t, MutMutable ) , ty:: Ref ( _, u, MutImmutable ) )
332
+ | ( ty:: Ref ( _, t, MutMutable ) , ty:: Ref ( _, u, MutMutable ) ) => {
333
+ assert_assignable ( fx, t, u) ;
334
+ // &mut T -> &T is allowed
335
+ // &'a T -> &'b T is allowed
336
+ }
337
+ ( ty:: Ref ( _, _, MutImmutable ) , ty:: Ref ( _, _, MutMutable ) ) => {
338
+ panic ! ( "Cant assign value of type {} to place of type {}" , from_ty. sty, to_ty. sty)
339
+ }
340
+ ( ty:: FnPtr ( _) , ty:: FnPtr ( _) ) => {
341
+ let from_sig = fx. tcx . normalize_erasing_late_bound_regions (
342
+ ParamEnv :: reveal_all ( ) ,
343
+ & from_ty. fn_sig ( fx. tcx ) ,
344
+ ) ;
345
+ let to_sig = fx. tcx . normalize_erasing_late_bound_regions (
346
+ ParamEnv :: reveal_all ( ) ,
347
+ & to_ty. fn_sig ( fx. tcx ) ,
348
+ ) ;
349
+ assert_eq ! (
350
+ from_sig, to_sig,
351
+ "Can't write fn ptr with incompatible sig {:?} to place with sig {:?}\n \n {:#?}" ,
352
+ from_sig, to_sig, fx,
353
+ ) ;
354
+ // fn(&T) -> for<'l> fn(&'l T) is allowed
355
+ }
356
+ ( ty:: Dynamic ( from_traits, _) , ty:: Dynamic ( to_traits, _) ) => {
357
+ let from_traits = fx. tcx . normalize_erasing_late_bound_regions (
358
+ ParamEnv :: reveal_all ( ) ,
359
+ from_traits,
360
+ ) ;
361
+ let to_traits = fx. tcx . normalize_erasing_late_bound_regions (
362
+ ParamEnv :: reveal_all ( ) ,
363
+ to_traits,
364
+ ) ;
365
+ assert_eq ! (
366
+ from_traits, to_traits,
367
+ "Can't write trait object of incompatible traits {:?} to place with traits {:?}\n \n {:#?}" ,
368
+ from_traits, to_traits, fx,
369
+ ) ;
370
+ // dyn for<'r> Trait<'r> -> dyn Trait<'_> is allowed
371
+ }
372
+ _ => {
373
+ assert_eq ! (
374
+ from_ty,
375
+ to_ty,
376
+ "Can't write value with incompatible type {:?} to place with type {:?}\n \n {:#?}" ,
377
+ from_ty. sty,
378
+ to_ty. sty,
379
+ fx,
380
+ ) ;
381
+ }
365
382
}
366
383
}
367
384
385
+ assert_assignable ( fx, from_ty, to_ty) ;
386
+
368
387
let ( addr, dst_layout) = match self {
369
388
CPlace :: Var ( var, _) => {
370
389
let data = from. load_scalar ( fx) ;
0 commit comments