@@ -92,24 +92,51 @@ impl InferenceContext<'_> {
92
92
let substs =
93
93
ty. as_adt ( ) . map ( |( _, s) | s. clone ( ) ) . unwrap_or_else ( || Substitution :: empty ( Interner ) ) ;
94
94
95
- let field_tys = def. map ( |it| self . db . field_types ( it) ) . unwrap_or_default ( ) ;
96
- let ( pre, post) = match ellipsis {
97
- Some ( idx) => subs. split_at ( idx) ,
98
- None => ( subs, & [ ] [ ..] ) ,
99
- } ;
100
- let post_idx_offset = field_tys. iter ( ) . count ( ) . saturating_sub ( post. len ( ) ) ;
101
-
102
- let pre_iter = pre. iter ( ) . enumerate ( ) ;
103
- let post_iter = ( post_idx_offset..) . zip ( post. iter ( ) ) ;
104
- for ( i, & subpat) in pre_iter. chain ( post_iter) {
105
- let expected_ty = var_data
106
- . as_ref ( )
107
- . and_then ( |d| d. field ( & Name :: new_tuple_field ( i) ) )
108
- . map_or ( self . err_ty ( ) , |field| {
109
- field_tys[ field] . clone ( ) . substitute ( Interner , & substs)
110
- } ) ;
111
- let expected_ty = self . normalize_associated_types_in ( expected_ty) ;
112
- T :: infer ( self , subpat, & expected_ty, default_bm) ;
95
+ match def {
96
+ _ if subs. len ( ) == 0 => { }
97
+ Some ( def) => {
98
+ let field_types = self . db . field_types ( def) ;
99
+ let variant_data = def. variant_data ( self . db . upcast ( ) ) ;
100
+ let visibilities = self . db . field_visibilities ( def) ;
101
+
102
+ let ( pre, post) = match ellipsis {
103
+ Some ( idx) => subs. split_at ( idx) ,
104
+ None => ( subs, & [ ] [ ..] ) ,
105
+ } ;
106
+ let post_idx_offset = field_types. iter ( ) . count ( ) . saturating_sub ( post. len ( ) ) ;
107
+
108
+ let pre_iter = pre. iter ( ) . enumerate ( ) ;
109
+ let post_iter = ( post_idx_offset..) . zip ( post. iter ( ) ) ;
110
+
111
+ for ( i, & subpat) in pre_iter. chain ( post_iter) {
112
+ let field_def = {
113
+ match variant_data. field ( & Name :: new_tuple_field ( i) ) {
114
+ Some ( local_id) => {
115
+ if !visibilities[ local_id]
116
+ . is_visible_from ( self . db . upcast ( ) , self . resolver . module ( ) )
117
+ {
118
+ // FIXME(DIAGNOSE): private tuple field
119
+ }
120
+ Some ( local_id)
121
+ }
122
+ None => None ,
123
+ }
124
+ } ;
125
+
126
+ let expected_ty = field_def. map_or ( self . err_ty ( ) , |f| {
127
+ field_types[ f] . clone ( ) . substitute ( Interner , & substs)
128
+ } ) ;
129
+ let expected_ty = self . normalize_associated_types_in ( expected_ty) ;
130
+
131
+ T :: infer ( self , subpat, & expected_ty, default_bm) ;
132
+ }
133
+ }
134
+ None => {
135
+ let err_ty = self . err_ty ( ) ;
136
+ for & inner in subs {
137
+ T :: infer ( self , inner, & err_ty, default_bm) ;
138
+ }
139
+ }
113
140
}
114
141
115
142
ty
@@ -122,7 +149,7 @@ impl InferenceContext<'_> {
122
149
expected : & Ty ,
123
150
default_bm : T :: BindingMode ,
124
151
id : T ,
125
- subs : impl Iterator < Item = ( Name , T ) > ,
152
+ subs : impl Iterator < Item = ( Name , T ) > + ExactSizeIterator ,
126
153
) -> Ty {
127
154
let ( ty, def) = self . resolve_variant ( path, false ) ;
128
155
if let Some ( variant) = def {
@@ -134,17 +161,51 @@ impl InferenceContext<'_> {
134
161
let substs =
135
162
ty. as_adt ( ) . map ( |( _, s) | s. clone ( ) ) . unwrap_or_else ( || Substitution :: empty ( Interner ) ) ;
136
163
137
- let field_tys = def. map ( |it| self . db . field_types ( it) ) . unwrap_or_default ( ) ;
138
- let var_data = def. map ( |it| it. variant_data ( self . db . upcast ( ) ) ) ;
164
+ match def {
165
+ _ if subs. len ( ) == 0 => { }
166
+ Some ( def) => {
167
+ let field_types = self . db . field_types ( def) ;
168
+ let variant_data = def. variant_data ( self . db . upcast ( ) ) ;
169
+ let visibilities = self . db . field_visibilities ( def) ;
170
+
171
+ for ( name, inner) in subs {
172
+ let field_def = {
173
+ match variant_data. field ( & name) {
174
+ Some ( local_id) => {
175
+ if !visibilities[ local_id]
176
+ . is_visible_from ( self . db . upcast ( ) , self . resolver . module ( ) )
177
+ {
178
+ self . push_diagnostic ( InferenceDiagnostic :: NoSuchField {
179
+ field : inner. into ( ) ,
180
+ private : true ,
181
+ } ) ;
182
+ }
183
+ Some ( local_id)
184
+ }
185
+ None => {
186
+ self . push_diagnostic ( InferenceDiagnostic :: NoSuchField {
187
+ field : inner. into ( ) ,
188
+ private : false ,
189
+ } ) ;
190
+ None
191
+ }
192
+ }
193
+ } ;
139
194
140
- for ( name, inner) in subs {
141
- let expected_ty = var_data
142
- . as_ref ( )
143
- . and_then ( |it| it. field ( & name) )
144
- . map_or ( self . err_ty ( ) , |f| field_tys[ f] . clone ( ) . substitute ( Interner , & substs) ) ;
145
- let expected_ty = self . normalize_associated_types_in ( expected_ty) ;
195
+ let expected_ty = field_def. map_or ( self . err_ty ( ) , |f| {
196
+ field_types[ f] . clone ( ) . substitute ( Interner , & substs)
197
+ } ) ;
198
+ let expected_ty = self . normalize_associated_types_in ( expected_ty) ;
146
199
147
- T :: infer ( self , inner, & expected_ty, default_bm) ;
200
+ T :: infer ( self , inner, & expected_ty, default_bm) ;
201
+ }
202
+ }
203
+ None => {
204
+ let err_ty = self . err_ty ( ) ;
205
+ for ( _, inner) in subs {
206
+ T :: infer ( self , inner, & err_ty, default_bm) ;
207
+ }
208
+ }
148
209
}
149
210
150
211
ty
0 commit comments