Skip to content

Commit 0c53668

Browse files
committed
---
yaml --- r: 177847 b: refs/heads/snap-stage3 c: e0f5980 h: refs/heads/master i: 177845: 206bc9b 177843: df27ed8 177839: 6b1c4e9 v: v3
1 parent dbe5484 commit 0c53668

File tree

6 files changed

+141
-24
lines changed

6 files changed

+141
-24
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: 474b324eda10440d6568ef872a7307d38e7de95b
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: ae076e1e3b037e557b613d97698a9f28a1683d8b
4+
refs/heads/snap-stage3: e0f5980ead4f88e78a47f4d84da4dc11472f66ba
55
refs/heads/try: fde4472848b662a4d1236388c4cf15e2450237e6
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d

branches/snap-stage3/src/librustc_borrowck/borrowck/mod.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -770,16 +770,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
770770
MutabilityViolation => {
771771
"cannot assign to data"
772772
}
773-
BorrowViolation(euv::ClosureCapture(_)) => {
774-
// I don't think we can get aliasability violations
775-
// with closure captures, so no need to come up with a
776-
// good error message. The reason this cannot happen
777-
// is because we only capture local variables in
778-
// closures, and those are never aliasable.
779-
self.tcx.sess.span_bug(
780-
span,
781-
"aliasability violation with closure");
782-
}
773+
BorrowViolation(euv::ClosureCapture(_)) |
783774
BorrowViolation(euv::OverloadedOperator) |
784775
BorrowViolation(euv::AddrOf) |
785776
BorrowViolation(euv::AutoRef) |
@@ -809,8 +800,17 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
809800
self.tcx.sess.span_err(span,
810801
format!("{} in a captured outer \
811802
variable in an `Fn` closure", prefix).as_slice());
812-
span_help!(self.tcx.sess, self.tcx.map.span(id),
803+
if let BorrowViolation(euv::ClosureCapture(_)) = kind {
804+
// The aliasability violation with closure captures can
805+
// happen for nested closures, so we know the enclosing
806+
// closure incorrectly accepts an `Fn` while it needs to
807+
// be `FnMut`.
808+
span_help!(self.tcx.sess, self.tcx.map.span(id),
809+
"consider changing this to accept closures that implement `FnMut`");
810+
} else {
811+
span_help!(self.tcx.sess, self.tcx.map.span(id),
813812
"consider changing this closure to take self by mutable reference");
813+
}
814814
}
815815
mc::AliasableStatic(..) |
816816
mc::AliasableStaticMut(..) => {

branches/snap-stage3/src/librustc_trans/trans/expr.rs

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,15 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
420420
let tcx = bcx.tcx();
421421

422422
let datum_ty = datum.ty;
423-
// Arrange cleanup
424-
let lval = unpack_datum!(bcx,
425-
datum.to_lvalue_datum(bcx, "unsize_unique_vec", expr.id));
423+
424+
debug!("unsize_unique_vec expr.id={} datum_ty={} len={}",
425+
expr.id, datum_ty.repr(tcx), len);
426+
427+
// We do not arrange cleanup ourselves; if we already are an
428+
// L-value, then cleanup will have already been scheduled (and
429+
// the `datum.store_to` call below will emit code to zero the
430+
// drop flag when moving out of the L-value). If we are an R-value,
431+
// then we do not need to schedule cleanup.
426432

427433
let ll_len = C_uint(bcx.ccx(), len);
428434
let unit_ty = ty::sequence_element_type(tcx, ty::type_content(datum_ty));
@@ -433,7 +439,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
433439
let base = PointerCast(bcx,
434440
base,
435441
type_of::type_of(bcx.ccx(), datum_ty).ptr_to());
436-
bcx = lval.store_to(bcx, base);
442+
bcx = datum.store_to(bcx, base);
437443

438444
Store(bcx, ll_len, get_len(bcx, scratch.val));
439445
DatumBlock::new(bcx, scratch.to_expr_datum())
@@ -455,22 +461,20 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
455461
};
456462
let result_ty = ty::mk_uniq(tcx, ty::unsize_ty(tcx, unboxed_ty, k, expr.span));
457463

458-
let lval = unpack_datum!(bcx,
459-
datum.to_lvalue_datum(bcx, "unsize_unique_expr", expr.id));
464+
// We do not arrange cleanup ourselves; if we already are an
465+
// L-value, then cleanup will have already been scheduled (and
466+
// the `datum.store_to` call below will emit code to zero the
467+
// drop flag when moving out of the L-value). If we are an R-value,
468+
// then we do not need to schedule cleanup.
460469

461470
let scratch = rvalue_scratch_datum(bcx, result_ty, "__uniq_fat_ptr");
462471
let llbox_ty = type_of::type_of(bcx.ccx(), datum_ty);
463472
let base = PointerCast(bcx, get_dataptr(bcx, scratch.val), llbox_ty.ptr_to());
464-
bcx = lval.store_to(bcx, base);
473+
bcx = datum.store_to(bcx, base);
465474

466475
let info = unsized_info(bcx, k, expr.id, unboxed_ty, |t| ty::mk_uniq(tcx, t));
467476
Store(bcx, info, get_len(bcx, scratch.val));
468477

469-
let scratch = unpack_datum!(bcx,
470-
scratch.to_expr_datum().to_lvalue_datum(bcx,
471-
"fresh_uniq_fat_ptr",
472-
expr.id));
473-
474478
DatumBlock::new(bcx, scratch.to_expr_datum())
475479
}
476480
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn call_it<F>(f: F) where F: Fn() { f(); }
12+
13+
struct A;
14+
15+
impl A {
16+
fn gen(&self) {}
17+
fn gen_mut(&mut self) {}
18+
}
19+
20+
fn main() {
21+
let mut x = A;
22+
call_it(|| { //~ HELP consider changing this to accept closures that implement `FnMut`
23+
call_it(|| x.gen());
24+
call_it(|| x.gen_mut()); //~ ERROR cannot borrow data mutably in a captured outer
25+
//~^ ERROR cannot borrow data mutably in a captured outer
26+
});
27+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// See Issues #20055 and #21695.
12+
13+
// We are checking here that the temporaries `Box<[i8, k]>`, for `k`
14+
// in 1, 2, 3, 4, that are induced by the match expression are
15+
// properly handled, in that only *one* will be initialized by
16+
// whichever arm is run, and subsequently dropped at the end of the
17+
// statement surrounding the `match`.
18+
19+
trait Boo { }
20+
21+
impl Boo for [i8; 1] { }
22+
impl Boo for [i8; 2] { }
23+
impl Boo for [i8; 3] { }
24+
impl Boo for [i8; 4] { }
25+
26+
pub fn foo(box_1: fn () -> Box<[i8; 1]>,
27+
box_2: fn () -> Box<[i8; 2]>,
28+
box_3: fn () -> Box<[i8; 3]>,
29+
box_4: fn () -> Box<[i8; 4]>,
30+
) {
31+
println!("Hello World 1");
32+
let _: Box<Boo> = match 3 {
33+
1 => box_1(),
34+
2 => box_2(),
35+
3 => box_3(),
36+
_ => box_4(),
37+
};
38+
println!("Hello World 2");
39+
}
40+
41+
pub fn main() {
42+
fn box_1() -> Box<[i8; 1]> { Box::new( [1i8; 1] ) }
43+
fn box_2() -> Box<[i8; 2]> { Box::new( [1i8; 2] ) }
44+
fn box_3() -> Box<[i8; 3]> { Box::new( [1i8; 3] ) }
45+
fn box_4() -> Box<[i8; 4]> { Box::new( [1i8; 4] ) }
46+
47+
foo(box_1, box_2, box_3, box_4);
48+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Issue #2005: Check that boxed fixed-size arrays are properly
12+
// accounted for (namely, only deallocated if they were actually
13+
// created) when they appear as temporaries in unused arms of a match
14+
// expression.
15+
16+
pub fn foo(box_1: fn () -> Box<[i8; 1]>,
17+
box_2: fn () -> Box<[i8; 20]>,
18+
box_3: fn () -> Box<[i8; 300]>,
19+
box_4: fn () -> Box<[i8; 4000]>,
20+
) {
21+
println!("Hello World 1");
22+
let _: Box<[i8]> = match 3 {
23+
1 => box_1(),
24+
2 => box_2(),
25+
3 => box_3(),
26+
_ => box_4(),
27+
};
28+
println!("Hello World 2");
29+
}
30+
31+
pub fn main() {
32+
fn box_1() -> Box<[i8; 1]> { Box::new( [1i8] ) }
33+
fn box_2() -> Box<[i8; 20]> { Box::new( [1i8; 20] ) }
34+
fn box_3() -> Box<[i8; 300]> { Box::new( [1i8; 300] ) }
35+
fn box_4() -> Box<[i8; 4000]> { Box::new( [1i8; 4000] ) }
36+
37+
foo(box_1, box_2, box_3, box_4);
38+
}

0 commit comments

Comments
 (0)