@@ -44,6 +44,8 @@ use rustc_hir::Expr;
44
44
use rustc_hir_analysis:: astconv:: AstConv ;
45
45
use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
46
46
use rustc_infer:: infer:: { Coercion , DefineOpaqueTypes , InferOk , InferResult } ;
47
+ use rustc_infer:: traits:: TraitEngine ;
48
+ use rustc_infer:: traits:: TraitEngineExt as _;
47
49
use rustc_infer:: traits:: { Obligation , PredicateObligation } ;
48
50
use rustc_middle:: lint:: in_external_macro;
49
51
use rustc_middle:: traits:: BuiltinImplSource ;
@@ -61,6 +63,7 @@ use rustc_target::spec::abi::Abi;
61
63
use rustc_trait_selection:: infer:: InferCtxtExt as _;
62
64
use rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt as _;
63
65
use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
66
+ use rustc_trait_selection:: traits:: TraitEngineExt as _;
64
67
use rustc_trait_selection:: traits:: {
65
68
self , NormalizeExt , ObligationCause , ObligationCauseCode , ObligationCtxt ,
66
69
} ;
@@ -157,17 +160,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
157
160
// In the new solver, lazy norm may allow us to shallowly equate
158
161
// more types, but we emit possibly impossible-to-satisfy obligations.
159
162
// Filter these cases out to make sure our coercion is more accurate.
160
- if self . next_trait_solver ( ) {
161
- if let Ok ( res) = & res {
162
- for obligation in & res. obligations {
163
- if !self . predicate_may_hold ( obligation) {
164
- return Err ( TypeError :: Mismatch ) ;
165
- }
163
+ match res {
164
+ Ok ( InferOk { value, obligations } ) if self . next_trait_solver ( ) => {
165
+ let mut fulfill_cx = <dyn TraitEngine < ' tcx > >:: new ( self ) ;
166
+ fulfill_cx. register_predicate_obligations ( self , obligations) ;
167
+ let errs = fulfill_cx. select_where_possible ( self ) ;
168
+ if errs. is_empty ( ) {
169
+ Ok ( InferOk { value, obligations : fulfill_cx. pending_obligations ( ) } )
170
+ } else {
171
+ Err ( TypeError :: Mismatch )
166
172
}
167
173
}
174
+ res => res,
168
175
}
169
-
170
- res
171
176
} )
172
177
}
173
178
@@ -625,19 +630,18 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
625
630
let traits = [ coerce_unsized_did, unsize_did] ;
626
631
while !queue. is_empty ( ) {
627
632
let obligation = queue. remove ( 0 ) ;
628
- debug ! ( "coerce_unsized resolve step: {:?}" , obligation) ;
629
633
let trait_pred = match obligation. predicate . kind ( ) . no_bound_vars ( ) {
630
634
Some ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: Trait ( trait_pred) ) )
631
635
if traits. contains ( & trait_pred. def_id ( ) ) =>
632
636
{
633
- trait_pred
637
+ self . resolve_vars_if_possible ( trait_pred)
634
638
}
635
639
_ => {
636
640
coercion. obligations . push ( obligation) ;
637
641
continue ;
638
642
}
639
643
} ;
640
- let trait_pred = self . resolve_vars_if_possible ( trait_pred) ;
644
+ debug ! ( "coerce_unsized resolve step: {:?}" , trait_pred) ;
641
645
match selcx. select ( & obligation. with ( selcx. tcx ( ) , trait_pred) ) {
642
646
// Uncertain or unimplemented.
643
647
Ok ( None ) => {
0 commit comments