@@ -68,16 +68,13 @@ use middle::traits::{predicate_for_trait_def, report_selection_error};
6868use middle:: ty:: { AutoDerefRef , AdjustDerefRef } ;
6969use middle:: ty:: { self , TypeAndMut , Ty , TypeError } ;
7070use middle:: ty_relate:: RelateResult ;
71- use util:: common:: indent;
7271
73- use std:: cell:: RefCell ;
7472use std:: collections:: VecDeque ;
7573use syntax:: ast;
7674
7775struct Coerce < ' a , ' tcx : ' a > {
7876 fcx : & ' a FnCtxt < ' a , ' tcx > ,
79- origin : infer:: TypeOrigin ,
80- unsizing_obligations : RefCell < Vec < traits:: PredicateObligation < ' tcx > > > ,
77+ origin : infer:: TypeOrigin
8178}
8279
8380type CoerceResult < ' tcx > = RelateResult < ' tcx , Option < ty:: AutoAdjustment < ' tcx > > > ;
@@ -101,7 +98,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
10198 debug ! ( "coerce({:?} => {:?})" , a, b) ;
10299
103100 // 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) ) ;
105102 if unsize. is_ok ( ) {
106103 return unsize;
107104 }
@@ -311,9 +308,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
311308 }
312309 }
313310
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+ }
317315
318316 let adjustment = AutoDerefRef {
319317 autoderefs : if reborrow. is_some ( ) { 1 } else { 0 } ,
@@ -395,8 +393,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
395393
396394 // Check that the types which they point at are compatible.
397395 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+ } ) ) ;
400400
401401 // Although references and unsafe ptrs have the same
402402 // representation, we still register an AutoDerefRef so that
@@ -419,29 +419,12 @@ pub fn mk_assignty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
419419 b : Ty < ' tcx > )
420420 -> RelateResult < ' tcx , ( ) > {
421421 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+ } ;
443426
444- if let Some ( adjustment) = adjustment {
427+ if let Some ( adjustment) = try! ( coerce . coerce ( expr , a , b ) ) {
445428 debug ! ( "Success, coerced with {:?}" , adjustment) ;
446429 fcx. write_adjustment ( expr. id , adjustment) ;
447430 }
0 commit comments