Skip to content

Commit d23b769

Browse files
committed
---
yaml --- r: 45023 b: refs/heads/master c: bb689c0 h: refs/heads/master i: 45021: 9379810 45019: 2ca1aef 45015: 92cfc01 45007: 8222f9f 44991: d157fdc v: v3
1 parent fffcd4c commit d23b769

File tree

3 files changed

+45
-114
lines changed

3 files changed

+45
-114
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 2a028c5ab8363d9263d0cda09d6ab884c5b73978
2+
refs/heads/master: bb689c09f5ea185e082254c514bae1f8940e04a4
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a6d9689399d091c3265f00434a69c551a61c28dc
55
refs/heads/try: ef355f6332f83371e4acf04fc4eb940ab41d78d3

trunk/src/librustc/middle/trans/base.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -828,30 +828,6 @@ pub fn trans_external_path(ccx: @CrateContext, did: ast::def_id, t: ty::t)
828828
};
829829
}
830830
831-
pub fn get_discrim_val(cx: @CrateContext, span: span, enum_did: ast::def_id,
832-
variant_did: ast::def_id) -> ValueRef {
833-
// Can't use `discrims` from the crate context here because
834-
// those discriminants have an extra level of indirection,
835-
// and there's no LLVM constant load instruction.
836-
let mut lldiscrim_opt = None;
837-
for ty::enum_variants(cx.tcx, enum_did).each |variant_info| {
838-
if variant_info.id == variant_did {
839-
lldiscrim_opt = Some(C_int(cx,
840-
variant_info.disr_val));
841-
break;
842-
}
843-
}
844-
845-
match lldiscrim_opt {
846-
None => {
847-
cx.tcx.sess.span_bug(span, ~"didn't find discriminant?!");
848-
}
849-
Some(found_lldiscrim) => {
850-
found_lldiscrim
851-
}
852-
}
853-
}
854-
855831
pub fn invoke(bcx: block, llfn: ValueRef, +llargs: ~[ValueRef]) -> block {
856832
let _icx = bcx.insn_ctxt("invoke_");
857833
if bcx.unreachable { return bcx; }

trunk/src/librustc/middle/trans/consts.rs

Lines changed: 44 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use core::prelude::*;
1212

1313
use lib::llvm::{llvm, ValueRef, TypeRef, Bool, True, False};
1414
use middle::const_eval;
15+
use middle::trans::adt;
1516
use middle::trans::base;
1617
use middle::trans::base::get_insn_ctxt;
1718
use middle::trans::common::*;
@@ -328,24 +329,8 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
328329
}
329330
(expr::cast_enum, expr::cast_integral) |
330331
(expr::cast_enum, expr::cast_float) => {
331-
let def = ty::resolve_expr(cx.tcx, base);
332-
let (enum_did, variant_did) = match def {
333-
ast::def_variant(enum_did, variant_did) => {
334-
(enum_did, variant_did)
335-
}
336-
_ => cx.sess.bug(~"enum cast source is not enum")
337-
};
338-
// Note that we know this is a C-like (nullary) enum
339-
// variant or we wouldn't have gotten here
340-
let variants = ty::enum_variants(cx.tcx, enum_did);
341-
let iv = if variants.len() == 1 {
342-
// Univariants don't have a discriminant field,
343-
// because there's only one value it could have:
344-
C_integral(T_i64(),
345-
variants[0].disr_val as u64, True)
346-
} else {
347-
base::get_discrim_val(cx, e.span, enum_did, variant_did)
348-
};
332+
let repr = adt::represent_type(cx, basety);
333+
let iv = C_int(cx, adt::const_get_discrim(cx, &repr, v));
349334
let ety_cast = expr::cast_type_kind(ety);
350335
match ety_cast {
351336
expr::cast_integral => {
@@ -373,28 +358,32 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
373358
gv
374359
}
375360
ast::expr_tup(es) => {
376-
C_struct(es.map(|e| const_expr(cx, *e)))
361+
let ety = ty::expr_ty(cx.tcx, e);
362+
let repr = adt::represent_type(cx, ety);
363+
adt::trans_const(cx, &repr, 0, es.map(|e| const_expr(cx, *e)))
377364
}
378365
ast::expr_rec(ref fs, None) => {
379-
C_struct([C_struct(
380-
(*fs).map(|f| const_expr(cx, f.node.expr)))])
366+
let ety = ty::expr_ty(cx.tcx, e);
367+
let repr = adt::represent_type(cx, ety);
368+
adt::trans_const(cx, &repr, 0,
369+
fs.map(|f| const_expr(cx, f.node.expr)))
381370
}
382-
ast::expr_struct(_, ref fs, _) => {
371+
ast::expr_struct(_, ref fs, None) => {
383372
let ety = ty::expr_ty(cx.tcx, e);
384-
let cs = do expr::with_field_tys(cx.tcx,
385-
ety,
386-
None) |_hd, field_tys| {
387-
field_tys.map(|field_ty| {
373+
let repr = adt::represent_type(cx, ety);
374+
do expr::with_field_tys(cx.tcx, ety, Some(e.id))
375+
|discr, field_tys| {
376+
let cs = field_tys.map(|field_ty| {
388377
match fs.find(|f| field_ty.ident == f.node.ident) {
389378
Some(ref f) => const_expr(cx, (*f).node.expr),
390379
None => {
391380
cx.tcx.sess.span_bug(
392381
e.span, ~"missing struct field");
393382
}
394383
}
395-
})
396-
};
397-
C_struct([C_struct(cs)])
384+
});
385+
adt::trans_const(cx, &repr, discr, cs)
386+
}
398387
}
399388
ast::expr_vec(es, ast::m_imm) => {
400389
let (v, _, _) = const_vec(cx, e, es);
@@ -452,78 +441,44 @@ fn const_expr_unchecked(cx: @CrateContext, e: @ast::expr) -> ValueRef {
452441
get_const_val(cx, def_id)
453442
}
454443
Some(ast::def_variant(enum_did, variant_did)) => {
455-
// Note that we know this is a C-like (nullary) enum
456-
// variant or we wouldn't have gotten here -- the constant
457-
// checker forbids paths that don't map to C-like enum
458-
// variants.
459-
if ty::enum_is_univariant(cx.tcx, enum_did) {
460-
// Univariants have no discriminant field.
461-
C_struct(~[])
462-
} else {
463-
let lldiscrim = base::get_discrim_val(cx, e.span,
464-
enum_did,
465-
variant_did);
466-
// However, we still have to pad it out to the
467-
// size of the full enum; see the expr_call case,
468-
// below.
469444
let ety = ty::expr_ty(cx.tcx, e);
470-
let size = machine::static_size_of_enum(cx, ety);
471-
let padding = C_null(T_array(T_i8(), size));
472-
C_struct(~[lldiscrim, padding])
473-
}
445+
let repr = adt::represent_type(cx, ety);
446+
let vinfo = ty::enum_variant_with_id(cx.tcx,
447+
enum_did,
448+
variant_did);
449+
adt::trans_const(cx, &repr, vinfo.disr_val, [])
474450
}
475451
Some(ast::def_struct(_)) => {
476452
let ety = ty::expr_ty(cx.tcx, e);
477453
let llty = type_of::type_of(cx, ety);
478454
C_null(llty)
479455
}
480456
_ => {
481-
cx.sess.span_bug(e.span,
482-
~"expected a const, fn, or variant def")
457+
cx.sess.span_bug(e.span, ~"expected a const, fn, \
458+
struct, or variant def")
483459
}
484460
}
485461
}
486462
ast::expr_call(callee, args, _) => {
487-
match cx.tcx.def_map.find(&callee.id) {
488-
Some(ast::def_struct(def_id)) => {
489-
let llstructbody =
490-
C_struct(args.map(|a| const_expr(cx, *a)));
491-
if ty::ty_dtor(cx.tcx, def_id).is_present() {
492-
C_struct(~[ llstructbody, C_u8(0) ])
493-
} else {
494-
C_struct(~[ llstructbody ])
495-
}
496-
}
497-
Some(ast::def_variant(tid, vid)) => {
498-
let ety = ty::expr_ty(cx.tcx, e);
499-
let univar = ty::enum_is_univariant(cx.tcx, tid);
500-
let size = machine::static_size_of_enum(cx, ety);
501-
502-
let discrim = base::get_discrim_val(cx, e.span, tid, vid);
503-
let c_args = C_struct(args.map(|a| const_expr(cx, *a)));
504-
505-
// FIXME (#1645): enum body alignment is generaly wrong.
506-
if !univar {
507-
// Pad out the data to the size of its type_of;
508-
// this is necessary if the enum is contained
509-
// within an aggregate (tuple, struct, vector) so
510-
// that the next element is at the right offset.
511-
let actual_size =
512-
machine::llsize_of_real(cx, llvm::LLVMTypeOf(c_args));
513-
let padding =
514-
C_null(T_array(T_i8(), size - actual_size));
515-
// A packed_struct has an alignment of 1; thus,
516-
// wrapping one around c_args will misalign it the
517-
// same way we normally misalign enum bodies
518-
// without affecting its internal alignment or
519-
// changing the alignment of the enum.
520-
C_struct(~[discrim, C_packed_struct(~[c_args]), padding])
521-
} else {
522-
C_struct(~[c_args])
523-
}
524-
}
525-
_ => cx.sess.span_bug(e.span, ~"expected a struct def")
526-
}
463+
match cx.tcx.def_map.find(&callee.id) {
464+
Some(ast::def_struct(_)) => {
465+
let ety = ty::expr_ty(cx.tcx, e);
466+
let repr = adt::represent_type(cx, ety);
467+
adt::trans_const(cx, &repr, 0,
468+
args.map(|a| const_expr(cx, *a)))
469+
}
470+
Some(ast::def_variant(enum_did, variant_did)) => {
471+
let ety = ty::expr_ty(cx.tcx, e);
472+
let repr = adt::represent_type(cx, ety);
473+
let vinfo = ty::enum_variant_with_id(cx.tcx,
474+
enum_did,
475+
variant_did);
476+
adt::trans_const(cx, &repr, vinfo.disr_val,
477+
args.map(|a| const_expr(cx, *a)))
478+
}
479+
_ => cx.sess.span_bug(e.span, ~"expected a struct or \
480+
variant def")
481+
}
527482
}
528483
ast::expr_paren(e) => { return const_expr(cx, e); }
529484
_ => cx.sess.span_bug(e.span,

0 commit comments

Comments
 (0)