11//! Type inference for patterns.
22
3- use std:: iter:: repeat_with ;
3+ use std:: { cmp , iter} ;
44
55use hir_def:: {
66 HasModule ,
@@ -19,7 +19,7 @@ use crate::{
1919 AllowTwoPhase , BindingMode , Expectation , InferenceContext , TypeMismatch , expr:: ExprIsRead ,
2020 } ,
2121 lower:: lower_mutability,
22- next_solver:: { GenericArgs , Ty , TyKind } ,
22+ next_solver:: { GenericArgs , Ty , TyKind , Tys , infer :: traits :: ObligationCause } ,
2323} ;
2424
2525impl < ' db > InferenceContext < ' _ , ' db > {
@@ -183,42 +183,61 @@ impl<'db> InferenceContext<'_, 'db> {
183183 /// Ellipses found in the original pattern or expression must be filtered out.
184184 pub ( super ) fn infer_tuple_pat_like (
185185 & mut self ,
186+ pat : PatId ,
186187 expected : Ty < ' db > ,
187188 default_bm : BindingMode ,
188189 ellipsis : Option < u32 > ,
189- subs : & [ PatId ] ,
190+ elements : & [ PatId ] ,
190191 decl : Option < DeclContext > ,
191192 ) -> Ty < ' db > {
192- let expected = self . table . structurally_resolve_type ( expected) ;
193- let expectations = match expected. kind ( ) {
194- TyKind :: Tuple ( parameters) => parameters,
195- _ => self . types . empty_tys ,
196- } ;
193+ let mut expected_len = elements. len ( ) ;
194+ if ellipsis. is_some ( ) {
195+ // Require known type only when `..` is present.
196+ if let TyKind :: Tuple ( tys) = self . table . structurally_resolve_type ( expected) . kind ( ) {
197+ expected_len = tys. len ( ) ;
198+ }
199+ }
200+ let max_len = cmp:: max ( expected_len, elements. len ( ) ) ;
197201
198- let ( ( pre, post) , n_uncovered_patterns) = match ellipsis {
199- Some ( idx) => {
200- ( subs. split_at ( idx as usize ) , expectations. len ( ) . saturating_sub ( subs. len ( ) ) )
202+ let element_tys_iter = ( 0 ..max_len) . map ( |_| self . table . next_ty_var ( ) ) ;
203+ let element_tys = Tys :: new_from_iter ( self . interner ( ) , element_tys_iter) ;
204+ let pat_ty = Ty :: new ( self . interner ( ) , TyKind :: Tuple ( element_tys) ) ;
205+ if self . demand_eqtype ( pat. into ( ) , expected, pat_ty) . is_err ( )
206+ && let TyKind :: Tuple ( expected) = expected. kind ( )
207+ {
208+ // Equate expected type with the infer vars, for better diagnostics.
209+ for ( expected, elem_ty) in iter:: zip ( expected, element_tys) {
210+ _ = self
211+ . table
212+ . at ( & ObligationCause :: dummy ( ) )
213+ . eq ( expected, elem_ty)
214+ . map ( |infer_ok| self . table . register_infer_ok ( infer_ok) ) ;
201215 }
202- None => ( ( subs, & [ ] [ ..] ) , 0 ) ,
216+ }
217+ let ( before_ellipsis, after_ellipsis) = match ellipsis {
218+ Some ( ellipsis) => {
219+ let element_tys = element_tys. as_slice ( ) ;
220+ // Don't check patterns twice.
221+ let from_end_start = cmp:: max (
222+ element_tys. len ( ) . saturating_sub ( elements. len ( ) - ellipsis as usize ) ,
223+ ellipsis as usize ,
224+ ) ;
225+ (
226+ element_tys. get ( ..ellipsis as usize ) . unwrap_or ( element_tys) ,
227+ element_tys. get ( from_end_start..) . unwrap_or_default ( ) ,
228+ )
229+ }
230+ None => ( element_tys. as_slice ( ) , & [ ] [ ..] ) ,
203231 } ;
204- let mut expectations_iter =
205- expectations. iter ( ) . chain ( repeat_with ( || self . table . next_ty_var ( ) ) ) ;
206-
207- let mut inner_tys = Vec :: with_capacity ( n_uncovered_patterns + subs. len ( ) ) ;
208-
209- inner_tys. extend ( expectations_iter. by_ref ( ) . take ( n_uncovered_patterns + subs. len ( ) ) ) ;
210-
211- // Process pre
212- for ( ty, pat) in inner_tys. iter_mut ( ) . zip ( pre) {
213- * ty = self . infer_pat ( * pat, * ty, default_bm, decl) ;
232+ for ( & elem, & elem_ty) in iter:: zip ( elements, before_ellipsis. iter ( ) . chain ( after_ellipsis) ) {
233+ self . infer_pat ( elem, elem_ty, default_bm, decl) ;
214234 }
215-
216- // Process post
217- for ( ty , pat ) in inner_tys . iter_mut ( ) . skip ( pre . len ( ) + n_uncovered_patterns ) . zip ( post ) {
218- * ty = self . infer_pat ( * pat , * ty , default_bm , decl ) ;
235+ if let Some ( uncovered ) = elements . get ( element_tys . len ( ) .. ) {
236+ for & elem in uncovered {
237+ self . infer_pat ( elem , self . types . error , default_bm , decl ) ;
238+ }
219239 }
220-
221- Ty :: new_tup_from_iter ( self . interner ( ) , inner_tys. into_iter ( ) )
240+ pat_ty
222241 }
223242
224243 /// The resolver needs to be updated to the surrounding expression when inside assignment
@@ -272,7 +291,7 @@ impl<'db> InferenceContext<'_, 'db> {
272291
273292 let ty = match & self . body [ pat] {
274293 Pat :: Tuple { args, ellipsis } => {
275- self . infer_tuple_pat_like ( expected, default_bm, * ellipsis, args, decl)
294+ self . infer_tuple_pat_like ( pat , expected, default_bm, * ellipsis, args, decl)
276295 }
277296 Pat :: Or ( pats) => {
278297 for pat in pats. iter ( ) {
@@ -356,7 +375,7 @@ impl<'db> InferenceContext<'_, 'db> {
356375 GenericArgs :: fill_with_defaults (
357376 self . interner ( ) ,
358377 box_adt. into ( ) ,
359- std :: iter:: once ( inner_ty. into ( ) ) . chain ( alloc_ty. map ( Into :: into) ) ,
378+ iter:: once ( inner_ty. into ( ) ) . chain ( alloc_ty. map ( Into :: into) ) ,
360379 |_, id, _| self . table . next_var_for_param ( id) ,
361380 ) ,
362381 )
@@ -416,7 +435,7 @@ impl<'db> InferenceContext<'_, 'db> {
416435 . result
417436 . pat_adjustments
418437 . get ( & pat)
419- . and_then ( |it| it. first ( ) )
438+ . and_then ( |it| it. last ( ) )
420439 . unwrap_or ( & self . result . type_of_pat [ pat] )
421440 }
422441
@@ -469,9 +488,9 @@ impl<'db> InferenceContext<'_, 'db> {
469488 let bound_ty = match mode {
470489 BindingMode :: Ref ( mutability) => {
471490 let inner_lt = self . table . next_region_var ( ) ;
472- Ty :: new_ref ( self . interner ( ) , inner_lt, inner_ty , mutability)
491+ Ty :: new_ref ( self . interner ( ) , inner_lt, expected , mutability)
473492 }
474- BindingMode :: Move => inner_ty ,
493+ BindingMode :: Move => expected ,
475494 } ;
476495 self . write_pat_ty ( pat, inner_ty) ;
477496 self . write_binding_ty ( binding, bound_ty) ;
0 commit comments