@@ -28,24 +28,28 @@ use test_utils::tested_by;
28
28
29
29
use super :: {
30
30
autoderef, method_resolution, op, primitive,
31
- traits:: { Guidance , Obligation , Solution } ,
32
- ApplicationTy , CallableDef , Substs , TraitRef , Ty , TypableDef , TypeCtor ,
31
+ traits:: { Guidance , Obligation , ProjectionPredicate , Solution } ,
32
+ ApplicationTy , CallableDef , ProjectionTy , Substs , TraitRef , Ty , TypableDef , TypeCtor ,
33
33
} ;
34
34
use crate :: {
35
35
adt:: VariantDef ,
36
+ code_model:: { ModuleDef :: Trait , TypeAlias } ,
36
37
diagnostics:: DiagnosticSink ,
37
38
expr:: {
38
39
self , Array , BinaryOp , BindingAnnotation , Body , Expr , ExprId , FieldPat , Literal , Pat ,
39
40
PatId , Statement , UnaryOp ,
40
41
} ,
41
42
generics:: { GenericParams , HasGenericParams } ,
42
- nameres:: Namespace ,
43
- path:: { GenericArg , GenericArgs } ,
44
- resolve:: { Resolution , Resolver } ,
43
+ nameres:: { Namespace , PerNs } ,
44
+ path:: { GenericArg , GenericArgs , PathKind , PathSegment } ,
45
+ resolve:: {
46
+ Resolution :: { self , Def } ,
47
+ Resolver ,
48
+ } ,
45
49
ty:: infer:: diagnostics:: InferenceDiagnostic ,
46
50
type_ref:: { Mutability , TypeRef } ,
47
- AdtDef , ConstData , DefWithBody , FnData , Function , HirDatabase , ImplItem , ModuleDef , Name , Path ,
48
- StructField ,
51
+ AdtDef , AsName , ConstData , DefWithBody , FnData , Function , HirDatabase , ImplItem , KnownName ,
52
+ ModuleDef , Name , Path , StructField ,
49
53
} ;
50
54
51
55
mod unify;
@@ -323,34 +327,53 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
323
327
fn resolve_obligations_as_possible ( & mut self ) {
324
328
let obligations = mem:: replace ( & mut self . obligations , Vec :: new ( ) ) ;
325
329
for obligation in obligations {
326
- let ( solution , canonicalized ) = match & obligation {
330
+ match & obligation {
327
331
Obligation :: Trait ( tr) => {
328
332
let canonicalized = self . canonicalizer ( ) . canonicalize_trait_ref ( tr. clone ( ) ) ;
329
- (
330
- self . db . implements (
331
- self . resolver . krate ( ) . unwrap ( ) ,
332
- canonicalized. value . clone ( ) ,
333
- ) ,
334
- canonicalized,
335
- )
336
- }
337
- } ;
338
- match solution {
339
- Some ( Solution :: Unique ( substs) ) => {
340
- canonicalized. apply_solution ( self , substs. 0 ) ;
341
- }
342
- Some ( Solution :: Ambig ( Guidance :: Definite ( substs) ) ) => {
343
- canonicalized. apply_solution ( self , substs. 0 ) ;
344
- self . obligations . push ( obligation) ;
345
- }
346
- Some ( _) => {
347
- // FIXME use this when trying to resolve everything at the end
348
- self . obligations . push ( obligation) ;
333
+ let solution = self
334
+ . db
335
+ . implements ( self . resolver . krate ( ) . unwrap ( ) , canonicalized. value . clone ( ) ) ;
336
+ match solution {
337
+ Some ( Solution :: Unique ( substs) ) => {
338
+ canonicalized. apply_solution ( self , substs. 0 ) ;
339
+ }
340
+ Some ( Solution :: Ambig ( Guidance :: Definite ( substs) ) ) => {
341
+ canonicalized. apply_solution ( self , substs. 0 ) ;
342
+ self . obligations . push ( obligation) ;
343
+ }
344
+ Some ( _) => {
345
+ // FIXME use this when trying to resolve everything at the end
346
+ self . obligations . push ( obligation) ;
347
+ }
348
+ None => {
349
+ // FIXME obligation cannot be fulfilled => diagnostic
350
+ }
351
+ } ;
349
352
}
350
- None => {
351
- // FIXME obligation cannot be fulfilled => diagnostic
353
+ Obligation :: Projection ( pr) => {
354
+ let canonicalized = self . canonicalizer ( ) . canonicalize_projection ( pr. clone ( ) ) ;
355
+ let solution = self
356
+ . db
357
+ . normalize ( self . resolver . krate ( ) . unwrap ( ) , canonicalized. value . clone ( ) ) ;
358
+
359
+ match solution {
360
+ Some ( Solution :: Unique ( substs) ) => {
361
+ canonicalized. apply_solution ( self , substs. 0 ) ;
362
+ }
363
+ Some ( Solution :: Ambig ( Guidance :: Definite ( substs) ) ) => {
364
+ canonicalized. apply_solution ( self , substs. 0 ) ;
365
+ self . obligations . push ( obligation) ;
366
+ }
367
+ Some ( _) => {
368
+ // FIXME use this when trying to resolve everything at the end
369
+ self . obligations . push ( obligation) ;
370
+ }
371
+ None => {
372
+ // FIXME obligation cannot be fulfilled => diagnostic
373
+ }
374
+ } ;
352
375
}
353
- }
376
+ } ;
354
377
}
355
378
}
356
379
@@ -967,8 +990,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
967
990
Ty :: unit ( )
968
991
}
969
992
Expr :: For { iterable, body, pat } => {
970
- let _iterable_ty = self . infer_expr ( * iterable, & Expectation :: none ( ) ) ;
971
- self . infer_pat ( * pat, & Ty :: Unknown , BindingMode :: default ( ) ) ;
993
+ let iterable_ty = self . infer_expr ( * iterable, & Expectation :: none ( ) ) ;
994
+
995
+ let pat_ty = match self . resolve_into_iter_item ( ) {
996
+ Some ( into_iter_item_alias) => {
997
+ let pat_ty = self . new_type_var ( ) ;
998
+ let projection = ProjectionPredicate {
999
+ ty : pat_ty. clone ( ) ,
1000
+ projection_ty : ProjectionTy {
1001
+ associated_ty : into_iter_item_alias,
1002
+ parameters : vec ! [ iterable_ty] . into ( ) ,
1003
+ } ,
1004
+ } ;
1005
+ self . obligations . push ( Obligation :: Projection ( projection) ) ;
1006
+ self . resolve_ty_as_possible ( & mut vec ! [ ] , pat_ty)
1007
+ }
1008
+ None => Ty :: Unknown ,
1009
+ } ;
1010
+
1011
+ self . infer_pat ( * pat, & pat_ty, BindingMode :: default ( ) ) ;
972
1012
self . infer_expr ( * body, & Expectation :: has_type ( Ty :: unit ( ) ) ) ;
973
1013
Ty :: unit ( )
974
1014
}
@@ -1301,6 +1341,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1301
1341
fn infer_body ( & mut self ) {
1302
1342
self . infer_expr ( self . body . body_expr ( ) , & Expectation :: has_type ( self . return_ty . clone ( ) ) ) ;
1303
1343
}
1344
+
1345
+ fn resolve_into_iter_item ( & self ) -> Option < TypeAlias > {
1346
+ let into_iter_path = Path {
1347
+ kind : PathKind :: Abs ,
1348
+ segments : vec ! [
1349
+ PathSegment { name: KnownName :: Std . as_name( ) , args_and_bindings: None } ,
1350
+ PathSegment { name: KnownName :: Iter . as_name( ) , args_and_bindings: None } ,
1351
+ PathSegment { name: KnownName :: IntoIterator . as_name( ) , args_and_bindings: None } ,
1352
+ ] ,
1353
+ } ;
1354
+
1355
+ match self . resolver . resolve_path_segments ( self . db , & into_iter_path) . into_fully_resolved ( ) {
1356
+ PerNs { types : Some ( Def ( Trait ( trait_) ) ) , .. } => {
1357
+ Some ( trait_. associated_type_by_name ( self . db , KnownName :: Item . as_name ( ) ) ?)
1358
+ }
1359
+ _ => None ,
1360
+ }
1361
+ }
1304
1362
}
1305
1363
1306
1364
/// The ID of a type variable.
0 commit comments