-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
RFC-2027: Add tests for new legal syntax and wf/coherence
- Loading branch information
1 parent
a18ee9a
commit c516035
Showing
11 changed files
with
316 additions
and
0 deletions.
There are no files selected for viewing
18 changes: 18 additions & 0 deletions
18
src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Check that unsafe trait object do not implement themselves | ||
// automatically | ||
|
||
#![feature(object_safe_for_dispatch)] | ||
|
||
trait Trait: Sized { | ||
fn call(&self); | ||
} | ||
|
||
fn takes_t<S: Trait>(s: S) { | ||
s.call(); | ||
} | ||
|
||
fn takes_t_obj(t: &dyn Trait) { | ||
takes_t(t); //~ ERROR E0277 | ||
} | ||
|
||
fn main() {} |
15 changes: 15 additions & 0 deletions
15
src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
error[E0277]: the trait bound `&dyn Trait: Trait` is not satisfied | ||
--> $DIR/coherence-unsafe-trait-object-impl.rs:15:5 | ||
| | ||
LL | takes_t(t); //~ ERROR E0277 | ||
| ^^^^^^^ the trait `Trait` is not implemented for `&dyn Trait` | ||
| | ||
note: required by `takes_t` | ||
--> $DIR/coherence-unsafe-trait-object-impl.rs:10:1 | ||
| | ||
LL | fn takes_t<S: Trait>(s: S) { | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0277`. |
23 changes: 23 additions & 0 deletions
23
src/test/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Check that we if we get ahold of an object unsafe trait | ||
// object with auto traits and lifetimes, we can downcast it | ||
// | ||
// compile-pass | ||
|
||
#![feature(object_safe_for_dispatch)] | ||
|
||
trait Trait: Sized {} | ||
|
||
fn downcast_auto(t: &(dyn Trait + Send)) -> &dyn Trait { | ||
t | ||
} | ||
|
||
fn downcast_lifetime<'a, 'b, 't>(t: &'a (dyn Trait + 't)) | ||
-> &'b (dyn Trait + 't) | ||
where | ||
'a: 'b, | ||
't: 'a + 'b, | ||
{ | ||
t | ||
} | ||
|
||
fn main() {} |
69 changes: 69 additions & 0 deletions
69
src/test/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Check that we can manually implement an object | ||
// unsafe trait for its trait object | ||
// | ||
// run-pass | ||
|
||
#![feature(object_safe_for_dispatch)] | ||
|
||
trait Bad { | ||
fn stat() -> char { | ||
'A' | ||
} | ||
fn virt(&self) -> char { | ||
'B' | ||
} | ||
fn indirect(&self) -> char { | ||
Self::stat() | ||
} | ||
} | ||
|
||
trait Good { | ||
fn good_virt(&self) -> char { | ||
panic!() | ||
} | ||
fn good_indirect(&self) -> char { | ||
panic!() | ||
} | ||
} | ||
|
||
impl<'a> Bad for dyn Bad + 'a { | ||
fn stat() -> char { | ||
'C' | ||
} | ||
fn virt(&self) -> char { | ||
'D' | ||
} | ||
} | ||
|
||
struct Struct {} | ||
|
||
impl Bad for Struct {} | ||
|
||
impl Good for Struct {} | ||
|
||
fn main() { | ||
let s = Struct {}; | ||
|
||
let mut res = String::new(); | ||
|
||
// Directly call static | ||
res.push(Struct::stat()); // "A" | ||
res.push(<dyn Bad>::stat()); // "AC" | ||
|
||
let good: &dyn Good = &s; | ||
|
||
// These look similar enough... | ||
let bad = unsafe { std::mem::transmute::<&dyn Good, &dyn Bad>(good) }; | ||
|
||
// Call virtual | ||
res.push(s.virt()); // "ACB" | ||
res.push(bad.virt()); // "ACBD" | ||
|
||
// Indirectly call static | ||
res.push(s.indirect()); // "ACBDA" | ||
res.push(bad.indirect()); // "ACBDAC" | ||
|
||
if &res != "ACBDAC" { | ||
panic!(); | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
src/test/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Check that we can statically dispatch methods for object | ||
// unsafe trait objects, directly and indirectly | ||
// | ||
// compile-pass | ||
|
||
#![feature(object_safe_for_dispatch)] | ||
|
||
trait Statics { | ||
fn plain() {} | ||
fn generic<T>() {} | ||
} | ||
|
||
trait Trait: Sized {} | ||
|
||
impl<'a> Statics for dyn Trait + 'a {} | ||
|
||
fn static_poly<T: Statics + ?Sized>() { | ||
T::plain(); | ||
T::generic::<usize>(); | ||
} | ||
|
||
fn inferred_poly<T: Statics + ?Sized>(t: &T) { | ||
static_poly::<T>(); | ||
T::plain(); | ||
T::generic::<usize>(); | ||
} | ||
|
||
fn call(t: &dyn Trait) { | ||
static_poly::<dyn Trait>(); | ||
inferred_poly(t); | ||
} | ||
|
||
fn main() { | ||
static_poly::<dyn Trait>(); | ||
<dyn Trait>::plain(); | ||
<dyn Trait>::generic::<usize>() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Check that we do not allow casts or coercions | ||
// to object unsafe trait objects inside a Box | ||
|
||
#![feature(object_safe_for_dispatch)] | ||
|
||
trait Trait: Sized {} | ||
|
||
struct S; | ||
|
||
impl Trait for S {} | ||
|
||
fn takes_box(t: Box<dyn Trait>) {} | ||
|
||
fn main() { | ||
Box::new(S) as Box<dyn Trait>; //~ ERROR E0038 | ||
let t_box: Box<dyn Trait> = Box::new(S); //~ ERROR E0038 | ||
takes_box(Box::new(S)); //~ ERROR E0038 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
error[E0038]: the trait `Trait` cannot be made into an object | ||
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33 | ||
| | ||
LL | let t_box: Box<dyn Trait> = Box::new(S); //~ ERROR E0038 | ||
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | ||
| | ||
= note: the trait cannot require that `Self : Sized` | ||
= note: required when trying to coerce from type `std::boxed::Box<S>` to type 'std::boxed::Box<dyn Trait>` | ||
|
||
error[E0038]: the trait `Trait` cannot be made into an object | ||
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15 | ||
| | ||
LL | takes_box(Box::new(S)); //~ ERROR E0038 | ||
| ^^^^^^^^^^^ the trait `Trait` cannot be made into an object | ||
| | ||
= note: the trait cannot require that `Self : Sized` | ||
= note: required when trying to coerce from type `std::boxed::Box<S>` to type 'std::boxed::Box<(dyn Trait + 'static)>` | ||
|
||
error[E0038]: the trait `Trait` cannot be made into an object | ||
--> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:20 | ||
| | ||
LL | Box::new(S) as Box<dyn Trait>; //~ ERROR E0038 | ||
| ^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object | ||
| | ||
= note: the trait cannot require that `Self : Sized` | ||
= note: required by cast to type 'std::boxed::Box<dyn Trait>' | ||
|
||
error: aborting due to 3 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0038`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Check that we do not allow casts or coercions | ||
// to object unsafe trait objects by ref | ||
|
||
#![feature(object_safe_for_dispatch)] | ||
|
||
trait Trait: Sized {} | ||
|
||
struct S; | ||
|
||
impl Trait for S {} | ||
|
||
fn takes_trait(t: &dyn Trait) {} | ||
|
||
fn main() { | ||
&S as &dyn Trait; //~ ERROR E0038 | ||
let t: &dyn Trait = &S; //~ ERROR E0038 | ||
takes_trait(&S); //~ ERROR E0038 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
error[E0038]: the trait `Trait` cannot be made into an object | ||
--> $DIR/wf-convert-unsafe-trait-obj.rs:16:25 | ||
| | ||
LL | let t: &dyn Trait = &S; //~ ERROR E0038 | ||
| ^^ the trait `Trait` cannot be made into an object | ||
| | ||
= note: the trait cannot require that `Self : Sized` | ||
= note: required when trying to coerce from type `&S` to type '&dyn Trait` | ||
|
||
error[E0038]: the trait `Trait` cannot be made into an object | ||
--> $DIR/wf-convert-unsafe-trait-obj.rs:17:17 | ||
| | ||
LL | takes_trait(&S); //~ ERROR E0038 | ||
| ^^ the trait `Trait` cannot be made into an object | ||
| | ||
= note: the trait cannot require that `Self : Sized` | ||
= note: required when trying to coerce from type `&S` to type '&dyn Trait` | ||
|
||
error[E0038]: the trait `Trait` cannot be made into an object | ||
--> $DIR/wf-convert-unsafe-trait-obj.rs:15:11 | ||
| | ||
LL | &S as &dyn Trait; //~ ERROR E0038 | ||
| ^^^^^^^^^^ the trait `Trait` cannot be made into an object | ||
| | ||
= note: the trait cannot require that `Self : Sized` | ||
= note: required by cast to type '&dyn Trait' | ||
|
||
error: aborting due to 3 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0038`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Check that we do not allow coercions to object | ||
// unsafe trait objects in match arms | ||
|
||
#![feature(object_safe_for_dispatch)] | ||
|
||
trait Trait: Sized {} | ||
|
||
struct S; | ||
|
||
impl Trait for S {} | ||
|
||
struct R; | ||
|
||
impl Trait for R {} | ||
|
||
fn opt() -> Option<()> { | ||
Some(()) | ||
} | ||
|
||
fn main() { | ||
match opt() { //~ ERROR E0308 | ||
Some(()) => &S, | ||
None => &R, | ||
} | ||
let t: &dyn Trait = match opt() { //~ ERROR E0308 | ||
Some(()) => &S, | ||
None => &R, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
error[E0308]: match arms have incompatible types | ||
--> $DIR/wf-unsafe-trait-obj-match.rs:21:5 | ||
| | ||
LL | / match opt() { //~ ERROR E0308 | ||
LL | | Some(()) => &S, | ||
LL | | None => &R, | ||
| | -- match arm with an incompatible type | ||
LL | | } | ||
| |_____^ expected struct `S`, found struct `R` | ||
| | ||
= note: expected type `&S` | ||
found type `&R` | ||
|
||
error[E0308]: match arms have incompatible types | ||
--> $DIR/wf-unsafe-trait-obj-match.rs:25:25 | ||
| | ||
LL | let t: &dyn Trait = match opt() { //~ ERROR E0308 | ||
| _________________________^ | ||
LL | | Some(()) => &S, | ||
| | -- match arm with an incompatible type | ||
LL | | None => &R, | ||
LL | | }; | ||
| |_____^ | ||
| | ||
= note: required when trying to coerce from type `&S` to type '&dyn Trait` | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0308`. |