@@ -41,7 +41,6 @@ use rustc_infer::infer::DefineOpaqueTypes;
41
41
use rustc_infer:: infer:: InferOk ;
42
42
use rustc_infer:: traits:: query:: NoSolution ;
43
43
use rustc_infer:: traits:: ObligationCause ;
44
- use rustc_middle:: middle:: stability;
45
44
use rustc_middle:: ty:: adjustment:: { Adjust , Adjustment , AllowTwoPhase } ;
46
45
use rustc_middle:: ty:: error:: {
47
46
ExpectedFound ,
@@ -1585,12 +1584,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1585
1584
self . check_expr_struct_fields (
1586
1585
adt_ty,
1587
1586
expected,
1588
- expr. hir_id ,
1587
+ expr,
1589
1588
qpath. span ( ) ,
1590
1589
variant,
1591
1590
fields,
1592
1591
base_expr,
1593
- expr. span ,
1594
1592
) ;
1595
1593
1596
1594
self . require_type_is_sized ( adt_ty, expr. span , traits:: StructInitializerSized ) ;
@@ -1601,12 +1599,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1601
1599
& self ,
1602
1600
adt_ty : Ty < ' tcx > ,
1603
1601
expected : Expectation < ' tcx > ,
1604
- expr_id : hir:: HirId ,
1602
+ expr : & hir:: Expr < ' _ > ,
1605
1603
span : Span ,
1606
1604
variant : & ' tcx ty:: VariantDef ,
1607
1605
ast_fields : & ' tcx [ hir:: ExprField < ' tcx > ] ,
1608
1606
base_expr : & ' tcx Option < & ' tcx hir:: Expr < ' tcx > > ,
1609
- expr_span : Span ,
1610
1607
) {
1611
1608
let tcx = self . tcx ;
1612
1609
@@ -1646,7 +1643,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1646
1643
// struct-like enums (yet...), but it's definitely not
1647
1644
// a bug to have constructed one.
1648
1645
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 ) ;
1650
1647
}
1651
1648
1652
1649
self . field_ty ( field. span , v_field, args)
@@ -1662,10 +1659,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1662
1659
self . report_unknown_field (
1663
1660
adt_ty,
1664
1661
variant,
1662
+ expr,
1665
1663
field,
1666
1664
ast_fields,
1667
1665
adt. variant_descr ( ) ,
1668
- expr_span,
1669
1666
)
1670
1667
} ;
1671
1668
@@ -1731,7 +1728,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1731
1728
. iter ( )
1732
1729
. map ( |f| {
1733
1730
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) ) ;
1735
1732
let ident = self . tcx . adjust_ident ( f. ident ( self . tcx ) , variant. def_id ) ;
1736
1733
if let Some ( _) = remaining_fields. remove ( & ident) {
1737
1734
let target_ty = self . field_ty ( base_expr. span , f, args) ;
@@ -1814,7 +1811,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1814
1811
ty:: Adt ( adt, args) if adt. is_struct ( ) => variant
1815
1812
. fields
1816
1813
. 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) ) )
1818
1815
. collect ( ) ,
1819
1816
_ => {
1820
1817
self . tcx
@@ -1824,13 +1821,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1824
1821
}
1825
1822
}
1826
1823
} ;
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) ;
1828
1825
} else if adt_kind != AdtKind :: Union && !remaining_fields. is_empty ( ) {
1829
1826
debug ! ( ?remaining_fields) ;
1830
1827
let private_fields: Vec < & ty:: FieldDef > = variant
1831
1828
. fields
1832
1829
. 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) )
1834
1831
. collect ( ) ;
1835
1832
1836
1833
if !private_fields. is_empty ( ) {
@@ -2049,16 +2046,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2049
2046
& self ,
2050
2047
ty : Ty < ' tcx > ,
2051
2048
variant : & ' tcx ty:: VariantDef ,
2049
+ expr : & hir:: Expr < ' _ > ,
2052
2050
field : & hir:: ExprField < ' _ > ,
2053
2051
skip_fields : & [ hir:: ExprField < ' _ > ] ,
2054
2052
kind_name : & str ,
2055
- expr_span : Span ,
2056
2053
) -> ErrorGuaranteed {
2057
2054
if variant. is_recovered ( ) {
2058
2055
let guar = self
2059
2056
. tcx
2060
2057
. 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" ) ;
2062
2059
self . set_tainted_by_errors ( guar) ;
2063
2060
return guar;
2064
2061
}
@@ -2102,7 +2099,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2102
2099
) ;
2103
2100
err. span_label ( field. ident . span , "field does not exist" ) ;
2104
2101
err. span_suggestion_verbose (
2105
- expr_span ,
2102
+ expr . span ,
2106
2103
format ! (
2107
2104
"`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax" ,
2108
2105
adt = ty,
@@ -2120,7 +2117,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2120
2117
err. span_label ( variant_ident_span, format ! ( "`{ty}` defined here" ) ) ;
2121
2118
err. span_label ( field. ident . span , "field does not exist" ) ;
2122
2119
err. span_suggestion_verbose (
2123
- expr_span ,
2120
+ expr . span ,
2124
2121
format ! ( "`{ty}` is a tuple {kind_name}, use the appropriate syntax" , ) ,
2125
2122
format ! ( "{ty}(/* fields */)" ) ,
2126
2123
Applicability :: HasPlaceholders ,
@@ -2129,9 +2126,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2129
2126
} ,
2130
2127
_ => {
2131
2128
// 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 ) ;
2133
2130
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 )
2135
2132
{
2136
2133
err. span_suggestion (
2137
2134
field. ident . span ,
@@ -2153,10 +2150,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2153
2150
format ! ( "`{ty}` does not have this field" ) ,
2154
2151
) ;
2155
2152
}
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) ) ;
2160
2153
if available_field_names. is_empty ( ) {
2161
2154
err. note ( "all struct fields are already assigned" ) ;
2162
2155
} else {
@@ -2174,63 +2167,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2174
2167
err. emit ( )
2175
2168
}
2176
2169
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
-
2209
2170
fn available_field_names (
2210
2171
& self ,
2211
2172
variant : & ' tcx ty:: VariantDef ,
2212
- access_span : Span ,
2173
+ expr : & hir:: Expr < ' _ > ,
2174
+ skip_fields : & [ hir:: ExprField < ' _ > ] ,
2213
2175
) -> Vec < Symbol > {
2214
- let body_owner_hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( self . body_id ) ;
2215
2176
variant
2216
2177
. fields
2217
2178
. iter ( )
2218
2179
. 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 )
2232
2182
} )
2233
- . filter ( |field| !self . tcx . is_doc_hidden ( field. did ) )
2234
2183
. map ( |field| field. name )
2235
2184
. collect ( )
2236
2185
}
@@ -2460,7 +2409,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2460
2409
self . suggest_first_deref_field ( & mut err, expr, base, ident) ;
2461
2410
}
2462
2411
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 ) ;
2464
2413
}
2465
2414
ty:: Param ( param_ty) => {
2466
2415
self . point_at_param_definition ( & mut err, param_ty) ;
@@ -2622,12 +2571,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2622
2571
fn suggest_fields_on_recordish (
2623
2572
& self ,
2624
2573
err : & mut Diagnostic ,
2574
+ expr : & hir:: Expr < ' _ > ,
2625
2575
def : ty:: AdtDef < ' tcx > ,
2626
2576
field : Ident ,
2627
- access_span : Span ,
2628
2577
) {
2578
+ let available_field_names = self . available_field_names ( def. non_enum_variant ( ) , expr, & [ ] ) ;
2629
2579
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 )
2631
2581
{
2632
2582
err. span_suggestion (
2633
2583
field. span ,
@@ -2637,12 +2587,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
2637
2587
) ;
2638
2588
} else {
2639
2589
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 ( ) {
2643
2591
err. note ( format ! (
2644
2592
"available fields are: {}" ,
2645
- self . name_series_display( field_names ) ,
2593
+ self . name_series_display( available_field_names ) ,
2646
2594
) ) ;
2647
2595
}
2648
2596
}
0 commit comments