From 485111c48e79e2b41381ff6d4f3301a38b5a167d Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 29 Aug 2019 13:40:27 +0200 Subject: [PATCH] Add regression tests for issues --- .../associated-const/defaults-cyclic-pass.rs | 3 +- .../associated-types/defaults-cyclic-pass.rs | 21 +++++--------- .../defaults-in-other-trait-items-pass.rs | 22 ++++++++++++++ .../defaults-unsound-62211-1.rs | 3 ++ .../defaults-unsound-62211-1.stderr | 24 +++++++-------- .../defaults-unsound-62211-2.rs | 3 ++ .../defaults-unsound-62211-2.stderr | 24 +++++++-------- src/test/ui/associated-types/issue-32350.rs | 29 +++++++++++++++++++ src/test/ui/associated-types/issue-41868.rs | 23 +++++++++++++++ src/test/ui/associated-types/issue-43924.rs | 15 ++++++++++ .../ui/associated-types/issue-43924.stderr | 27 +++++++++++++++++ src/test/ui/associated-types/issue-47385.rs | 16 ++++++++++ src/test/ui/associated-types/issue-63593.rs | 11 +++++++ .../ui/associated-types/issue-63593.stderr | 23 +++++++++++++++ 14 files changed, 206 insertions(+), 38 deletions(-) create mode 100644 src/test/ui/associated-types/defaults-in-other-trait-items-pass.rs create mode 100644 src/test/ui/associated-types/issue-32350.rs create mode 100644 src/test/ui/associated-types/issue-41868.rs create mode 100644 src/test/ui/associated-types/issue-43924.rs create mode 100644 src/test/ui/associated-types/issue-43924.stderr create mode 100644 src/test/ui/associated-types/issue-47385.rs create mode 100644 src/test/ui/associated-types/issue-63593.rs create mode 100644 src/test/ui/associated-types/issue-63593.stderr diff --git a/src/test/ui/associated-const/defaults-cyclic-pass.rs b/src/test/ui/associated-const/defaults-cyclic-pass.rs index 1de733cfc37a..82105f25f924 100644 --- a/src/test/ui/associated-const/defaults-cyclic-pass.rs +++ b/src/test/ui/associated-const/defaults-cyclic-pass.rs @@ -6,7 +6,8 @@ trait Tr { const B: u8 = Self::A; } -// This impl is *allowed* unless its assoc. consts are used +// This impl is *allowed* unless its assoc. consts are used, matching the +// behavior without defaults. impl Tr for () {} // Overriding either constant breaks the cycle diff --git a/src/test/ui/associated-types/defaults-cyclic-pass.rs b/src/test/ui/associated-types/defaults-cyclic-pass.rs index 618a20385078..74a0cfa6b73a 100644 --- a/src/test/ui/associated-types/defaults-cyclic-pass.rs +++ b/src/test/ui/associated-types/defaults-cyclic-pass.rs @@ -2,21 +2,16 @@ #![feature(associated_type_defaults)] +// Having a cycle in assoc. type defaults is okay, as long as there's no impl +// that retains it. trait Tr { - type Item = u8; - type Container = Vec; + type A = Self::B; + type B = Self::A; } -impl Tr for () {} - -impl Tr for u16 { - type Item = u16; +// An impl has to break the cycle to be accepted. +impl Tr for u8 { + type A = u8; } -fn main() { - let _container: <() as Tr>::Container = Vec::::new(); - let _item: <() as Tr>::Item = 0u8; - - let _container: ::Container = Vec::::new(); - let _item: ::Item = 0u16; -} +fn main() {} diff --git a/src/test/ui/associated-types/defaults-in-other-trait-items-pass.rs b/src/test/ui/associated-types/defaults-in-other-trait-items-pass.rs new file mode 100644 index 000000000000..618a20385078 --- /dev/null +++ b/src/test/ui/associated-types/defaults-in-other-trait-items-pass.rs @@ -0,0 +1,22 @@ +// check-pass + +#![feature(associated_type_defaults)] + +trait Tr { + type Item = u8; + type Container = Vec; +} + +impl Tr for () {} + +impl Tr for u16 { + type Item = u16; +} + +fn main() { + let _container: <() as Tr>::Container = Vec::::new(); + let _item: <() as Tr>::Item = 0u8; + + let _container: ::Container = Vec::::new(); + let _item: ::Item = 0u16; +} diff --git a/src/test/ui/associated-types/defaults-unsound-62211-1.rs b/src/test/ui/associated-types/defaults-unsound-62211-1.rs index aa7beca00476..37d52ed16b61 100644 --- a/src/test/ui/associated-types/defaults-unsound-62211-1.rs +++ b/src/test/ui/associated-types/defaults-unsound-62211-1.rs @@ -3,6 +3,9 @@ //! The old implementation of defaults did not check whether the provided //! default actually fulfills all bounds on the assoc. type, leading to //! unsoundness, demonstrated here as a use-after-free. +//! +//! Note that the underlying cause of this is still not yet fixed. +//! See: https://github.com/rust-lang/rust/issues/33017 // compile-fail diff --git a/src/test/ui/associated-types/defaults-unsound-62211-1.stderr b/src/test/ui/associated-types/defaults-unsound-62211-1.stderr index 417edd873ec3..0cad08f67522 100644 --- a/src/test/ui/associated-types/defaults-unsound-62211-1.stderr +++ b/src/test/ui/associated-types/defaults-unsound-62211-1.stderr @@ -1,18 +1,18 @@ error[E0277]: the trait bound `Self: std::marker::Copy` is not satisfied - --> $DIR/defaults-unsound-62211-1.rs:20:18 + --> $DIR/defaults-unsound-62211-1.rs:23:18 | LL | type Output: Copy | ^^^^ the trait `std::marker::Copy` is not implemented for `Self` | = help: consider adding a `where Self: std::marker::Copy` bound note: required by `UncheckedCopy` - --> $DIR/defaults-unsound-62211-1.rs:17:1 + --> $DIR/defaults-unsound-62211-1.rs:20:1 | LL | trait UncheckedCopy: Sized { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: cannot add-assign `&'static str` to `Self` - --> $DIR/defaults-unsound-62211-1.rs:24:7 + --> $DIR/defaults-unsound-62211-1.rs:27:7 | LL | + AddAssign<&'static str> | ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Self += &'static str` @@ -20,26 +20,26 @@ LL | + AddAssign<&'static str> = help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `Self` = help: consider adding a `where Self: std::ops::AddAssign<&'static str>` bound note: required by `UncheckedCopy` - --> $DIR/defaults-unsound-62211-1.rs:17:1 + --> $DIR/defaults-unsound-62211-1.rs:20:1 | LL | trait UncheckedCopy: Sized { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Self: std::ops::Deref` is not satisfied - --> $DIR/defaults-unsound-62211-1.rs:22:7 + --> $DIR/defaults-unsound-62211-1.rs:25:7 | LL | + Deref | ^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `Self` | = help: consider adding a `where Self: std::ops::Deref` bound note: required by `UncheckedCopy` - --> $DIR/defaults-unsound-62211-1.rs:17:1 + --> $DIR/defaults-unsound-62211-1.rs:20:1 | LL | trait UncheckedCopy: Sized { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `Self` doesn't implement `std::fmt::Display` - --> $DIR/defaults-unsound-62211-1.rs:27:7 + --> $DIR/defaults-unsound-62211-1.rs:30:7 | LL | + Display = Self; | ^^^^^^^ `Self` cannot be formatted with the default formatter @@ -48,13 +48,13 @@ LL | + Display = Self; = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = help: consider adding a `where Self: std::fmt::Display` bound note: required by `UncheckedCopy` - --> $DIR/defaults-unsound-62211-1.rs:17:1 + --> $DIR/defaults-unsound-62211-1.rs:20:1 | LL | trait UncheckedCopy: Sized { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `T` doesn't implement `std::fmt::Display` - --> $DIR/defaults-unsound-62211-1.rs:40:9 + --> $DIR/defaults-unsound-62211-1.rs:43:9 | LL | impl UncheckedCopy for T {} | ^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter @@ -64,7 +64,7 @@ LL | impl UncheckedCopy for T {} = help: consider adding a `where T: std::fmt::Display` bound error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied - --> $DIR/defaults-unsound-62211-1.rs:40:9 + --> $DIR/defaults-unsound-62211-1.rs:43:9 | LL | impl UncheckedCopy for T {} | ^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `T` @@ -72,7 +72,7 @@ LL | impl UncheckedCopy for T {} = help: consider adding a `where T: std::ops::Deref` bound error[E0277]: cannot add-assign `&'static str` to `T` - --> $DIR/defaults-unsound-62211-1.rs:40:9 + --> $DIR/defaults-unsound-62211-1.rs:43:9 | LL | impl UncheckedCopy for T {} | ^^^^^^^^^^^^^ no implementation for `T += &'static str` @@ -81,7 +81,7 @@ LL | impl UncheckedCopy for T {} = help: consider adding a `where T: std::ops::AddAssign<&'static str>` bound error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/defaults-unsound-62211-1.rs:40:9 + --> $DIR/defaults-unsound-62211-1.rs:43:9 | LL | impl UncheckedCopy for T {} | ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` diff --git a/src/test/ui/associated-types/defaults-unsound-62211-2.rs b/src/test/ui/associated-types/defaults-unsound-62211-2.rs index ce12bd485875..d042a1478a3a 100644 --- a/src/test/ui/associated-types/defaults-unsound-62211-2.rs +++ b/src/test/ui/associated-types/defaults-unsound-62211-2.rs @@ -3,6 +3,9 @@ //! The old implementation of defaults did not check whether the provided //! default actually fulfills all bounds on the assoc. type, leading to //! unsoundness and ICEs, the latter being demonstrated here. +//! +//! Note that the underlying cause of this is still not yet fixed. +//! See: https://github.com/rust-lang/rust/issues/33017 // compile-fail diff --git a/src/test/ui/associated-types/defaults-unsound-62211-2.stderr b/src/test/ui/associated-types/defaults-unsound-62211-2.stderr index a1ce1f6db316..3a57f7df055f 100644 --- a/src/test/ui/associated-types/defaults-unsound-62211-2.stderr +++ b/src/test/ui/associated-types/defaults-unsound-62211-2.stderr @@ -1,18 +1,18 @@ error[E0277]: the trait bound `Self: std::marker::Copy` is not satisfied - --> $DIR/defaults-unsound-62211-2.rs:20:18 + --> $DIR/defaults-unsound-62211-2.rs:23:18 | LL | type Output: Copy | ^^^^ the trait `std::marker::Copy` is not implemented for `Self` | = help: consider adding a `where Self: std::marker::Copy` bound note: required by `UncheckedCopy` - --> $DIR/defaults-unsound-62211-2.rs:17:1 + --> $DIR/defaults-unsound-62211-2.rs:20:1 | LL | trait UncheckedCopy: Sized { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: cannot add-assign `&'static str` to `Self` - --> $DIR/defaults-unsound-62211-2.rs:24:7 + --> $DIR/defaults-unsound-62211-2.rs:27:7 | LL | + AddAssign<&'static str> | ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `Self += &'static str` @@ -20,26 +20,26 @@ LL | + AddAssign<&'static str> = help: the trait `std::ops::AddAssign<&'static str>` is not implemented for `Self` = help: consider adding a `where Self: std::ops::AddAssign<&'static str>` bound note: required by `UncheckedCopy` - --> $DIR/defaults-unsound-62211-2.rs:17:1 + --> $DIR/defaults-unsound-62211-2.rs:20:1 | LL | trait UncheckedCopy: Sized { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: the trait bound `Self: std::ops::Deref` is not satisfied - --> $DIR/defaults-unsound-62211-2.rs:22:7 + --> $DIR/defaults-unsound-62211-2.rs:25:7 | LL | + Deref | ^^^^^^^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `Self` | = help: consider adding a `where Self: std::ops::Deref` bound note: required by `UncheckedCopy` - --> $DIR/defaults-unsound-62211-2.rs:17:1 + --> $DIR/defaults-unsound-62211-2.rs:20:1 | LL | trait UncheckedCopy: Sized { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `Self` doesn't implement `std::fmt::Display` - --> $DIR/defaults-unsound-62211-2.rs:27:7 + --> $DIR/defaults-unsound-62211-2.rs:30:7 | LL | + Display = Self; | ^^^^^^^ `Self` cannot be formatted with the default formatter @@ -48,13 +48,13 @@ LL | + Display = Self; = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = help: consider adding a `where Self: std::fmt::Display` bound note: required by `UncheckedCopy` - --> $DIR/defaults-unsound-62211-2.rs:17:1 + --> $DIR/defaults-unsound-62211-2.rs:20:1 | LL | trait UncheckedCopy: Sized { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `T` doesn't implement `std::fmt::Display` - --> $DIR/defaults-unsound-62211-2.rs:40:9 + --> $DIR/defaults-unsound-62211-2.rs:43:9 | LL | impl UncheckedCopy for T {} | ^^^^^^^^^^^^^ `T` cannot be formatted with the default formatter @@ -64,7 +64,7 @@ LL | impl UncheckedCopy for T {} = help: consider adding a `where T: std::fmt::Display` bound error[E0277]: the trait bound `T: std::ops::Deref` is not satisfied - --> $DIR/defaults-unsound-62211-2.rs:40:9 + --> $DIR/defaults-unsound-62211-2.rs:43:9 | LL | impl UncheckedCopy for T {} | ^^^^^^^^^^^^^ the trait `std::ops::Deref` is not implemented for `T` @@ -72,7 +72,7 @@ LL | impl UncheckedCopy for T {} = help: consider adding a `where T: std::ops::Deref` bound error[E0277]: cannot add-assign `&'static str` to `T` - --> $DIR/defaults-unsound-62211-2.rs:40:9 + --> $DIR/defaults-unsound-62211-2.rs:43:9 | LL | impl UncheckedCopy for T {} | ^^^^^^^^^^^^^ no implementation for `T += &'static str` @@ -81,7 +81,7 @@ LL | impl UncheckedCopy for T {} = help: consider adding a `where T: std::ops::AddAssign<&'static str>` bound error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied - --> $DIR/defaults-unsound-62211-2.rs:40:9 + --> $DIR/defaults-unsound-62211-2.rs:43:9 | LL | impl UncheckedCopy for T {} | ^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` diff --git a/src/test/ui/associated-types/issue-32350.rs b/src/test/ui/associated-types/issue-32350.rs new file mode 100644 index 000000000000..bda21eb0e0ac --- /dev/null +++ b/src/test/ui/associated-types/issue-32350.rs @@ -0,0 +1,29 @@ +// check-pass + +// This is another instance of the "normalizations don't work" issue with +// defaulted associated types. + +#![feature(associated_type_defaults)] + +pub trait Emitter<'a> { + type Ctxt: 'a; + type CtxtBrw: 'a = &'a Self::Ctxt; + + fn get_cx(&'a self) -> Self::CtxtBrw; +} + +struct MyCtxt; + +struct MyEmitter { + ctxt: MyCtxt +} + +impl <'a> Emitter<'a> for MyEmitter { + type Ctxt = MyCtxt; + + fn get_cx(&'a self) -> &'a MyCtxt { + &self.ctxt + } +} + +fn main() {} diff --git a/src/test/ui/associated-types/issue-41868.rs b/src/test/ui/associated-types/issue-41868.rs new file mode 100644 index 000000000000..52bbd1f5d286 --- /dev/null +++ b/src/test/ui/associated-types/issue-41868.rs @@ -0,0 +1,23 @@ +// check-pass + +// Defaulted assoc. types should normalize properly in impls that don't +// override them. + +#![feature(associated_type_defaults)] + +pub struct Foo; + +pub trait CanDecode: Sized { + type Output = Self; + fn read(rdr: &mut Foo) -> Option; +} + +impl CanDecode for u8 { + fn read(rdr: &mut Foo) -> Option { Some(42) } +} + +impl CanDecode for u16 { + fn read(rdr: &mut Foo) -> Option { Some(17) } +} + +fn main() {} diff --git a/src/test/ui/associated-types/issue-43924.rs b/src/test/ui/associated-types/issue-43924.rs new file mode 100644 index 000000000000..26f1183c6bd7 --- /dev/null +++ b/src/test/ui/associated-types/issue-43924.rs @@ -0,0 +1,15 @@ +#![feature(associated_type_defaults)] + +// This used to cause an ICE because assoc. type defaults weren't properly +// type-checked. + +trait Foo { + type Out: Default + ToString + ?Sized = dyn ToString; //~ error: not satisfied +} + +impl Foo for () {} //~ error: not satisfied +impl Foo for () {} //~ error: not satisfied + +fn main() { + assert_eq!(<() as Foo>::Out::default().to_string(), "false"); +} diff --git a/src/test/ui/associated-types/issue-43924.stderr b/src/test/ui/associated-types/issue-43924.stderr new file mode 100644 index 000000000000..67a963b50135 --- /dev/null +++ b/src/test/ui/associated-types/issue-43924.stderr @@ -0,0 +1,27 @@ +error[E0277]: the trait bound `(dyn std::string::ToString + 'static): std::default::Default` is not satisfied + --> $DIR/issue-43924.rs:7:15 + | +LL | type Out: Default + ToString + ?Sized = dyn ToString; + | ^^^^^^^ the trait `std::default::Default` is not implemented for `(dyn std::string::ToString + 'static)` + | +note: required by `Foo` + --> $DIR/issue-43924.rs:6:1 + | +LL | trait Foo { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `(dyn std::string::ToString + 'static): std::default::Default` is not satisfied + --> $DIR/issue-43924.rs:10:6 + | +LL | impl Foo for () {} + | ^^^^^^^^ the trait `std::default::Default` is not implemented for `(dyn std::string::ToString + 'static)` + +error[E0277]: the trait bound `(dyn std::string::ToString + 'static): std::default::Default` is not satisfied + --> $DIR/issue-43924.rs:11:6 + | +LL | impl Foo for () {} + | ^^^^^^^^ the trait `std::default::Default` is not implemented for `(dyn std::string::ToString + 'static)` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/associated-types/issue-47385.rs b/src/test/ui/associated-types/issue-47385.rs new file mode 100644 index 000000000000..d43d674e9c3a --- /dev/null +++ b/src/test/ui/associated-types/issue-47385.rs @@ -0,0 +1,16 @@ +// check-pass + +#![feature(associated_type_defaults)] + +pub struct Foo; + +pub trait Bar: From<::Input> { + type Input = Self; +} + +impl Bar for Foo { + // Will compile with explicit type: + // type Input = Self; +} + +fn main() {} diff --git a/src/test/ui/associated-types/issue-63593.rs b/src/test/ui/associated-types/issue-63593.rs new file mode 100644 index 000000000000..1452467f3736 --- /dev/null +++ b/src/test/ui/associated-types/issue-63593.rs @@ -0,0 +1,11 @@ +#![feature(associated_type_defaults)] + +// Tests that `Self` is not assumed to implement `Sized` when used as an +// associated type default. + +trait Inner {} + +trait MyTrait { + type This = Self; //~ error: size for values of type `Self` cannot be known + fn something>(i: I); +} diff --git a/src/test/ui/associated-types/issue-63593.stderr b/src/test/ui/associated-types/issue-63593.stderr new file mode 100644 index 000000000000..ea462eac9b4d --- /dev/null +++ b/src/test/ui/associated-types/issue-63593.stderr @@ -0,0 +1,23 @@ +error[E0601]: `main` function not found in crate `issue_63593` + | + = note: consider adding a `main` function to `$DIR/issue-63593.rs` + +error[E0277]: the size for values of type `Self` cannot be known at compilation time + --> $DIR/issue-63593.rs:9:5 + | +LL | type This = Self; + | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `std::marker::Sized` is not implemented for `Self` + = note: to learn more, visit + = help: consider adding a `where Self: std::marker::Sized` bound +note: required by `MyTrait` + --> $DIR/issue-63593.rs:8:1 + | +LL | trait MyTrait { + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0277, E0601. +For more information about an error, try `rustc --explain E0277`.