@@ -28,24 +28,28 @@ use test_utils::tested_by;
2828
2929use super :: {
3030 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 ,
3333} ;
3434use crate :: {
3535 adt:: VariantDef ,
36+ code_model:: { ModuleDef :: Trait , TypeAlias } ,
3637 diagnostics:: DiagnosticSink ,
3738 expr:: {
3839 self , Array , BinaryOp , BindingAnnotation , Body , Expr , ExprId , FieldPat , Literal , Pat ,
3940 PatId , Statement , UnaryOp ,
4041 } ,
4142 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+ } ,
4549 ty:: infer:: diagnostics:: InferenceDiagnostic ,
4650 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 ,
4953} ;
5054
5155mod unify;
@@ -323,34 +327,53 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
323327 fn resolve_obligations_as_possible ( & mut self ) {
324328 let obligations = mem:: replace ( & mut self . obligations , Vec :: new ( ) ) ;
325329 for obligation in obligations {
326- let ( solution , canonicalized ) = match & obligation {
330+ match & obligation {
327331 Obligation :: Trait ( tr) => {
328332 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+ } ;
349352 }
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+ } ;
352375 }
353- }
376+ } ;
354377 }
355378 }
356379
@@ -967,8 +990,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
967990 Ty :: unit ( )
968991 }
969992 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 ( ) ) ;
9721012 self . infer_expr ( * body, & Expectation :: has_type ( Ty :: unit ( ) ) ) ;
9731013 Ty :: unit ( )
9741014 }
@@ -1301,6 +1341,24 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
13011341 fn infer_body ( & mut self ) {
13021342 self . infer_expr ( self . body . body_expr ( ) , & Expectation :: has_type ( self . return_ty . clone ( ) ) ) ;
13031343 }
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+ }
13041362}
13051363
13061364/// The ID of a type variable.
0 commit comments