Skip to content

Commit

Permalink
avoid loading constructor attributes in AdtDef decoding
Browse files Browse the repository at this point in the history
During metadata loading, the AdtDefs for every ADT in the universe need
to be loaded (for example, for coherence of builtin traits). For that,
the attributes of the AdtDef need to be loaded too.

The attributes of a struct are duplicated between 2 def ids - the
constructor def-id, and the "type" def id. Loading attributes for both
def-ids, which was done in #53721, slowed the compilation of small
crates by 2-3%. This PR makes sure we only load the attributes for the
"type" def-id, avoiding the slowdown.
  • Loading branch information
arielb1 committed Sep 22, 2018
1 parent af50e38 commit 2c28c4e
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 11 deletions.
18 changes: 14 additions & 4 deletions src/librustc/ty/mod.rs
Expand Up @@ -1724,19 +1724,29 @@ impl<'a, 'gcx, 'tcx> VariantDef {
/// - `did` is the DefId used for the variant - for tuple-structs, it is the constructor DefId,
/// and for everything else, it is the variant DefId.
/// - `attribute_def_id` is the DefId that has the variant's attributes.
/// this is the struct DefId for structs, and the variant DefId for variants.
///
/// Note that we *could* use the constructor DefId, because the constructor attributes
/// redirect to the base attributes, but compiling a small crate requires
/// loading the AdtDefs for all the structs in the universe (e.g. coherence for any
/// built-in trait), and we do not want to load attributes twice.
///
/// If someone speeds up attribute loading to not be a performance concern, they can
/// remove this hack and use the constructor DefId everywhere.
pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>,
did: DefId,
name: Name,
discr: VariantDiscr,
fields: Vec<FieldDef>,
adt_kind: AdtKind,
ctor_kind: CtorKind)
ctor_kind: CtorKind,
attribute_def_id: DefId)
-> Self
{
debug!("VariantDef::new({:?}, {:?}, {:?}, {:?}, {:?}, {:?})", did, name, discr, fields,
adt_kind, ctor_kind);
debug!("VariantDef::new({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?})", did, name, discr,
fields, adt_kind, ctor_kind, attribute_def_id);
let mut flags = VariantFlags::NO_VARIANT_FLAGS;
if adt_kind == AdtKind::Struct && tcx.has_attr(did, "non_exhaustive") {
if adt_kind == AdtKind::Struct && tcx.has_attr(attribute_def_id, "non_exhaustive") {
debug!("found non-exhaustive field list for {:?}", did);
flags = flags | VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE;
}
Expand Down
8 changes: 6 additions & 2 deletions src/librustc_metadata/decoder.rs
Expand Up @@ -556,9 +556,12 @@ impl<'a, 'tcx> CrateMetadata {
_ => bug!(),
};

let def_id = self.local_def_id(data.struct_ctor.unwrap_or(index));
let attribute_def_id = self.local_def_id(index);

ty::VariantDef::new(
tcx,
self.local_def_id(data.struct_ctor.unwrap_or(index)),
def_id,
self.item_name(index).as_symbol(),
data.discr,
item.children.decode(self).map(|index| {
Expand All @@ -570,7 +573,8 @@ impl<'a, 'tcx> CrateMetadata {
}
}).collect(),
adt_kind,
data.ctor_kind
data.ctor_kind,
attribute_def_id
)
}

Expand Down
15 changes: 10 additions & 5 deletions src/librustc_typeck/collect.rs
Expand Up @@ -555,7 +555,8 @@ fn convert_variant<'a, 'tcx>(
name: ast::Name,
discr: ty::VariantDiscr,
def: &hir::VariantData,
adt_kind: ty::AdtKind
adt_kind: ty::AdtKind,
attribute_def_id: DefId
) -> ty::VariantDef {
let mut seen_fields: FxHashMap<ast::Ident, Span> = FxHashMap();
let node_id = tcx.hir.as_local_node_id(did).unwrap();
Expand Down Expand Up @@ -592,7 +593,8 @@ fn convert_variant<'a, 'tcx>(
discr,
fields,
adt_kind,
CtorKind::from_hir(def))
CtorKind::from_hir(def),
attribute_def_id)
}

fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::AdtDef {
Expand Down Expand Up @@ -622,7 +624,8 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
};
distance_from_explicit += 1;

convert_variant(tcx, did, v.node.name, discr, &v.node.data, AdtKind::Enum)
convert_variant(tcx, did, v.node.name, discr, &v.node.data, AdtKind::Enum,
did)
})
.collect(),
)
Expand All @@ -642,7 +645,8 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
item.name,
ty::VariantDiscr::Relative(0),
def,
AdtKind::Struct
AdtKind::Struct,
def_id
)],
)
}
Expand All @@ -654,7 +658,8 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad
item.name,
ty::VariantDiscr::Relative(0),
def,
AdtKind::Union
AdtKind::Union,
def_id
)],
),
_ => bug!(),
Expand Down

0 comments on commit 2c28c4e

Please sign in to comment.