Fix subtle error in caching during kind computation that could cause linear
values to be copied. Rewrite kind computation so that instead of directly computing the kind it computes what kinds of values are present in the type, and then derive kinds based on that. I find this easier to think about. Fixes #4821.
This commit is contained in:
parent
6647a3402b
commit
a380df809c
31 changed files with 612 additions and 579 deletions
|
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
fn foo<T>() {
|
||||
1u.bar::<T>(); //~ ERROR: missing `copy`
|
||||
1u.bar::<T>(); //~ ERROR: does not fulfill `Copy`
|
||||
}
|
||||
|
||||
trait bar {
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: copying a noncopyable value
|
||||
|
||||
struct foo {
|
||||
i: int,
|
||||
}
|
||||
|
|
@ -24,4 +22,9 @@ fn foo(i:int) -> foo {
|
|||
}
|
||||
}
|
||||
|
||||
fn main() { let x = move foo(10); let y = copy x; log(error, x); }
|
||||
fn main() {
|
||||
let x = move foo(10);
|
||||
let _y = copy x;
|
||||
//~^ ERROR copying a value of non-copyable type `foo`
|
||||
log(error, x);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ fn main() {
|
|||
let mut res = foo(x);
|
||||
|
||||
let mut v = ~[mut];
|
||||
v = move ~[mut (move res)] + v; //~ ERROR instantiating a type parameter with an incompatible type (needs `copy`, got `&static`, missing `copy`)
|
||||
v = move ~[mut (move res)] + v; //~ ERROR does not fulfill `Copy`
|
||||
assert (v.len() == 2);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,6 @@ impl C : Drop {
|
|||
|
||||
fn main() {
|
||||
let c = C{ x: 2};
|
||||
let d = copy c; //~ ERROR copying a noncopyable value
|
||||
let d = copy c; //~ ERROR copying a value of non-copyable type `C`
|
||||
error!("%?", d.x);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ fn foo(_x: @uint) {}
|
|||
|
||||
fn main() {
|
||||
let x = @3u;
|
||||
let _ = fn~() { foo(x); }; //~ ERROR not a sendable value
|
||||
let _ = fn~(copy x) { foo(x); }; //~ ERROR not a sendable value
|
||||
let _ = fn~(move x) { foo(x); }; //~ ERROR not a sendable value
|
||||
let _ = fn~() { foo(x); }; //~ ERROR value has non-owned type `@uint`
|
||||
let _ = fn~(copy x) { foo(x); }; //~ ERROR value has non-owned type `@uint`
|
||||
let _ = fn~(move x) { foo(x); }; //~ ERROR value has non-owned type `@uint`
|
||||
}
|
||||
|
|
@ -18,12 +18,12 @@ fn copy2<T: Copy &static>(t: T) -> fn@() -> T {
|
|||
|
||||
fn main() {
|
||||
let x = &3;
|
||||
copy2(&x); //~ ERROR missing `&static`
|
||||
copy2(&x); //~ ERROR does not fulfill `&static`
|
||||
|
||||
copy2(@3);
|
||||
copy2(@&x); //~ ERROR missing `&static`
|
||||
copy2(@&x); //~ ERROR does not fulfill `&static`
|
||||
|
||||
copy2(fn@() {});
|
||||
copy2(fn~() {}); //~ ERROR missing `copy`
|
||||
copy2(fn&() {}); //~ ERROR missing `&static`
|
||||
copy2(fn~() {}); //~ ERROR does not fulfill `Copy`
|
||||
copy2(fn&() {}); //~ ERROR does not fulfill `&static`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,5 +68,5 @@ impl r : Drop {
|
|||
|
||||
fn main() {
|
||||
let x = r { x: () };
|
||||
fn@(move x) { copy x; }; //~ ERROR copying a noncopyable value
|
||||
fn@(move x) { copy x; }; //~ ERROR copying a value of non-copyable type
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test for a subtle failure computing kinds of cyclic types, in which
|
||||
// temporary kinds wound up being stored in a cache and used later.
|
||||
// See middle::ty::type_contents() for more information.
|
||||
|
||||
extern mod std;
|
||||
use core::cmp::Ord;
|
||||
use core::option::swap_unwrap;
|
||||
|
||||
struct List { key: int, next: Option<~List> }
|
||||
|
||||
fn foo(node: ~List) -> int {
|
||||
let r = match node.next {
|
||||
Some(right) => consume(right),
|
||||
None => 0
|
||||
};
|
||||
consume(node) + r //~ ERROR use of partially moved value: `node`
|
||||
}
|
||||
|
||||
fn consume(v: ~List) -> int {
|
||||
v.key
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ fn main() {
|
|||
|
||||
do task::spawn {
|
||||
let mut y = None;
|
||||
*x <-> y; //~ ERROR not a sendable value
|
||||
*x <-> y; //~ ERROR value has non-owned type
|
||||
log(error, y);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,14 +42,14 @@ fn r2(x:@mut int) -> r2 {
|
|||
|
||||
fn main() {
|
||||
foo({f: 3});
|
||||
foo({mut f: 3}); //~ ERROR missing `const`
|
||||
foo({mut f: 3}); //~ ERROR does not fulfill `Const`
|
||||
foo(~[1]);
|
||||
foo(~[mut 1]); //~ ERROR missing `const`
|
||||
foo(~[mut 1]); //~ ERROR does not fulfill `Const`
|
||||
foo(~1);
|
||||
foo(~mut 1); //~ ERROR missing `const`
|
||||
foo(~mut 1); //~ ERROR does not fulfill `Const`
|
||||
foo(@1);
|
||||
foo(@mut 1); //~ ERROR missing `const`
|
||||
foo(@mut 1); //~ ERROR does not fulfill `Const`
|
||||
foo(r(1)); // this is okay now.
|
||||
foo(r2(@mut 1)); //~ ERROR missing `const`
|
||||
foo({f: {mut f: 1}}); //~ ERROR missing `const`
|
||||
foo(r2(@mut 1)); //~ ERROR does not fulfill `Const`
|
||||
foo({f: {mut f: 1}}); //~ ERROR does not fulfill `Const`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,6 @@ fn main() {
|
|||
let y : *libc::c_void = x as *libc::c_void;
|
||||
unsafe {
|
||||
let _z = copy *y;
|
||||
//~^ ERROR copying a noncopyable value
|
||||
//~^ ERROR copying a value of non-copyable type
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: copying a noncopyable value
|
||||
|
||||
// Test that a class with a non-copyable field can't be
|
||||
// copied
|
||||
struct bar {
|
||||
|
|
@ -38,4 +36,8 @@ fn foo(i:int) -> foo {
|
|||
}
|
||||
}
|
||||
|
||||
fn main() { let x = move foo(10); let y = copy x; log(error, x); }
|
||||
fn main() {
|
||||
let x = move foo(10);
|
||||
let _y = copy x; //~ ERROR copying a value of non-copyable type
|
||||
log(error, x);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
fn main() {
|
||||
let x = Some(private::exclusive(false));
|
||||
match x {
|
||||
Some(copy z) => { //~ ERROR copying a noncopyable value
|
||||
Some(copy z) => { //~ ERROR copying a value of non-copyable type
|
||||
do z.with |b| { assert !*b; }
|
||||
}
|
||||
None => die!()
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: copying a noncopyable value
|
||||
|
||||
struct r {
|
||||
i: @mut int,
|
||||
}
|
||||
|
|
@ -31,7 +29,7 @@ fn main() {
|
|||
{
|
||||
// Can't do this copy
|
||||
let x = ~~~{y: r(i)};
|
||||
let z = copy x;
|
||||
let _z = copy x; //~ ERROR copying a value of non-copyable type
|
||||
log(debug, x);
|
||||
}
|
||||
log(error, *i);
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: copying a noncopyable value
|
||||
|
||||
struct my_resource {
|
||||
x: int,
|
||||
}
|
||||
|
|
@ -29,7 +27,7 @@ fn my_resource(x: int) -> my_resource {
|
|||
fn main() {
|
||||
{
|
||||
let a = {x: 0, y: my_resource(20)};
|
||||
let b = {x: 2,.. copy a};
|
||||
let b = {x: 2,.. copy a}; //~ ERROR copying a value of non-copyable type
|
||||
log(error, (a, b));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,6 @@ impl Foo : Drop {
|
|||
|
||||
fn main() {
|
||||
let a = Foo { x: 3 };
|
||||
let _ = [ a, ..5 ]; //~ ERROR copying a noncopyable value
|
||||
let _ = [ a, ..5 ]; //~ ERROR copying a value of non-copyable type
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
trait Foo {
|
||||
fn f();
|
||||
fn f(&self);
|
||||
}
|
||||
|
||||
struct Bar {
|
||||
|
|
@ -21,14 +21,14 @@ impl Bar : Drop {
|
|||
}
|
||||
|
||||
impl Bar : Foo {
|
||||
fn f() {
|
||||
fn f(&self) {
|
||||
io::println("hi");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = ~Bar { x: 10 };
|
||||
let y = (move x) as ~Foo; //~ ERROR uniquely-owned trait objects must be copyable
|
||||
let _z = copy y;
|
||||
let y: ~Foo = x as ~Foo;
|
||||
let _z = copy y; //~ ERROR copying a value of non-copyable type
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: copying a noncopyable value
|
||||
|
||||
struct r {
|
||||
b:bool,
|
||||
}
|
||||
|
|
@ -20,6 +18,6 @@ impl r : Drop {
|
|||
|
||||
fn main() {
|
||||
let i = move ~r { b: true };
|
||||
let j = copy i;
|
||||
let _j = copy i; //~ ERROR copying a value of non-copyable type
|
||||
log(debug, i);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,5 +13,5 @@ fn f<T: Owned>(_i: T) {
|
|||
|
||||
fn main() {
|
||||
let i = ~@100;
|
||||
f(move i); //~ ERROR missing `owned`
|
||||
f(move i); //~ ERROR does not fulfill `Owned`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: copying a noncopyable value
|
||||
|
||||
struct r {
|
||||
i: @mut int,
|
||||
}
|
||||
|
|
@ -20,7 +18,7 @@ impl r : Drop {
|
|||
}
|
||||
}
|
||||
|
||||
fn f<T>(+i: ~[T], +j: ~[T]) {
|
||||
fn f<T>(+_i: ~[T], +_j: ~[T]) {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
@ -29,6 +27,8 @@ fn main() {
|
|||
let r1 = move ~[~r { i: i1 }];
|
||||
let r2 = move ~[~r { i: i2 }];
|
||||
f(copy r1, copy r2);
|
||||
//~^ ERROR copying a value of non-copyable type
|
||||
//~^^ ERROR copying a value of non-copyable type
|
||||
log(debug, (r2, *i1));
|
||||
log(debug, (r1, *i2));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,6 @@ fn foo(i:int, j: @~str) -> foo {
|
|||
|
||||
fn main() {
|
||||
let cat = ~"kitty";
|
||||
let (_, ch) = pipes::stream(); //~ ERROR missing `owned`
|
||||
ch.send(foo(42, @(move cat))); //~ ERROR missing `owned`
|
||||
let (_, ch) = pipes::stream(); //~ ERROR does not fulfill `Owned`
|
||||
ch.send(foo(42, @(move cat))); //~ ERROR does not fulfill `Owned`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@ pub fn main() {
|
|||
let x = ~S { x: 3 };
|
||||
let y = x as ~Foo;
|
||||
y.f();
|
||||
y.f();
|
||||
y.f();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
trait Foo {
|
||||
fn f();
|
||||
fn f(&self) -> int;
|
||||
}
|
||||
|
||||
struct Bar {
|
||||
|
|
@ -17,16 +17,14 @@ struct Bar {
|
|||
}
|
||||
|
||||
impl Bar : Foo {
|
||||
fn f() {
|
||||
io::println("hi");
|
||||
fn f(&self) -> int {
|
||||
self.x
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let x = ~Bar { x: 10 };
|
||||
let y = x as ~Foo;
|
||||
let z = copy y;
|
||||
y.f();
|
||||
z.f();
|
||||
assert y.f() == 10;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue