From dc0db358abe19481e475e10c32149b53370f1a1c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 05:57:31 +0200 Subject: Merging upstream version 1.72.1+dfsg1. Signed-off-by: Daniel Baumann --- ...st-default-bound-non-const-specialized-bound.rs | 58 ++++++++++++++++++++++ ...efault-bound-non-const-specialized-bound.stderr | 18 +++++++ .../const-default-const-specialized.rs | 39 +++++++++++++++ ...onst-default-impl-non-const-specialized-impl.rs | 26 ++++++++++ ...-default-impl-non-const-specialized-impl.stderr | 8 +++ .../specialization/default-keyword.rs | 15 ++++++ .../issue-95186-specialize-on-tilde-const.rs | 49 ++++++++++++++++++ ...e-95187-same-trait-bound-different-constness.rs | 57 +++++++++++++++++++++ .../non-const-default-const-specialized.rs | 39 +++++++++++++++ 9 files changed, 309 insertions(+) create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs (limited to 'tests/ui/rfcs/rfc-2632-const-trait-impl/specialization') diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs new file mode 100644 index 000000000..f31123f16 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.rs @@ -0,0 +1,58 @@ +// Tests that trait bounds on specializing trait impls must be `~const` if the +// same bound is present on the default impl and is `~const` there. + +#![feature(const_trait_impl)] +#![feature(rustc_attrs)] +#![feature(min_specialization)] + +#[rustc_specialization_trait] +trait Specialize {} + +#[const_trait] +trait Foo {} + +#[const_trait] +trait Bar { + fn bar(); +} + +// bgr360: I was only able to exercise the code path that raises the +// "missing ~const qualifier" error by making this base impl non-const, even +// though that doesn't really make sense to do. As seen below, if the base impl +// is made const, rustc fails earlier with an overlapping impl failure. +impl Bar for T +where + T: ~const Foo, +{ + default fn bar() {} +} + +impl Bar for T +where + T: Foo, //~ ERROR missing `~const` qualifier + T: Specialize, +{ + fn bar() {} +} + +#[const_trait] +trait Baz { + fn baz(); +} + +impl const Baz for T +where + T: ~const Foo, +{ + default fn baz() {} +} + +impl const Baz for T //~ ERROR conflicting implementations of trait `Baz` +where + T: Foo, + T: Specialize, +{ + fn baz() {} +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr new file mode 100644 index 000000000..057cf4aea --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-bound-non-const-specialized-bound.stderr @@ -0,0 +1,18 @@ +error: missing `~const` qualifier for specialization + --> $DIR/const-default-bound-non-const-specialized-bound.rs:32:8 + | +LL | T: Foo, + | ^^^ + +error[E0119]: conflicting implementations of trait `Baz` + --> $DIR/const-default-bound-non-const-specialized-bound.rs:50:1 + | +LL | impl const Baz for T + | ----------------------- first implementation here +... +LL | impl const Baz for T + | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs new file mode 100644 index 000000000..9ddea427c --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-const-specialized.rs @@ -0,0 +1,39 @@ +// Tests that a const default trait impl can be specialized by another const +// trait impl and that the specializing impl will be used during const-eval. + +// run-pass + +#![feature(const_trait_impl)] +#![feature(min_specialization)] + +#[const_trait] +trait Value { + fn value() -> u32; +} + +const fn get_value() -> u32 { + T::value() +} + +impl const Value for T { + default fn value() -> u32 { + 0 + } +} + +struct FortyTwo; + +impl const Value for FortyTwo { + fn value() -> u32 { + 42 + } +} + +const ZERO: u32 = get_value::<()>(); + +const FORTY_TWO: u32 = get_value::(); + +fn main() { + assert_eq!(ZERO, 0); + assert_eq!(FORTY_TWO, 42); +} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs new file mode 100644 index 000000000..a3bb9b3f9 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.rs @@ -0,0 +1,26 @@ +// Tests that specializing trait impls must be at least as const as the default impl. + +#![feature(const_trait_impl)] +#![feature(min_specialization)] + +#[const_trait] +trait Value { + fn value() -> u32; +} + +impl const Value for T { + default fn value() -> u32 { + 0 + } +} + +struct FortyTwo; + +impl Value for FortyTwo { //~ ERROR cannot specialize on const impl with non-const impl + fn value() -> u32 { + println!("You can't do that (constly)"); + 42 + } +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr new file mode 100644 index 000000000..247668047 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/const-default-impl-non-const-specialized-impl.stderr @@ -0,0 +1,8 @@ +error: cannot specialize on const impl with non-const impl + --> $DIR/const-default-impl-non-const-specialized-impl.rs:19:1 + | +LL | impl Value for FortyTwo { + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs new file mode 100644 index 000000000..2aac0a2b4 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/default-keyword.rs @@ -0,0 +1,15 @@ +// check-pass + +#![feature(const_trait_impl)] +#![feature(min_specialization)] + +#[const_trait] +trait Foo { + fn foo(); +} + +impl const Foo for u32 { + default fn foo() {} +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs new file mode 100644 index 000000000..92d8be6bb --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95186-specialize-on-tilde-const.rs @@ -0,0 +1,49 @@ +// Tests that `~const` trait bounds can be used to specialize const trait impls. + +// check-pass + +#![feature(const_trait_impl)] +#![feature(rustc_attrs)] +#![feature(min_specialization)] + +#[const_trait] +#[rustc_specialization_trait] +trait Specialize {} + +#[const_trait] +trait Foo { + fn foo(); +} + +impl const Foo for T { + default fn foo() {} +} + +impl const Foo for T +where + T: ~const Specialize, +{ + fn foo() {} +} + +#[const_trait] +trait Bar { + fn bar() {} +} + +impl const Bar for T +where + T: ~const Foo, +{ + default fn bar() {} +} + +impl const Bar for T +where + T: ~const Foo, + T: ~const Specialize, +{ + fn bar() {} +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs new file mode 100644 index 000000000..51bfaf73b --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/issue-95187-same-trait-bound-different-constness.rs @@ -0,0 +1,57 @@ +// Tests that `T: ~const Foo` in a specializing impl is treated as equivalent to +// `T: Foo` in the default impl for the purposes of specialization (i.e., it +// does not think that the user is attempting to specialize on trait `Foo`). + +// check-pass + +#![feature(rustc_attrs)] +#![feature(min_specialization)] +#![feature(const_trait_impl)] + +#[rustc_specialization_trait] +trait Specialize {} + +#[const_trait] +trait Foo {} + +#[const_trait] +trait Bar { + fn bar(); +} + +impl Bar for T +where + T: Foo, +{ + default fn bar() {} +} + +impl const Bar for T +where + T: ~const Foo, + T: Specialize, +{ + fn bar() {} +} + +#[const_trait] +trait Baz { + fn baz(); +} + +impl const Baz for T +where + T: Foo, +{ + default fn baz() {} +} + +impl const Baz for T +where + T: ~const Foo, + T: Specialize, +{ + fn baz() {} +} + +fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs new file mode 100644 index 000000000..35aa52fbd --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specialization/non-const-default-const-specialized.rs @@ -0,0 +1,39 @@ +// Tests that a non-const default impl can be specialized by a const trait impl, +// but that the default impl cannot be used in a const context. + +// run-pass + +#![feature(const_trait_impl)] +#![feature(min_specialization)] + +#[const_trait] +trait Value { + fn value() -> u32; +} + +const fn get_value() -> u32 { + T::value() +} + +impl Value for T { + default fn value() -> u32 { + println!("You can't do that (constly)"); + 0 + } +} + +struct FortyTwo; + +impl const Value for FortyTwo { + fn value() -> u32 { + 42 + } +} + +fn main() { + let zero = get_value::<()>(); + assert_eq!(zero, 0); + + const FORTY_TWO: u32 = get_value::(); + assert_eq!(FORTY_TWO, 42); +} -- cgit v1.2.3