@@ -41,7 +41,6 @@ use rustc_infer::infer::DefineOpaqueTypes;
4141use rustc_infer:: infer:: InferOk ;
4242use rustc_infer:: traits:: query:: NoSolution ;
4343use rustc_infer:: traits:: ObligationCause ;
44- use rustc_middle:: middle:: stability;
4544use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AllowTwoPhase } ;
4645use rustc_middle:: ty:: error:: {
4746 ExpectedFound ,
@@ -1585,12 +1584,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15851584 self . check_expr_struct_fields (
15861585 adt_ty,
15871586 expected,
1588- expr. hir_id ,
1587+ expr,
15891588 qpath. span ( ) ,
15901589 variant,
15911590 fields,
15921591 base_expr,
1593- expr. span ,
15941592 ) ;
15951593
15961594 self . require_type_is_sized ( adt_ty, expr. span , traits:: StructInitializerSized ) ;
@@ -1601,12 +1599,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16011599 & self ,
16021600 adt_ty : Ty < ' tcx > ,
16031601 expected : Expectation < ' tcx > ,
1604- expr_id : hir:: HirId ,
1602+ expr : & hir:: Expr < ' _ > ,
16051603 span : Span ,
16061604 variant : & ' tcx ty:: VariantDef ,
16071605 ast_fields : & ' tcx [ hir:: ExprField < ' tcx > ] ,
16081606 base_expr : & ' tcx Option < & ' tcx hir:: Expr < ' tcx > > ,
1609- expr_span : Span ,
16101607 ) {
16111608 let tcx = self . tcx ;
16121609
@@ -1646,7 +1643,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16461643 // struct-like enums (yet...), but it's definitely not
16471644 // a bug to have constructed one.
16481645 if adt_kind != AdtKind :: Enum {
1649- tcx. check_stability ( v_field. did , Some ( expr_id ) , field. span , None ) ;
1646+ tcx. check_stability ( v_field. did , Some ( expr . hir_id ) , field. span , None ) ;
16501647 }
16511648
16521649 self . field_ty ( field. span , v_field, args)
@@ -1662,10 +1659,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16621659 self . report_unknown_field (
16631660 adt_ty,
16641661 variant,
1662+ expr,
16651663 field,
16661664 ast_fields,
16671665 adt. variant_descr ( ) ,
1668- expr_span,
16691666 )
16701667 } ;
16711668
@@ -1731,7 +1728,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17311728 . iter ( )
17321729 . map ( |f| {
17331730 let fru_ty = self
1734- . normalize ( expr_span , self . field_ty ( base_expr. span , f, fresh_args) ) ;
1731+ . normalize ( expr . span , self . field_ty ( base_expr. span , f, fresh_args) ) ;
17351732 let ident = self . tcx . adjust_ident ( f. ident ( self . tcx ) , variant. def_id ) ;
17361733 if let Some ( _) = remaining_fields. remove ( & ident) {
17371734 let target_ty = self . field_ty ( base_expr. span , f, args) ;
@@ -1814,7 +1811,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18141811 ty:: Adt ( adt, args) if adt. is_struct ( ) => variant
18151812 . fields
18161813 . iter ( )
1817- . map ( |f| self . normalize ( expr_span , f. ty ( self . tcx , args) ) )
1814+ . map ( |f| self . normalize ( expr . span , f. ty ( self . tcx , args) ) )
18181815 . collect ( ) ,
18191816 _ => {
18201817 self . tcx
@@ -1824,13 +1821,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18241821 }
18251822 }
18261823 } ;
1827- self . typeck_results . borrow_mut ( ) . fru_field_types_mut ( ) . insert ( expr_id , fru_tys) ;
1824+ self . typeck_results . borrow_mut ( ) . fru_field_types_mut ( ) . insert ( expr . hir_id , fru_tys) ;
18281825 } else if adt_kind != AdtKind :: Union && !remaining_fields. is_empty ( ) {
18291826 debug ! ( ?remaining_fields) ;
18301827 let private_fields: Vec < & ty:: FieldDef > = variant
18311828 . fields
18321829 . iter ( )
1833- . filter ( |field| !field. vis . is_accessible_from ( tcx. parent_module ( expr_id ) , tcx) )
1830+ . filter ( |field| !field. vis . is_accessible_from ( tcx. parent_module ( expr . hir_id ) , tcx) )
18341831 . collect ( ) ;
18351832
18361833 if !private_fields. is_empty ( ) {
@@ -2049,16 +2046,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20492046 & self ,
20502047 ty : Ty < ' tcx > ,
20512048 variant : & ' tcx ty:: VariantDef ,
2049+ expr : & hir:: Expr < ' _ > ,
20522050 field : & hir:: ExprField < ' _ > ,
20532051 skip_fields : & [ hir:: ExprField < ' _ > ] ,
20542052 kind_name : & str ,
2055- expr_span : Span ,
20562053 ) -> ErrorGuaranteed {
20572054 if variant. is_recovered ( ) {
20582055 let guar = self
20592056 . tcx
20602057 . sess
2061- . delay_span_bug ( expr_span , "parser recovered but no error was emitted" ) ;
2058+ . delay_span_bug ( expr . span , "parser recovered but no error was emitted" ) ;
20622059 self . set_tainted_by_errors ( guar) ;
20632060 return guar;
20642061 }
@@ -2102,7 +2099,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21022099 ) ;
21032100 err. span_label ( field. ident . span , "field does not exist" ) ;
21042101 err. span_suggestion_verbose (
2105- expr_span ,
2102+ expr . span ,
21062103 format ! (
21072104 "`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax" ,
21082105 adt = ty,
@@ -2120,7 +2117,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21202117 err. span_label ( variant_ident_span, format ! ( "`{ty}` defined here" ) ) ;
21212118 err. span_label ( field. ident . span , "field does not exist" ) ;
21222119 err. span_suggestion_verbose (
2123- expr_span ,
2120+ expr . span ,
21242121 format ! ( "`{ty}` is a tuple {kind_name}, use the appropriate syntax" , ) ,
21252122 format ! ( "{ty}(/* fields */)" ) ,
21262123 Applicability :: HasPlaceholders ,
@@ -2129,9 +2126,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21292126 } ,
21302127 _ => {
21312128 // prevent all specified fields from being suggested
2132- let skip_fields : Vec < _ > = skip_fields . iter ( ) . map ( |x| x . ident . name ) . collect ( ) ;
2129+ let available_field_names = self . available_field_names ( variant , expr , skip_fields ) ;
21332130 if let Some ( field_name) =
2134- self . suggest_field_name ( variant , field. ident . name , & skip_fields , expr_span )
2131+ find_best_match_for_name ( & available_field_names , field. ident . name , None )
21352132 {
21362133 err. span_suggestion (
21372134 field. ident . span ,
@@ -2153,10 +2150,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21532150 format ! ( "`{ty}` does not have this field" ) ,
21542151 ) ;
21552152 }
2156- let mut available_field_names =
2157- self . available_field_names ( variant, expr_span) ;
2158- available_field_names
2159- . retain ( |name| skip_fields. iter ( ) . all ( |skip| name != skip) ) ;
21602153 if available_field_names. is_empty ( ) {
21612154 err. note ( "all struct fields are already assigned" ) ;
21622155 } else {
@@ -2174,63 +2167,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
21742167 err. emit ( )
21752168 }
21762169
2177- // Return a hint about the closest match in field names
2178- fn suggest_field_name (
2179- & self ,
2180- variant : & ' tcx ty:: VariantDef ,
2181- field : Symbol ,
2182- skip : & [ Symbol ] ,
2183- // The span where stability will be checked
2184- span : Span ,
2185- ) -> Option < Symbol > {
2186- let names = variant
2187- . fields
2188- . iter ( )
2189- . filter_map ( |field| {
2190- // ignore already set fields and private fields from non-local crates
2191- // and unstable fields.
2192- if skip. iter ( ) . any ( |& x| x == field. name )
2193- || ( !variant. def_id . is_local ( ) && !field. vis . is_public ( ) )
2194- || matches ! (
2195- self . tcx. eval_stability( field. did, None , span, None ) ,
2196- stability:: EvalResult :: Deny { .. }
2197- )
2198- {
2199- None
2200- } else {
2201- Some ( field. name )
2202- }
2203- } )
2204- . collect :: < Vec < Symbol > > ( ) ;
2205-
2206- find_best_match_for_name ( & names, field, None )
2207- }
2208-
22092170 fn available_field_names (
22102171 & self ,
22112172 variant : & ' tcx ty:: VariantDef ,
2212- access_span : Span ,
2173+ expr : & hir:: Expr < ' _ > ,
2174+ skip_fields : & [ hir:: ExprField < ' _ > ] ,
22132175 ) -> Vec < Symbol > {
2214- let body_owner_hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( self . body_id ) ;
22152176 variant
22162177 . fields
22172178 . iter ( )
22182179 . filter ( |field| {
2219- let def_scope = self
2220- . tcx
2221- . adjust_ident_and_get_scope (
2222- field. ident ( self . tcx ) ,
2223- variant. def_id ,
2224- body_owner_hir_id,
2225- )
2226- . 1 ;
2227- field. vis . is_accessible_from ( def_scope, self . tcx )
2228- && !matches ! (
2229- self . tcx. eval_stability( field. did, None , access_span, None ) ,
2230- stability:: EvalResult :: Deny { .. }
2231- )
2180+ skip_fields. iter ( ) . all ( |& skip| skip. ident . name != field. name )
2181+ && self . is_field_suggestable ( field, expr. hir_id , expr. span )
22322182 } )
2233- . filter ( |field| !self . tcx . is_doc_hidden ( field. did ) )
22342183 . map ( |field| field. name )
22352184 . collect ( )
22362185 }
@@ -2460,7 +2409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24602409 self . suggest_first_deref_field ( & mut err, expr, base, ident) ;
24612410 }
24622411 ty:: Adt ( def, _) if !def. is_enum ( ) => {
2463- self . suggest_fields_on_recordish ( & mut err, def , ident , expr . span ) ;
2412+ self . suggest_fields_on_recordish ( & mut err, expr , def , ident ) ;
24642413 }
24652414 ty:: Param ( param_ty) => {
24662415 self . point_at_param_definition ( & mut err, param_ty) ;
@@ -2622,12 +2571,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26222571 fn suggest_fields_on_recordish (
26232572 & self ,
26242573 err : & mut Diagnostic ,
2574+ expr : & hir:: Expr < ' _ > ,
26252575 def : ty:: AdtDef < ' tcx > ,
26262576 field : Ident ,
2627- access_span : Span ,
26282577 ) {
2578+ let available_field_names = self . available_field_names ( def. non_enum_variant ( ) , expr, & [ ] ) ;
26292579 if let Some ( suggested_field_name) =
2630- self . suggest_field_name ( def . non_enum_variant ( ) , field. name , & [ ] , access_span )
2580+ find_best_match_for_name ( & available_field_names , field. name , None )
26312581 {
26322582 err. span_suggestion (
26332583 field. span ,
@@ -2637,12 +2587,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26372587 ) ;
26382588 } else {
26392589 err. span_label ( field. span , "unknown field" ) ;
2640- let struct_variant_def = def. non_enum_variant ( ) ;
2641- let field_names = self . available_field_names ( struct_variant_def, access_span) ;
2642- if !field_names. is_empty ( ) {
2590+ if !available_field_names. is_empty ( ) {
26432591 err. note ( format ! (
26442592 "available fields are: {}" ,
2645- self . name_series_display( field_names ) ,
2593+ self . name_series_display( available_field_names ) ,
26462594 ) ) ;
26472595 }
26482596 }
0 commit comments