@@ -68,16 +68,13 @@ use middle::traits::{predicate_for_trait_def, report_selection_error};
68
68
use middle:: ty:: { AutoDerefRef , AdjustDerefRef } ;
69
69
use middle:: ty:: { self , TypeAndMut , Ty , TypeError } ;
70
70
use middle:: ty_relate:: RelateResult ;
71
- use util:: common:: indent;
72
71
73
- use std:: cell:: RefCell ;
74
72
use std:: collections:: VecDeque ;
75
73
use syntax:: ast;
76
74
77
75
struct Coerce < ' a , ' tcx : ' a > {
78
76
fcx : & ' a FnCtxt < ' a , ' tcx > ,
79
- origin : infer:: TypeOrigin ,
80
- unsizing_obligations : RefCell < Vec < traits:: PredicateObligation < ' tcx > > > ,
77
+ origin : infer:: TypeOrigin
81
78
}
82
79
83
80
type CoerceResult < ' tcx > = RelateResult < ' tcx , Option < ty:: AutoAdjustment < ' tcx > > > ;
@@ -101,7 +98,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
101
98
debug ! ( "coerce({:?} => {:?})" , a, b) ;
102
99
103
100
// Consider coercing the subtype to a DST
104
- let unsize = self . coerce_unsized ( a, b) ;
101
+ let unsize = self . fcx . infcx ( ) . commit_if_ok ( |_| self . coerce_unsized ( a, b) ) ;
105
102
if unsize. is_ok ( ) {
106
103
return unsize;
107
104
}
@@ -311,9 +308,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
311
308
}
312
309
}
313
310
314
- let mut obligations = self . unsizing_obligations . borrow_mut ( ) ;
315
- assert ! ( obligations. is_empty( ) ) ;
316
- * obligations = leftover_predicates;
311
+ // Save all the obligations that are not for CoerceUnsized or Unsize.
312
+ for obligation in leftover_predicates {
313
+ self . fcx . register_predicate ( obligation) ;
314
+ }
317
315
318
316
let adjustment = AutoDerefRef {
319
317
autoderefs : if reborrow. is_some ( ) { 1 } else { 0 } ,
@@ -395,8 +393,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
395
393
396
394
// Check that the types which they point at are compatible.
397
395
let a_unsafe = self . tcx ( ) . mk_ptr ( ty:: TypeAndMut { mutbl : mutbl_b, ty : mt_a. ty } ) ;
398
- try!( self . subtype ( a_unsafe, b) ) ;
399
- try!( coerce_mutbls ( mt_a. mutbl , mutbl_b) ) ;
396
+ try!( self . fcx . infcx ( ) . commit_if_ok ( |_| {
397
+ try!( self . subtype ( a_unsafe, b) ) ;
398
+ coerce_mutbls ( mt_a. mutbl , mutbl_b)
399
+ } ) ) ;
400
400
401
401
// Although references and unsafe ptrs have the same
402
402
// representation, we still register an AutoDerefRef so that
@@ -419,29 +419,12 @@ pub fn mk_assignty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
419
419
b : Ty < ' tcx > )
420
420
-> RelateResult < ' tcx , ( ) > {
421
421
debug ! ( "mk_assignty({:?} -> {:?})" , a, b) ;
422
- let mut unsizing_obligations = vec ! [ ] ;
423
- let adjustment = try!( indent ( || {
424
- fcx. infcx ( ) . commit_if_ok ( |_| {
425
- let coerce = Coerce {
426
- fcx : fcx,
427
- origin : infer:: ExprAssignable ( expr. span ) ,
428
- unsizing_obligations : RefCell :: new ( vec ! [ ] )
429
- } ;
430
- let adjustment = try!( coerce. coerce ( expr, a, b) ) ;
431
- unsizing_obligations = coerce. unsizing_obligations . into_inner ( ) ;
432
- Ok ( adjustment)
433
- } )
434
- } ) ) ;
435
-
436
- if let Some ( AdjustDerefRef ( auto) ) = adjustment {
437
- if auto. unsize . is_some ( ) {
438
- for obligation in unsizing_obligations {
439
- fcx. register_predicate ( obligation) ;
440
- }
441
- }
442
- }
422
+ let coerce = Coerce {
423
+ fcx : fcx,
424
+ origin : infer:: ExprAssignable ( expr. span )
425
+ } ;
443
426
444
- if let Some ( adjustment) = adjustment {
427
+ if let Some ( adjustment) = try! ( coerce . coerce ( expr , a , b ) ) {
445
428
debug ! ( "Success, coerced with {:?}" , adjustment) ;
446
429
fcx. write_adjustment ( expr. id , adjustment) ;
447
430
}
0 commit comments