diff --git a/src/test/compile-fail/ret-by-reference-from-temporary.rs b/src/test/compile-fail/ret-by-reference-from-temporary.rs new file mode 100644 index 00000000000..2a6d05f23d4 --- /dev/null +++ b/src/test/compile-fail/ret-by-reference-from-temporary.rs @@ -0,0 +1,9 @@ +// error-pattern:a reference binding can't be rooted in a temporary + +fn f(a: {x: int}) -> &int { + ret a.x; +} + +fn main() { + let &_a = f({x: 4}); +} diff --git a/src/test/compile-fail/ret-by-reference-local-value.rs b/src/test/compile-fail/ret-by-reference-local-value.rs new file mode 100644 index 00000000000..5e0df4fc3cd --- /dev/null +++ b/src/test/compile-fail/ret-by-reference-local-value.rs @@ -0,0 +1,8 @@ +// error-pattern:can not return a reference to a function-local value + +fn f(a: {mutable x: int}) -> &int { + let x = {y: 4}; + ret x.y; +} + +fn main() {} diff --git a/src/test/compile-fail/ret-by-reference-mutable-field.rs b/src/test/compile-fail/ret-by-reference-mutable-field.rs new file mode 100644 index 00000000000..a40b9aeba2d --- /dev/null +++ b/src/test/compile-fail/ret-by-reference-mutable-field.rs @@ -0,0 +1,7 @@ +// error-pattern:can not return a reference to a mutable field + +fn f(a: {mutable x: int}) -> &int { + ret a.x; +} + +fn main() {} diff --git a/src/test/compile-fail/ret-by-reference-safety-1.rs b/src/test/compile-fail/ret-by-reference-safety-1.rs new file mode 100644 index 00000000000..f6cd81308e9 --- /dev/null +++ b/src/test/compile-fail/ret-by-reference-safety-1.rs @@ -0,0 +1,12 @@ +// error-pattern:taking the value of x will invalidate reference a + +fn f(a: {mutable x: int}) -> &!int { + ret a.x; +} + +fn main() { + let x = {mutable x: 4}; + let &a = f(x); + x; + a; +} diff --git a/src/test/compile-fail/ret-by-reference-safety-2.rs b/src/test/compile-fail/ret-by-reference-safety-2.rs new file mode 100644 index 00000000000..546511419c1 --- /dev/null +++ b/src/test/compile-fail/ret-by-reference-safety-2.rs @@ -0,0 +1,12 @@ +// error-pattern:overwriting x will invalidate reference a + +fn f(a: {x: {mutable x: int}}) -> &{mutable x: int} { + ret a.x; +} + +fn main() { + let x = {x: {mutable x: 4}}; + let &a = f(x); + x = {x: {mutable x: 5}}; + a; +} diff --git a/src/test/compile-fail/ret-by-reference-specify-param.rs b/src/test/compile-fail/ret-by-reference-specify-param.rs new file mode 100644 index 00000000000..a99dfc1c8dd --- /dev/null +++ b/src/test/compile-fail/ret-by-reference-specify-param.rs @@ -0,0 +1,7 @@ +// error-pattern:must specify referenced parameter + +fn f(a: int, b: int) -> &int { + ret a; +} + +fn main() {} diff --git a/src/test/compile-fail/ret-by-reference-temporary.rs b/src/test/compile-fail/ret-by-reference-temporary.rs new file mode 100644 index 00000000000..5a571cf3ecc --- /dev/null +++ b/src/test/compile-fail/ret-by-reference-temporary.rs @@ -0,0 +1,7 @@ +// error-pattern:can not return a reference to a temporary + +fn f(a: int) -> &int { + ret 10; +} + +fn main() {} diff --git a/src/test/compile-fail/ret-by-reference-wrong-param.rs b/src/test/compile-fail/ret-by-reference-wrong-param.rs new file mode 100644 index 00000000000..41014bb17d7 --- /dev/null +++ b/src/test/compile-fail/ret-by-reference-wrong-param.rs @@ -0,0 +1,7 @@ +// error-pattern:can not return a reference to the wrong parameter + +fn f(a: int, b: int) -> &1 int { + ret a; +} + +fn main() {} diff --git a/src/test/run-pass/ret-by-reference.rs b/src/test/run-pass/ret-by-reference.rs new file mode 100644 index 00000000000..6f098160e6a --- /dev/null +++ b/src/test/run-pass/ret-by-reference.rs @@ -0,0 +1,23 @@ +tag option { some(T); none; } + +fn get<@T>(opt: option) -> &T { + alt opt { + some(x) { ret x; } + } +} + +fn get_mut(a: {mutable x: @int}, _b: int) -> &!0 @int { + ret a.x; +} + +fn main() { + let x = some(@50); + let &y = get(x); + assert *y == 50; + assert get(some(10)) == 10; + + let y = {mutable x: @50}; + let &box = get_mut(y, 4); + assert *box == 50; + assert *get_mut({mutable x: @70}, 5) == 70; +}