1
Fork 0

resolve: Remove struct_field_names_untracked

This commit is contained in:
Vadim Petrochenkov 2023-02-22 13:55:06 +04:00
parent 2a716f3563
commit b3ee735993
8 changed files with 56 additions and 76 deletions

View file

@ -30,7 +30,6 @@ use rustc_session::cstore::{
}; };
use rustc_session::Session; use rustc_session::Session;
use rustc_span::hygiene::ExpnIndex; use rustc_span::hygiene::ExpnIndex;
use rustc_span::source_map::{respan, Spanned};
use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::{self, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP}; use rustc_span::{self, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP};
@ -1134,20 +1133,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
.decode((self, sess)) .decode((self, sess))
} }
fn get_struct_field_names(
self,
id: DefIndex,
sess: &'a Session,
) -> impl Iterator<Item = Spanned<Symbol>> + 'a {
self.root
.tables
.children
.get(self, id)
.expect("fields not encoded for a struct")
.decode(self)
.map(move |index| respan(self.get_span(index, sess), self.item_name(index)))
}
fn get_inherent_implementations_for_type( fn get_inherent_implementations_for_type(
self, self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,

View file

@ -19,8 +19,8 @@ use rustc_middle::ty::{self, TyCtxt};
use rustc_session::cstore::{CrateSource, CrateStore}; use rustc_session::cstore::{CrateSource, CrateStore};
use rustc_session::{Session, StableCrateId}; use rustc_session::{Session, StableCrateId};
use rustc_span::hygiene::{ExpnHash, ExpnId}; use rustc_span::hygiene::{ExpnHash, ExpnId};
use rustc_span::source_map::{Span, Spanned};
use rustc_span::symbol::{kw, Symbol}; use rustc_span::symbol::{kw, Symbol};
use rustc_span::Span;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use std::any::Any; use std::any::Any;
@ -507,14 +507,6 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
} }
impl CStore { impl CStore {
pub fn struct_field_names_untracked<'a>(
&'a self,
def: DefId,
sess: &'a Session,
) -> impl Iterator<Item = Spanned<Symbol>> + 'a {
self.get_crate_data(def.krate).get_struct_field_names(def.index, sess)
}
pub fn ctor_untracked(&self, def: DefId) -> Option<(CtorKind, DefId)> { pub fn ctor_untracked(&self, def: DefId) -> Option<(CtorKind, DefId)> {
self.get_crate_data(def.krate).get_ctor(def.index) self.get_crate_data(def.krate).get_ctor(def.index)
} }

View file

@ -29,7 +29,6 @@ use rustc_middle::metadata::ModChild;
use rustc_middle::{bug, ty}; use rustc_middle::{bug, ty};
use rustc_session::cstore::CrateStore; use rustc_session::cstore::CrateStore;
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind}; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind};
use rustc_span::source_map::respan;
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::Span; use rustc_span::Span;
@ -327,13 +326,13 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
} }
} }
fn insert_field_names_local(&mut self, def_id: DefId, vdata: &ast::VariantData) { fn insert_field_def_ids(&mut self, def_id: LocalDefId, vdata: &ast::VariantData) {
let field_names = vdata if vdata.fields().iter().any(|field| field.is_placeholder) {
.fields() // The fields are not expanded yet.
.iter() return;
.map(|field| respan(field.span, field.ident.map_or(kw::Empty, |ident| ident.name))) }
.collect(); let def_ids = vdata.fields().iter().map(|field| self.r.local_def_id(field.id).to_def_id());
self.r.field_names.insert(def_id, field_names); self.r.field_def_ids.insert(def_id, self.r.tcx.arena.alloc_from_iter(def_ids));
} }
fn insert_field_visibilities_local(&mut self, def_id: DefId, vdata: &ast::VariantData) { fn insert_field_visibilities_local(&mut self, def_id: DefId, vdata: &ast::VariantData) {
@ -345,12 +344,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
self.r.field_visibility_spans.insert(def_id, field_vis); self.r.field_visibility_spans.insert(def_id, field_vis);
} }
fn insert_field_names_extern(&mut self, def_id: DefId) {
let field_names =
self.r.cstore().struct_field_names_untracked(def_id, self.r.tcx.sess).collect();
self.r.field_names.insert(def_id, field_names);
}
fn block_needs_anonymous_module(&mut self, block: &Block) -> bool { fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
// If any statements are items, we need to create an anonymous module // If any statements are items, we need to create an anonymous module
block block
@ -748,7 +741,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
// Record field names for error reporting. // Record field names for error reporting.
self.insert_field_names_local(def_id, vdata); self.insert_field_def_ids(local_def_id, vdata);
self.insert_field_visibilities_local(def_id, vdata); self.insert_field_visibilities_local(def_id, vdata);
// If this is a tuple or unit struct, define a name // If this is a tuple or unit struct, define a name
@ -797,7 +790,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
// Record field names for error reporting. // Record field names for error reporting.
self.insert_field_names_local(def_id, vdata); self.insert_field_def_ids(local_def_id, vdata);
self.insert_field_visibilities_local(def_id, vdata); self.insert_field_visibilities_local(def_id, vdata);
} }
@ -1003,12 +996,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
| Res::SelfCtor(..) | Res::SelfCtor(..)
| Res::Err => bug!("unexpected resolution: {:?}", res), | Res::Err => bug!("unexpected resolution: {:?}", res),
} }
// Record some extra data for better diagnostics.
match res {
Res::Def(DefKind::Struct, def_id) => self.insert_field_names_extern(def_id),
Res::Def(DefKind::Union, def_id) => self.insert_field_names_extern(def_id),
_ => {}
}
} }
fn add_macro_use_binding( fn add_macro_use_binding(
@ -1519,7 +1506,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
} }
// Record field names for error reporting. // Record field names for error reporting.
self.insert_field_names_local(def_id.to_def_id(), &variant.data); self.insert_field_def_ids(def_id, &variant.data);
self.insert_field_visibilities_local(def_id.to_def_id(), &variant.data); self.insert_field_visibilities_local(def_id.to_def_id(), &variant.data);
visit::walk_variant(self, variant); visit::walk_variant(self, variant);

View file

@ -1581,8 +1581,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
)) = binding.kind )) = binding.kind
{ {
let def_id = self.tcx.parent(ctor_def_id); let def_id = self.tcx.parent(ctor_def_id);
let fields = self.field_names.get(&def_id)?; return self
return fields.iter().map(|name| name.span).reduce(Span::to); // None for `struct Foo()` .field_def_ids(def_id)?
.iter()
.map(|&field_id| self.def_span(field_id))
.reduce(Span::to); // None for `struct Foo()`
} }
None None
} }

View file

@ -1295,19 +1295,23 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
} }
_ => (": val", "literal", Applicability::HasPlaceholders), _ => (": val", "literal", Applicability::HasPlaceholders),
}; };
let (fields, applicability) = match self.r.field_names.get(&def_id) {
Some(fields) => ( let field_ids = self.r.field_def_ids(def_id);
fields let (fields, applicability) = match field_ids {
Some(field_ids) => (
field_ids
.iter() .iter()
.map(|f| format!("{}{}", f.node, tail)) .map(|&field_id| {
format!("{}{tail}", self.r.tcx.item_name(field_id))
})
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join(", "), .join(", "),
applicability, applicability,
), ),
None => ("/* fields */".to_string(), Applicability::HasPlaceholders), None => ("/* fields */".to_string(), Applicability::HasPlaceholders),
}; };
let pad = match self.r.field_names.get(&def_id) { let pad = match field_ids {
Some(fields) if fields.is_empty() => "", Some(field_ids) if field_ids.is_empty() => "",
_ => " ", _ => " ",
}; };
err.span_suggestion( err.span_suggestion(
@ -1451,10 +1455,12 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
); );
// Use spans of the tuple struct definition. // Use spans of the tuple struct definition.
self.r self.r.field_def_ids(def_id).map(|field_ids| {
.field_names field_ids
.get(&def_id) .iter()
.map(|fields| fields.iter().map(|f| f.span).collect::<Vec<_>>()) .map(|&field_id| self.r.def_span(field_id))
.collect::<Vec<_>>()
})
} }
_ => None, _ => None,
}; };
@ -1517,9 +1523,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
(Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_def_id), _) if ns == ValueNS => { (Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_def_id), _) if ns == ValueNS => {
let def_id = self.r.tcx.parent(ctor_def_id); let def_id = self.r.tcx.parent(ctor_def_id);
err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here")); err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here"));
let fields = self.r.field_names.get(&def_id).map_or_else( let fields = self.r.field_def_ids(def_id).map_or_else(
|| "/* fields */".to_string(), || "/* fields */".to_string(),
|fields| vec!["_"; fields.len()].join(", "), |field_ids| vec!["_"; field_ids.len()].join(", "),
); );
err.span_suggestion( err.span_suggestion(
span, span,
@ -1600,8 +1606,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
if let Some(Res::Def(DefKind::Struct | DefKind::Union, did)) = if let Some(Res::Def(DefKind::Struct | DefKind::Union, did)) =
resolution.full_res() resolution.full_res()
{ {
if let Some(field_names) = self.r.field_names.get(&did) { if let Some(field_ids) = self.r.field_def_ids(did) {
if field_names.iter().any(|&field_name| ident.name == field_name.node) { if field_ids
.iter()
.any(|&field_id| ident.name == self.r.tcx.item_name(field_id))
{
return Some(AssocSuggestion::Field); return Some(AssocSuggestion::Field);
} }
} }
@ -2015,11 +2024,12 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
} else { } else {
let needs_placeholder = |ctor_def_id: DefId, kind: CtorKind| { let needs_placeholder = |ctor_def_id: DefId, kind: CtorKind| {
let def_id = self.r.tcx.parent(ctor_def_id); let def_id = self.r.tcx.parent(ctor_def_id);
let has_no_fields = self.r.field_names.get(&def_id).map_or(false, |f| f.is_empty());
match kind { match kind {
CtorKind::Const => false, CtorKind::Const => false,
CtorKind::Fn if has_no_fields => false, CtorKind::Fn => !self
_ => true, .r
.field_def_ids(def_id)
.map_or(false, |field_ids| field_ids.is_empty()),
} }
}; };

View file

@ -50,7 +50,6 @@ use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs};
use rustc_query_system::ich::StableHashingContext; use rustc_query_system::ich::StableHashingContext;
use rustc_session::lint::LintBuffer; use rustc_session::lint::LintBuffer;
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency}; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
@ -881,10 +880,7 @@ pub struct Resolver<'a, 'tcx> {
/// N.B., this is used only for better diagnostics, not name resolution itself. /// N.B., this is used only for better diagnostics, not name resolution itself.
has_self: LocalDefIdSet, has_self: LocalDefIdSet,
field_def_ids: LocalDefIdMap<&'tcx [DefId]>,
/// Names of fields of an item `DefId` accessible with dot syntax.
/// Used for hints during error reporting.
field_names: FxHashMap<DefId, Vec<Spanned<Symbol>>>,
/// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax. /// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax.
/// Used for hints during error reporting. /// Used for hints during error reporting.
@ -1249,7 +1245,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
extern_prelude, extern_prelude,
has_self: Default::default(), has_self: Default::default(),
field_names: FxHashMap::default(), field_def_ids: Default::default(),
field_visibility_spans: FxHashMap::default(), field_visibility_spans: FxHashMap::default(),
determined_imports: Vec::new(), determined_imports: Vec::new(),
@ -1877,6 +1873,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
} }
} }
fn field_def_ids(&self, def_id: DefId) -> Option<&'tcx [DefId]> {
match def_id.as_local() {
Some(def_id) => self.field_def_ids.get(&def_id).copied(),
None => Some(self.tcx.associated_item_def_ids(def_id)),
}
}
/// Checks if an expression refers to a function marked with /// Checks if an expression refers to a function marked with
/// `#[rustc_legacy_const_generics]` and returns the argument index list /// `#[rustc_legacy_const_generics]` and returns the argument index list
/// from the attribute. /// from the attribute.

View file

@ -46,8 +46,8 @@ LL | XEmpty5(),
| |
help: use the tuple variant pattern syntax instead help: use the tuple variant pattern syntax instead
| |
LL | XE::XEmpty5(/* fields */) => (), LL | XE::XEmpty5() => (),
| ~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~
help: a unit variant with a similar name exists help: a unit variant with a similar name exists
| |
LL | XE::XEmpty4 => (), LL | XE::XEmpty4 => (),

View file

@ -113,8 +113,8 @@ LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) }
| |
help: use the tuple variant pattern syntax instead help: use the tuple variant pattern syntax instead
| |
LL | E1::Z1(/* fields */) => {} LL | E1::Z1() => {}
| ~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~
help: a unit variant with a similar name exists help: a unit variant with a similar name exists
| |
LL | E1::Z0 => {} LL | E1::Z0 => {}