@@ -8,7 +8,8 @@ use test_utils::tested_by;
8
8
9
9
use super :: { InferenceContext , Obligation } ;
10
10
use crate :: {
11
- BoundVar , Canonical , DebruijnIndex , InEnvironment , InferTy , Substs , Ty , TypeCtor , TypeWalk ,
11
+ BoundVar , Canonical , DebruijnIndex , GenericPredicate , InEnvironment , InferTy , Substs , Ty ,
12
+ TypeCtor , TypeWalk ,
12
13
} ;
13
14
14
15
impl < ' a > InferenceContext < ' a > {
@@ -226,16 +227,26 @@ impl InferenceTable {
226
227
( Ty :: Apply ( a_ty1) , Ty :: Apply ( a_ty2) ) if a_ty1. ctor == a_ty2. ctor => {
227
228
self . unify_substs ( & a_ty1. parameters , & a_ty2. parameters , depth + 1 )
228
229
}
229
- _ => self . unify_inner_trivial ( & ty1, & ty2) ,
230
+
231
+ _ => self . unify_inner_trivial ( & ty1, & ty2, depth) ,
230
232
}
231
233
}
232
234
233
- pub ( super ) fn unify_inner_trivial ( & mut self , ty1 : & Ty , ty2 : & Ty ) -> bool {
235
+ pub ( super ) fn unify_inner_trivial ( & mut self , ty1 : & Ty , ty2 : & Ty , depth : usize ) -> bool {
234
236
match ( ty1, ty2) {
235
237
( Ty :: Unknown , _) | ( _, Ty :: Unknown ) => true ,
236
238
237
239
( Ty :: Placeholder ( p1) , Ty :: Placeholder ( p2) ) if * p1 == * p2 => true ,
238
240
241
+ ( Ty :: Dyn ( dyn1) , Ty :: Dyn ( dyn2) ) if dyn1. len ( ) == dyn2. len ( ) => {
242
+ for ( pred1, pred2) in dyn1. iter ( ) . zip ( dyn2. iter ( ) ) {
243
+ if !self . unify_preds ( pred1, pred2, depth + 1 ) {
244
+ return false ;
245
+ }
246
+ }
247
+ true
248
+ }
249
+
239
250
( Ty :: Infer ( InferTy :: TypeVar ( tv1) ) , Ty :: Infer ( InferTy :: TypeVar ( tv2) ) )
240
251
| ( Ty :: Infer ( InferTy :: IntVar ( tv1) ) , Ty :: Infer ( InferTy :: IntVar ( tv2) ) )
241
252
| ( Ty :: Infer ( InferTy :: FloatVar ( tv1) ) , Ty :: Infer ( InferTy :: FloatVar ( tv2) ) )
@@ -268,6 +279,31 @@ impl InferenceTable {
268
279
}
269
280
}
270
281
282
+ fn unify_preds (
283
+ & mut self ,
284
+ pred1 : & GenericPredicate ,
285
+ pred2 : & GenericPredicate ,
286
+ depth : usize ,
287
+ ) -> bool {
288
+ match ( pred1, pred2) {
289
+ ( GenericPredicate :: Implemented ( tr1) , GenericPredicate :: Implemented ( tr2) )
290
+ if tr1. trait_ == tr2. trait_ =>
291
+ {
292
+ self . unify_substs ( & tr1. substs , & tr2. substs , depth + 1 )
293
+ }
294
+ ( GenericPredicate :: Projection ( proj1) , GenericPredicate :: Projection ( proj2) )
295
+ if proj1. projection_ty . associated_ty == proj2. projection_ty . associated_ty =>
296
+ {
297
+ self . unify_substs (
298
+ & proj1. projection_ty . parameters ,
299
+ & proj2. projection_ty . parameters ,
300
+ depth + 1 ,
301
+ ) && self . unify_inner ( & proj1. ty , & proj2. ty , depth + 1 )
302
+ }
303
+ _ => false ,
304
+ }
305
+ }
306
+
271
307
/// If `ty` is a type variable with known type, returns that type;
272
308
/// otherwise, return ty.
273
309
pub fn resolve_ty_shallow < ' b > ( & mut self , ty : & ' b Ty ) -> Cow < ' b , Ty > {
0 commit comments