Skip to content

Commit 2deb8e2

Browse files
committed
---
yaml --- r: 48813 b: refs/heads/snap-stage3 c: a14ec73 h: refs/heads/master i: 48811: 3a0a14a v: v3
1 parent 03482dc commit 2deb8e2

File tree

18 files changed

+248
-102
lines changed

18 files changed

+248
-102
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 3bbcac322669cff3abde5be937cc4ec3860f3985
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: e82167198900a8d592535f40307f7c3a71b8b72b
4+
refs/heads/snap-stage3: a14ec73cd2d15a2454113011835557ccf447f14d
55
refs/heads/try: 2a8fb58d79e685d5ca07b039badcf2ae3ef077ea
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/librustc/driver/driver.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,15 @@ pub fn build_configuration(sess: Session, +argv0: ~str, input: input) ->
132132
}
133133

134134
// Convert strings provided as --cfg [cfgspec] into a crate_cfg
135-
pub fn parse_cfgspecs(cfgspecs: ~[~str]) -> ast::crate_cfg {
136-
// FIXME (#2399): It would be nice to use the parser to parse all
137-
// varieties of meta_item here. At the moment we just support the
138-
// meta_word variant.
139-
let mut words = ~[];
135+
fn parse_cfgspecs(cfgspecs: ~[~str],
136+
demitter: diagnostic::Emitter) -> ast::crate_cfg {
137+
let mut meta = ~[];
140138
for cfgspecs.each |s| {
141-
words.push(attr::mk_word_item(@/*bad*/copy *s));
139+
let sess = parse::new_parse_sess(Some(demitter));
140+
let m = parse::parse_meta_from_source_str(~"cfgspec", @/*bad*/ copy *s, ~[], sess);
141+
meta.push(m)
142142
}
143-
return words;
143+
return meta;
144144
}
145145

146146
pub enum input {
@@ -639,7 +639,7 @@ pub fn build_session_options(+binary: ~str,
639639
let addl_lib_search_paths =
640640
getopts::opt_strs(matches, ~"L")
641641
.map(|s| Path(*s));
642-
let cfg = parse_cfgspecs(getopts::opt_strs(matches, ~"cfg"));
642+
let cfg = parse_cfgspecs(getopts::opt_strs(matches, ~"cfg"), demitter);
643643
let test = opt_present(matches, ~"test");
644644
let android_cross_path = getopts::opt_maybe_str(
645645
matches, ~"android-cross-path");

branches/snap-stage3/src/librustc/middle/lint.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,12 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
498498
// not traverse into subitems, since that is handled by the outer
499499
// lint visitor.
500500
fn item_stopping_visitor<E>(v: visit::vt<E>) -> visit::vt<E> {
501-
visit::mk_vt(@visit::Visitor {visit_item: |_i, _e, _v| { },.. **v})
501+
visit::mk_vt(@visit::Visitor {visit_item: |_i, _e, _v| { },
502+
.. **(ty_stopping_visitor(v))})
503+
}
504+
505+
fn ty_stopping_visitor<E>(v: visit::vt<E>) -> visit::vt<E> {
506+
visit::mk_vt(@visit::Visitor {visit_ty: |_t, _e, _v| { },.. **v})
502507
}
503508

504509
fn check_item_while_true(cx: ty::ctxt, it: @ast::item) {

branches/snap-stage3/src/librustc/middle/trans/adt.rs

Lines changed: 48 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@
2323
* Having everything in one place will enable improvements to data
2424
* structure representation; possibilities include:
2525
*
26-
* - Aligning enum bodies correctly, which in turn makes possible SIMD
27-
* vector types (which are strict-alignment even on x86) and ports
28-
* to strict-alignment architectures (PowerPC, SPARC, etc.).
29-
*
3026
* - User-specified alignment (e.g., cacheline-aligning parts of
3127
* concurrently accessed data structures); LLVM can't represent this
3228
* directly, so we'd have to insert padding fields in any structure
@@ -82,10 +78,8 @@ pub enum Repr {
8278
*/
8379
Univariant(Struct, bool),
8480
/**
85-
* General-case enums: discriminant as int, followed by fields.
86-
* The fields start immediately after the discriminant, meaning
87-
* that they may not be correctly aligned for the platform's ABI;
88-
* see above.
81+
* General-case enums: for each case there is a struct, and they
82+
* all start with a field for the discriminant.
8983
*/
9084
General(~[Struct])
9185
}
@@ -156,7 +150,8 @@ pub fn represent_type(cx: @CrateContext, t: ty::t) -> @Repr {
156150
discriminants",
157151
ty::item_path_str(cx.tcx, def_id)))
158152
}
159-
General(cases.map(|c| mk_struct(cx, c.tys)))
153+
let discr = ~[ty::mk_int(cx.tcx)];
154+
General(cases.map(|c| mk_struct(cx, discr + c.tys)))
160155
}
161156
}
162157
_ => cx.sess.bug(~"adt::represent_type called on non-ADT type")
@@ -191,20 +186,44 @@ fn generic_fields_of(cx: @CrateContext, r: &Repr, sizing: bool)
191186
-> ~[TypeRef] {
192187
match *r {
193188
CEnum(*) => ~[T_enum_discrim(cx)],
194-
Univariant(ref st, _dtor) => {
195-
if sizing {
196-
st.fields.map(|&ty| type_of::sizing_type_of(cx, ty))
197-
} else {
198-
st.fields.map(|&ty| type_of::type_of(cx, ty))
199-
}
200-
}
189+
Univariant(ref st, _dtor) => struct_llfields(cx, st, sizing),
201190
General(ref sts) => {
202-
~[T_enum_discrim(cx),
203-
T_array(T_i8(), sts.map(|st| st.size).max() /*bad*/as uint)]
191+
// To get "the" type of a general enum, we pick the case
192+
// with the largest alignment (so it will always align
193+
// correctly in containing structures) and pad it out.
194+
fail_unless!(sts.len() >= 1);
195+
let mut most_aligned = None;
196+
let mut largest_align = 0;
197+
let mut largest_size = 0;
198+
for sts.each |st| {
199+
if largest_size < st.size {
200+
largest_size = st.size;
201+
}
202+
if largest_align < st.align {
203+
// Clang breaks ties by size; it is unclear if
204+
// that accomplishes anything important.
205+
largest_align = st.align;
206+
most_aligned = Some(st);
207+
}
208+
}
209+
let most_aligned = most_aligned.get();
210+
let padding = largest_size - most_aligned.size;
211+
212+
struct_llfields(cx, most_aligned, sizing)
213+
+ [T_array(T_i8(), padding /*bad*/as uint)]
204214
}
205215
}
206216
}
207217

218+
fn struct_llfields(cx: @CrateContext, st: &Struct, sizing: bool)
219+
-> ~[TypeRef] {
220+
if sizing {
221+
st.fields.map(|&ty| type_of::sizing_type_of(cx, ty))
222+
} else {
223+
st.fields.map(|&ty| type_of::type_of(cx, ty))
224+
}
225+
}
226+
208227
/**
209228
* Obtain a representation of the discriminant sufficient to translate
210229
* destructuring; this may or may not involve the actual discriminant.
@@ -309,7 +328,7 @@ pub fn num_args(r: &Repr, discr: int) -> uint {
309328
fail_unless!(discr == 0);
310329
st.fields.len() - (if dtor { 1 } else { 0 })
311330
}
312-
General(ref cases) => cases[discr as uint].fields.len()
331+
General(ref cases) => cases[discr as uint].fields.len() - 1
313332
}
314333
}
315334

@@ -328,8 +347,7 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int,
328347
struct_field_ptr(bcx, st, val, ix, false)
329348
}
330349
General(ref cases) => {
331-
struct_field_ptr(bcx, &cases[discr as uint],
332-
GEPi(bcx, val, [0, 1]), ix, true)
350+
struct_field_ptr(bcx, &cases[discr as uint], val, ix + 1, true)
333351
}
334352
}
335353
}
@@ -371,13 +389,12 @@ pub fn trans_drop_flag_ptr(bcx: block, r: &Repr, val: ValueRef) -> ValueRef {
371389
* depending on which case of an enum it is.
372390
*
373391
* To understand the alignment situation, consider `enum E { V64(u64),
374-
* V32(u32, u32) }` on win32. The type should have 8-byte alignment
375-
* to accommodate the u64 (currently it doesn't; this is a known bug),
376-
* but `V32(x, y)` would have LLVM type `{i32, i32, i32}`, which is
377-
* 4-byte aligned.
392+
* V32(u32, u32) }` on win32. The type has 8-byte alignment to
393+
* accommodate the u64, but `V32(x, y)` would have LLVM type `{i32,
394+
* i32, i32}`, which is 4-byte aligned.
378395
*
379396
* Currently the returned value has the same size as the type, but
380-
* this may be changed in the future to avoid allocating unnecessary
397+
* this could be changed in the future to avoid allocating unnecessary
381398
* space after values of shorter-than-maximum cases.
382399
*/
383400
pub fn trans_const(ccx: @CrateContext, r: &Repr, discr: int,
@@ -395,14 +412,9 @@ pub fn trans_const(ccx: @CrateContext, r: &Repr, discr: int,
395412
General(ref cases) => {
396413
let case = &cases[discr as uint];
397414
let max_sz = cases.map(|s| s.size).max();
398-
let body = build_const_struct(ccx, case, vals);
399-
400-
// The unary packed struct has alignment 1 regardless of
401-
// its contents, so it will always be located at the
402-
// expected offset at runtime.
403-
C_struct([C_int(ccx, discr),
404-
C_packed_struct([C_struct(body)]),
405-
padding(max_sz - case.size)])
415+
let contents = build_const_struct(ccx, case,
416+
~[C_int(ccx, discr)] + vals);
417+
C_struct(contents + [padding(max_sz - case.size)])
406418
}
407419
}
408420
}
@@ -472,11 +484,9 @@ pub fn const_get_discrim(ccx: @CrateContext, r: &Repr, val: ValueRef)
472484
pub fn const_get_field(ccx: @CrateContext, r: &Repr, val: ValueRef,
473485
_discr: int, ix: uint) -> ValueRef {
474486
match *r {
475-
CEnum(*) => ccx.sess.bug(~"element access in C-like enum \
476-
const"),
487+
CEnum(*) => ccx.sess.bug(~"element access in C-like enum const"),
477488
Univariant(*) => const_struct_field(ccx, val, ix),
478-
General(*) => const_struct_field(ccx, const_get_elt(ccx, val,
479-
[1, 0]), ix)
489+
General(*) => const_struct_field(ccx, val, ix + 1)
480490
}
481491
}
482492

branches/snap-stage3/src/librustc/middle/trans/callee.rs

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -491,14 +491,12 @@ pub fn trans_call_inner(
491491
}
492492
};
493493

494-
let llretslot = trans_ret_slot(bcx, fn_expr_ty, dest);
495-
496-
let mut llargs = ~[];
497-
llargs.push(llretslot);
498-
llargs.push(llenv);
499-
bcx = trans_args(bcx, args, fn_expr_ty,
500-
ret_flag, autoref_arg, &mut llargs);
494+
let args_res = trans_args(bcx, llenv, args, fn_expr_ty,
495+
dest, ret_flag, autoref_arg);
496+
bcx = args_res.bcx;
497+
let mut llargs = /*bad*/copy args_res.args;
501498

499+
let llretslot = args_res.retslot;
502500

503501
// Now that the arguments have finished evaluating, we need to revoke
504502
// the cleanup for the self argument, if it exists
@@ -556,12 +554,30 @@ pub enum CallArgs {
556554
ArgVals(&'self [ValueRef])
557555
}
558556

559-
pub fn trans_ret_slot(+bcx: block,
560-
+fn_ty: ty::t,
561-
+dest: expr::Dest) -> ValueRef
562-
{
557+
pub struct Args {
558+
bcx: block,
559+
args: ~[ValueRef],
560+
retslot: ValueRef
561+
}
562+
563+
pub fn trans_args(cx: block,
564+
llenv: ValueRef,
565+
+args: CallArgs,
566+
fn_ty: ty::t,
567+
dest: expr::Dest,
568+
ret_flag: Option<ValueRef>,
569+
+autoref_arg: AutorefArg) -> Args {
570+
let _icx = cx.insn_ctxt("trans_args");
571+
let mut temp_cleanups = ~[];
572+
let arg_tys = ty::ty_fn_args(fn_ty);
573+
let mut llargs: ~[ValueRef] = ~[];
574+
575+
let mut bcx = cx;
576+
563577
let retty = ty::ty_fn_ret(fn_ty);
564-
match dest {
578+
579+
// Arg 0: Output pointer.
580+
let llretslot = match dest {
565581
expr::SaveIn(dst) => dst,
566582
expr::Ignore => {
567583
if ty::type_is_nil(retty) {
@@ -572,21 +588,13 @@ pub fn trans_ret_slot(+bcx: block,
572588
alloc_ty(bcx, retty)
573589
}
574590
}
575-
}
576-
}
591+
};
592+
llargs.push(llretslot);
577593

578-
pub fn trans_args(+cx: block,
579-
+args: CallArgs,
580-
+fn_ty: ty::t,
581-
+ret_flag: Option<ValueRef>,
582-
+autoref_arg: AutorefArg,
583-
+llargs: &mut ~[ValueRef]) -> block
584-
{
585-
let _icx = cx.insn_ctxt("trans_args");
586-
let mut temp_cleanups = ~[];
587-
let arg_tys = ty::ty_fn_args(fn_ty);
594+
// Arg 1: Env (closure-bindings / self value)
595+
llargs.push(llenv);
588596

589-
let mut bcx = cx;
597+
// ... then explicit args.
590598

591599
// First we figure out the caller's view of the types of the arguments.
592600
// This will be needed if this is a generic call, because the callee has
@@ -615,7 +623,7 @@ pub fn trans_args(+cx: block,
615623
revoke_clean(bcx, *c)
616624
}
617625

618-
return bcx;
626+
Args { bcx: bcx, args: llargs, retslot: llretslot }
619627
}
620628

621629
pub enum AutorefArg {

branches/snap-stage3/src/librustc/middle/typeck/astconv.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454

5555
use core::prelude::*;
5656

57+
use middle::const_eval;
5758
use middle::ty::{arg, field, substs};
5859
use middle::ty::{ty_param_substs_and_ty};
5960
use middle::ty;
@@ -412,9 +413,29 @@ pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
412413
}
413414
}
414415
}
415-
ast::ty_fixed_length_vec(a_mt, u) => {
416-
ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, a_mt),
417-
ty::vstore_fixed(u))
416+
ast::ty_fixed_length_vec(a_mt, e) => {
417+
match const_eval::eval_const_expr_partial(tcx, e) {
418+
Ok(ref r) => {
419+
match *r {
420+
const_eval::const_int(i) =>
421+
ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, a_mt),
422+
ty::vstore_fixed(i as uint)),
423+
const_eval::const_uint(i) =>
424+
ty::mk_evec(tcx, ast_mt_to_mt(self, rscope, a_mt),
425+
ty::vstore_fixed(i as uint)),
426+
_ => {
427+
tcx.sess.span_fatal(
428+
ast_ty.span, ~"expected constant expr for vector length");
429+
}
430+
}
431+
}
432+
Err(ref r) => {
433+
tcx.sess.span_fatal(
434+
ast_ty.span,
435+
fmt!("expected constant expr for vector length: %s",
436+
*r));
437+
}
438+
}
418439
}
419440
ast::ty_infer => {
420441
// ty_infer should only appear as the type of arguments or return

branches/snap-stage3/src/librustc/middle/typeck/check/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,7 +2169,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
21692169
}
21702170
ast::expr_repeat(element, count_expr, mutbl) => {
21712171
let count = ty::eval_repeat_count(tcx, count_expr);
2172-
fcx.write_ty(count_expr.id, ty::mk_uint(tcx));
2172+
check_expr_with_hint(fcx, count_expr, ty::mk_uint(tcx));
21732173
let tt = ast_expr_vstore_to_vstore(fcx, ev, count, vst);
21742174
let t: ty::t = fcx.infcx().next_ty_var();
21752175
bot |= check_expr_has_type(fcx, element, t);
@@ -2537,7 +2537,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
25372537
}
25382538
ast::expr_repeat(element, count_expr, mutbl) => {
25392539
let count = ty::eval_repeat_count(tcx, count_expr);
2540-
fcx.write_ty(count_expr.id, ty::mk_uint(tcx));
2540+
check_expr_with_hint(fcx, count_expr, ty::mk_uint(tcx));
25412541
let t: ty::t = fcx.infcx().next_ty_var();
25422542
bot |= check_expr_has_type(fcx, element, t);
25432543
let t = ty::mk_evec(tcx, ty::mt {ty: t, mutbl: mutbl},

branches/snap-stage3/src/libsyntax/ast.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,6 @@ pub enum vstore {
386386
#[auto_decode]
387387
#[deriving_eq]
388388
pub enum expr_vstore {
389-
// FIXME (#3469): Change uint to @expr (actually only constant exprs)
390389
expr_vstore_fixed(Option<uint>), // [1,2,3,4]
391390
expr_vstore_uniq, // ~[1,2,3,4]
392391
expr_vstore_box, // @[1,2,3,4]
@@ -916,7 +915,7 @@ pub enum ty_ {
916915
ty_box(mt),
917916
ty_uniq(mt),
918917
ty_vec(mt),
919-
ty_fixed_length_vec(mt, uint),
918+
ty_fixed_length_vec(mt, @expr),
920919
ty_ptr(mt),
921920
ty_rptr(Option<@Lifetime>, mt),
922921
ty_closure(@TyClosure),

branches/snap-stage3/src/libsyntax/fold.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -622,10 +622,10 @@ pub fn noop_fold_ty(t: &ty_, fld: @ast_fold) -> ty_ {
622622
}
623623
ty_tup(ref tys) => ty_tup(tys.map(|ty| fld.fold_ty(*ty))),
624624
ty_path(path, id) => ty_path(fld.fold_path(path), fld.new_id(id)),
625-
ty_fixed_length_vec(ref mt, vs) => {
625+
ty_fixed_length_vec(ref mt, e) => {
626626
ty_fixed_length_vec(
627627
fold_mt(mt, fld),
628-
vs
628+
fld.fold_expr(e)
629629
)
630630
}
631631
ty_mac(ref mac) => ty_mac(fold_mac(*mac))

0 commit comments

Comments
 (0)