Rollup merge of #116429 - fmease:clean-up-struct-field-suggs, r=compi… · rust-lang/rust@a9a389c (original) (raw)
`@@ -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 {
`
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>();
`
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 {
`
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
`}
`