Skip to content

Commit dc8d1bc

Browse files
committed
Add more tests
1 parent ed172db commit dc8d1bc

16 files changed

+262
-6
lines changed

tests/ui/impl-trait/unsize_adt.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//! Test that we do not allow unsizing `Foo<[Opaque; N]>` to `Foo<[Concrete]>`.
2+
3+
struct Foo<T: ?Sized>(T);
4+
5+
fn hello() -> Foo<[impl Sized; 2]> {
6+
if false {
7+
let x = hello();
8+
let _: &Foo<[i32]> = &x;
9+
//~^ ERROR: mismatched types
10+
}
11+
todo!()
12+
}
13+
14+
fn main() {}

tests/ui/impl-trait/unsize_adt.stderr

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/unsize_adt.rs:8:30
3+
|
4+
LL | fn hello() -> Foo<[impl Sized; 2]> {
5+
| ---------- the found opaque type
6+
...
7+
LL | let _: &Foo<[i32]> = &x;
8+
| ----------- ^^ expected `&Foo<[i32]>`, found `&Foo<[impl Sized; 2]>`
9+
| |
10+
| expected due to this
11+
|
12+
= note: expected reference `&Foo<[i32]>`
13+
found reference `&Foo<[impl Sized; 2]>`
14+
15+
error: aborting due to 1 previous error
16+
17+
For more information about this error, try `rustc --explain E0308`.

tests/ui/impl-trait/unsize_slice.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//! Test that we do not allow unsizing `[Opaque; N]` to `[Concrete]`.
2+
3+
fn hello() -> [impl Sized; 2] {
4+
if false {
5+
let x = hello();
6+
let _: &[i32] = &x;
7+
//~^ ERROR: mismatched types
8+
}
9+
todo!()
10+
}
11+
12+
fn main() {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/unsize_slice.rs:6:25
3+
|
4+
LL | fn hello() -> [impl Sized; 2] {
5+
| ---------- the found opaque type
6+
...
7+
LL | let _: &[i32] = &x;
8+
| ------ ^^ expected `&[i32]`, found `&[impl Sized; 2]`
9+
| |
10+
| expected due to this
11+
|
12+
= note: expected reference `&[i32]`
13+
found reference `&[impl Sized; 2]`
14+
15+
error: aborting due to 1 previous error
16+
17+
For more information about this error, try `rustc --explain E0308`.

tests/ui/impl-trait/unsize_tuple.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//! Test that we do not allow unsizing `([Opaque; N],)` to `([Concrete],)`.
2+
3+
#![feature(unsized_tuple_coercion)]
4+
5+
fn hello() -> ([impl Sized; 2],) {
6+
if false {
7+
let x = hello();
8+
let _: &([i32],) = &x;
9+
//~^ ERROR: mismatched types
10+
}
11+
todo!()
12+
}
13+
14+
fn main() {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/unsize_tuple.rs:8:28
3+
|
4+
LL | fn hello() -> ([impl Sized; 2],) {
5+
| ---------- the found opaque type
6+
...
7+
LL | let _: &([i32],) = &x;
8+
| --------- ^^ expected `&([i32],)`, found `&([impl Sized; 2],)`
9+
| |
10+
| expected due to this
11+
|
12+
= note: expected reference `&([i32],)`
13+
found reference `&([impl Sized; 2],)`
14+
15+
error: aborting due to 1 previous error
16+
17+
For more information about this error, try `rustc --explain E0308`.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//@ revisions: current next
2+
//@[next] compile-flags: -Znext-solver
3+
//@[next] failure-status: 101
4+
//@[next] known-bug: unknown
5+
//@[next] normalize-stderr-test "note: .*\n\n" -> ""
6+
//@[next] normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> ""
7+
//@[next] normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
8+
//@[next] normalize-stderr-test "delayed at .*" -> ""
9+
//@[next] rustc-env:RUST_BACKTRACE=0
10+
//@ check-pass
11+
12+
#![feature(trait_upcasting)]
13+
14+
trait Super {
15+
type Assoc;
16+
}
17+
18+
trait Sub: Super {}
19+
20+
impl<T: ?Sized> Super for T {
21+
type Assoc = i32;
22+
}
23+
24+
fn illegal(x: &dyn Sub<Assoc = i32>) -> &dyn Super<Assoc = impl Sized> {
25+
x
26+
}
27+
28+
fn main() {}

tests/ui/traits/trait-upcasting/type-checking-test-4.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ fn test_correct(x: &dyn Foo<'static>) {
1111
let _ = x as &dyn Bar<'static, 'static>;
1212
}
1313

14+
fn test_correct2<'a>(x: &dyn Foo<'a>) {
15+
let _ = x as &dyn Bar<'_, '_>;
16+
}
17+
1418
fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
1519
let _ = x as &dyn Bar<'static, 'a>; // Error
1620
//~^ ERROR lifetime may not live long enough

tests/ui/traits/trait-upcasting/type-checking-test-4.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
error: lifetime may not live long enough
2-
--> $DIR/type-checking-test-4.rs:15:13
2+
--> $DIR/type-checking-test-4.rs:19:13
33
|
44
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
55
| -- lifetime `'a` defined here
66
LL | let _ = x as &dyn Bar<'static, 'a>; // Error
77
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
88

99
error: lifetime may not live long enough
10-
--> $DIR/type-checking-test-4.rs:20:13
10+
--> $DIR/type-checking-test-4.rs:24:13
1111
|
1212
LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
1313
| -- lifetime `'a` defined here
1414
LL | let _ = x as &dyn Bar<'a, 'static>; // Error
1515
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
1616

1717
error: lifetime may not live long enough
18-
--> $DIR/type-checking-test-4.rs:26:5
18+
--> $DIR/type-checking-test-4.rs:30:5
1919
|
2020
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
2121
| -- lifetime `'a` defined here
@@ -24,23 +24,23 @@ LL | y.get_b() // ERROR
2424
| ^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
2525

2626
error: lifetime may not live long enough
27-
--> $DIR/type-checking-test-4.rs:31:5
27+
--> $DIR/type-checking-test-4.rs:35:5
2828
|
2929
LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
3030
| -- lifetime `'a` defined here
3131
LL | <_ as Bar>::get_b(x) // ERROR
3232
| ^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
3333

3434
error: lifetime may not live long enough
35-
--> $DIR/type-checking-test-4.rs:36:5
35+
--> $DIR/type-checking-test-4.rs:40:5
3636
|
3737
LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
3838
| -- lifetime `'a` defined here
3939
LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR
4040
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
4141

4242
error: lifetime may not live long enough
43-
--> $DIR/type-checking-test-4.rs:44:5
43+
--> $DIR/type-checking-test-4.rs:48:5
4444
|
4545
LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
4646
| -- lifetime `'a` defined here
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![feature(trait_upcasting, type_alias_impl_trait)]
2+
3+
type Tait = impl Sized;
4+
5+
trait Foo<'a>: Bar<'a, 'a, Tait> {}
6+
trait Bar<'a, 'b, T> {}
7+
8+
fn test_correct(x: &dyn Foo<'static>) {
9+
let _ = x as &dyn Bar<'static, 'static, Tait>;
10+
}
11+
12+
fn test_correct2<'a>(x: &dyn Foo<'a>) {
13+
let _ = x as &dyn Bar<'_, '_, Tait>;
14+
}
15+
16+
fn test_correct3<'a>(x: &dyn Foo<'a>, _: Tait) {
17+
let _ = x as &dyn Bar<'_, '_, ()>;
18+
//~^ ERROR: non-primitive cast
19+
}
20+
21+
fn main() {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0605]: non-primitive cast: `&dyn Foo<'a>` as `&dyn Bar<'_, '_, ()>`
2+
--> $DIR/type-checking-test-opaques.rs:17:13
3+
|
4+
LL | let _ = x as &dyn Bar<'_, '_, ()>;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
6+
7+
error: aborting due to 1 previous error
8+
9+
For more information about this error, try `rustc --explain E0605`.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error[E0277]: the trait bound `Foo: Trait<Bar>` is not satisfied
2+
--> $DIR/constrain_in_projection.rs:24:14
3+
|
4+
LL | let x = <Foo as Trait<Bar>>::Assoc::default();
5+
| ^^^ the trait `Trait<Bar>` is not implemented for `Foo`
6+
|
7+
= help: the trait `Trait<()>` is implemented for `Foo`
8+
9+
error: aborting due to 1 previous error
10+
11+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//! Check that projections will constrain opaque types while looking for
2+
//! matching impls.
3+
4+
//@ revisions: current next
5+
//@ ignore-compare-mode-next-solver (explicit revisions)
6+
//@[next] compile-flags: -Znext-solver
7+
//@[next]check-pass
8+
9+
#![feature(type_alias_impl_trait)]
10+
11+
struct Foo;
12+
13+
type Bar = impl Sized;
14+
15+
trait Trait<T> {
16+
type Assoc: Default;
17+
}
18+
19+
impl Trait<()> for Foo {
20+
type Assoc = u32;
21+
}
22+
23+
fn bop(_: Bar) {
24+
let x = <Foo as Trait<Bar>>::Assoc::default();
25+
//[current]~^ `Foo: Trait<Bar>` is not satisfied
26+
}
27+
28+
fn main() {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
error[E0277]: the trait bound `Foo: Trait<Bar>` is not satisfied
2+
--> $DIR/constrain_in_projection2.rs:27:14
3+
|
4+
LL | let x = <Foo as Trait<Bar>>::Assoc::default();
5+
| ^^^ the trait `Trait<Bar>` is not implemented for `Foo`
6+
|
7+
= help: the following other types implement trait `Trait<T>`:
8+
<Foo as Trait<()>>
9+
<Foo as Trait<u32>>
10+
11+
error: aborting due to 1 previous error
12+
13+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error[E0283]: type annotations needed: cannot satisfy `Foo: Trait<Bar>`
2+
--> $DIR/constrain_in_projection2.rs:27:14
3+
|
4+
LL | let x = <Foo as Trait<Bar>>::Assoc::default();
5+
| ^^^ help: use the fully qualified path to an implementation: `<Type as Trait>::Assoc`
6+
|
7+
note: multiple `impl`s satisfying `Foo: Trait<Bar>` found
8+
--> $DIR/constrain_in_projection2.rs:18:1
9+
|
10+
LL | impl Trait<()> for Foo {
11+
| ^^^^^^^^^^^^^^^^^^^^^^
12+
...
13+
LL | impl Trait<u32> for Foo {
14+
| ^^^^^^^^^^^^^^^^^^^^^^^
15+
= note: associated types cannot be accessed directly on a `trait`, they can only be accessed through a specific `impl`
16+
17+
error: aborting due to 1 previous error
18+
19+
For more information about this error, try `rustc --explain E0283`.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//! Check that projections will constrain opaque types while looking for
2+
//! matching impls and error if ambiguous.
3+
4+
//@ revisions: current next
5+
//@ ignore-compare-mode-next-solver (explicit revisions)
6+
//@[next] compile-flags: -Znext-solver
7+
8+
#![feature(type_alias_impl_trait)]
9+
10+
struct Foo;
11+
12+
type Bar = impl Sized;
13+
14+
trait Trait<T> {
15+
type Assoc: Default;
16+
}
17+
18+
impl Trait<()> for Foo {
19+
type Assoc = u32;
20+
}
21+
22+
impl Trait<u32> for Foo {
23+
type Assoc = u32;
24+
}
25+
26+
fn bop(_: Bar) {
27+
let x = <Foo as Trait<Bar>>::Assoc::default();
28+
//[next]~^ ERROR: cannot satisfy `Foo: Trait<Bar>`
29+
//[current]~^^ ERROR: `Foo: Trait<Bar>` is not satisfied
30+
}
31+
32+
fn main() {}

0 commit comments

Comments
 (0)