Skip to content

Commit 485111c

Browse files
Add regression tests for issues
1 parent fead458 commit 485111c

14 files changed

+206
-38
lines changed

src/test/ui/associated-const/defaults-cyclic-pass.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ trait Tr {
66
const B: u8 = Self::A;
77
}
88

9-
// This impl is *allowed* unless its assoc. consts are used
9+
// This impl is *allowed* unless its assoc. consts are used, matching the
10+
// behavior without defaults.
1011
impl Tr for () {}
1112

1213
// Overriding either constant breaks the cycle

src/test/ui/associated-types/defaults-cyclic-pass.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,16 @@
22

33
#![feature(associated_type_defaults)]
44

5+
// Having a cycle in assoc. type defaults is okay, as long as there's no impl
6+
// that retains it.
57
trait Tr {
6-
type Item = u8;
7-
type Container = Vec<Self::Item>;
8+
type A = Self::B;
9+
type B = Self::A;
810
}
911

10-
impl Tr for () {}
11-
12-
impl Tr for u16 {
13-
type Item = u16;
12+
// An impl has to break the cycle to be accepted.
13+
impl Tr for u8 {
14+
type A = u8;
1415
}
1516

16-
fn main() {
17-
let _container: <() as Tr>::Container = Vec::<u8>::new();
18-
let _item: <() as Tr>::Item = 0u8;
19-
20-
let _container: <u16 as Tr>::Container = Vec::<u16>::new();
21-
let _item: <u16 as Tr>::Item = 0u16;
22-
}
17+
fn main() {}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// check-pass
2+
3+
#![feature(associated_type_defaults)]
4+
5+
trait Tr {
6+
type Item = u8;
7+
type Container = Vec<Self::Item>;
8+
}
9+
10+
impl Tr for () {}
11+
12+
impl Tr for u16 {
13+
type Item = u16;
14+
}
15+
16+
fn main() {
17+
let _container: <() as Tr>::Container = Vec::<u8>::new();
18+
let _item: <() as Tr>::Item = 0u8;
19+
20+
let _container: <u16 as Tr>::Container = Vec::<u16>::new();
21+
let _item: <u16 as Tr>::Item = 0u16;
22+
}

src/test/ui/associated-types/defaults-unsound-62211-1.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
//! The old implementation of defaults did not check whether the provided
44
//! default actually fulfills all bounds on the assoc. type, leading to
55
//! unsoundness, demonstrated here as a use-after-free.
6+
//!
7+
//! Note that the underlying cause of this is still not yet fixed.
8+
//! See: https://github.com/rust-lang/rust/issues/33017
69
710
// compile-fail
811

src/test/ui/associated-types/defaults-unsound-62211-1.stderr

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
11
error[E0277]: the trait bound `Self: std::marker::Copy` is not satisfied
2-
--> $DIR/defaults-unsound-62211-1.rs:20:18
2+
--> $DIR/defaults-unsound-62211-1.rs:23:18
33
|
44
LL | type Output: Copy
55
| ^^^^ the trait `std::marker::Copy` is not implemented for `Self`
66
|
77
= help: consider adding a `where Self: std::marker::Copy` bound
88
note: required by `UncheckedCopy`
9-
--> $DIR/defaults-unsound-62211-1.rs:17:1
9+
--> $DIR/defaults-unsound-62211-1.rs:20:1
1010
|
1111
LL | trait UncheckedCopy: Sized {
1212
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
1313

1414
error[E0277]: cannot add-assign `&'static str` to `Self`
15-
--> $DIR/defaults-unsound-62211-1.rs:24:7
15+
--> $DIR/defaults-unsound-62211-1.rs:27:7
1616
|
1717
LL | + AddAssign<&'static str>
1818
| ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Self += &'static str`
1919
|
2020
= help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `Self`
2121
= help: consider adding a `where Self: std::ops::AddAssign<&'static str>` bound
2222
note: required by `UncheckedCopy`
23-
--> $DIR/defaults-unsound-62211-1.rs:17:1
23+
--> $DIR/defaults-unsound-62211-1.rs:20:1
2424
|
2525
LL | trait UncheckedCopy: Sized {
2626
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
2727

2828
error[E0277]: the trait bound `Self: std::ops::Deref` is not satisfied
29-
--> $DIR/defaults-unsound-62211-1.rs:22:7
29+
--> $DIR/defaults-unsound-62211-1.rs:25:7
3030
|
3131
LL | + Deref<Target = str>
3232
| ^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `Self`
3333
|
3434
= help: consider adding a `where Self: std::ops::Deref` bound
3535
note: required by `UncheckedCopy`
36-
--> $DIR/defaults-unsound-62211-1.rs:17:1
36+
--> $DIR/defaults-unsound-62211-1.rs:20:1
3737
|
3838
LL | trait UncheckedCopy: Sized {
3939
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
4040

4141
error[E0277]: `Self` doesn't implement `std::fmt::Display`
42-
--> $DIR/defaults-unsound-62211-1.rs:27:7
42+
--> $DIR/defaults-unsound-62211-1.rs:30:7
4343
|
4444
LL | + Display = Self;
4545
| ^^^^^^^ `Self` cannot be formatted with the default formatter
@@ -48,13 +48,13 @@ LL | + Display = Self;
4848
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
4949
= help: consider adding a `where Self: std::fmt::Display` bound
5050
note: required by `UncheckedCopy`
51-
--> $DIR/defaults-unsound-62211-1.rs:17:1
51+
--> $DIR/defaults-unsound-62211-1.rs:20:1
5252
|
5353
LL | trait UncheckedCopy: Sized {
5454
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
5555

5656
error[E0277]: `T` doesn't implement `std::fmt::Display`
57-
--> $DIR/defaults-unsound-62211-1.rs:40:9
57+
--> $DIR/defaults-unsound-62211-1.rs:43:9
5858
|
5959
LL | impl<T> UncheckedCopy for T {}
6060
| ^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter
@@ -64,15 +64,15 @@ LL | impl<T> UncheckedCopy for T {}
6464
= help: consider adding a `where T: std::fmt::Display` bound
6565

6666
error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied
67-
--> $DIR/defaults-unsound-62211-1.rs:40:9
67+
--> $DIR/defaults-unsound-62211-1.rs:43:9
6868
|
6969
LL | impl<T> UncheckedCopy for T {}
7070
| ^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `T`
7171
|
7272
= help: consider adding a `where T: std::ops::Deref` bound
7373

7474
error[E0277]: cannot add-assign `&'static str` to `T`
75-
--> $DIR/defaults-unsound-62211-1.rs:40:9
75+
--> $DIR/defaults-unsound-62211-1.rs:43:9
7676
|
7777
LL | impl<T> UncheckedCopy for T {}
7878
| ^^^^^^^^^^^^^ no implementation for `T += &'static str`
@@ -81,7 +81,7 @@ LL | impl<T> UncheckedCopy for T {}
8181
= help: consider adding a `where T: std::ops::AddAssign<&'static str>` bound
8282

8383
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
84-
--> $DIR/defaults-unsound-62211-1.rs:40:9
84+
--> $DIR/defaults-unsound-62211-1.rs:43:9
8585
|
8686
LL | impl<T> UncheckedCopy for T {}
8787
| ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`

src/test/ui/associated-types/defaults-unsound-62211-2.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
//! The old implementation of defaults did not check whether the provided
44
//! default actually fulfills all bounds on the assoc. type, leading to
55
//! unsoundness and ICEs, the latter being demonstrated here.
6+
//!
7+
//! Note that the underlying cause of this is still not yet fixed.
8+
//! See: https://github.com/rust-lang/rust/issues/33017
69
710
// compile-fail
811

src/test/ui/associated-types/defaults-unsound-62211-2.stderr

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
11
error[E0277]: the trait bound `Self: std::marker::Copy` is not satisfied
2-
--> $DIR/defaults-unsound-62211-2.rs:20:18
2+
--> $DIR/defaults-unsound-62211-2.rs:23:18
33
|
44
LL | type Output: Copy
55
| ^^^^ the trait `std::marker::Copy` is not implemented for `Self`
66
|
77
= help: consider adding a `where Self: std::marker::Copy` bound
88
note: required by `UncheckedCopy`
9-
--> $DIR/defaults-unsound-62211-2.rs:17:1
9+
--> $DIR/defaults-unsound-62211-2.rs:20:1
1010
|
1111
LL | trait UncheckedCopy: Sized {
1212
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
1313

1414
error[E0277]: cannot add-assign `&'static str` to `Self`
15-
--> $DIR/defaults-unsound-62211-2.rs:24:7
15+
--> $DIR/defaults-unsound-62211-2.rs:27:7
1616
|
1717
LL | + AddAssign<&'static str>
1818
| ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Self += &'static str`
1919
|
2020
= help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `Self`
2121
= help: consider adding a `where Self: std::ops::AddAssign<&'static str>` bound
2222
note: required by `UncheckedCopy`
23-
--> $DIR/defaults-unsound-62211-2.rs:17:1
23+
--> $DIR/defaults-unsound-62211-2.rs:20:1
2424
|
2525
LL | trait UncheckedCopy: Sized {
2626
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
2727

2828
error[E0277]: the trait bound `Self: std::ops::Deref` is not satisfied
29-
--> $DIR/defaults-unsound-62211-2.rs:22:7
29+
--> $DIR/defaults-unsound-62211-2.rs:25:7
3030
|
3131
LL | + Deref<Target = str>
3232
| ^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `Self`
3333
|
3434
= help: consider adding a `where Self: std::ops::Deref` bound
3535
note: required by `UncheckedCopy`
36-
--> $DIR/defaults-unsound-62211-2.rs:17:1
36+
--> $DIR/defaults-unsound-62211-2.rs:20:1
3737
|
3838
LL | trait UncheckedCopy: Sized {
3939
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
4040

4141
error[E0277]: `Self` doesn't implement `std::fmt::Display`
42-
--> $DIR/defaults-unsound-62211-2.rs:27:7
42+
--> $DIR/defaults-unsound-62211-2.rs:30:7
4343
|
4444
LL | + Display = Self;
4545
| ^^^^^^^ `Self` cannot be formatted with the default formatter
@@ -48,13 +48,13 @@ LL | + Display = Self;
4848
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
4949
= help: consider adding a `where Self: std::fmt::Display` bound
5050
note: required by `UncheckedCopy`
51-
--> $DIR/defaults-unsound-62211-2.rs:17:1
51+
--> $DIR/defaults-unsound-62211-2.rs:20:1
5252
|
5353
LL | trait UncheckedCopy: Sized {
5454
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
5555

5656
error[E0277]: `T` doesn't implement `std::fmt::Display`
57-
--> $DIR/defaults-unsound-62211-2.rs:40:9
57+
--> $DIR/defaults-unsound-62211-2.rs:43:9
5858
|
5959
LL | impl<T> UncheckedCopy for T {}
6060
| ^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter
@@ -64,15 +64,15 @@ LL | impl<T> UncheckedCopy for T {}
6464
= help: consider adding a `where T: std::fmt::Display` bound
6565

6666
error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied
67-
--> $DIR/defaults-unsound-62211-2.rs:40:9
67+
--> $DIR/defaults-unsound-62211-2.rs:43:9
6868
|
6969
LL | impl<T> UncheckedCopy for T {}
7070
| ^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `T`
7171
|
7272
= help: consider adding a `where T: std::ops::Deref` bound
7373

7474
error[E0277]: cannot add-assign `&'static str` to `T`
75-
--> $DIR/defaults-unsound-62211-2.rs:40:9
75+
--> $DIR/defaults-unsound-62211-2.rs:43:9
7676
|
7777
LL | impl<T> UncheckedCopy for T {}
7878
| ^^^^^^^^^^^^^ no implementation for `T += &'static str`
@@ -81,7 +81,7 @@ LL | impl<T> UncheckedCopy for T {}
8181
= help: consider adding a `where T: std::ops::AddAssign<&'static str>` bound
8282

8383
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
84-
--> $DIR/defaults-unsound-62211-2.rs:40:9
84+
--> $DIR/defaults-unsound-62211-2.rs:43:9
8585
|
8686
LL | impl<T> UncheckedCopy for T {}
8787
| ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// check-pass
2+
3+
// This is another instance of the "normalizations don't work" issue with
4+
// defaulted associated types.
5+
6+
#![feature(associated_type_defaults)]
7+
8+
pub trait Emitter<'a> {
9+
type Ctxt: 'a;
10+
type CtxtBrw: 'a = &'a Self::Ctxt;
11+
12+
fn get_cx(&'a self) -> Self::CtxtBrw;
13+
}
14+
15+
struct MyCtxt;
16+
17+
struct MyEmitter {
18+
ctxt: MyCtxt
19+
}
20+
21+
impl <'a> Emitter<'a> for MyEmitter {
22+
type Ctxt = MyCtxt;
23+
24+
fn get_cx(&'a self) -> &'a MyCtxt {
25+
&self.ctxt
26+
}
27+
}
28+
29+
fn main() {}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// check-pass
2+
3+
// Defaulted assoc. types should normalize properly in impls that don't
4+
// override them.
5+
6+
#![feature(associated_type_defaults)]
7+
8+
pub struct Foo;
9+
10+
pub trait CanDecode: Sized {
11+
type Output = Self;
12+
fn read(rdr: &mut Foo) -> Option<Self::Output>;
13+
}
14+
15+
impl CanDecode for u8 {
16+
fn read(rdr: &mut Foo) -> Option<Self::Output> { Some(42) }
17+
}
18+
19+
impl CanDecode for u16 {
20+
fn read(rdr: &mut Foo) -> Option<u16> { Some(17) }
21+
}
22+
23+
fn main() {}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(associated_type_defaults)]
2+
3+
// This used to cause an ICE because assoc. type defaults weren't properly
4+
// type-checked.
5+
6+
trait Foo<T: Default + ToString> {
7+
type Out: Default + ToString + ?Sized = dyn ToString; //~ error: not satisfied
8+
}
9+
10+
impl Foo<u32> for () {} //~ error: not satisfied
11+
impl Foo<u64> for () {} //~ error: not satisfied
12+
13+
fn main() {
14+
assert_eq!(<() as Foo<u32>>::Out::default().to_string(), "false");
15+
}

0 commit comments

Comments
 (0)