Skip to content

Commit 48b59d1

Browse files
committed
---
yaml --- r: 128860 b: refs/heads/try c: cf71f1c h: refs/heads/master v: v3
1 parent 62b88fa commit 48b59d1

File tree

10 files changed

+198
-78
lines changed

10 files changed

+198
-78
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
refs/heads/master: 07d86b46a949a94223da714e35b343243e4ecce4
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: a86d9ad15e339ab343a12513f9c90556f677b9ca
5-
refs/heads/try: 48edb32a3fc8ba6cc3db9a9d11f5201a919391f5
5+
refs/heads/try: cf71f1c7b077c93b33360fd5af6442fff2e39876
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: 147ecfdd8221e4a4d4e090486829a06da1e0ca3c

branches/try/src/libnum/complex.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,14 @@ mod test {
257257
assert_eq!(_1_0i.inv(), _1_0i.inv());
258258
}
259259

260+
#[test]
261+
#[should_fail]
262+
fn test_divide_by_zero_natural() {
263+
let n = Complex::new(2i, 3i);
264+
let d = Complex::new(0, 0);
265+
let _x = n / d;
266+
}
267+
260268
#[test]
261269
#[should_fail]
262270
#[ignore]

branches/try/src/librustc/middle/trans/base.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,12 +1947,10 @@ pub fn trans_named_tuple_constructor<'a>(mut bcx: &'a Block<'a>,
19471947
};
19481948

19491949
if !type_is_zero_size(ccx, result_ty) {
1950-
let repr = adt::represent_type(ccx, result_ty);
1951-
19521950
match args {
19531951
callee::ArgExprs(exprs) => {
19541952
let fields = exprs.iter().map(|x| *x).enumerate().collect::<Vec<_>>();
1955-
bcx = expr::trans_adt(bcx, &*repr, disr, fields.as_slice(),
1953+
bcx = expr::trans_adt(bcx, result_ty, disr, fields.as_slice(),
19561954
None, expr::SaveIn(llresult));
19571955
}
19581956
_ => ccx.sess().bug("expected expr as arguments for variant/struct tuple constructor")

branches/try/src/librustc/middle/trans/controlflow.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,13 +330,12 @@ pub fn trans_for<'a>(
330330
// Check the discriminant; if the `None` case, exit the loop.
331331
let option_representation = adt::represent_type(loopback_bcx_out.ccx(),
332332
method_result_type);
333-
let i8_type = Type::i8(loopback_bcx_out.ccx());
334333
let lldiscriminant = adt::trans_get_discr(loopback_bcx_out,
335334
&*option_representation,
336335
option_datum.val,
337-
Some(i8_type));
338-
let llzero = C_u8(loopback_bcx_out.ccx(), 0);
339-
let llcondition = ICmp(loopback_bcx_out, IntNE, lldiscriminant, llzero);
336+
None);
337+
let i1_type = Type::i1(loopback_bcx_out.ccx());
338+
let llcondition = Trunc(loopback_bcx_out, lldiscriminant, i1_type);
340339
CondBr(loopback_bcx_out, llcondition, body_bcx_in.llbb, cleanup_llbb);
341340

342341
// Now we're in the body. Unpack the `Option` value into the programmer-

branches/try/src/librustc/middle/trans/expr.rs

Lines changed: 55 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -746,18 +746,17 @@ fn trans_rvalue_dps_unadjusted<'a>(bcx: &'a Block<'a>,
746746
controlflow::trans_block(bcx, &**blk, dest)
747747
}
748748
ast::ExprStruct(_, ref fields, base) => {
749-
trans_rec_or_struct(bcx,
750-
fields.as_slice(),
751-
base,
752-
expr.span,
753-
expr.id,
754-
dest)
749+
trans_struct(bcx,
750+
fields.as_slice(),
751+
base,
752+
expr.span,
753+
expr.id,
754+
dest)
755755
}
756756
ast::ExprTup(ref args) => {
757-
let repr = adt::represent_type(bcx.ccx(), expr_ty(bcx, expr));
758757
let numbered_fields: Vec<(uint, Gc<ast::Expr>)> =
759758
args.iter().enumerate().map(|(i, arg)| (i, *arg)).collect();
760-
trans_adt(bcx, &*repr, 0, numbered_fields.as_slice(), None, dest)
759+
trans_adt(bcx, expr_ty(bcx, expr), 0, numbered_fields.as_slice(), None, dest)
761760
}
762761
ast::ExprLit(lit) => {
763762
match lit.node {
@@ -1042,16 +1041,13 @@ pub fn with_field_tys<R>(tcx: &ty::ctxt,
10421041
}
10431042
}
10441043

1045-
fn trans_rec_or_struct<'a>(
1046-
bcx: &'a Block<'a>,
1047-
fields: &[ast::Field],
1048-
base: Option<Gc<ast::Expr>>,
1049-
expr_span: codemap::Span,
1050-
id: ast::NodeId,
1051-
dest: Dest)
1052-
-> &'a Block<'a> {
1044+
fn trans_struct<'a>(bcx: &'a Block<'a>,
1045+
fields: &[ast::Field],
1046+
base: Option<Gc<ast::Expr>>,
1047+
expr_span: codemap::Span,
1048+
id: ast::NodeId,
1049+
dest: Dest) -> &'a Block<'a> {
10531050
let _icx = push_ctxt("trans_rec");
1054-
let bcx = bcx;
10551051

10561052
let ty = node_id_type(bcx, id);
10571053
let tcx = bcx.tcx();
@@ -1092,8 +1088,7 @@ fn trans_rec_or_struct<'a>(
10921088
}
10931089
};
10941090

1095-
let repr = adt::represent_type(bcx.ccx(), ty);
1096-
trans_adt(bcx, &*repr, discr, numbered_fields.as_slice(), optbase, dest)
1091+
trans_adt(bcx, ty, discr, numbered_fields.as_slice(), optbase, dest)
10971092
})
10981093
}
10991094

@@ -1121,60 +1116,71 @@ pub struct StructBaseInfo {
11211116
* - `optbase` contains information on the base struct (if any) from
11221117
* which remaining fields are copied; see comments on `StructBaseInfo`.
11231118
*/
1124-
pub fn trans_adt<'a>(bcx: &'a Block<'a>,
1125-
repr: &adt::Repr,
1119+
pub fn trans_adt<'a>(mut bcx: &'a Block<'a>,
1120+
ty: ty::t,
11261121
discr: ty::Disr,
11271122
fields: &[(uint, Gc<ast::Expr>)],
11281123
optbase: Option<StructBaseInfo>,
11291124
dest: Dest) -> &'a Block<'a> {
11301125
let _icx = push_ctxt("trans_adt");
11311126
let fcx = bcx.fcx;
1132-
let mut bcx = bcx;
1127+
let repr = adt::represent_type(bcx.ccx(), ty);
1128+
1129+
// If we don't care about the result, just make a
1130+
// temporary stack slot
11331131
let addr = match dest {
1134-
Ignore => {
1135-
for &(_i, ref e) in fields.iter() {
1136-
bcx = trans_into(bcx, &**e, Ignore);
1137-
}
1138-
for sbi in optbase.iter() {
1139-
// FIXME #7261: this moves entire base, not just certain fields
1140-
bcx = trans_into(bcx, &*sbi.expr, Ignore);
1141-
}
1142-
return bcx;
1143-
}
1144-
SaveIn(pos) => pos
1132+
SaveIn(pos) => pos,
1133+
Ignore => alloc_ty(bcx, ty, "temp"),
11451134
};
11461135

11471136
// This scope holds intermediates that must be cleaned should
11481137
// failure occur before the ADT as a whole is ready.
11491138
let custom_cleanup_scope = fcx.push_custom_cleanup_scope();
11501139

1140+
// First we trans the base, if we have one, to the dest
1141+
for base in optbase.iter() {
1142+
assert_eq!(discr, 0);
1143+
1144+
match ty::expr_kind(bcx.tcx(), &*base.expr) {
1145+
ty::LvalueExpr => {
1146+
let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &*base.expr, "base"));
1147+
for &(i, t) in base.fields.iter() {
1148+
let datum = base_datum.get_element(
1149+
t, |srcval| adt::trans_field_ptr(bcx, &*repr, srcval, discr, i));
1150+
let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
1151+
bcx = datum.store_to(bcx, dest);
1152+
}
1153+
},
1154+
ty::RvalueDpsExpr | ty::RvalueDatumExpr => {
1155+
bcx = trans_into(bcx, &*base.expr, SaveIn(addr));
1156+
},
1157+
ty::RvalueStmtExpr => bcx.tcx().sess.bug("unexpected expr kind for struct base expr")
1158+
}
1159+
}
1160+
1161+
// Now, we just overwrite the fields we've explicity specified
11511162
for &(i, ref e) in fields.iter() {
1152-
let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i);
1163+
let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
11531164
let e_ty = expr_ty_adjusted(bcx, &**e);
11541165
bcx = trans_into(bcx, &**e, SaveIn(dest));
11551166
let scope = cleanup::CustomScope(custom_cleanup_scope);
11561167
fcx.schedule_lifetime_end(scope, dest);
11571168
fcx.schedule_drop_mem(scope, dest, e_ty);
11581169
}
11591170

1160-
for base in optbase.iter() {
1161-
// FIXME #6573: is it sound to use the destination's repr on the base?
1162-
// And, would it ever be reasonable to be here with discr != 0?
1163-
let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &*base.expr, "base"));
1164-
for &(i, t) in base.fields.iter() {
1165-
let datum = base_datum.get_element(
1166-
t,
1167-
|srcval| adt::trans_field_ptr(bcx, repr, srcval, discr, i));
1168-
let dest = adt::trans_field_ptr(bcx, repr, addr, discr, i);
1169-
bcx = datum.store_to(bcx, dest);
1170-
}
1171-
}
1172-
1173-
adt::trans_set_discr(bcx, repr, addr, discr);
1171+
adt::trans_set_discr(bcx, &*repr, addr, discr);
11741172

11751173
fcx.pop_custom_cleanup_scope(custom_cleanup_scope);
11761174

1177-
return bcx;
1175+
// If we don't care about the result drop the temporary we made
1176+
match dest {
1177+
SaveIn(_) => bcx,
1178+
Ignore => {
1179+
bcx = glue::drop_ty(bcx, addr, ty);
1180+
base::call_lifetime_end(bcx, addr);
1181+
bcx
1182+
}
1183+
}
11781184
}
11791185

11801186

branches/try/src/librustc/middle/trans/glue.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,9 @@ fn trans_struct_drop<'a>(bcx: &'a Block<'a>,
250250
let args = vec!(self_arg);
251251

252252
// Add all the fields as a value which needs to be cleaned at the end of
253-
// this scope.
254-
for (i, ty) in st.fields.iter().enumerate() {
253+
// this scope. Iterate in reverse order so a Drop impl doesn't reverse
254+
// the order in which fields get dropped.
255+
for (i, ty) in st.fields.iter().enumerate().rev() {
255256
let llfld_a = adt::struct_field_ptr(variant_cx, &*st, value, i, false);
256257
variant_cx.fcx.schedule_drop_mem(cleanup::CustomScope(field_scope),
257258
llfld_a, *ty);

branches/try/src/libstd/io/util.rs

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,12 @@ impl<R: Reader> Reader for LimitReader<R> {
4848
}
4949

5050
let len = cmp::min(self.limit, buf.len());
51-
self.inner.read(buf.mut_slice_to(len)).map(|len| {
52-
self.limit -= len;
53-
len
54-
})
51+
let res = self.inner.read(buf.mut_slice_to(len));
52+
match res {
53+
Ok(len) => self.limit -= len,
54+
_ => {}
55+
}
56+
res
5557
}
5658
}
5759

@@ -67,6 +69,8 @@ impl<R: Buffer> Buffer for LimitReader<R> {
6769
}
6870

6971
fn consume(&mut self, amt: uint) {
72+
// Don't let callers reset the limit by passing an overlarge value
73+
let amt = cmp::min(amt, self.limit);
7074
self.limit -= amt;
7175
self.inner.consume(amt);
7276
}
@@ -97,6 +101,7 @@ impl Buffer for ZeroReader {
97101
static DATA: [u8, ..64] = [0, ..64];
98102
Ok(DATA.as_slice())
99103
}
104+
100105
fn consume(&mut self, _amt: uint) {}
101106
}
102107

@@ -117,7 +122,10 @@ impl Buffer for NullReader {
117122
fn consume(&mut self, _amt: uint) {}
118123
}
119124

120-
/// A `Writer` which multiplexes writes to a set of `Writers`.
125+
/// A `Writer` which multiplexes writes to a set of `Writer`s.
126+
///
127+
/// The `Writer`s are delegated to in order. If any `Writer` returns an error,
128+
/// that error is returned immediately and remaining `Writer`s are not called.
121129
pub struct MultiWriter {
122130
writers: Vec<Box<Writer>>
123131
}
@@ -132,24 +140,22 @@ impl MultiWriter {
132140
impl Writer for MultiWriter {
133141
#[inline]
134142
fn write(&mut self, buf: &[u8]) -> io::IoResult<()> {
135-
let mut ret = Ok(());
136143
for writer in self.writers.mut_iter() {
137-
ret = ret.and(writer.write(buf));
144+
try!(writer.write(buf));
138145
}
139-
return ret;
146+
Ok(())
140147
}
141148

142149
#[inline]
143150
fn flush(&mut self) -> io::IoResult<()> {
144-
let mut ret = Ok(());
145151
for writer in self.writers.mut_iter() {
146-
ret = ret.and(writer.flush());
152+
try!(writer.flush());
147153
}
148-
return ret;
154+
Ok(())
149155
}
150156
}
151157

152-
/// A `Reader` which chains input from multiple `Readers`, reading each to
158+
/// A `Reader` which chains input from multiple `Reader`s, reading each to
153159
/// completion before moving onto the next.
154160
pub struct ChainedReader<I, R> {
155161
readers: I,
@@ -229,17 +235,16 @@ pub fn copy<R: Reader, W: Writer>(r: &mut R, w: &mut W) -> io::IoResult<()> {
229235
}
230236
}
231237

232-
/// A `Reader` which converts an `Iterator<u8>` into a `Reader`.
238+
/// An adaptor converting an `Iterator<u8>` to a `Reader`.
233239
pub struct IterReader<T> {
234240
iter: T,
235241
}
236242

237243
impl<T: Iterator<u8>> IterReader<T> {
238-
/// Create a new `IterReader` which will read from the specified `Iterator`.
244+
/// Creates a new `IterReader` which will read from the specified
245+
/// `Iterator`.
239246
pub fn new(iter: T) -> IterReader<T> {
240-
IterReader {
241-
iter: iter,
242-
}
247+
IterReader { iter: iter }
243248
}
244249
}
245250

@@ -251,7 +256,7 @@ impl<T: Iterator<u8>> Reader for IterReader<T> {
251256
*slot = elt;
252257
len += 1;
253258
}
254-
if len == 0 {
259+
if len == 0 && buf.len() != 0 {
255260
Err(io::standard_error(io::EndOfFile))
256261
} else {
257262
Ok(len)
@@ -297,6 +302,14 @@ mod test {
297302
assert_eq!(0, r.limit());
298303
}
299304

305+
#[test]
306+
fn test_limit_reader_overlong_consume() {
307+
let mut r = MemReader::new(vec![0, 1, 2, 3, 4, 5]);
308+
let mut r = LimitReader::new(r.by_ref(), 1);
309+
r.consume(2);
310+
assert_eq!(vec![], r.read_to_end().unwrap());
311+
}
312+
300313
#[test]
301314
fn test_null_writer() {
302315
let mut s = NullWriter;
@@ -415,4 +428,11 @@ mod test {
415428

416429
assert_eq!(r.read(buf).unwrap_err().kind, io::EndOfFile);
417430
}
431+
432+
#[test]
433+
fn iter_reader_zero_length() {
434+
let mut r = IterReader::new(range(0u8, 8));
435+
let mut buf = [];
436+
assert_eq!(Ok(0), r.read(buf));
437+
}
418438
}

branches/try/src/libstd/time/duration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ macro_rules! try_opt(
3838
// FIXME #16466: This could be represented as (i64 seconds, u32 nanos)
3939
/// ISO 8601 time duration with nanosecond precision.
4040
/// This also allows for the negative duration; see individual methods for details.
41-
#[deriving(PartialEq, Eq, PartialOrd, Ord)]
41+
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
4242
pub struct Duration {
4343
days: i32,
4444
secs: u32, // Always < SECS_PER_DAY

branches/try/src/rustllvm/RustWrapper.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,11 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateSubroutineType(
282282
LLVMValueRef ParameterTypes) {
283283
return wrap(Builder->createSubroutineType(
284284
unwrapDI<DIFile>(File),
285+
#if LLVM_VERSION_MINOR >= 6
285286
unwrapDI<DITypeArray>(ParameterTypes)));
287+
#else
288+
unwrapDI<DIArray>(ParameterTypes)));
289+
#endif
286290
}
287291

288292
extern "C" LLVMValueRef LLVMDIBuilderCreateFunction(
@@ -634,7 +638,11 @@ extern "C" void LLVMDICompositeTypeSetTypeArray(
634638
LLVMValueRef CompositeType,
635639
LLVMValueRef TypeArray)
636640
{
641+
#if LLVM_VERSION_MINOR >= 6
637642
unwrapDI<DICompositeType>(CompositeType).setArrays(unwrapDI<DIArray>(TypeArray));
643+
#else
644+
unwrapDI<DICompositeType>(CompositeType).setTypeArray(unwrapDI<DIArray>(TypeArray));
645+
#endif
638646
}
639647

640648
extern "C" char *LLVMTypeToString(LLVMTypeRef Type) {

0 commit comments

Comments
 (0)