Skip to content

Commit

Permalink
kill the fake provided method stubs
Browse files Browse the repository at this point in the history
this simplifies the code while reducing the size of libcore.rlib by
3.3 MiB (~1M of which is bloat a separate patch of mine removes
too), while reducing rustc memory usage on small crates by 18MiB.

This also simplifies the code considerably.
  • Loading branch information
Ariel Ben-Yehuda committed Sep 30, 2015
1 parent 3e6d724 commit 709ce9f
Show file tree
Hide file tree
Showing 14 changed files with 139 additions and 334 deletions.
2 changes: 1 addition & 1 deletion src/librustc/metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ pub const tag_mod_child: usize = 0x7b;
pub const tag_misc_info: usize = 0x108; // top-level only
pub const tag_misc_info_crate_items: usize = 0x7c;

pub const tag_item_method_provided_source: usize = 0x7d;
// GAP 0x7d
pub const tag_item_impl_vtables: usize = 0x7e;

pub const tag_impls: usize = 0x109; // top-level only
Expand Down
55 changes: 25 additions & 30 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,6 @@ fn item_def_id(d: rbml::Doc, cdata: Cmd) -> DefId {
translated_def_id(cdata, reader::get_doc(d, tag_def_id))
}

fn get_provided_source(d: rbml::Doc, cdata: Cmd) -> Option<DefId> {
reader::maybe_get_doc(d, tag_item_method_provided_source).map(|doc| {
translated_def_id(cdata, doc)
})
}

fn reexports<'a>(d: rbml::Doc<'a>) -> reader::TaggedDocsIterator<'a> {
reader::tagged_docs(d, tag_items_data_item_reexport)
}
Expand Down Expand Up @@ -276,11 +270,14 @@ fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: DefId) -> DefLike {
match fam {
Constant => {
// Check whether we have an associated const item.
if item_sort(item) == Some('C') {
DlDef(def::DefAssociatedConst(did))
} else {
// Regular const item.
DlDef(def::DefConst(did))
match item_sort(item) {
Some('C') | Some('c') => {
DlDef(def::DefAssociatedConst(did))
}
_ => {
// Regular const item.
DlDef(def::DefConst(did))
}
}
}
ImmStatic => DlDef(def::DefStatic(did, false)),
Expand Down Expand Up @@ -818,7 +815,7 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
reader::tagged_docs(cdata.lookup_item(impl_id), tag_item_impl_item).map(|doc| {
let def_id = item_def_id(doc, cdata);
match item_sort(doc) {
Some('C') => ty::ConstTraitItemId(def_id),
Some('C') | Some('c') => ty::ConstTraitItemId(def_id),
Some('r') | Some('p') => ty::MethodTraitItemId(def_id),
Some('t') => ty::TypeTraitItemId(def_id),
_ => panic!("unknown impl item sort"),
Expand Down Expand Up @@ -864,24 +861,22 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
let vis = item_visibility(item_doc);

match item_sort(item_doc) {
Some('C') => {
sort @ Some('C') | sort @ Some('c') => {
let ty = doc_type(item_doc, tcx, cdata);
let default = get_provided_source(item_doc, cdata);
ty::ConstTraitItem(Rc::new(ty::AssociatedConst {
name: name,
ty: ty,
vis: vis,
def_id: def_id,
container: container,
default: default,
has_value: sort == Some('C')
}))
}
Some('r') | Some('p') => {
let generics = doc_generics(item_doc, tcx, cdata, tag_method_ty_generics);
let predicates = doc_predicates(item_doc, tcx, cdata, tag_method_ty_generics);
let fty = doc_method_fty(item_doc, tcx, cdata);
let explicit_self = get_explicit_self(item_doc);
let provided_source = get_provided_source(item_doc, cdata);

ty::MethodTraitItem(Rc::new(ty::Method::new(name,
generics,
Expand All @@ -890,8 +885,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
explicit_self,
vis,
def_id,
container,
provided_source)))
container)))
}
Some('t') => {
let ty = maybe_doc_type(item_doc, tcx, cdata);
Expand All @@ -913,7 +907,7 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
reader::tagged_docs(item, tag_item_trait_item).map(|mth| {
let def_id = item_def_id(mth, cdata);
match item_sort(mth) {
Some('C') => ty::ConstTraitItemId(def_id),
Some('C') | Some('c') => ty::ConstTraitItemId(def_id),
Some('r') | Some('p') => ty::MethodTraitItemId(def_id),
Some('t') => ty::TypeTraitItemId(def_id),
_ => panic!("unknown trait item sort"),
Expand Down Expand Up @@ -967,18 +961,19 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
let did = item_def_id(ac_id, cdata);
let ac_doc = cdata.lookup_item(did.node);

if item_sort(ac_doc) == Some('C') {
let trait_item = get_impl_or_trait_item(intr.clone(),
cdata,
did.node,
tcx);
if let ty::ConstTraitItem(ref ac) = trait_item {
Some((*ac).clone())
} else {
None
match item_sort(ac_doc) {
Some('C') | Some('c') => {
let trait_item = get_impl_or_trait_item(intr.clone(),
cdata,
did.node,
tcx);
if let ty::ConstTraitItem(ref ac) = trait_item {
Some((*ac).clone())
} else {
None
}
}
} else {
None
_ => None
}
})
}).collect()
Expand Down
20 changes: 7 additions & 13 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,13 +609,6 @@ fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) {
rbml_w.wr_tagged_u8(tag_item_trait_parent_sort, sort as u8);
}

fn encode_provided_source(rbml_w: &mut Encoder,
source_opt: Option<DefId>) {
if let Some(source) = source_opt {
rbml_w.wr_tagged_u64(tag_item_method_provided_source, def_to_u64(source));
}
}

fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
rbml_w: &mut Encoder,
field: ty::FieldDef<'tcx>,
Expand Down Expand Up @@ -776,7 +769,6 @@ fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
}
_ => encode_family(rbml_w, METHOD_FAMILY)
}
encode_provided_source(rbml_w, method_ty.provided_source);
}

fn encode_info_for_associated_const(ecx: &EncodeContext,
Expand All @@ -795,7 +787,6 @@ fn encode_info_for_associated_const(ecx: &EncodeContext,
encode_name(rbml_w, associated_const.name);
encode_visibility(rbml_w, associated_const.vis);
encode_family(rbml_w, 'C');
encode_provided_source(rbml_w, associated_const.default);

encode_parent_item(rbml_w, DefId::local(parent_id));
encode_item_sort(rbml_w, 'C');
Expand Down Expand Up @@ -1367,13 +1358,10 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_def_id(rbml_w, associated_const.def_id);
encode_visibility(rbml_w, associated_const.vis);

encode_provided_source(rbml_w, associated_const.default);

let elem = ast_map::PathName(associated_const.name);
encode_path(rbml_w,
path.clone().chain(Some(elem)));

encode_item_sort(rbml_w, 'C');
encode_family(rbml_w, 'C');

encode_bounds_and_type_for_item(rbml_w, ecx,
Expand Down Expand Up @@ -1429,7 +1417,13 @@ fn encode_info_for_item(ecx: &EncodeContext,
let trait_item = &*ms[i];
encode_attributes(rbml_w, &trait_item.attrs);
match trait_item.node {
hir::ConstTraitItem(_, _) => {
hir::ConstTraitItem(_, ref default) => {
if default.is_some() {
encode_item_sort(rbml_w, 'C');
} else {
encode_item_sort(rbml_w, 'c');
}

encode_inlined_item(ecx, rbml_w,
InlinedItemRef::TraitItem(def_id, trait_item));
}
Expand Down
3 changes: 0 additions & 3 deletions src/librustc/middle/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,6 @@ pub struct ctxt<'tcx> {
pub ty_param_defs: RefCell<NodeMap<ty::TypeParameterDef<'tcx>>>,
pub normalized_cache: RefCell<FnvHashMap<Ty<'tcx>, Ty<'tcx>>>,
pub lang_items: middle::lang_items::LanguageItems,
/// A mapping of fake provided method def_ids to the default implementation
pub provided_method_sources: RefCell<DefIdMap<DefId>>,

/// Maps from def-id of a type or region parameter to its
/// (inferred) variance.
Expand Down Expand Up @@ -471,7 +469,6 @@ impl<'tcx> ctxt<'tcx> {
ty_param_defs: RefCell::new(NodeMap()),
normalized_cache: RefCell::new(FnvHashMap()),
lang_items: lang_items,
provided_method_sources: RefCell::new(DefIdMap()),
inherent_impls: RefCell::new(DefIdMap()),
impl_items: RefCell::new(DefIdMap()),
used_unsafe: RefCell::new(NodeSet()),
Expand Down
26 changes: 5 additions & 21 deletions src/librustc/middle/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,6 @@ pub struct Method<'tcx> {
pub vis: hir::Visibility,
pub def_id: DefId,
pub container: ImplOrTraitItemContainer,

// If this method is provided, we need to know where it came from
pub provided_source: Option<DefId>
}

impl<'tcx> Method<'tcx> {
Expand All @@ -248,8 +245,7 @@ impl<'tcx> Method<'tcx> {
explicit_self: ExplicitSelfCategory,
vis: hir::Visibility,
def_id: DefId,
container: ImplOrTraitItemContainer,
provided_source: Option<DefId>)
container: ImplOrTraitItemContainer)
-> Method<'tcx> {
Method {
name: name,
Expand All @@ -260,7 +256,6 @@ impl<'tcx> Method<'tcx> {
vis: vis,
def_id: def_id,
container: container,
provided_source: provided_source
}
}

Expand Down Expand Up @@ -293,7 +288,7 @@ pub struct AssociatedConst<'tcx> {
pub vis: hir::Visibility,
pub def_id: DefId,
pub container: ImplOrTraitItemContainer,
pub default: Option<DefId>,
pub has_value: bool
}

#[derive(Clone, Copy, Debug)]
Expand Down Expand Up @@ -2105,10 +2100,6 @@ impl<'tcx> ctxt<'tcx> {
}
}

pub fn provided_source(&self, id: DefId) -> Option<DefId> {
self.provided_method_sources.borrow().get(&id).cloned()
}

pub fn provided_trait_methods(&self, id: DefId) -> Vec<Rc<Method<'tcx>>> {
if id.is_local() {
if let ItemTrait(_, _, _, ref ms) = self.map.expect_item(id.node).node {
Expand Down Expand Up @@ -2477,16 +2468,9 @@ impl<'tcx> ctxt<'tcx> {
// the map. This is a bit unfortunate.
for impl_item_def_id in &impl_items {
let method_def_id = impl_item_def_id.def_id();
match self.impl_or_trait_item(method_def_id) {
MethodTraitItem(method) => {
if let Some(source) = method.provided_source {
self.provided_method_sources
.borrow_mut()
.insert(method_def_id, source);
}
}
_ => {}
}
// load impl items eagerly for convenience
// FIXME: we may want to load these lazily
self.impl_or_trait_item(method_def_id);
}

// Store the implementation info.
Expand Down
55 changes: 54 additions & 1 deletion src/librustc/middle/ty/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use back::svh::Svh;
use middle::const_eval::{self, ConstVal, ErrKind};
use middle::const_eval::EvalHint::UncheckedExprHint;
use middle::def_id::DefId;
use middle::subst;
use middle::subst::{self, Subst, Substs};
use middle::infer;
use middle::pat_util;
use middle::traits;
Expand All @@ -26,6 +26,7 @@ use util::num::ToPrimitive;

use std::cmp;
use std::hash::{Hash, SipHasher, Hasher};
use std::rc::Rc;
use syntax::ast::{self, Name};
use syntax::attr::{self, AttrMetaMethods, SignedInt, UnsignedInt};
use syntax::codemap::Span;
Expand Down Expand Up @@ -646,6 +647,58 @@ impl<'tcx> ty::ctxt<'tcx> {
}
}

#[derive(Debug)]
pub struct ImplMethod<'tcx> {
pub method: Rc<ty::Method<'tcx>>,
pub substs: Substs<'tcx>,
pub is_provided: bool
}

impl<'tcx> ty::ctxt<'tcx> {
#[inline(never)] // is this perfy enough?
pub fn get_impl_method(&self,
impl_def_id: DefId,
substs: Substs<'tcx>,
name: Name)
-> ImplMethod<'tcx>
{
// there don't seem to be nicer accessors to these:
let impl_or_trait_items_map = self.impl_or_trait_items.borrow();

for impl_item in &self.impl_items.borrow()[&impl_def_id] {
if let ty::MethodTraitItem(ref meth) =
impl_or_trait_items_map[&impl_item.def_id()] {
if meth.name == name {
return ImplMethod {
method: meth.clone(),
substs: substs,
is_provided: false
}
}
}
}

// It is not in the impl - get the default from the trait.
let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
for trait_item in self.trait_items(trait_ref.def_id).iter() {
if let &ty::MethodTraitItem(ref meth) = trait_item {
if meth.name == name {
let impl_to_trait_substs = self
.make_substs_for_receiver_types(&trait_ref, meth);
return ImplMethod {
method: meth.clone(),
substs: impl_to_trait_substs.subst(self, &substs),
is_provided: true
}
}
}
}

self.sess.bug(&format!("method {:?} not found in {:?}",
name, impl_def_id))
}
}

impl<'tcx> ty::TyS<'tcx> {
fn impls_bound<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
bound: ty::BuiltinBound,
Expand Down
13 changes: 0 additions & 13 deletions src/librustc_privacy/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -725,19 +725,6 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
span: Span,
method_id: DefId,
name: ast::Name) {
// If the method is a default method, we need to use the def_id of
// the default implementation.
let method_id = match self.tcx.impl_or_trait_item(method_id) {
ty::MethodTraitItem(method_type) => {
method_type.provided_source.unwrap_or(method_id)
}
_ => {
self.tcx.sess
.span_bug(span,
"got non-method item in check_static_method")
}
};

self.report_error(self.ensure_public(span,
method_id,
None,
Expand Down
Loading

0 comments on commit 709ce9f

Please sign in to comment.