librustc: Only emit constructor functions as necessary.
This commit is contained in:
parent
06bf73a646
commit
27748b09d8
3 changed files with 27 additions and 62 deletions
|
@ -314,8 +314,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
|
|||
ebml_w: &mut Encoder,
|
||||
id: NodeId,
|
||||
variants: &[P<Variant>],
|
||||
index: &mut Vec<entry<i64>>,
|
||||
generics: &ast::Generics) {
|
||||
index: &mut Vec<entry<i64>>) {
|
||||
debug!("encode_enum_variant_info(id={:?})", id);
|
||||
|
||||
let mut disr_val = 0;
|
||||
|
@ -343,10 +342,6 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
|
|||
encode_stability(ebml_w, stab);
|
||||
|
||||
match variant.node.kind {
|
||||
ast::TupleVariantKind(ref args)
|
||||
if args.len() > 0 && generics.ty_params.len() == 0 => {
|
||||
encode_symbol(ecx, ebml_w, variant.node.id);
|
||||
}
|
||||
ast::TupleVariantKind(_) => {},
|
||||
ast::StructVariantKind(_) => {
|
||||
let fields = ty::lookup_struct_fields(ecx.tcx, def_id);
|
||||
|
@ -1019,7 +1014,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
encode_stability(ebml_w, stab);
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
ItemEnum(ref enum_definition, ref generics) => {
|
||||
ItemEnum(ref enum_definition, _) => {
|
||||
add_to_index(item, ebml_w, index);
|
||||
|
||||
ebml_w.start_tag(tag_items_data_item);
|
||||
|
@ -1046,8 +1041,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
ebml_w,
|
||||
item.id,
|
||||
(*enum_definition).variants.as_slice(),
|
||||
index,
|
||||
generics);
|
||||
index);
|
||||
}
|
||||
ItemStruct(struct_def, _) => {
|
||||
let fields = ty::lookup_struct_fields(tcx, def_id);
|
||||
|
|
|
@ -80,7 +80,6 @@ use std::c_str::ToCStr;
|
|||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
use std::{i8, i16, i32, i64};
|
||||
use std::gc::Gc;
|
||||
use syntax::abi::{X86, X86_64, Arm, Mips, Mipsel, Rust, RustCall};
|
||||
use syntax::abi::{RustIntrinsic, Abi};
|
||||
use syntax::ast_util::{local_def, is_local};
|
||||
|
@ -1815,31 +1814,6 @@ fn trans_enum_variant_or_tuple_like_struct(ccx: &CrateContext,
|
|||
finish_fn(&fcx, bcx, result_ty);
|
||||
}
|
||||
|
||||
fn trans_enum_def(ccx: &CrateContext, enum_definition: &ast::EnumDef,
|
||||
sp: Span, id: ast::NodeId, vi: &[Rc<ty::VariantInfo>],
|
||||
i: &mut uint) {
|
||||
for variant in enum_definition.variants.iter() {
|
||||
let disr_val = vi[*i].disr_val;
|
||||
*i += 1;
|
||||
|
||||
match variant.node.kind {
|
||||
ast::TupleVariantKind(ref args) if args.len() > 0 => {
|
||||
let llfn = get_item_val(ccx, variant.node.id);
|
||||
trans_enum_variant(ccx, id, &**variant, args.as_slice(),
|
||||
disr_val, ¶m_substs::empty(), llfn);
|
||||
}
|
||||
ast::TupleVariantKind(_) => {
|
||||
// Nothing to do.
|
||||
}
|
||||
ast::StructVariantKind(struct_def) => {
|
||||
trans_struct_def(ccx, struct_def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum_variant_size_lint(ccx, enum_definition, sp, id);
|
||||
}
|
||||
|
||||
fn enum_variant_size_lint(ccx: &CrateContext, enum_def: &ast::EnumDef, sp: Span, id: ast::NodeId) {
|
||||
let mut sizes = Vec::new(); // does no allocation if no pushes, thankfully
|
||||
|
||||
|
@ -1932,12 +1906,8 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
|
|||
ast::ItemMod(ref m) => {
|
||||
trans_mod(ccx, m);
|
||||
}
|
||||
ast::ItemEnum(ref enum_definition, ref generics) => {
|
||||
if !generics.is_type_parameterized() {
|
||||
let vi = ty::enum_variants(ccx.tcx(), local_def(item.id));
|
||||
let mut i = 0;
|
||||
trans_enum_def(ccx, enum_definition, item.span, item.id, vi.as_slice(), &mut i);
|
||||
}
|
||||
ast::ItemEnum(ref enum_definition, _) => {
|
||||
enum_variant_size_lint(ccx, enum_definition, item.span, item.id);
|
||||
}
|
||||
ast::ItemStatic(_, m, ref expr) => {
|
||||
// Recurse on the expression to catch items in blocks
|
||||
|
@ -1964,11 +1934,6 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
|
|||
ast::ItemForeignMod(ref foreign_mod) => {
|
||||
foreign::trans_foreign_mod(ccx, foreign_mod);
|
||||
}
|
||||
ast::ItemStruct(struct_def, ref generics) => {
|
||||
if !generics.is_type_parameterized() {
|
||||
trans_struct_def(ccx, struct_def);
|
||||
}
|
||||
}
|
||||
ast::ItemTrait(..) => {
|
||||
// Inside of this trait definition, we won't be actually translating any
|
||||
// functions, but the trait still needs to be walked. Otherwise default
|
||||
|
@ -1981,20 +1946,6 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn trans_struct_def(ccx: &CrateContext, struct_def: Gc<ast::StructDef>) {
|
||||
// If this is a tuple-like struct, translate the constructor.
|
||||
match struct_def.ctor_id {
|
||||
// We only need to translate a constructor if there are fields;
|
||||
// otherwise this is a unit-like struct.
|
||||
Some(ctor_id) if struct_def.fields.len() > 0 => {
|
||||
let llfndecl = get_item_val(ccx, ctor_id);
|
||||
trans_tuple_struct(ccx, struct_def.fields.as_slice(),
|
||||
ctor_id, ¶m_substs::empty(), llfndecl);
|
||||
}
|
||||
Some(_) | None => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Translate a module. Doing this amounts to translating the items in the
|
||||
// module; there ends up being no artifact (aside from linkage names) of
|
||||
// separate modules in the compiled program. That's because modules exist
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
use arena::TypedArena;
|
||||
use back::abi;
|
||||
use back::link;
|
||||
use driver::session;
|
||||
use llvm::{ValueRef, get_param};
|
||||
use llvm;
|
||||
use metadata::csearch;
|
||||
|
@ -521,8 +522,27 @@ pub fn trans_fn_ref_with_vtables(
|
|||
}
|
||||
};
|
||||
|
||||
// We must monomorphise if the fn has type parameters or is a default method.
|
||||
let must_monomorphise = !substs.types.is_empty() || is_default;
|
||||
// We must monomorphise if the fn has type parameters, is a default method,
|
||||
// or is a named tuple constructor.
|
||||
let must_monomorphise = if !substs.types.is_empty() || is_default {
|
||||
true
|
||||
} else if def_id.krate == ast::LOCAL_CRATE {
|
||||
let map_node = session::expect(
|
||||
ccx.sess(),
|
||||
tcx.map.find(def_id.node),
|
||||
|| "local item should be in ast map".to_string());
|
||||
|
||||
match map_node {
|
||||
ast_map::NodeVariant(v) => match v.node.kind {
|
||||
ast::TupleVariantKind(ref args) => args.len() > 0,
|
||||
_ => false
|
||||
},
|
||||
ast_map::NodeStructCtor(_) => true,
|
||||
_ => false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
// Create a monomorphic version of generic functions
|
||||
if must_monomorphise {
|
||||
|
|
Loading…
Reference in a new issue