librustc: Only emit constructor functions as necessary.

This commit is contained in:
Luqman Aden 2014-07-10 10:59:52 -07:00
parent 06bf73a646
commit 27748b09d8
3 changed files with 27 additions and 62 deletions

View file

@ -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);

View file

@ -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, &param_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, &param_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

View file

@ -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 {