@@ -92,24 +92,51 @@ impl InferenceContext<'_> {
9292 let substs =
9393 ty. as_adt ( ) . map ( |( _, s) | s. clone ( ) ) . unwrap_or_else ( || Substitution :: empty ( Interner ) ) ;
9494
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+ }
113140 }
114141
115142 ty
@@ -122,7 +149,7 @@ impl InferenceContext<'_> {
122149 expected : & Ty ,
123150 default_bm : T :: BindingMode ,
124151 id : T ,
125- subs : impl Iterator < Item = ( Name , T ) > ,
152+ subs : impl Iterator < Item = ( Name , T ) > + ExactSizeIterator ,
126153 ) -> Ty {
127154 let ( ty, def) = self . resolve_variant ( path, false ) ;
128155 if let Some ( variant) = def {
@@ -134,17 +161,51 @@ impl InferenceContext<'_> {
134161 let substs =
135162 ty. as_adt ( ) . map ( |( _, s) | s. clone ( ) ) . unwrap_or_else ( || Substitution :: empty ( Interner ) ) ;
136163
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+ } ;
139194
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) ;
146199
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+ }
148209 }
149210
150211 ty
0 commit comments