Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc_metadata: Some minor cleanups and optimizations #92607

Merged
merged 4 commits into from
Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 64 additions & 71 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
use rustc_middle::mir::{self, Body, Promoted};
use rustc_middle::thir;
use rustc_middle::ty::codec::TyDecoder;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::{self, Ty, TyCtxt, Visibility};
use rustc_serialize::{opaque, Decodable, Decoder};
use rustc_session::cstore::{
Expand Down Expand Up @@ -92,8 +93,7 @@ crate struct CrateMetadata {
/// Trait impl data.
/// FIXME: Used only from queries and can use query cache,
/// so pre-decoding can probably be avoided.
trait_impls:
FxHashMap<(u32, DefIndex), Lazy<[(DefIndex, Option<ty::fast_reject::SimplifiedType>)]>>,
trait_impls: FxHashMap<(u32, DefIndex), Lazy<[(DefIndex, Option<SimplifiedType>)]>>,
/// Proc macro descriptions for this crate, if it's a proc macro crate.
raw_proc_macros: Option<&'static [ProcMacro]>,
/// Source maps for code from the crate.
Expand Down Expand Up @@ -722,25 +722,24 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
&self.raw_proc_macros.unwrap()[pos]
}

fn try_item_ident(&self, item_index: DefIndex, sess: &Session) -> Result<Ident, String> {
let name = self
.def_key(item_index)
.disambiguated_data
.data
.get_opt_name()
.ok_or_else(|| format!("Missing opt name for {:?}", item_index))?;
let span = self
.root
.tables
.ident_span
.get(self, item_index)
.ok_or_else(|| format!("Missing ident span for {:?} ({:?})", name, item_index))?
.decode((self, sess));
Ok(Ident::new(name, span))
fn opt_item_ident(&self, item_index: DefIndex, sess: &Session) -> Option<Ident> {
let name = self.def_key(item_index).disambiguated_data.data.get_opt_name()?;
let span = match self.root.tables.ident_span.get(self, item_index) {
Some(lazy_span) => lazy_span.decode((self, sess)),
None => {
// FIXME: this weird case of a name with no span is specific to `extern crate`
// items, which are supposed to be treated like `use` items and only be encoded
// to metadata as `Export`s, return `None` because that's what all the callers
// expect in this case.
assert_eq!(self.def_kind(item_index), DefKind::ExternCrate);
return None;
}
};
Some(Ident::new(name, span))
}

fn item_ident(&self, item_index: DefIndex, sess: &Session) -> Ident {
self.try_item_ident(item_index, sess).unwrap()
self.opt_item_ident(item_index, sess).expect("no encoded ident for item")
}

fn maybe_kind(&self, item_id: DefIndex) -> Option<EntryKind> {
Expand Down Expand Up @@ -1102,27 +1101,19 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
// Iterate over all children.
if let Some(children) = self.root.tables.children.get(self, id) {
for child_index in children.decode((self, sess)) {
// FIXME: Merge with the logic below.
if let None | Some(EntryKind::ForeignMod | EntryKind::Impl(_)) =
self.maybe_kind(child_index)
{
continue;
}

let def_key = self.def_key(child_index);
if def_key.disambiguated_data.data.get_opt_name().is_some() {
let span = self.get_span(child_index, sess);
if let Some(ident) = self.opt_item_ident(child_index, sess) {
let kind = self.def_kind(child_index);
let ident = self.item_ident(child_index, sess);
let vis = self.get_visibility(child_index);
if matches!(kind, DefKind::Macro(..)) {
// FIXME: Macros are currently encoded twice, once as items and once as
// reexports. We ignore the items here and only use the reexports.
continue;
}
let def_id = self.local_def_id(child_index);
let res = Res::Def(kind, def_id);
let vis = self.get_visibility(child_index);
let span = self.get_span(child_index, sess);

// FIXME: Macros are currently encoded twice, once as items and once as
// reexports. We ignore the items here and only use the reexports.
if !matches!(kind, DefKind::Macro(..)) {
callback(Export { res, ident, vis, span });
}
callback(Export { ident, res, vis, span });

// For non-re-export structs and variants add their constructors to children.
// Re-export lists automatically contain constructors when necessary.
Expand Down Expand Up @@ -1309,24 +1300,26 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {

fn get_item_attrs(
&'a self,
node_id: DefIndex,
id: DefIndex,
sess: &'a Session,
) -> impl Iterator<Item = ast::Attribute> + 'a {
// The attributes for a tuple struct/variant are attached to the definition, not the ctor;
// we assume that someone passing in a tuple struct ctor is actually wanting to
// look at the definition
let def_key = self.def_key(node_id);
let item_id = if def_key.disambiguated_data.data == DefPathData::Ctor {
def_key.parent.unwrap()
} else {
node_id
};

self.root
.tables
.attributes
.get(self, item_id)
.unwrap_or_else(Lazy::empty)
.get(self, id)
.unwrap_or_else(|| {
// Structure and variant constructors don't have any attributes encoded for them,
// but we assume that someone passing a constructor ID actually wants to look at
// the attributes on the corresponding struct or variant.
let def_key = self.def_key(id);
assert_eq!(def_key.disambiguated_data.data, DefPathData::Ctor);
let parent_id = def_key.parent.expect("no parent for a constructor");
self.root
.tables
.attributes
.get(self, parent_id)
.expect("no encoded attributes for a structure or variant")
})
.decode((self, sess))
}

Expand Down Expand Up @@ -1372,39 +1365,39 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
self.root.traits.decode(self).map(|index| self.local_def_id(index))
}

fn get_implementations_for_trait(
fn get_trait_impls(&'a self) -> impl Iterator<Item = (DefId, Option<SimplifiedType>)> + 'a {
self.trait_impls.values().flat_map(move |impls| {
impls
.decode(self)
.map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty))
})
}

fn get_implementations_of_trait(
&self,
tcx: TyCtxt<'tcx>,
filter: Option<DefId>,
) -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] {
trait_def_id: DefId,
) -> &'tcx [(DefId, Option<SimplifiedType>)] {
if self.root.is_proc_macro_crate() {
// proc-macro crates export no trait impls.
return &[];
}

if let Some(def_id) = filter {
// Do a reverse lookup beforehand to avoid touching the crate_num
// hash map in the loop below.
let filter = match self.reverse_translate_def_id(def_id) {
Some(def_id) => (def_id.krate.as_u32(), def_id.index),
None => return &[],
};
// Do a reverse lookup beforehand to avoid touching the crate_num
// hash map in the loop below.
let key = match self.reverse_translate_def_id(trait_def_id) {
Some(def_id) => (def_id.krate.as_u32(), def_id.index),
None => return &[],
};

if let Some(impls) = self.trait_impls.get(&filter) {
tcx.arena.alloc_from_iter(
impls.decode(self).map(|(idx, simplified_self_ty)| {
(self.local_def_id(idx), simplified_self_ty)
}),
)
} else {
&[]
}
} else {
tcx.arena.alloc_from_iter(self.trait_impls.values().flat_map(|impls| {
if let Some(impls) = self.trait_impls.get(&key) {
tcx.arena.alloc_from_iter(
impls
.decode(self)
.map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty))
}))
.map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty)),
)
} else {
&[]
}
}

Expand Down
19 changes: 5 additions & 14 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
generator_kind => { cdata.generator_kind(def_id.index) }
opt_def_kind => { Some(cdata.def_kind(def_id.index)) }
def_span => { cdata.get_span(def_id.index, &tcx.sess) }
def_ident_span => {
cdata.try_item_ident(def_id.index, &tcx.sess).ok().map(|ident| ident.span)
}
def_ident_span => { cdata.opt_item_ident(def_id.index, &tcx.sess).map(|ident| ident.span) }
lookup_stability => {
cdata.get_stability(def_id.index).map(|s| tcx.intern_stability(s))
}
Expand All @@ -145,9 +143,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
lookup_deprecation_entry => {
cdata.get_deprecation(def_id.index).map(DeprecationEntry::external)
}
item_attrs => { tcx.arena.alloc_from_iter(
cdata.get_item_attrs(def_id.index, tcx.sess)
) }
item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) }
fn_arg_names => { cdata.get_fn_param_names(tcx, def_id.index) }
rendered_const => { cdata.get_rendered_const(def_id.index) }
impl_parent => { cdata.get_parent_impl(def_id.index) }
Expand Down Expand Up @@ -196,14 +192,9 @@ provide! { <'tcx> tcx, def_id, other, cdata,
extra_filename => { cdata.root.extra_filename.clone() }

traits_in_crate => { tcx.arena.alloc_from_iter(cdata.get_traits()) }
all_trait_implementations => { tcx.arena.alloc_from_iter(cdata.get_trait_impls()) }

implementations_of_trait => {
cdata.get_implementations_for_trait(tcx, Some(other))
}

all_trait_implementations => {
cdata.get_implementations_for_trait(tcx, None)
}
implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) }

visibility => { cdata.get_visibility(def_id.index) }
dep_kind => {
Expand Down Expand Up @@ -470,7 +461,7 @@ impl CStore {
self.get_crate_data(cnum).num_def_ids()
}

pub fn item_attrs(&self, def_id: DefId, sess: &Session) -> Vec<ast::Attribute> {
pub fn item_attrs_untracked(&self, def_id: DefId, sess: &Session) -> Vec<ast::Attribute> {
self.get_crate_data(def_id.krate).get_item_attrs(def_id.index, sess).collect()
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use rustc_middle::mir::interpret;
use rustc_middle::thir;
use rustc_middle::traits::specialization_graph;
use rustc_middle::ty::codec::TyEncoder;
use rustc_middle::ty::fast_reject::{self, SimplifyParams, StripReferences};
use rustc_middle::ty::fast_reject::{self, SimplifiedType, SimplifyParams, StripReferences};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
use rustc_serialize::{opaque, Encodable, Encoder};
Expand Down Expand Up @@ -2055,7 +2055,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {

struct ImplsVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
impls: FxHashMap<DefId, Vec<(DefIndex, Option<fast_reject::SimplifiedType>)>>,
impls: FxHashMap<DefId, Vec<(DefIndex, Option<SimplifiedType>)>>,
}

impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplsVisitor<'tcx> {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use rustc_middle::hir::exports::Export;
use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
use rustc_middle::mir;
use rustc_middle::thir;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, ReprOptions, Ty};
use rustc_serialize::opaque::Encoder;
Expand Down Expand Up @@ -261,7 +262,7 @@ crate struct CrateDep {
#[derive(MetadataEncodable, MetadataDecodable)]
crate struct TraitImpls {
trait_id: (u32, DefIndex),
impls: Lazy<[(DefIndex, Option<ty::fast_reject::SimplifiedType>)]>,
impls: Lazy<[(DefIndex, Option<SimplifiedType>)]>,
}

/// Define `LazyTables` and `TableBuilders` at the same time.
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1411,16 +1411,14 @@ rustc_queries! {

/// Given a crate and a trait, look up all impls of that trait in the crate.
/// Return `(impl_id, self_ty)`.
query implementations_of_trait(_: (CrateNum, DefId))
-> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] {
query implementations_of_trait(_: (CrateNum, DefId)) -> &'tcx [(DefId, Option<SimplifiedType>)] {
desc { "looking up implementations of a trait in a crate" }
separate_provide_extern
}

/// Given a crate, look up all trait impls in that crate.
/// Return `(impl_id, self_ty)`.
query all_trait_implementations(_: CrateNum)
-> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] {
query all_trait_implementations(_: CrateNum) -> &'tcx [(DefId, Option<SimplifiedType>)] {
desc { "looking up all (?) trait implementations" }
separate_provide_extern
}
Expand Down
12 changes: 12 additions & 0 deletions compiler/rustc_middle/src/ty/fast_reject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ pub fn simplify_type(
}

impl<D: Copy + Debug + Ord + Eq> SimplifiedTypeGen<D> {
pub fn def(self) -> Option<D> {
match self {
AdtSimplifiedType(d)
| ForeignSimplifiedType(d)
| TraitSimplifiedType(d)
| ClosureSimplifiedType(d)
| GeneratorSimplifiedType(d)
| OpaqueSimplifiedType(d) => Some(d),
_ => None,
}
}

pub fn map_def<U, F>(self, map: F) -> SimplifiedTypeGen<U>
where
F: Fn(D) -> U,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/ty/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use crate::traits::query::{
};
use crate::traits::specialization_graph;
use crate::traits::{self, ImplSource};
use crate::ty::fast_reject::SimplifiedType;
use crate::ty::subst::{GenericArg, SubstsRef};
use crate::ty::util::AlwaysRequiresDrop;
use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/trait_def.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::traits::specialization_graph;
use crate::ty::fast_reject::{self, SimplifyParams, StripReferences};
use crate::ty::fast_reject::{self, SimplifiedType, SimplifyParams, StripReferences};
use crate::ty::fold::TypeFoldable;
use crate::ty::{Ty, TyCtxt};
use rustc_hir as hir;
Expand Down Expand Up @@ -68,7 +68,7 @@ pub enum TraitSpecializationKind {
pub struct TraitImpls {
blanket_impls: Vec<DefId>,
/// Impls indexed by their simplified self type, for fast lookup.
non_blanket_impls: FxIndexMap<fast_reject::SimplifiedType, Vec<DefId>>,
non_blanket_impls: FxIndexMap<SimplifiedType, Vec<DefId>>,
}

impl TraitImpls {
Expand Down
10 changes: 6 additions & 4 deletions compiler/rustc_resolve/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -895,17 +895,19 @@ impl<'a> Resolver<'a> {
// a note about editions
let note = if let Some(did) = did {
let requires_note = !did.is_local()
&& this.cstore().item_attrs(did, this.session).iter().any(
|attr| {
&& this
.cstore()
.item_attrs_untracked(did, this.session)
.iter()
.any(|attr| {
if attr.has_name(sym::rustc_diagnostic_item) {
[sym::TryInto, sym::TryFrom, sym::FromIterator]
.map(|x| Some(x))
.contains(&attr.value_str())
} else {
false
}
},
);
});

requires_note.then(|| {
format!(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3420,7 +3420,7 @@ impl<'a> Resolver<'a> {

let attr = self
.cstore()
.item_attrs(def_id, self.session)
.item_attrs_untracked(def_id, self.session)
.into_iter()
.find(|a| a.has_name(sym::rustc_legacy_const_generics))?;
let mut ret = Vec::new();
Expand Down