Store a Symbol
instead of an Ident
in VariantDef
/FieldDef
The field is also renamed from `ident` to `name. In most cases, we don't actually need the `Span`. A new `ident` method is added to `VariantDef` and `FieldDef`, which constructs the full `Ident` using `tcx.def_ident_span()`. This method is used in the cases where we actually need an `Ident`. This makes incremental compilation properly track changes to the `Span`, without all of the invalidations caused by storing a `Span` directly via an `Ident`.
This commit is contained in:
parent
e4b1d58414
commit
450ef8613c
38 changed files with 120 additions and 107 deletions
|
@ -1727,7 +1727,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
let variant_def = adt_def
|
||||
.variants
|
||||
.iter()
|
||||
.find(|vd| tcx.hygienic_eq(assoc_ident, vd.ident, adt_def.did));
|
||||
.find(|vd| tcx.hygienic_eq(assoc_ident, vd.ident(tcx), adt_def.did));
|
||||
if let Some(variant_def) = variant_def {
|
||||
if permit_variants {
|
||||
tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None);
|
||||
|
@ -1786,7 +1786,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
&adt_def
|
||||
.variants
|
||||
.iter()
|
||||
.map(|variant| variant.ident.name)
|
||||
.map(|variant| variant.name)
|
||||
.collect::<Vec<Symbol>>(),
|
||||
assoc_ident.name,
|
||||
None,
|
||||
|
|
|
@ -1173,7 +1173,7 @@ pub(super) fn check_packed_inner(
|
|||
if let ty::Adt(def, _) = field.ty(tcx, substs).kind() {
|
||||
if !stack.contains(&def.did) {
|
||||
if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) {
|
||||
defs.push((def.did, field.ident.span));
|
||||
defs.push((def.did, field.ident(tcx).span));
|
||||
return Some(defs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1376,7 +1376,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
.fields
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, field)| (field.ident.normalize_to_macros_2_0(), (i, field)))
|
||||
.map(|(i, field)| (field.ident(tcx).normalize_to_macros_2_0(), (i, field)))
|
||||
.collect::<FxHashMap<_, _>>();
|
||||
|
||||
let mut seen_fields = FxHashMap::default();
|
||||
|
@ -1457,7 +1457,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
expr_span,
|
||||
self.field_ty(base_expr.span, f, base_subs),
|
||||
);
|
||||
let ident = self.tcx.adjust_ident(f.ident, variant.def_id);
|
||||
let ident = self
|
||||
.tcx
|
||||
.adjust_ident(f.ident(self.tcx), variant.def_id);
|
||||
if let Some(_) = remaining_fields.remove(&ident) {
|
||||
let target_ty =
|
||||
self.field_ty(base_expr.span, f, substs);
|
||||
|
@ -1475,10 +1477,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&cause,
|
||||
target_ty,
|
||||
fru_ty,
|
||||
FieldMisMatch(
|
||||
variant.ident.name,
|
||||
ident.name,
|
||||
),
|
||||
FieldMisMatch(variant.name, ident.name),
|
||||
)
|
||||
.emit(),
|
||||
}
|
||||
|
@ -1665,7 +1664,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
"{} `{}::{}` has no field named `{}`",
|
||||
kind_name,
|
||||
actual,
|
||||
variant.ident,
|
||||
variant.name,
|
||||
field.ident
|
||||
),
|
||||
_ => struct_span_err!(
|
||||
|
@ -1680,15 +1679,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
},
|
||||
ty,
|
||||
);
|
||||
|
||||
let variant_ident_span = self.tcx.def_ident_span(variant.def_id).unwrap();
|
||||
match variant.ctor_kind {
|
||||
CtorKind::Fn => match ty.kind() {
|
||||
ty::Adt(adt, ..) if adt.is_enum() => {
|
||||
err.span_label(
|
||||
variant.ident.span,
|
||||
variant_ident_span,
|
||||
format!(
|
||||
"`{adt}::{variant}` defined here",
|
||||
adt = ty,
|
||||
variant = variant.ident,
|
||||
variant = variant.name,
|
||||
),
|
||||
);
|
||||
err.span_label(field.ident.span, "field does not exist");
|
||||
|
@ -1697,18 +1698,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
&format!(
|
||||
"`{adt}::{variant}` is a tuple {kind_name}, use the appropriate syntax",
|
||||
adt = ty,
|
||||
variant = variant.ident,
|
||||
variant = variant.name,
|
||||
),
|
||||
format!(
|
||||
"{adt}::{variant}(/* fields */)",
|
||||
adt = ty,
|
||||
variant = variant.ident,
|
||||
variant = variant.name,
|
||||
),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
err.span_label(variant.ident.span, format!("`{adt}` defined here", adt = ty));
|
||||
err.span_label(variant_ident_span, format!("`{adt}` defined here", adt = ty));
|
||||
err.span_label(field.ident.span, "field does not exist");
|
||||
err.span_suggestion_verbose(
|
||||
expr_span,
|
||||
|
@ -1740,7 +1741,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
if adt.is_enum() {
|
||||
err.span_label(
|
||||
field.ident.span,
|
||||
format!("`{}::{}` does not have this field", ty, variant.ident),
|
||||
format!("`{}::{}` does not have this field", ty, variant.name),
|
||||
);
|
||||
} else {
|
||||
err.span_label(
|
||||
|
@ -1775,12 +1776,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
.iter()
|
||||
.filter_map(|field| {
|
||||
// ignore already set fields and private fields from non-local crates
|
||||
if skip.iter().any(|&x| x == field.ident.name)
|
||||
if skip.iter().any(|&x| x == field.name)
|
||||
|| (!variant.def_id.is_local() && !field.vis.is_public())
|
||||
{
|
||||
None
|
||||
} else {
|
||||
Some(field.ident.name)
|
||||
Some(field.name)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<Symbol>>();
|
||||
|
@ -1795,11 +1796,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
.filter(|field| {
|
||||
let def_scope = self
|
||||
.tcx
|
||||
.adjust_ident_and_get_scope(field.ident, variant.def_id, self.body_id)
|
||||
.adjust_ident_and_get_scope(field.ident(self.tcx), variant.def_id, self.body_id)
|
||||
.1;
|
||||
field.vis.is_accessible_from(def_scope, self.tcx)
|
||||
})
|
||||
.map(|field| field.ident.name)
|
||||
.map(|field| field.name)
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
@ -1834,8 +1835,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let (ident, def_scope) =
|
||||
self.tcx.adjust_ident_and_get_scope(field, base_def.did, self.body_id);
|
||||
let fields = &base_def.non_enum_variant().fields;
|
||||
if let Some(index) =
|
||||
fields.iter().position(|f| f.ident.normalize_to_macros_2_0() == ident)
|
||||
if let Some(index) = fields
|
||||
.iter()
|
||||
.position(|f| f.ident(self.tcx).normalize_to_macros_2_0() == ident)
|
||||
{
|
||||
let field = &fields[index];
|
||||
let field_ty = self.field_ty(expr.span, field, substs);
|
||||
|
@ -1916,7 +1918,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
if let ty::Adt(def, _) = output_ty.kind() {
|
||||
// no field access on enum type
|
||||
if !def.is_enum() {
|
||||
if def.non_enum_variant().fields.iter().any(|field| field.ident == field_ident) {
|
||||
if def
|
||||
.non_enum_variant()
|
||||
.fields
|
||||
.iter()
|
||||
.any(|field| field.ident(self.tcx) == field_ident)
|
||||
{
|
||||
add_label = false;
|
||||
err.span_label(
|
||||
field_ident.span,
|
||||
|
@ -2075,7 +2082,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
.unwrap()
|
||||
.fields
|
||||
.iter()
|
||||
.any(|f| f.ident == field)
|
||||
.any(|f| f.ident(self.tcx) == field)
|
||||
{
|
||||
if let Some(dot_loc) = expr_snippet.rfind('.') {
|
||||
found = true;
|
||||
|
@ -2262,7 +2269,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
span, candidate_field, field_path
|
||||
);
|
||||
|
||||
if candidate_field.ident == target_field {
|
||||
if candidate_field.ident(self.tcx) == target_field {
|
||||
Some(field_path)
|
||||
} else if field_path.len() > 3 {
|
||||
// For compile-time reasons and to avoid infinite recursion we only check for fields
|
||||
|
@ -2271,11 +2278,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
} else {
|
||||
// recursively search fields of `candidate_field` if it's a ty::Adt
|
||||
|
||||
field_path.push(candidate_field.ident.normalize_to_macros_2_0());
|
||||
field_path.push(candidate_field.ident(self.tcx).normalize_to_macros_2_0());
|
||||
let field_ty = candidate_field.ty(self.tcx, subst);
|
||||
if let Some((nested_fields, subst)) = self.get_field_candidates(span, &field_ty) {
|
||||
for field in nested_fields.iter() {
|
||||
let ident = field.ident.normalize_to_macros_2_0();
|
||||
let ident = field.ident(self.tcx).normalize_to_macros_2_0();
|
||||
if ident == target_field {
|
||||
return Some(field_path);
|
||||
} else {
|
||||
|
|
|
@ -482,7 +482,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let variant_def = adt_def
|
||||
.variants
|
||||
.iter()
|
||||
.find(|vd| tcx.hygienic_eq(method_name, vd.ident, adt_def.did));
|
||||
.find(|vd| tcx.hygienic_eq(method_name, vd.ident(tcx), adt_def.did));
|
||||
if let Some(variant_def) = variant_def {
|
||||
// Braced variants generate unusable names in value namespace (reserved for
|
||||
// possible future use), so variants resolved as associated items may refer to
|
||||
|
|
|
@ -997,7 +997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
if unsatisfied_predicates.is_empty() && actual.is_enum() {
|
||||
let adt_def = actual.ty_adt_def().expect("enum is not an ADT");
|
||||
if let Some(suggestion) = lev_distance::find_best_match_for_name(
|
||||
&adt_def.variants.iter().map(|s| s.ident.name).collect::<Vec<_>>(),
|
||||
&adt_def.variants.iter().map(|s| s.name).collect::<Vec<_>>(),
|
||||
item_name.name,
|
||||
None,
|
||||
) {
|
||||
|
|
|
@ -1029,7 +1029,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let field_def_spans = if fields.is_empty() {
|
||||
vec![res_span]
|
||||
} else {
|
||||
fields.iter().map(|f| f.ident.span).collect()
|
||||
fields.iter().map(|f| f.ident(self.tcx).span).collect()
|
||||
};
|
||||
let last_field_def_span = *field_def_spans.last().unwrap();
|
||||
|
||||
|
@ -1231,7 +1231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
.fields
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, field)| (field.ident.normalize_to_macros_2_0(), (i, field)))
|
||||
.map(|(i, field)| (field.ident(self.tcx).normalize_to_macros_2_0(), (i, field)))
|
||||
.collect::<FxHashMap<_, _>>();
|
||||
|
||||
// Keep track of which fields have already appeared in the pattern.
|
||||
|
@ -1272,7 +1272,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let mut unmentioned_fields = variant
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| (field, field.ident.normalize_to_macros_2_0()))
|
||||
.map(|field| (field, field.ident(self.tcx).normalize_to_macros_2_0()))
|
||||
.filter(|(_, ident)| !used_fields.contains_key(ident))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
@ -1579,7 +1579,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
fields: &[hir::PatField<'_>],
|
||||
variant: &VariantDef,
|
||||
) -> String {
|
||||
let variant_field_idents = variant.fields.iter().map(|f| f.ident).collect::<Vec<Ident>>();
|
||||
let variant_field_idents =
|
||||
variant.fields.iter().map(|f| f.ident(self.tcx)).collect::<Vec<Ident>>();
|
||||
fields
|
||||
.iter()
|
||||
.map(|field| {
|
||||
|
|
|
@ -199,7 +199,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
|
|||
)
|
||||
.note(&format!(
|
||||
"extra field `{}` of type `{}` is not allowed",
|
||||
field.ident, ty_a,
|
||||
field.name, ty_a,
|
||||
))
|
||||
.emit();
|
||||
|
||||
|
@ -235,7 +235,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did:
|
|||
.map(|field| {
|
||||
format!(
|
||||
"`{}` (`{}` to `{}`)",
|
||||
field.ident,
|
||||
field.name,
|
||||
field.ty(tcx, substs_a),
|
||||
field.ty(tcx, substs_b),
|
||||
)
|
||||
|
@ -479,7 +479,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
|
|||
diff_fields
|
||||
.iter()
|
||||
.map(|&(i, a, b)| {
|
||||
format!("`{}` (`{}` to `{}`)", fields[i].ident, a, b)
|
||||
format!("`{}` (`{}` to `{}`)", fields[i].name, a, b)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
|
|
|
@ -994,7 +994,7 @@ fn convert_variant(
|
|||
seen_fields.insert(f.ident.normalize_to_macros_2_0(), f.span);
|
||||
}
|
||||
|
||||
ty::FieldDef { did: fid.to_def_id(), ident: f.ident, vis: tcx.visibility(fid) }
|
||||
ty::FieldDef { did: fid.to_def_id(), name: f.ident.name, vis: tcx.visibility(fid) }
|
||||
})
|
||||
.collect();
|
||||
let recovered = match def {
|
||||
|
@ -1002,7 +1002,7 @@ fn convert_variant(
|
|||
_ => false,
|
||||
};
|
||||
ty::VariantDef::new(
|
||||
ident,
|
||||
ident.name,
|
||||
variant_did.map(LocalDefId::to_def_id),
|
||||
ctor_did.map(LocalDefId::to_def_id),
|
||||
discr,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue