1
- use crate :: infer:: InferCtxtExt as _;
2
1
use crate :: traits:: { self , ObligationCause , PredicateObligation } ;
3
2
use rustc_data_structures:: fx:: FxHashMap ;
4
3
use rustc_data_structures:: sync:: Lrc ;
@@ -995,31 +994,37 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
995
994
debug ! ( "generated new type inference var {:?}" , ty_var. kind( ) ) ;
996
995
997
996
let item_bounds = tcx. explicit_item_bounds ( def_id) ;
998
- debug ! ( ?item_bounds) ;
999
- let bounds: Vec < _ > =
1000
- item_bounds. iter ( ) . map ( |( bound, _) | bound. subst ( tcx, substs) ) . collect ( ) ;
1001
-
1002
- let param_env = tcx. param_env ( def_id) ;
1003
- let InferOk { value : bounds, obligations } = infcx. partially_normalize_associated_types_in (
1004
- ObligationCause :: misc ( self . value_span , self . body_id ) ,
1005
- param_env,
1006
- bounds,
1007
- ) ;
1008
- self . obligations . extend ( obligations) ;
1009
997
1010
- debug ! ( ?bounds) ;
998
+ self . obligations . reserve ( item_bounds. len ( ) ) ;
999
+ for ( predicate, _) in item_bounds {
1000
+ debug ! ( ?predicate) ;
1001
+ let predicate = predicate. subst ( tcx, substs) ;
1002
+ debug ! ( ?predicate) ;
1003
+
1004
+ // We can't normalize associated types from `rustc_infer`, but we can eagerly register inference variables for them.
1005
+ let predicate = predicate. fold_with ( & mut BottomUpFolder {
1006
+ tcx,
1007
+ ty_op : |ty| match ty. kind ( ) {
1008
+ ty:: Projection ( projection_ty) => infcx. infer_projection (
1009
+ self . param_env ,
1010
+ * projection_ty,
1011
+ ObligationCause :: misc ( self . value_span , self . body_id ) ,
1012
+ 0 ,
1013
+ & mut self . obligations ,
1014
+ ) ,
1015
+ _ => ty,
1016
+ } ,
1017
+ lt_op : |lt| lt,
1018
+ ct_op : |ct| ct,
1019
+ } ) ;
1020
+ debug ! ( ?predicate) ;
1011
1021
1012
- for predicate in & bounds {
1013
1022
if let ty:: PredicateKind :: Projection ( projection) = predicate. kind ( ) . skip_binder ( ) {
1014
1023
if projection. ty . references_error ( ) {
1015
1024
// No point on adding these obligations since there's a type error involved.
1016
1025
return ty_var;
1017
1026
}
1018
1027
}
1019
- }
1020
-
1021
- self . obligations . reserve ( bounds. len ( ) ) ;
1022
- for predicate in bounds {
1023
1028
// Change the predicate to refer to the type variable,
1024
1029
// which will be the concrete type instead of the opaque type.
1025
1030
// This also instantiates nested instances of `impl Trait`.
@@ -1029,7 +1034,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
1029
1034
traits:: ObligationCause :: new ( self . value_span , self . body_id , traits:: OpaqueType ) ;
1030
1035
1031
1036
// Require that the predicate holds for the concrete type.
1032
- debug ! ( "instantiate_opaque_types: predicate={:?}" , predicate) ;
1037
+ debug ! ( ? predicate) ;
1033
1038
self . obligations . push ( traits:: Obligation :: new ( cause, self . param_env , predicate) ) ;
1034
1039
}
1035
1040
0 commit comments