new liveness pass to supercede last_use / initedness
This commit is contained in:
parent
a3be0b1054
commit
30b47649ea
89 changed files with 2104 additions and 162 deletions
|
@ -351,7 +351,7 @@ enum expr_ {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_serialize]
|
#[auto_serialize]
|
||||||
type capture_item = {
|
type capture_item = @{
|
||||||
id: int,
|
id: int,
|
||||||
is_move: bool,
|
is_move: bool,
|
||||||
name: ident, // Currently, can only capture a local var.
|
name: ident, // Currently, can only capture a local var.
|
||||||
|
|
|
@ -434,7 +434,7 @@ class parser {
|
||||||
fn parse_capture_item(p:parser, is_move: bool) -> capture_item {
|
fn parse_capture_item(p:parser, is_move: bool) -> capture_item {
|
||||||
let sp = mk_sp(p.span.lo, p.span.hi);
|
let sp = mk_sp(p.span.lo, p.span.hi);
|
||||||
let ident = parse_ident(p);
|
let ident = parse_ident(p);
|
||||||
{id: p.get_id(), is_move: is_move, name: ident, span: sp}
|
@{id: p.get_id(), is_move: is_move, name: ident, span: sp}
|
||||||
}
|
}
|
||||||
|
|
||||||
if eat_keyword(self, "move") {
|
if eat_keyword(self, "move") {
|
||||||
|
@ -1710,7 +1710,7 @@ class parser {
|
||||||
let id = p.get_id();
|
let id = p.get_id();
|
||||||
let sp = mk_sp(p.span.lo, p.span.hi);
|
let sp = mk_sp(p.span.lo, p.span.hi);
|
||||||
let ident = parse_ident(p);
|
let ident = parse_ident(p);
|
||||||
res += [{id:id, is_move: is_move, name:ident, span:sp}];
|
res += [@{id:id, is_move: is_move, name:ident, span:sp}];
|
||||||
if !eat(p, token::COMMA) {
|
if !eat(p, token::COMMA) {
|
||||||
ret res;
|
ret res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,6 +192,9 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
|
||||||
bind middle::check_loop::check_crate(ty_cx, crate));
|
bind middle::check_loop::check_crate(ty_cx, crate));
|
||||||
time(time_passes, "alt checking",
|
time(time_passes, "alt checking",
|
||||||
bind middle::check_alt::check_crate(ty_cx, crate));
|
bind middle::check_alt::check_crate(ty_cx, crate));
|
||||||
|
let _last_use_map =
|
||||||
|
time(time_passes, "liveness checking",
|
||||||
|
bind middle::liveness::check_crate(ty_cx, method_map, crate));
|
||||||
time(time_passes, "typestate checking",
|
time(time_passes, "typestate checking",
|
||||||
bind middle::tstate::ck::check_crate(ty_cx, crate));
|
bind middle::tstate::ck::check_crate(ty_cx, crate));
|
||||||
let (root_map, mutbl_map) = time(
|
let (root_map, mutbl_map) = time(
|
||||||
|
|
|
@ -541,6 +541,15 @@ enum assignment_type {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl methods for assignment_type {
|
impl methods for assignment_type {
|
||||||
|
fn checked_by_liveness() -> bool {
|
||||||
|
// the liveness pass guarantees that immutable local variables
|
||||||
|
// are only assigned once; but it doesn't consider &mut
|
||||||
|
alt self {
|
||||||
|
at_straight_up {true}
|
||||||
|
at_swap {true}
|
||||||
|
at_mutbl_ref {false}
|
||||||
|
}
|
||||||
|
}
|
||||||
fn ing_form(desc: str) -> str {
|
fn ing_form(desc: str) -> str {
|
||||||
alt self {
|
alt self {
|
||||||
at_straight_up { "assigning to " + desc }
|
at_straight_up { "assigning to " + desc }
|
||||||
|
@ -717,6 +726,13 @@ impl methods for check_loan_ctxt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_local_variable(cmt: cmt) -> bool {
|
||||||
|
alt cmt.cat {
|
||||||
|
cat_local(_) {true}
|
||||||
|
_ {false}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_self_field(cmt: cmt) -> bool {
|
fn is_self_field(cmt: cmt) -> bool {
|
||||||
alt cmt.cat {
|
alt cmt.cat {
|
||||||
cat_comp(cmt_base, comp_field(_)) {
|
cat_comp(cmt_base, comp_field(_)) {
|
||||||
|
@ -735,9 +751,13 @@ impl methods for check_loan_ctxt {
|
||||||
#debug["check_assignment(cmt=%s)",
|
#debug["check_assignment(cmt=%s)",
|
||||||
self.bccx.cmt_to_repr(cmt)];
|
self.bccx.cmt_to_repr(cmt)];
|
||||||
|
|
||||||
// check that the lvalue `ex` is assignable, but be careful
|
if self.in_ctor && self.is_self_field(cmt)
|
||||||
// because assigning to self.foo in a ctor is always allowed.
|
&& at.checked_by_liveness() {
|
||||||
if !self.in_ctor || !self.is_self_field(cmt) {
|
// assigning to self.foo in a ctor is always allowed.
|
||||||
|
} else if self.is_local_variable(cmt) && at.checked_by_liveness() {
|
||||||
|
// liveness guarantees that immutable local variables
|
||||||
|
// are only assigned once
|
||||||
|
} else {
|
||||||
alt cmt.mutbl {
|
alt cmt.mutbl {
|
||||||
m_mutbl { /*ok*/ }
|
m_mutbl { /*ok*/ }
|
||||||
m_const | m_imm {
|
m_const | m_imm {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import syntax::{ast, ast_util};
|
import syntax::{ast, ast_util};
|
||||||
import driver::session::session;
|
import driver::session::session;
|
||||||
|
import syntax::codemap::span;
|
||||||
import std::map;
|
import std::map;
|
||||||
import std::map::hashmap;
|
import std::map::hashmap;
|
||||||
|
|
||||||
|
@ -14,15 +15,17 @@ export cap_drop;
|
||||||
export cap_ref;
|
export cap_ref;
|
||||||
|
|
||||||
enum capture_mode {
|
enum capture_mode {
|
||||||
cap_copy, //< Copy the value into the closure.
|
cap_copy, // Copy the value into the closure.
|
||||||
cap_move, //< Move the value into the closure.
|
cap_move, // Move the value into the closure.
|
||||||
cap_drop, //< Drop value after creating closure.
|
cap_drop, // Drop value after creating closure.
|
||||||
cap_ref, //< Reference directly from parent stack frame (block fn).
|
cap_ref, // Reference directly from parent stack frame (block fn).
|
||||||
}
|
}
|
||||||
|
|
||||||
type capture_var = {
|
type capture_var = {
|
||||||
def: ast::def, //< The variable being accessed free.
|
def: ast::def, // Variable being accessed free
|
||||||
mode: capture_mode //< How is the variable being accessed.
|
span: span, // Location of access or cap item
|
||||||
|
cap_item: option<ast::capture_item>, // Capture item, if any
|
||||||
|
mode: capture_mode // How variable is being accessed
|
||||||
};
|
};
|
||||||
|
|
||||||
type capture_map = map::hashmap<ast::def_id, capture_var>;
|
type capture_map = map::hashmap<ast::def_id, capture_var>;
|
||||||
|
@ -70,15 +73,24 @@ fn compute_capture_vars(tcx: ty::ctxt,
|
||||||
// if we are moving the value in, but it's not actually used,
|
// if we are moving the value in, but it's not actually used,
|
||||||
// must drop it.
|
// must drop it.
|
||||||
if vec::any(*freevars, {|fv| fv.def == cap_def}) {
|
if vec::any(*freevars, {|fv| fv.def == cap_def}) {
|
||||||
cap_map.insert(cap_def_id, { def:cap_def, mode:cap_move });
|
cap_map.insert(cap_def_id, {def:cap_def,
|
||||||
|
span: cap_item.span,
|
||||||
|
cap_item: some(cap_item),
|
||||||
|
mode:cap_move});
|
||||||
} else {
|
} else {
|
||||||
cap_map.insert(cap_def_id, { def:cap_def, mode:cap_drop });
|
cap_map.insert(cap_def_id, {def:cap_def,
|
||||||
|
span: cap_item.span,
|
||||||
|
cap_item: some(cap_item),
|
||||||
|
mode:cap_drop});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if we are copying the value in, but it's not actually used,
|
// if we are copying the value in, but it's not actually used,
|
||||||
// just ignore it.
|
// just ignore it.
|
||||||
if vec::any(*freevars, {|fv| fv.def == cap_def}) {
|
if vec::any(*freevars, {|fv| fv.def == cap_def}) {
|
||||||
cap_map.insert(cap_def_id, { def:cap_def, mode:cap_copy });
|
cap_map.insert(cap_def_id, {def:cap_def,
|
||||||
|
span: cap_item.span,
|
||||||
|
cap_item: some(cap_item),
|
||||||
|
mode:cap_copy});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,7 +108,10 @@ fn compute_capture_vars(tcx: ty::ctxt,
|
||||||
alt cap_map.find(fvar_def_id) {
|
alt cap_map.find(fvar_def_id) {
|
||||||
option::some(_) { /* was explicitly named, do nothing */ }
|
option::some(_) { /* was explicitly named, do nothing */ }
|
||||||
option::none {
|
option::none {
|
||||||
cap_map.insert(fvar_def_id, {def:fvar.def, mode:implicit_mode});
|
cap_map.insert(fvar_def_id, {def:fvar.def,
|
||||||
|
span: fvar.span,
|
||||||
|
cap_item: none,
|
||||||
|
mode:implicit_mode});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1502
src/rustc/middle/liveness.rs
Normal file
1502
src/rustc/middle/liveness.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -72,6 +72,7 @@ mod middle {
|
||||||
mod borrowck;
|
mod borrowck;
|
||||||
mod alias;
|
mod alias;
|
||||||
mod last_use;
|
mod last_use;
|
||||||
|
mod liveness;
|
||||||
mod block_use;
|
mod block_use;
|
||||||
mod kind;
|
mod kind;
|
||||||
mod freevars;
|
mod freevars;
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition constraint (for example, init(i
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let i: int;
|
|
||||||
|
|
||||||
log(debug, false && { i = 5; true });
|
|
||||||
log(debug, i);
|
|
||||||
}
|
|
9
src/test/compile-fail/assign-imm-local-twice.rs
Normal file
9
src/test/compile-fail/assign-imm-local-twice.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
fn test(cond: bool) {
|
||||||
|
let v: int;
|
||||||
|
v = 1; //! NOTE prior assignment occurs here
|
||||||
|
v = 2; //! ERROR re-assignment of immutable variable
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test(true);
|
||||||
|
}
|
|
@ -1,4 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition constraint
|
|
||||||
|
|
||||||
fn force(f: fn()) { f(); }
|
|
||||||
fn main() { let x: int; force(fn&() { log(error, x); }); }
|
|
|
@ -1,14 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition
|
|
||||||
|
|
||||||
fn foo() -> int {
|
|
||||||
let x: int;
|
|
||||||
let i: int;
|
|
||||||
|
|
||||||
loop { i = 0; break; x = 0; }
|
|
||||||
|
|
||||||
log(debug, x);
|
|
||||||
|
|
||||||
ret 17;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() { log(debug, foo()); }
|
|
|
@ -1,14 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition
|
|
||||||
|
|
||||||
fn foo() -> int {
|
|
||||||
let x: int;
|
|
||||||
let i: int;
|
|
||||||
|
|
||||||
while 1 != 2 { i = 0; break; x = 0; }
|
|
||||||
|
|
||||||
log(debug, x);
|
|
||||||
|
|
||||||
ret 17;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() { log(debug, foo()); }
|
|
|
@ -1,7 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// Typestate should work even in a fn@. we should reject this program.
|
|
||||||
let f = fn@() -> int { let i: int; ret i; };
|
|
||||||
log(error, f());
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let j = fn@() -> int { let i: int; ret i; }();
|
|
||||||
log(error, j);
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
// -*- rust -*-
|
|
||||||
|
|
||||||
// error-pattern: precondition
|
|
||||||
|
|
||||||
type point = {x: int, y: int};
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let origin: point;
|
|
||||||
|
|
||||||
let right: point = {x: 10 with origin};
|
|
||||||
origin = {x: 0, y: 0};
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
fn main(s: [str]) {
|
|
||||||
let a: [int] = [];
|
|
||||||
vec::each(a) { |x| //! ERROR in function `anon`, not all control paths
|
|
||||||
} //! ERROR see function return type of `bool`
|
|
||||||
}
|
|
6
src/test/compile-fail/liveness-and-init.rs
Normal file
6
src/test/compile-fail/liveness-and-init.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
fn main() {
|
||||||
|
let i: int;
|
||||||
|
|
||||||
|
log(debug, false && { i = 5; true });
|
||||||
|
log(debug, i); //! ERROR use of possibly uninitialized variable: `i`
|
||||||
|
}
|
11
src/test/compile-fail/liveness-assign-imm-local-in-loop.rs
Normal file
11
src/test/compile-fail/liveness-assign-imm-local-in-loop.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
fn test(cond: bool) {
|
||||||
|
let v: int;
|
||||||
|
loop {
|
||||||
|
v = 1; //! ERROR re-assignment of immutable variable
|
||||||
|
//!^ NOTE prior assignment occurs here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test(true);
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
fn test(cond: bool) {
|
||||||
|
let v: int;
|
||||||
|
v = 2; //! NOTE prior assignment occurs here
|
||||||
|
v += 1; //! ERROR re-assignment of immutable variable
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test(true);
|
||||||
|
}
|
18
src/test/compile-fail/liveness-assign-imm-local-in-swap.rs
Normal file
18
src/test/compile-fail/liveness-assign-imm-local-in-swap.rs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
fn test1() {
|
||||||
|
let v: int;
|
||||||
|
let mut w: int;
|
||||||
|
v = 1; //! NOTE prior assignment occurs here
|
||||||
|
w = 2;
|
||||||
|
v <-> w; //! ERROR re-assignment of immutable variable
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test2() {
|
||||||
|
let v: int;
|
||||||
|
let mut w: int;
|
||||||
|
v = 1; //! NOTE prior assignment occurs here
|
||||||
|
w = 2;
|
||||||
|
w <-> v; //! ERROR re-assignment of immutable variable
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
7
src/test/compile-fail/liveness-block-unint.rs
Normal file
7
src/test/compile-fail/liveness-block-unint.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
fn force(f: fn()) { f(); }
|
||||||
|
fn main() {
|
||||||
|
let x: int;
|
||||||
|
force(fn&() {
|
||||||
|
log(debug, x); //! ERROR capture of possibly uninitialized variable: `x`
|
||||||
|
});
|
||||||
|
}
|
16
src/test/compile-fail/liveness-break-uninit-2.rs
Normal file
16
src/test/compile-fail/liveness-break-uninit-2.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
fn foo() -> int {
|
||||||
|
let x: int;
|
||||||
|
let i: int;
|
||||||
|
|
||||||
|
while 1 != 2 {
|
||||||
|
i = 0;
|
||||||
|
break;
|
||||||
|
x = 0; //! WARNING unreachable statement
|
||||||
|
}
|
||||||
|
|
||||||
|
log(debug, x); //! ERROR use of possibly uninitialized variable: `x`
|
||||||
|
|
||||||
|
ret 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { log(debug, foo()); }
|
16
src/test/compile-fail/liveness-break-uninit.rs
Normal file
16
src/test/compile-fail/liveness-break-uninit.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
fn foo() -> int {
|
||||||
|
let x: int;
|
||||||
|
let i: int;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
i = 0;
|
||||||
|
break;
|
||||||
|
x = 0; //! WARNING unreachable statement
|
||||||
|
}
|
||||||
|
|
||||||
|
log(debug, x); //! ERROR use of possibly uninitialized variable: `x`
|
||||||
|
|
||||||
|
ret 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { log(debug, foo()); }
|
|
@ -0,0 +1,11 @@
|
||||||
|
class cat {
|
||||||
|
let how_hungry : int;
|
||||||
|
fn meow() {}
|
||||||
|
new() {
|
||||||
|
self.meow();
|
||||||
|
//!^ ERROR use of possibly uninitialized field: `self.how_hungry`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
7
src/test/compile-fail/liveness-ctor-field-never-init.rs
Normal file
7
src/test/compile-fail/liveness-ctor-field-never-init.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
class cat {
|
||||||
|
let how_hungry : int;
|
||||||
|
new() {} //! ERROR field `self.how_hungry` is never initialized
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
14
src/test/compile-fail/liveness-ctor-uninit-field.rs
Normal file
14
src/test/compile-fail/liveness-ctor-uninit-field.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
class cat {
|
||||||
|
let mut a: int;
|
||||||
|
let mut b: int;
|
||||||
|
let mut c: int;
|
||||||
|
|
||||||
|
new() {
|
||||||
|
self.a = 3;
|
||||||
|
self.b = self.a;
|
||||||
|
self.a += self.c; //! ERROR use of possibly uninitialized field: `self.c`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
// error-pattern:unsatisfied precondition
|
|
||||||
class cat {
|
class cat {
|
||||||
priv {
|
priv {
|
||||||
let mut meows : uint;
|
let mut meows : uint;
|
||||||
|
@ -13,7 +12,7 @@ class cat {
|
||||||
new(in_x : uint, in_y : int) {
|
new(in_x : uint, in_y : int) {
|
||||||
let foo;
|
let foo;
|
||||||
self.meows = in_x + (in_y as uint);
|
self.meows = in_x + (in_y as uint);
|
||||||
self.how_hungry = foo;
|
self.how_hungry = foo; //! ERROR use of possibly uninitialized variable: `foo`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
6
src/test/compile-fail/liveness-if-no-else.rs
Normal file
6
src/test/compile-fail/liveness-if-no-else.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
fn foo(x: int) { log(debug, x); }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: int; if 1 > 2 { x = 10; }
|
||||||
|
foo(x); //! ERROR use of possibly uninitialized variable: `x`
|
||||||
|
}
|
|
@ -1,5 +1,3 @@
|
||||||
// error-pattern:unsatisfied precondition
|
|
||||||
|
|
||||||
fn foo(x: int) { log(debug, x); }
|
fn foo(x: int) { log(debug, x); }
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -9,5 +7,5 @@ fn main() {
|
||||||
} else {
|
} else {
|
||||||
x = 10;
|
x = 10;
|
||||||
}
|
}
|
||||||
foo(x);
|
foo(x); //! ERROR use of possibly uninitialized variable: `x`
|
||||||
}
|
}
|
7
src/test/compile-fail/liveness-init-in-called-fn-expr.rs
Normal file
7
src/test/compile-fail/liveness-init-in-called-fn-expr.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
fn main() {
|
||||||
|
let j = fn@() -> int {
|
||||||
|
let i: int;
|
||||||
|
ret i; //! ERROR use of possibly uninitialized variable: `i`
|
||||||
|
};
|
||||||
|
j();
|
||||||
|
}
|
7
src/test/compile-fail/liveness-init-in-fn-expr.rs
Normal file
7
src/test/compile-fail/liveness-init-in-fn-expr.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
fn main() {
|
||||||
|
let f = fn@() -> int {
|
||||||
|
let i: int;
|
||||||
|
ret i; //! ERROR use of possibly uninitialized variable: `i`
|
||||||
|
};
|
||||||
|
log(error, f());
|
||||||
|
}
|
8
src/test/compile-fail/liveness-init-in-fru.rs
Normal file
8
src/test/compile-fail/liveness-init-in-fru.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// -*- rust -*-
|
||||||
|
|
||||||
|
type point = {x: int, y: int};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut origin: point;
|
||||||
|
origin = {x: 10 with origin}; //! ERROR use of possibly uninitialized variable: `origin`
|
||||||
|
}
|
8
src/test/compile-fail/liveness-init-op-equal.rs
Normal file
8
src/test/compile-fail/liveness-init-op-equal.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fn test(cond: bool) {
|
||||||
|
let v: int;
|
||||||
|
v += 1; //! ERROR use of possibly uninitialized variable: `v`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test(true);
|
||||||
|
}
|
8
src/test/compile-fail/liveness-init-plus-equal.rs
Normal file
8
src/test/compile-fail/liveness-init-plus-equal.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
fn test(cond: bool) {
|
||||||
|
let mut v: int;
|
||||||
|
v = v + 1; //! ERROR use of possibly uninitialized variable: `v`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test(true);
|
||||||
|
}
|
5
src/test/compile-fail/liveness-issue-2163.rs
Normal file
5
src/test/compile-fail/liveness-issue-2163.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
fn main(s: [str]) {
|
||||||
|
let a: [int] = [];
|
||||||
|
vec::each(a) { |x| //! ERROR not all control paths return a value
|
||||||
|
}
|
||||||
|
}
|
10
src/test/compile-fail/liveness-move-from-mode.rs
Normal file
10
src/test/compile-fail/liveness-move-from-mode.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
fn take(-x: int) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
let x: int = 25;
|
||||||
|
loop {
|
||||||
|
take(x); //! ERROR use of moved variable: `x`
|
||||||
|
//!^ NOTE move of variable occurred here
|
||||||
|
}
|
||||||
|
}
|
16
src/test/compile-fail/liveness-move-in-loop.rs
Normal file
16
src/test/compile-fail/liveness-move-in-loop.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
let y: int = 42;
|
||||||
|
let mut x: int;
|
||||||
|
loop {
|
||||||
|
log(debug, y);
|
||||||
|
loop {
|
||||||
|
loop {
|
||||||
|
loop {
|
||||||
|
x <- y; //! ERROR use of moved variable
|
||||||
|
//!^ NOTE move of variable occurred here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,11 @@
|
||||||
// error-pattern:unsatisfied precondition constraint (for example, init(y
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
||||||
let y: int = 42;
|
let y: int = 42;
|
||||||
let x: int;
|
let mut x: int;
|
||||||
loop {
|
loop {
|
||||||
log(debug, y);
|
log(debug, y);
|
||||||
while true { while true { while true { x <- y; } } }
|
while true { while true { while true { x <- y; } } }
|
||||||
|
//!^ ERROR use of moved variable: `y`
|
||||||
|
//!^^ NOTE move of variable occurred here
|
||||||
}
|
}
|
||||||
}
|
}
|
6
src/test/compile-fail/liveness-or-init.rs
Normal file
6
src/test/compile-fail/liveness-or-init.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
fn main() {
|
||||||
|
let i: int;
|
||||||
|
|
||||||
|
log(debug, false || { i = 5; true });
|
||||||
|
log(debug, i); //! ERROR use of possibly uninitialized variable: `i`
|
||||||
|
}
|
6
src/test/compile-fail/liveness-return.rs
Normal file
6
src/test/compile-fail/liveness-return.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
fn f() -> int {
|
||||||
|
let x: int;
|
||||||
|
ret x; //! ERROR use of possibly uninitialized variable: `x`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { f(); }
|
5
src/test/compile-fail/liveness-swap-uninit.rs
Normal file
5
src/test/compile-fail/liveness-swap-uninit.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
fn main() {
|
||||||
|
let x = 3;
|
||||||
|
let y;
|
||||||
|
x <-> y; //! ERROR use of possibly uninitialized variable: `y`
|
||||||
|
}
|
6
src/test/compile-fail/liveness-uninit-after-item.rs
Normal file
6
src/test/compile-fail/liveness-uninit-after-item.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
fn main() {
|
||||||
|
let bar;
|
||||||
|
fn baz(x: int) { }
|
||||||
|
bind baz(bar); //! ERROR use of possibly uninitialized variable: `bar`
|
||||||
|
}
|
||||||
|
|
6
src/test/compile-fail/liveness-uninit.rs
Normal file
6
src/test/compile-fail/liveness-uninit.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
fn foo(x: int) { log(debug, x); }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: int;
|
||||||
|
foo(x); //! ERROR use of possibly uninitialized variable: `x`
|
||||||
|
}
|
5
src/test/compile-fail/liveness-use-after-move.rs
Normal file
5
src/test/compile-fail/liveness-use-after-move.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
fn main() {
|
||||||
|
let x = @5;
|
||||||
|
let y <- x; //! NOTE move of variable occurred here
|
||||||
|
log(debug, *x); //! ERROR use of moved variable: `x`
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
// error-pattern:unsatisfied precondition constraint
|
|
||||||
fn send<T: send>(ch: _chan<T>, -data: T) {
|
fn send<T: send>(ch: _chan<T>, -data: T) {
|
||||||
log(debug, ch);
|
log(debug, ch);
|
||||||
log(debug, data);
|
log(debug, data);
|
||||||
|
@ -10,8 +9,8 @@ enum _chan<T> = int;
|
||||||
// Tests that "log(debug, message);" is flagged as using
|
// Tests that "log(debug, message);" is flagged as using
|
||||||
// message after the send deinitializes it
|
// message after the send deinitializes it
|
||||||
fn test00_start(ch: _chan<int>, message: int, count: int) {
|
fn test00_start(ch: _chan<int>, message: int, count: int) {
|
||||||
send(ch, message);
|
send(ch, message); //! NOTE move of variable occurred here
|
||||||
log(debug, message);
|
log(debug, message); //! ERROR use of moved variable: `message`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { fail; }
|
fn main() { fail; }
|
6
src/test/compile-fail/liveness-use-in-index-lvalue.rs
Normal file
6
src/test/compile-fail/liveness-use-in-index-lvalue.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
fn test() {
|
||||||
|
let w: [int];
|
||||||
|
w[5] = 0; //! ERROR use of possibly uninitialized variable: `w`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { test(); }
|
12
src/test/compile-fail/liveness-while-break.rs
Normal file
12
src/test/compile-fail/liveness-while-break.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
fn test(cond: bool) {
|
||||||
|
let v;
|
||||||
|
while cond {
|
||||||
|
v = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#debug["%d", v]; //! ERROR use of possibly uninitialized variable: `v`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test(true);
|
||||||
|
}
|
4
src/test/compile-fail/liveness-while-cond.rs
Normal file
4
src/test/compile-fail/liveness-while-cond.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
fn main() {
|
||||||
|
let x: bool;
|
||||||
|
while x { } //! ERROR use of possibly uninitialized variable: `x`
|
||||||
|
}
|
7
src/test/compile-fail/liveness-while.rs
Normal file
7
src/test/compile-fail/liveness-while.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
fn f() -> int {
|
||||||
|
let mut x: int;
|
||||||
|
while 1 == 1 { x = 10; }
|
||||||
|
ret x; //! ERROR use of possibly uninitialized variable: `x`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { f(); }
|
|
@ -1,4 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition constraint
|
|
||||||
fn test(-foo: int) { assert (foo == 10); }
|
|
||||||
|
|
||||||
fn main() { let x = 10; test(x); log(debug, x); }
|
|
|
@ -1,8 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition constraint (for example, init(i
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let i: int;
|
|
||||||
|
|
||||||
log(debug, false || { i = 5; true });
|
|
||||||
log(debug, i);
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
// error-pattern: precondition constraint
|
|
||||||
|
|
||||||
fn f() -> int { let x: int; ret x; }
|
|
||||||
|
|
||||||
fn main() { f(); }
|
|
|
@ -1,3 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition
|
|
||||||
|
|
||||||
fn main() { let x = 3; let y; x <-> y; }
|
|
7
src/test/compile-fail/tstate-and-init.rs
Normal file
7
src/test/compile-fail/tstate-and-init.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
fn main() {
|
||||||
|
let i: int = 4;
|
||||||
|
log(debug, false && { check is_even(i); true });
|
||||||
|
even(i); //! ERROR unsatisfied precondition
|
||||||
|
}
|
11
src/test/compile-fail/tstate-block-uninit.rs
Normal file
11
src/test/compile-fail/tstate-block-uninit.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn force(f: fn()) { f(); }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: int = 4;
|
||||||
|
force(fn&() {
|
||||||
|
even(x); //! ERROR unsatisfied precondition
|
||||||
|
});
|
||||||
|
}
|
16
src/test/compile-fail/tstate-break-uninit-2.rs
Normal file
16
src/test/compile-fail/tstate-break-uninit-2.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn foo() -> int {
|
||||||
|
let x: int = 4;
|
||||||
|
|
||||||
|
while 1 != 2 {
|
||||||
|
break;
|
||||||
|
check is_even(x); //! WARNING unreachable statement
|
||||||
|
}
|
||||||
|
|
||||||
|
even(x); //! ERROR unsatisfied precondition
|
||||||
|
ret 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { log(debug, foo()); }
|
16
src/test/compile-fail/tstate-break-uninit.rs
Normal file
16
src/test/compile-fail/tstate-break-uninit.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn foo() -> int {
|
||||||
|
let x: int = 4;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
break;
|
||||||
|
check is_even(x); //! WARNING unreachable statement
|
||||||
|
}
|
||||||
|
|
||||||
|
even(x); //! ERROR unsatisfied precondition
|
||||||
|
ret 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { log(debug, foo()); }
|
25
src/test/compile-fail/tstate-ctor-unsat.rs
Normal file
25
src/test/compile-fail/tstate-ctor-unsat.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
class cat {
|
||||||
|
priv {
|
||||||
|
let mut meows : uint;
|
||||||
|
}
|
||||||
|
|
||||||
|
let how_hungry : int;
|
||||||
|
|
||||||
|
fn eat() {
|
||||||
|
self.how_hungry -= 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
new(in_x : uint, in_y : int) {
|
||||||
|
let foo = 3;
|
||||||
|
self.meows = in_x + (in_y as uint);
|
||||||
|
self.how_hungry = even(foo); //! ERROR unsatisfied precondition
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let nyan : cat = cat(52u, 99);
|
||||||
|
nyan.eat();
|
||||||
|
}
|
13
src/test/compile-fail/tstate-fru.rs
Normal file
13
src/test/compile-fail/tstate-fru.rs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
// -*- rust -*-
|
||||||
|
|
||||||
|
type point = {x: int, y: int};
|
||||||
|
|
||||||
|
pure fn test(_p: point) -> bool { true }
|
||||||
|
fn tested(p: point) : test(p) -> point { p }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let origin: point;
|
||||||
|
origin = {x: 0, y: 0};
|
||||||
|
let right: point = {x: 10 with tested(origin)};
|
||||||
|
//!^ ERROR precondition
|
||||||
|
}
|
10
src/test/compile-fail/tstate-if-no-else.rs
Normal file
10
src/test/compile-fail/tstate-if-no-else.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn foo(x: int) { log(debug, x); }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: int = 10;
|
||||||
|
if 1 > 2 { check is_even(x); }
|
||||||
|
even(x); //! ERROR unsatisfied precondition
|
||||||
|
}
|
14
src/test/compile-fail/tstate-if-with-else.rs
Normal file
14
src/test/compile-fail/tstate-if-with-else.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn foo(x: int) { log(debug, x); }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: int = 10;
|
||||||
|
if 1 > 2 {
|
||||||
|
#debug("whoops");
|
||||||
|
} else {
|
||||||
|
check is_even(x);
|
||||||
|
}
|
||||||
|
even(x); //! ERROR unsatisfied precondition
|
||||||
|
}
|
19
src/test/compile-fail/tstate-loop-constraints.rs
Normal file
19
src/test/compile-fail/tstate-loop-constraints.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
let mut x: int = 42;
|
||||||
|
loop {
|
||||||
|
loop {
|
||||||
|
loop {
|
||||||
|
check is_even(x);
|
||||||
|
even(x); // OK
|
||||||
|
loop {
|
||||||
|
even(x); //! ERROR unsatisfied precondition
|
||||||
|
x = 11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
src/test/compile-fail/tstate-or-init.rs
Normal file
7
src/test/compile-fail/tstate-or-init.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
fn main() {
|
||||||
|
let i: int = 4;
|
||||||
|
log(debug, false || { check is_even(i); true });
|
||||||
|
even(i); //! ERROR unsatisfied precondition
|
||||||
|
}
|
9
src/test/compile-fail/tstate-return.rs
Normal file
9
src/test/compile-fail/tstate-return.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn f() -> int {
|
||||||
|
let x: int = 4;
|
||||||
|
ret even(x); //! ERROR unsatisfied precondition
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { f(); }
|
9
src/test/compile-fail/tstate-unsat-after-item.rs
Normal file
9
src/test/compile-fail/tstate-unsat-after-item.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = 4;
|
||||||
|
fn baz(_x: int) { }
|
||||||
|
bind baz(even(x)); //! ERROR unsatisfied precondition
|
||||||
|
}
|
||||||
|
|
9
src/test/compile-fail/tstate-unsat-in-called-fn-expr.rs
Normal file
9
src/test/compile-fail/tstate-unsat-in-called-fn-expr.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
fn foo(v: [int]) : vec::is_empty(v) { #debug("%d", v[0]); }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let f = fn@() {
|
||||||
|
let v = [1];
|
||||||
|
foo(v); //! ERROR unsatisfied precondition constraint
|
||||||
|
}();
|
||||||
|
log(error, f);
|
||||||
|
}
|
9
src/test/compile-fail/tstate-unsat-in-fn-expr.rs
Normal file
9
src/test/compile-fail/tstate-unsat-in-fn-expr.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
fn foo(v: [int]) : vec::is_empty(v) { #debug("%d", v[0]); }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let f = fn@() {
|
||||||
|
let v = [1];
|
||||||
|
foo(v); //! ERROR unsatisfied precondition constraint
|
||||||
|
};
|
||||||
|
log(error, f());
|
||||||
|
}
|
7
src/test/compile-fail/tstate-unsat.rs
Normal file
7
src/test/compile-fail/tstate-unsat.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: int = 4;
|
||||||
|
even(x); //! ERROR unsatisfied precondition
|
||||||
|
}
|
15
src/test/compile-fail/tstate-while-break.rs
Normal file
15
src/test/compile-fail/tstate-while-break.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn test(cond: bool) {
|
||||||
|
let v = 4;
|
||||||
|
while cond {
|
||||||
|
check is_even(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
even(v); //! ERROR unsatisfied precondition
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test(true);
|
||||||
|
}
|
7
src/test/compile-fail/tstate-while-cond.rs
Normal file
7
src/test/compile-fail/tstate-while-cond.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x: int = 4;
|
||||||
|
while even(x) != 0 { } //! ERROR unsatisfied precondition
|
||||||
|
}
|
10
src/test/compile-fail/tstate-while.rs
Normal file
10
src/test/compile-fail/tstate-while.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn f() {
|
||||||
|
let mut x: int = 10;
|
||||||
|
while 1 == 1 { x = 10; }
|
||||||
|
even(x); //! ERROR unsatisfied precondition
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() { f(); }
|
|
@ -1,7 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition constraint (for example, init(bar
|
|
||||||
fn main() {
|
|
||||||
let bar;
|
|
||||||
fn baz(x: int) { }
|
|
||||||
bind baz(bar);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition constraint (for example, init(x
|
|
||||||
fn main() { let x = @5; let y <- x; log(debug, *x); }
|
|
|
@ -1,5 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition
|
|
||||||
|
|
||||||
fn foo(x: int) { log(debug, x); }
|
|
||||||
|
|
||||||
fn main() { let x: int; if 1 > 2 { x = 10; } foo(x); }
|
|
|
@ -1,5 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition
|
|
||||||
|
|
||||||
fn foo(x: int) { log(debug, x); }
|
|
||||||
|
|
||||||
fn main() { let x: int; foo(x); }
|
|
|
@ -1,5 +0,0 @@
|
||||||
// error-pattern: precondition constraint
|
|
||||||
|
|
||||||
fn f() -> int { let x: int; while 1 == 1 { x = 10; } ret x; }
|
|
||||||
|
|
||||||
fn main() { f(); }
|
|
|
@ -1,3 +0,0 @@
|
||||||
// error-pattern: precondition constraint
|
|
||||||
|
|
||||||
fn main() { let x: bool; while x { } }
|
|
|
@ -1,14 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition constraint (for example, init(y
|
|
||||||
fn main() {
|
|
||||||
|
|
||||||
let y: int = 42;
|
|
||||||
let x: int;
|
|
||||||
loop {
|
|
||||||
log(debug, y);
|
|
||||||
loop {
|
|
||||||
loop {
|
|
||||||
loop { x <- y; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
// error-pattern:unsatisfied precondition constraint
|
|
||||||
|
|
||||||
fn test() { let w: [int]; w[5] = 0; }
|
|
||||||
|
|
||||||
fn main() { test(); }
|
|
10
src/test/run-pass/liveness-assign-imm-local-after-loop.rs
Normal file
10
src/test/run-pass/liveness-assign-imm-local-after-loop.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
fn test(cond: bool) {
|
||||||
|
let v: int;
|
||||||
|
v = 1;
|
||||||
|
loop { } // loop never terminates, so no error is reported
|
||||||
|
v = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// note: don't call test()... :)
|
||||||
|
}
|
9
src/test/run-pass/liveness-assign-imm-local-after-ret.rs
Normal file
9
src/test/run-pass/liveness-assign-imm-local-after-ret.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
fn test() {
|
||||||
|
let _v: int;
|
||||||
|
_v = 1;
|
||||||
|
ret;
|
||||||
|
_v = 2; //! WARNING: unreachable statement
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
14
src/test/run-pass/liveness-loop-break.rs
Normal file
14
src/test/run-pass/liveness-loop-break.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// xfail-test --- tstate incorrectly fails this
|
||||||
|
|
||||||
|
fn test() {
|
||||||
|
let v;
|
||||||
|
loop {
|
||||||
|
v = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#debug["%d", v];
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test();
|
||||||
|
}
|
15
src/test/run-pass/liveness-move-in-loop.rs
Normal file
15
src/test/run-pass/liveness-move-in-loop.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
fn take(-x: int) -> int {x}
|
||||||
|
|
||||||
|
fn the_loop() {
|
||||||
|
let mut list = [];
|
||||||
|
loop {
|
||||||
|
let x = 5;
|
||||||
|
if x > 3 {
|
||||||
|
list += [take(x)];
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
17
src/test/run-pass/tstate-loop-break.rs
Normal file
17
src/test/run-pass/tstate-loop-break.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// xfail-test
|
||||||
|
|
||||||
|
pure fn is_even(i: int) -> bool { (i%2) == 0 }
|
||||||
|
fn even(i: int) : is_even(i) -> int { i }
|
||||||
|
|
||||||
|
fn test() {
|
||||||
|
let v = 4;
|
||||||
|
loop {
|
||||||
|
check is_even(v);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
even(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
test();
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue