@@ -42,7 +42,7 @@ use rustc_hir as hir;
4242use rustc_hir:: def_id:: DefId ;
4343use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
4444use rustc_infer:: infer:: { Coercion , InferOk , InferResult } ;
45- use rustc_infer:: traits:: Obligation ;
45+ use rustc_infer:: traits:: { Obligation , TraitEngine , TraitEngineExt } ;
4646use rustc_middle:: lint:: in_external_macro;
4747use rustc_middle:: ty:: adjustment:: {
4848 Adjust , Adjustment , AllowTwoPhase , AutoBorrow , AutoBorrowMutability , PointerCast ,
@@ -146,6 +146,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
146146 . and_then ( |InferOk { value : ty, obligations } | success ( f ( ty) , ty, obligations) )
147147 }
148148
149+ #[ instrument( skip( self ) ) ]
149150 fn coerce ( & self , a : Ty < ' tcx > , b : Ty < ' tcx > ) -> CoerceResult < ' tcx > {
150151 // First, remove any resolved type variables (at the top level, at least):
151152 let a = self . shallow_resolve ( a) ;
@@ -933,14 +934,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
933934 }
934935
935936 /// Same as `try_coerce()`, but without side-effects.
937+ ///
938+ /// Returns false if the coercion creates any obligations that result in
939+ /// errors.
936940 pub fn can_coerce ( & self , expr_ty : Ty < ' tcx > , target : Ty < ' tcx > ) -> bool {
937941 let source = self . resolve_vars_with_obligations ( expr_ty) ;
938- debug ! ( "coercion::can ({:?} -> {:?})" , source, target) ;
942+ debug ! ( "coercion::can_with_predicates ({:?} -> {:?})" , source, target) ;
939943
940944 let cause = self . cause ( rustc_span:: DUMMY_SP , ObligationCauseCode :: ExprAssignable ) ;
941945 // We don't ever need two-phase here since we throw out the result of the coercion
942946 let coerce = Coerce :: new ( self , cause, AllowTwoPhase :: No ) ;
943- self . probe ( |_| coerce. coerce ( source, target) ) . is_ok ( )
947+ self . probe ( |_| {
948+ let ok = match coerce. coerce ( source, target) {
949+ Ok ( ok) => ok,
950+ _ => return false ,
951+ } ;
952+ let mut fcx = traits:: FulfillmentContext :: new_in_snapshot ( ) ;
953+ fcx. register_predicate_obligations ( self , ok. obligations ) ;
954+ fcx. select_where_possible ( & self ) . is_ok ( )
955+ } )
944956 }
945957
946958 /// Given a type and a target type, this function will calculate and return
0 commit comments