2
2
3
3
use std:: iter:: repeat_with;
4
4
5
- use chalk_ir:: Mutability ;
6
5
use hir_def:: {
7
6
body:: Body ,
8
7
hir:: { Binding , BindingAnnotation , BindingId , Expr , ExprId , ExprOrPatId , Literal , Pat , PatId } ,
9
8
path:: Path ,
10
9
} ;
11
10
use hir_expand:: name:: Name ;
11
+ use stdx:: TupleExt ;
12
12
13
13
use crate :: {
14
14
consteval:: { try_const_usize, usize_const} ,
15
15
error_lifetime,
16
16
infer:: { BindingMode , Expectation , InferenceContext , TypeMismatch } ,
17
17
lower:: lower_to_chalk_mutability,
18
18
primitive:: UintTy ,
19
- static_lifetime, InferenceDiagnostic , Interner , Scalar , Substitution , Ty , TyBuilder , TyExt ,
20
- TyKind ,
19
+ static_lifetime, InferenceDiagnostic , Interner , Mutability , Scalar , Substitution , Ty ,
20
+ TyBuilder , TyExt , TyKind ,
21
21
} ;
22
22
23
23
/// Used to generalize patterns and assignee expressions.
@@ -90,9 +90,6 @@ impl InferenceContext<'_> {
90
90
91
91
self . unify ( & ty, expected) ;
92
92
93
- let substs =
94
- ty. as_adt ( ) . map ( |( _, s) | s. clone ( ) ) . unwrap_or_else ( || Substitution :: empty ( Interner ) ) ;
95
-
96
93
match def {
97
94
_ if subs. is_empty ( ) => { }
98
95
Some ( def) => {
@@ -109,26 +106,28 @@ impl InferenceContext<'_> {
109
106
let pre_iter = pre. iter ( ) . enumerate ( ) ;
110
107
let post_iter = ( post_idx_offset..) . zip ( post. iter ( ) ) ;
111
108
109
+ let substs = ty. as_adt ( ) . map ( TupleExt :: tail) ;
110
+
112
111
for ( i, & subpat) in pre_iter. chain ( post_iter) {
113
- let field_def = {
112
+ let expected_ty = {
114
113
match variant_data. field ( & Name :: new_tuple_field ( i) ) {
115
114
Some ( local_id) => {
116
115
if !visibilities[ local_id]
117
116
. is_visible_from ( self . db . upcast ( ) , self . resolver . module ( ) )
118
117
{
119
118
// FIXME(DIAGNOSE): private tuple field
120
119
}
121
- Some ( local_id)
120
+ let f = field_types[ local_id] . clone ( ) ;
121
+ let expected_ty = match substs {
122
+ Some ( substs) => f. substitute ( Interner , substs) ,
123
+ None => f. substitute ( Interner , & Substitution :: empty ( Interner ) ) ,
124
+ } ;
125
+ self . normalize_associated_types_in ( expected_ty)
122
126
}
123
- None => None ,
127
+ None => self . err_ty ( ) ,
124
128
}
125
129
} ;
126
130
127
- let expected_ty = field_def. map_or ( self . err_ty ( ) , |f| {
128
- field_types[ f] . clone ( ) . substitute ( Interner , & substs)
129
- } ) ;
130
- let expected_ty = self . normalize_associated_types_in ( expected_ty) ;
131
-
132
131
T :: infer ( self , subpat, & expected_ty, default_bm) ;
133
132
}
134
133
}
@@ -159,18 +158,17 @@ impl InferenceContext<'_> {
159
158
160
159
self . unify ( & ty, expected) ;
161
160
162
- let substs =
163
- ty. as_adt ( ) . map ( |( _, s) | s. clone ( ) ) . unwrap_or_else ( || Substitution :: empty ( Interner ) ) ;
164
-
165
161
match def {
166
162
_ if subs. len ( ) == 0 => { }
167
163
Some ( def) => {
168
164
let field_types = self . db . field_types ( def) ;
169
165
let variant_data = def. variant_data ( self . db . upcast ( ) ) ;
170
166
let visibilities = self . db . field_visibilities ( def) ;
171
167
168
+ let substs = ty. as_adt ( ) . map ( TupleExt :: tail) ;
169
+
172
170
for ( name, inner) in subs {
173
- let field_def = {
171
+ let expected_ty = {
174
172
match variant_data. field ( & name) {
175
173
Some ( local_id) => {
176
174
if !visibilities[ local_id]
@@ -181,23 +179,23 @@ impl InferenceContext<'_> {
181
179
private : true ,
182
180
} ) ;
183
181
}
184
- Some ( local_id)
182
+ let f = field_types[ local_id] . clone ( ) ;
183
+ let expected_ty = match substs {
184
+ Some ( substs) => f. substitute ( Interner , substs) ,
185
+ None => f. substitute ( Interner , & Substitution :: empty ( Interner ) ) ,
186
+ } ;
187
+ self . normalize_associated_types_in ( expected_ty)
185
188
}
186
189
None => {
187
190
self . push_diagnostic ( InferenceDiagnostic :: NoSuchField {
188
191
field : inner. into ( ) ,
189
192
private : false ,
190
193
} ) ;
191
- None
194
+ self . err_ty ( )
192
195
}
193
196
}
194
197
} ;
195
198
196
- let expected_ty = field_def. map_or ( self . err_ty ( ) , |f| {
197
- field_types[ f] . clone ( ) . substitute ( Interner , & substs)
198
- } ) ;
199
- let expected_ty = self . normalize_associated_types_in ( expected_ty) ;
200
-
201
199
T :: infer ( self , inner, & expected_ty, default_bm) ;
202
200
}
203
201
}
0 commit comments