Refactor object-safety into its own (cached) module so that we can
check it more easily; also extend object safety to cover sized types as well as static methods. This makes it sufficient so that we can always ensure that `Foo : Foo` holds for any trait `Foo`.
This commit is contained in:
parent
2c1d7a7caa
commit
19dcecb225
14 changed files with 601 additions and 272 deletions
|
|
@ -21,6 +21,6 @@ impl Foo for Thing {
|
|||
|
||||
fn main() {
|
||||
let mut thing = Thing;
|
||||
let test: &Bar = &mut thing; //~ ERROR cannot convert to a trait object because trait `Foo`
|
||||
let test: &Bar = &mut thing; //~ ERROR cannot convert to a trait object
|
||||
foo(test);
|
||||
}
|
||||
|
|
|
|||
47
src/test/compile-fail/object-safety-by-value-self.rs
Normal file
47
src/test/compile-fail/object-safety-by-value-self.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Check that we correctly prevent users from making trait objects
|
||||
// from traits with a `fn(self)` method.
|
||||
|
||||
trait Bar {
|
||||
fn bar(self);
|
||||
}
|
||||
|
||||
trait Baz {
|
||||
fn baz(self: Self);
|
||||
}
|
||||
|
||||
fn make_bar<T:Bar>(t: &T) -> &Bar {
|
||||
t
|
||||
//~^ ERROR `Bar` is not object-safe
|
||||
//~| NOTE method `bar` has a receiver type of `Self`
|
||||
}
|
||||
|
||||
fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
|
||||
t as &Bar
|
||||
//~^ ERROR `Bar` is not object-safe
|
||||
//~| NOTE method `bar` has a receiver type of `Self`
|
||||
}
|
||||
|
||||
fn make_baz<T:Baz>(t: &T) -> &Baz {
|
||||
t
|
||||
//~^ ERROR `Baz` is not object-safe
|
||||
//~| NOTE method `baz` has a receiver type of `Self`
|
||||
}
|
||||
|
||||
fn make_baz_explicit<T:Baz>(t: &T) -> &Baz {
|
||||
t as &Baz
|
||||
//~^ ERROR `Baz` is not object-safe
|
||||
//~| NOTE method `baz` has a receiver type of `Self`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
@ -8,19 +8,24 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Check that object-safe methods are identified as such.
|
||||
// Check that we correctly prevent users from making trait objects
|
||||
// from traits with generic methods.
|
||||
|
||||
trait Tr {
|
||||
fn foo(&self);
|
||||
trait Bar {
|
||||
fn bar<T>(&self, t: T);
|
||||
}
|
||||
|
||||
struct St;
|
||||
fn make_bar<T:Bar>(t: &T) -> &Bar {
|
||||
t
|
||||
//~^ ERROR `Bar` is not object-safe
|
||||
//~| NOTE method `bar` has generic type parameters
|
||||
}
|
||||
|
||||
impl Tr for St {
|
||||
fn foo(&self) {}
|
||||
fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
|
||||
t as &Bar
|
||||
//~^ ERROR `Bar` is not object-safe
|
||||
//~| NOTE method `bar` has generic type parameters
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s: &Tr = &St;
|
||||
s.foo();
|
||||
}
|
||||
47
src/test/compile-fail/object-safety-mentions-Self.rs
Normal file
47
src/test/compile-fail/object-safety-mentions-Self.rs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Check that we correctly prevent users from making trait objects
|
||||
// form traits that make use of `Self` in an argument or return position.
|
||||
|
||||
trait Bar {
|
||||
fn bar(&self, x: &Self);
|
||||
}
|
||||
|
||||
trait Baz {
|
||||
fn bar(&self) -> Self;
|
||||
}
|
||||
|
||||
fn make_bar<T:Bar>(t: &T) -> &Bar {
|
||||
t
|
||||
//~^ ERROR `Bar` is not object-safe
|
||||
//~| NOTE method `bar` references the `Self` type in its arguments or return type
|
||||
}
|
||||
|
||||
fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
|
||||
t as &Bar
|
||||
//~^ ERROR `Bar` is not object-safe
|
||||
//~| NOTE method `bar` references the `Self` type in its arguments or return type
|
||||
}
|
||||
|
||||
fn make_baz<T:Baz>(t: &T) -> &Baz {
|
||||
t
|
||||
//~^ ERROR `Baz` is not object-safe
|
||||
//~| NOTE method `bar` references the `Self` type in its arguments or return type
|
||||
}
|
||||
|
||||
fn make_baz_explicit<T:Baz>(t: &T) -> &Baz {
|
||||
t as &Baz
|
||||
//~^ ERROR `Baz` is not object-safe
|
||||
//~| NOTE method `bar` references the `Self` type in its arguments or return type
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
31
src/test/compile-fail/object-safety-no-static.rs
Normal file
31
src/test/compile-fail/object-safety-no-static.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Check that we correctly prevent users from making trait objects
|
||||
// from traits with static methods.
|
||||
|
||||
trait Foo {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
fn foo_implicit<T:Foo+'static>(b: Box<T>) -> Box<Foo+'static> {
|
||||
b
|
||||
//~^ ERROR cannot convert to a trait object
|
||||
//~| NOTE method `foo` has no receiver
|
||||
}
|
||||
|
||||
fn foo_explicit<T:Foo+'static>(b: Box<T>) -> Box<Foo+'static> {
|
||||
b as Box<Foo>
|
||||
//~^ ERROR cannot convert to a trait object
|
||||
//~| NOTE method `foo` has no receiver
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
33
src/test/compile-fail/object-safety-sized-2.rs
Normal file
33
src/test/compile-fail/object-safety-sized-2.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Check that we correctly prevent users from making trait objects
|
||||
// from traits where `Self : Sized`.
|
||||
|
||||
trait Bar
|
||||
where Self : Sized
|
||||
{
|
||||
fn bar<T>(&self, t: T);
|
||||
}
|
||||
|
||||
fn make_bar<T:Bar>(t: &T) -> &Bar {
|
||||
t
|
||||
//~^ ERROR `Bar` is not object-safe
|
||||
//~| NOTE the trait cannot require that `Self : Sized`
|
||||
}
|
||||
|
||||
fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
|
||||
t as &Bar
|
||||
//~^ ERROR `Bar` is not object-safe
|
||||
//~| NOTE the trait cannot require that `Self : Sized`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
31
src/test/compile-fail/object-safety-sized.rs
Normal file
31
src/test/compile-fail/object-safety-sized.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// Check that we correctly prevent users from making trait objects
|
||||
// from traits where `Self : Sized`.
|
||||
|
||||
trait Bar : Sized {
|
||||
fn bar<T>(&self, t: T);
|
||||
}
|
||||
|
||||
fn make_bar<T:Bar>(t: &T) -> &Bar {
|
||||
t
|
||||
//~^ ERROR `Bar` is not object-safe
|
||||
//~| NOTE the trait cannot require that `Self : Sized`
|
||||
}
|
||||
|
||||
fn make_bar_explicit<T:Bar>(t: &T) -> &Bar {
|
||||
t as &Bar
|
||||
//~^ ERROR `Bar` is not object-safe
|
||||
//~| NOTE the trait cannot require that `Self : Sized`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
trait Foo {
|
||||
fn foo(self);
|
||||
}
|
||||
|
||||
trait Bar {
|
||||
fn bar(&self, x: &Self);
|
||||
}
|
||||
|
||||
trait Baz {
|
||||
fn baz<T>(&self, x: &T);
|
||||
}
|
||||
|
||||
impl Foo for int {
|
||||
fn foo(self) {}
|
||||
}
|
||||
|
||||
impl Bar for int {
|
||||
fn bar(&self, _x: &int) {}
|
||||
}
|
||||
|
||||
impl Baz for int {
|
||||
fn baz<T>(&self, _x: &T) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: &Foo = &42i; //~ ERROR cannot convert to a trait object
|
||||
let _: &Bar = &42i; //~ ERROR cannot convert to a trait object
|
||||
let _: &Baz = &42i; //~ ERROR cannot convert to a trait object
|
||||
|
||||
let _ = &42i as &Foo; //~ ERROR cannot convert to a trait object
|
||||
let _ = &42i as &Bar; //~ ERROR cannot convert to a trait object
|
||||
let _ = &42i as &Baz; //~ ERROR cannot convert to a trait object
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
|
||||
trait Foo : Sized {
|
||||
fn foo(self: Box<Self>) { bar(self as Box<Foo>); }
|
||||
}
|
||||
|
||||
fn bar(_b: Box<Foo>) { }
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue