rust/src/test/compile-fail/regions-scoping.rs
Niko Matsakis 5d32d03b89 Fix #2979: inference for lifetimes of & expressions
What we now do is to create a region variable for each &
expression (and also each borrow).  The lifetime of this
variable will be checked by borrowck to ensure it is not greater
than the lifetime of the underlying data.  This both leads to
shorter lifetimes in some cases but also longer in others,
such as taking the address to the interior of unique boxes
tht are rooted in region pointers (e.g., returning a pointer
to the interior of a sendable map).

This may lead to issue #2977 if the rvalue is not POD, because
we may drop the data in trans sooner than borrowck expects us
to.  Need to work out precisely where that fix ought to occur.
2012-07-30 14:49:28 -07:00

48 lines
2.5 KiB
Rust

fn with<T>(t: T, f: fn(T)) { f(t) }
fn nested(x: &x/int) { // (1)
do with(
fn&(x: &x/int, // Refers to the region `x` at (1)
y: &y/int, // A fresh region `y` (2)
z: fn(x: &x/int, // Refers to `x` at (1)
y: &y/int, // Refers to `y` at (2)
z: &z/int) -> &z/int) // A fresh region `z` (3)
-> &x/int {
if false { ret z(x, x, x); } //~ ERROR mismatched types: expected `&y/int` but found `&x/int`
if false { ret z(x, x, y); } //~ ERROR mismatched types: expected `&y/int` but found `&x/int`
//~^ ERROR mismatched types: expected `&x/int` but found `&y/int`
if false { ret z(x, y, x); }
if false { ret z(x, y, y); } //~ ERROR mismatched types: expected `&x/int` but found `&y/int`
if false { ret z(y, x, x); } //~ ERROR mismatched types: expected `&x/int` but found `&y/int`
//~^ ERROR mismatched types: expected `&y/int` but found `&x/int`
if false { ret z(y, x, y); } //~ ERROR mismatched types: expected `&x/int` but found `&y/int`
//~^ ERROR mismatched types: expected `&y/int` but found `&x/int`
//~^^ ERROR mismatched types: expected `&x/int` but found `&y/int`
if false { ret z(y, y, x); } //~ ERROR mismatched types: expected `&x/int` but found `&y/int`
if false { ret z(y, y, y); } //~ ERROR mismatched types: expected `&x/int` but found `&y/int`
//~^ ERROR mismatched types: expected `&x/int` but found `&y/int`
fail;
}
) |foo| {
let a: &x/int = foo(x, x, |_x, _y, z| z );
let b: &x/int = foo(x, a, |_x, _y, z| z );
let c: &x/int = foo(a, a, |_x, _y, z| z );
let z = 3i;
let d: &x/int = foo(x, x, |_x, _y, z| z );
let e: &x/int = foo(x, &z, |_x, _y, z| z );
// This would result in an error, but it is not reported by typeck
// anymore but rather borrowck. Therefore, it doesn't end up
// getting printed out since compilation fails after typeck.
//
// let f: &x/int = foo(&z, &z, |_x, _y, z| z ); // ERROR mismatched types: expected `&x/int` but found
foo(x, &z, |x, _y, _z| x ); //~ ERROR mismatched types: expected `&z/int` but found `&x/int`
foo(x, &z, |_x, y, _z| y ); //~ ERROR mismatched types: expected `&z/int` but found `&<expression at
}
}
fn main() {}