move borrowck tests to use ref, fix a few exposed shortcomings
This commit is contained in:
parent
793c0a1116
commit
dbef6e593d
@ -166,7 +166,9 @@ fn check_pat(pcx: pat_ctxt, pat: @ast::pat, expected: ty::t) {
|
||||
// ref x | ref const x | ref mut x
|
||||
// then the type of x is &M T where M is the mutability
|
||||
// and T is the expected type
|
||||
let region_var = fcx.infcx.next_region_var_nb();
|
||||
let region_var =
|
||||
fcx.infcx.next_region_var({lb: some(pcx.block_region),
|
||||
ub: none});
|
||||
let mt = {ty: expected, mutbl: mutbl};
|
||||
let region_ty = ty::mk_rptr(tcx, region_var, mt);
|
||||
demand::eqtype(fcx, pat.span, region_ty, typ);
|
||||
|
@ -22,6 +22,7 @@ import syntax::print::pprust;
|
||||
import infer::{resolve_type, resolve_all, force_all,
|
||||
resolve_rvar, force_rvar, fres};
|
||||
import middle::kind::check_owned;
|
||||
import middle::pat_util::pat_bindings;
|
||||
|
||||
enum rcx { rcx_({fcx: @fn_ctxt, mut errors_reported: uint}) }
|
||||
type rvt = visit::vt<@rcx>;
|
||||
@ -80,7 +81,6 @@ fn regionck_visitor() -> rvt {
|
||||
visit_stmt: visit_stmt,
|
||||
visit_expr: visit_expr,
|
||||
visit_block: visit_block,
|
||||
visit_pat: visit_pat,
|
||||
visit_local: visit_local
|
||||
with *visit::default_visitor()})
|
||||
}
|
||||
@ -90,8 +90,26 @@ fn visit_item(_item: @ast::item, &&_rcx: @rcx, _v: rvt) {
|
||||
}
|
||||
|
||||
fn visit_local(l: @ast::local, &&rcx: @rcx, v: rvt) {
|
||||
// Check to make sure that the regions in all local variables are
|
||||
// within scope.
|
||||
//
|
||||
// Note: we do this here rather than in visit_pat because we do
|
||||
// not wish to constrain the regions in *patterns* in quite the
|
||||
// same way. `visit_node()` guarantees that the region encloses
|
||||
// the node in question, which ultimately constraints the regions
|
||||
// in patterns to enclose the match expression as a whole. But we
|
||||
// want them to enclose the *arm*. However, regions in patterns
|
||||
// must either derive from the discriminant or a ref pattern: in
|
||||
// the case of the discriminant, the regions will be constrained
|
||||
// when the type of the discriminant is checked. In the case of a
|
||||
// ref pattern, the variable is created with a suitable lower
|
||||
// bound.
|
||||
let e = rcx.errors_reported;
|
||||
v.visit_pat(l.node.pat, rcx, v);
|
||||
let def_map = rcx.fcx.ccx.tcx.def_map;
|
||||
do pat_bindings(def_map, l.node.pat) |_bm, id, sp, _path| {
|
||||
visit_node(id, sp, rcx);
|
||||
}
|
||||
if e != rcx.errors_reported {
|
||||
return; // if decl has errors, skip initializer expr
|
||||
}
|
||||
@ -102,20 +120,6 @@ fn visit_local(l: @ast::local, &&rcx: @rcx, v: rvt) {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_pat(p: @ast::pat, &&rcx: @rcx, v: rvt) {
|
||||
let fcx = rcx.fcx;
|
||||
match p.node {
|
||||
ast::pat_ident(_, path, _)
|
||||
if !pat_util::pat_is_variant(fcx.ccx.tcx.def_map, p) => {
|
||||
debug!{"visit_pat binding=%s", *path.idents[0]};
|
||||
visit_node(p.id, p.span, rcx);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
|
||||
visit::visit_pat(p, rcx, v);
|
||||
}
|
||||
|
||||
fn visit_block(b: ast::blk, &&rcx: @rcx, v: rvt) {
|
||||
visit::visit_block(b, rcx, v);
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
fn impure(_v: ~[int]) {
|
||||
fn impure(_v: &[int]) {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = {mut f: ~[3]};
|
||||
|
||||
match x {
|
||||
{f: v} => {
|
||||
impure(v); //~ ERROR illegal borrow unless pure: unique value in aliasable, mutable location
|
||||
{f: ref mut v} => {
|
||||
impure(*v); //~ ERROR illegal borrow unless pure
|
||||
//~^ NOTE impure due to access to impure function
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
fn main() {
|
||||
let x = some(~1);
|
||||
match x { //~ NOTE loan of immutable local variable granted here
|
||||
some(y) => {
|
||||
some(ref y) => {
|
||||
let _a <- x; //~ ERROR moving out of immutable local variable prohibited due to outstanding loan
|
||||
}
|
||||
_ => {}
|
||||
|
@ -1,8 +1,8 @@
|
||||
fn main() {
|
||||
let x = some(~1);
|
||||
match x {
|
||||
some(y) => {
|
||||
let _b <- y; //~ ERROR moving out of pattern binding
|
||||
some(ref y) => {
|
||||
let _b <- *y; //~ ERROR moving out of dereference of immutable & pointer
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ fn main() {
|
||||
let x = ~node({mut a: ~empty});
|
||||
// Create a cycle!
|
||||
match check *x { //~ NOTE loan of immutable local variable granted here
|
||||
node(y) => {
|
||||
node(ref y) => {
|
||||
y.a <- x; //~ ERROR moving out of immutable local variable prohibited due to outstanding loan
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
fn match_imm_box(v: &const @option<int>) -> int {
|
||||
match *v {
|
||||
@some(i) => {i}
|
||||
@some(ref i) => {*i}
|
||||
@none => {0}
|
||||
}
|
||||
}
|
||||
|
||||
fn match_const_box(v: &const @const option<int>) -> int {
|
||||
match *v {
|
||||
@some(i) => { i } // ok because this is pure
|
||||
@some(ref i) => { *i } // ok because this is pure
|
||||
@none => {0}
|
||||
}
|
||||
}
|
||||
@ -16,8 +16,8 @@ pure fn pure_process(_i: int) {}
|
||||
|
||||
fn match_const_box_and_do_pure_things(v: &const @const option<int>) {
|
||||
match *v {
|
||||
@some(i) => {
|
||||
pure_process(i)
|
||||
@some(ref i) => {
|
||||
pure_process(*i)
|
||||
}
|
||||
@none => {}
|
||||
}
|
||||
@ -27,8 +27,8 @@ fn process(_i: int) {}
|
||||
|
||||
fn match_const_box_and_do_bad_things(v: &const @const option<int>) {
|
||||
match *v {
|
||||
@some(i) => { //~ ERROR illegal borrow unless pure: enum variant in aliasable, mutable location
|
||||
process(i) //~ NOTE impure due to access to impure function
|
||||
@some(ref i) => { //~ ERROR illegal borrow unless pure
|
||||
process(*i) //~ NOTE impure due to access to impure function
|
||||
}
|
||||
@none => {}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
fn match_ref(&&v: option<int>) -> int {
|
||||
match v {
|
||||
some(i) => {
|
||||
i
|
||||
some(ref i) => {
|
||||
*i
|
||||
}
|
||||
none => {0}
|
||||
}
|
||||
@ -16,7 +16,7 @@ fn match_ref_unused(&&v: option<int>) {
|
||||
|
||||
fn match_const_reg(v: &const option<int>) -> int {
|
||||
match *v {
|
||||
some(i) => {i} // OK because this is pure
|
||||
some(ref i) => {*i} // OK because this is pure
|
||||
none => {0}
|
||||
}
|
||||
}
|
||||
@ -33,7 +33,7 @@ fn match_const_reg_unused(v: &const option<int>) {
|
||||
|
||||
fn match_const_reg_impure(v: &const option<int>) {
|
||||
match *v {
|
||||
some(i) => {impure(i)} //~ ERROR illegal borrow unless pure: enum variant in aliasable, mutable location
|
||||
some(ref i) => {impure(*i)} //~ ERROR illegal borrow unless pure
|
||||
//~^ NOTE impure due to access to impure function
|
||||
none => {}
|
||||
}
|
||||
@ -41,7 +41,7 @@ fn match_const_reg_impure(v: &const option<int>) {
|
||||
|
||||
fn match_imm_reg(v: &option<int>) {
|
||||
match *v {
|
||||
some(i) => {impure(i)} // OK because immutable
|
||||
some(ref i) => {impure(*i)} // OK because immutable
|
||||
none => {}
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ fn main() {
|
||||
let mut x: option<int> = none;
|
||||
match x { //~ NOTE loan of mutable local variable granted here
|
||||
none => {}
|
||||
some(i) => {
|
||||
some(ref i) => {
|
||||
// Not ok: i is an outstanding ptr into x.
|
||||
x = some(i+1); //~ ERROR assigning to mutable local variable prohibited due to outstanding loan
|
||||
x = some(*i+1); //~ ERROR assigning to mutable local variable prohibited due to outstanding loan
|
||||
}
|
||||
}
|
||||
copy x; // just to prevent liveness warnings
|
||||
|
@ -8,7 +8,7 @@ fn main() {
|
||||
// fact no outstanding loan of x!
|
||||
x = some(0);
|
||||
}
|
||||
some(i) => {
|
||||
some(ref i) => {
|
||||
x = some(1); //~ ERROR assigning to mutable local variable prohibited due to outstanding loan
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ fn impure(_i: int) {}
|
||||
// check that unchecked alone does not override borrowck:
|
||||
fn foo(v: &const option<int>) {
|
||||
match *v {
|
||||
some(i) => {
|
||||
//~^ ERROR illegal borrow unless pure: enum variant in aliasable, mutable location
|
||||
some(ref i) => {
|
||||
//~^ ERROR illegal borrow unless pure
|
||||
unchecked {
|
||||
impure(i); //~ NOTE impure due to access to impure function
|
||||
impure(*i); //~ NOTE impure due to access to impure function
|
||||
}
|
||||
}
|
||||
none => {
|
||||
@ -16,9 +16,9 @@ fn foo(v: &const option<int>) {
|
||||
|
||||
fn bar(v: &const option<int>) {
|
||||
match *v {
|
||||
some(i) => {
|
||||
some(ref i) => {
|
||||
unsafe {
|
||||
impure(i);
|
||||
impure(*i);
|
||||
}
|
||||
}
|
||||
none => {
|
||||
@ -27,4 +27,4 @@ fn bar(v: &const option<int>) {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
}
|
||||
|
8
src/test/run-pass/alt-ref-binding-mut-option.rs
Normal file
8
src/test/run-pass/alt-ref-binding-mut-option.rs
Normal file
@ -0,0 +1,8 @@
|
||||
fn main() {
|
||||
let mut v = some(22);
|
||||
match v {
|
||||
none => {}
|
||||
some(ref mut p) => { *p += 1; }
|
||||
}
|
||||
assert v == some(23);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user