From e4f237d39eed56803540eb57bc6297ad07488a58 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 19 Dec 2023 04:28:21 +0000 Subject: [PATCH 1/4] bless ui tests --- .../auxiliary/closure-in-foreign-crate.rs | 2 +- tests/ui/consts/const-float-classify.rs | 29 +++-------- tests/ui/consts/const-float-classify.stderr | 11 ----- tests/ui/consts/const-try.stderr | 2 + tests/ui/consts/const_cmp_type_id.rs | 2 +- tests/ui/consts/const_cmp_type_id.stderr | 38 +++++++-------- ...constifconst-call-in-const-position.stderr | 2 + .../ui/consts/issue-73976-monomorphic.stderr | 1 + tests/ui/consts/issue-94675.stderr | 1 + .../const-trait-impl.stderr | 1 + .../call-const-trait-method-pass.stderr | 2 + .../ui/rfcs/rfc-2632-const-trait-impl/call.rs | 2 +- ...ross-crate-default-method-body-is-const.rs | 2 +- ...nst_closure-const_trait_impl-ice-113381.rs | 4 +- ...closure-const_trait_impl-ice-113381.stderr | 11 ----- .../generic-bound.stderr | 1 + .../issue-102985.stderr | 2 + .../rfc-2632-const-trait-impl/issue-79450.rs | 2 +- .../issue-88155.stderr | 1 + .../match-non-const-eq.gated.stderr | 1 + ...st-op-const-closure-non-const-outer.stderr | 1 + .../specializing-constness-2.rs | 2 +- .../specializing-constness-2.stderr | 15 +++--- .../super-traits-fail-2.nn.stderr | 8 ++-- .../super-traits-fail-2.ny.stderr | 4 +- .../super-traits-fail-2.rs | 11 +++-- .../super-traits-fail-2.yn.stderr | 16 +++++-- .../super-traits-fail-2.yy.stderr | 11 +++-- .../super-traits-fail-3.nn.stderr | 10 ++-- .../super-traits-fail-3.ny.stderr | 4 +- .../super-traits-fail-3.rs | 5 +- .../super-traits-fail-3.yn.stderr | 6 +-- .../super-traits-fail-3.yy.stderr | 11 ----- .../trait-default-body-stability.rs | 2 +- .../trait-default-body-stability.stderr | 48 +++++++++++-------- 35 files changed, 127 insertions(+), 144 deletions(-) delete mode 100644 tests/ui/consts/const-float-classify.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.stderr delete mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr diff --git a/tests/ui/consts/auxiliary/closure-in-foreign-crate.rs b/tests/ui/consts/auxiliary/closure-in-foreign-crate.rs index edc7fa81abb4f..411707133a889 100644 --- a/tests/ui/consts/auxiliary/closure-in-foreign-crate.rs +++ b/tests/ui/consts/auxiliary/closure-in-foreign-crate.rs @@ -1,5 +1,5 @@ #![crate_type = "lib"] -#![feature(const_closures, const_trait_impl)] +#![feature(const_closures, const_trait_impl, effects)] #![allow(incomplete_features)] pub const fn test() { diff --git a/tests/ui/consts/const-float-classify.rs b/tests/ui/consts/const-float-classify.rs index 877ce02193c76..e8bd095ed25f7 100644 --- a/tests/ui/consts/const-float-classify.rs +++ b/tests/ui/consts/const-float-classify.rs @@ -1,41 +1,24 @@ // compile-flags: -Zmir-opt-level=0 -// known-bug: #110395 -// FIXME run-pass +// run-pass #![feature(const_float_bits_conv)] #![feature(const_float_classify)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] // Don't promote const fn nop(x: T) -> T { x } -// FIXME(const-hack): replace with PartialEq -#[const_trait] -trait MyEq { - fn eq(self, b: T) -> bool; -} - -impl const MyEq for bool { - fn eq(self, b: bool) -> bool { - self == b - } -} - -impl const MyEq for bool { - fn eq(self, _: NonDet) -> bool { +impl const PartialEq for bool { + fn eq(&self, _: &NonDet) -> bool { true } } -const fn eq, B>(x: A, y: B) -> bool { - x.eq(y) -} - macro_rules! const_assert { ($a:expr, $b:expr) => { { - const _: () = assert!(eq($a, $b)); - assert!(eq(nop($a), nop($b))); + const _: () = assert!($a == $b); + assert!(nop($a) == nop($b)); } }; } diff --git a/tests/ui/consts/const-float-classify.stderr b/tests/ui/consts/const-float-classify.stderr deleted file mode 100644 index f0c6c69eac4e6..0000000000000 --- a/tests/ui/consts/const-float-classify.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0015]: cannot call non-const fn `>::eq` in constant functions - --> $DIR/const-float-classify.rs:31:7 - | -LL | x.eq(y) - | ^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-try.stderr b/tests/ui/consts/const-try.stderr index 94f4153a29e7b..37a6598af9e6e 100644 --- a/tests/ui/consts/const-try.stderr +++ b/tests/ui/consts/const-try.stderr @@ -10,6 +10,7 @@ note: impl defined here, but it is not `const` LL | impl const Try for TryMe { | ^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error[E0015]: `?` cannot convert from residual of `TryMe` in constant functions --> $DIR/const-try.rs:33:5 @@ -23,6 +24,7 @@ note: impl defined here, but it is not `const` LL | impl const FromResidual for TryMe { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const_cmp_type_id.rs b/tests/ui/consts/const_cmp_type_id.rs index 19cee2022ac07..cda811144c76d 100644 --- a/tests/ui/consts/const_cmp_type_id.rs +++ b/tests/ui/consts/const_cmp_type_id.rs @@ -1,6 +1,6 @@ // known-bug: #110395 #![feature(const_type_id)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] use std::any::TypeId; diff --git a/tests/ui/consts/const_cmp_type_id.stderr b/tests/ui/consts/const_cmp_type_id.stderr index 0d915cec07deb..84be0b67307d8 100644 --- a/tests/ui/consts/const_cmp_type_id.stderr +++ b/tests/ui/consts/const_cmp_type_id.stderr @@ -1,34 +1,28 @@ -error[E0015]: cannot call non-const operator in constant functions +error[E0131]: `main` function is not allowed to have generic parameters + --> $DIR/const_cmp_type_id.rs:7:14 + | +LL | const fn main() { + | ^ `main` cannot have generic parameters + +error[E0308]: mismatched types --> $DIR/const_cmp_type_id.rs:8:13 | LL | assert!(TypeId::of::() == TypeId::of::()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `host`, found `true` | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/any.rs:LL:COL - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: expected constant `host` + found constant `true` -error[E0015]: cannot call non-const operator in constant functions +error[E0308]: mismatched types --> $DIR/const_cmp_type_id.rs:9:13 | LL | assert!(TypeId::of::<()>() != TypeId::of::()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/any.rs:LL:COL - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error[E0015]: cannot call non-const operator in constants - --> $DIR/const_cmp_type_id.rs:10:22 - | -LL | const _A: bool = TypeId::of::() < TypeId::of::(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `host`, found `true` | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/any.rs:LL:COL - = note: calls in constants are limited to constant functions, tuple structs and tuple variants - = note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: expected constant `host` + found constant `true` error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0131, E0308. +For more information about an error, try `rustc --explain E0131`. diff --git a/tests/ui/consts/constifconst-call-in-const-position.stderr b/tests/ui/consts/constifconst-call-in-const-position.stderr index 6eee466611c28..42ad412582484 100644 --- a/tests/ui/consts/constifconst-call-in-const-position.stderr +++ b/tests/ui/consts/constifconst-call-in-const-position.stderr @@ -14,6 +14,7 @@ LL | [0; T::a()] | ^^^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error[E0015]: cannot call non-const fn `::a` in constants --> $DIR/constifconst-call-in-const-position.rs:16:38 @@ -22,6 +23,7 @@ LL | const fn foo() -> [u8; T::a()] { | ^^^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/consts/issue-73976-monomorphic.stderr b/tests/ui/consts/issue-73976-monomorphic.stderr index ef754b23ff06e..465efc7bfc249 100644 --- a/tests/ui/consts/issue-73976-monomorphic.stderr +++ b/tests/ui/consts/issue-73976-monomorphic.stderr @@ -7,6 +7,7 @@ LL | GetTypeId::::VALUE == GetTypeId::::VALUE note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/any.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error: aborting due to 1 previous error diff --git a/tests/ui/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr index f51f305ac381b..60a56f85c11fd 100644 --- a/tests/ui/consts/issue-94675.stderr +++ b/tests/ui/consts/issue-94675.stderr @@ -15,6 +15,7 @@ LL | self.bar[0] = baz.len(); note: impl defined here, but it is not `const` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/tests/ui/generic-const-items/const-trait-impl.stderr b/tests/ui/generic-const-items/const-trait-impl.stderr index e7e905427960b..cdcd24eceffe5 100644 --- a/tests/ui/generic-const-items/const-trait-impl.stderr +++ b/tests/ui/generic-const-items/const-trait-impl.stderr @@ -5,6 +5,7 @@ LL | const CREATE: T = T::create(); | ^^^^^^^^^^^ | = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr index 60cd000f2d8c4..e72d259e8a561 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call-const-trait-method-pass.stderr @@ -5,6 +5,7 @@ LL | a.plus(b) | ^^^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error[E0015]: cannot call non-const operator in constants --> $DIR/call-const-trait-method-pass.rs:39:22 @@ -18,6 +19,7 @@ note: impl defined here, but it is not `const` LL | impl const std::ops::Add for Int { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs index 5f48c23537352..e85976b7e1dc9 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/call.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(const_closures, const_trait_impl)] +#![feature(const_closures, const_trait_impl, effects)] #![allow(incomplete_features)] pub const _: () = { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs index bde8bf20f46c5..34a0ba1e271e5 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs @@ -3,7 +3,7 @@ // // check-pass -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] // aux-build: cross-crate.rs extern crate cross_crate; diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs index 6598d1da0f866..7d811a2cc1f35 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.rs @@ -1,3 +1,5 @@ +// check-pass +// FIXME(effects) this shouldn't pass #![feature(const_closures, const_trait_impl, effects)] #![allow(incomplete_features)] @@ -11,5 +13,5 @@ impl Foo for () { fn main() { (const || { (()).foo() })(); - //~^ ERROR: cannot call non-const fn + // FIXME(effects) ~^ ERROR: cannot call non-const fn } diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.stderr deleted file mode 100644 index 413e217020d4a..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/const_closure-const_trait_impl-ice-113381.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0015]: cannot call non-const fn `<() as Foo>::foo` in constant functions - --> $DIR/const_closure-const_trait_impl-ice-113381.rs:13:22 - | -LL | (const || { (()).foo() })(); - | ^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr index 1e8a70ffd2914..f42fee59bf092 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/generic-bound.stderr @@ -10,6 +10,7 @@ note: impl defined here, but it is not `const` LL | impl const std::ops::Add for S { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.stderr index 077f6c7b2348a..0fa4c8fe04c1a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-102985.stderr @@ -4,7 +4,9 @@ error[E0015]: cannot call non-const closure in constants LL | n => n(), | ^^^ | + = note: closures need an RFC before allowed to be called in constants = note: calls in constants are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs index b604c65d75100..269fd87ba0d49 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-79450.rs @@ -1,5 +1,5 @@ #![feature(const_fmt_arguments_new)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #[const_trait] trait Tr { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-88155.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-88155.stderr index 157b54214fa73..e5347a095981c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-88155.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/issue-88155.stderr @@ -5,6 +5,7 @@ LL | T::assoc() | ^^^^^^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr index 89e59e5db6ed3..28254ac15a87a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/match-non-const-eq.gated.stderr @@ -6,6 +6,7 @@ LL | "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in | = note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-const-closure-non-const-outer.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-const-closure-non-const-outer.stderr index 97ad83130d444..d82a49be75e40 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-const-closure-non-const-outer.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/non-const-op-const-closure-non-const-outer.stderr @@ -5,6 +5,7 @@ LL | (const || { (()).foo() })(); | ^^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = help: add `#![feature(effects)]` to the crate attributes to enable error: aborting due to 1 previous error diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs index ada475909a3d3..e0c20b819e84f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.rs @@ -1,4 +1,4 @@ -#![feature(const_trait_impl, min_specialization, rustc_attrs)] +#![feature(const_trait_impl, effects, min_specialization, rustc_attrs)] // known-bug: #110395 #[rustc_specialization_trait] #[const_trait] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr index 0b35feddc5533..5210a6942010d 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/specializing-constness-2.stderr @@ -1,11 +1,12 @@ -error[E0015]: cannot call non-const fn `::a` in constant functions - --> $DIR/specializing-constness-2.rs:27:5 +error[E0119]: conflicting implementations of trait `A` + --> $DIR/specializing-constness-2.rs:20:1 | -LL | ::a(); - | ^^^^^^^^^^^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +LL | impl A for T { + | ------------------------ first implementation here +... +LL | impl const A for T { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr index 12bcdb034bc23..fd4d7ff347501 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.nn.stderr @@ -1,23 +1,23 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-2.rs:11:12 + --> $DIR/super-traits-fail-2.rs:10:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-2.rs:11:1 + --> $DIR/super-traits-fail-2.rs:10:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:11:19 + --> $DIR/super-traits-fail-2.rs:10:19 | LL | trait Bar: ~const Foo {} | ^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:11:19 + --> $DIR/super-traits-fail-2.rs:10:19 | LL | trait Bar: ~const Foo {} | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr index b60399c57dca9..d2e3a5cec1d9f 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.ny.stderr @@ -1,11 +1,11 @@ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:11:19 + --> $DIR/super-traits-fail-2.rs:10:19 | LL | trait Bar: ~const Foo {} | ^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-2.rs:11:19 + --> $DIR/super-traits-fail-2.rs:10:19 | LL | trait Bar: ~const Foo {} | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs index 93fd96f8f2942..3820d06924342 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.rs @@ -1,5 +1,4 @@ -#![feature(const_trait_impl)] -// known-bug: #110395 +#![feature(const_trait_impl, effects)] // revisions: yy yn ny nn #[cfg_attr(any(yy, yn), const_trait)] @@ -9,12 +8,14 @@ trait Foo { #[cfg_attr(any(yy, ny), const_trait)] trait Bar: ~const Foo {} -// FIXME [ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` -// FIXME [ny,nn]~| ERROR: ~const can only be applied to `#[const_trait]` +//[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]` +//[ny,nn]~| ERROR: ~const can only be applied to `#[const_trait]` +//[yn,nn]~^^^ ERROR: `~const` is not allowed here const fn foo(x: &T) { x.a(); - // FIXME [yn,yy]~^ ERROR the trait bound + //[yy,yn]~^ ERROR mismatched types + // FIXME(effects) diagnostic } fn main() {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr index e465ebaffa84e..c05c4d50a33d3 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yn.stderr @@ -1,14 +1,24 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-2.rs:11:12 + --> $DIR/super-traits-fail-2.rs:10:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-2.rs:11:1 + --> $DIR/super-traits-fail-2.rs:10:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +error[E0308]: mismatched types + --> $DIR/super-traits-fail-2.rs:16:5 + | +LL | x.a(); + | ^^^^^ expected `host`, found `true` + | + = note: expected constant `host` + found constant `true` + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr index 1faa5b4dd2c40..852c02cad5ca5 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-2.yy.stderr @@ -1,11 +1,12 @@ -error[E0015]: cannot call non-const fn `::a` in constant functions - --> $DIR/super-traits-fail-2.rs:16:7 +error[E0308]: mismatched types + --> $DIR/super-traits-fail-2.rs:16:5 | LL | x.a(); - | ^^^ + | ^^^^^ expected `host`, found `true` | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + = note: expected constant `host` + found constant `true` error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr index e10c51ef45aba..199d2199c4ae8 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.nn.stderr @@ -1,23 +1,23 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-3.rs:13:12 + --> $DIR/super-traits-fail-3.rs:12:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-3.rs:13:1 + --> $DIR/super-traits-fail-3.rs:12:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ @@ -25,7 +25,7 @@ LL | trait Bar: ~const Foo {} = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:18:24 + --> $DIR/super-traits-fail-3.rs:17:24 | LL | const fn foo(x: &T) { | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr index cd0ee73277d60..46eedc333f148 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.ny.stderr @@ -1,11 +1,11 @@ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:13:19 + --> $DIR/super-traits-fail-3.rs:12:19 | LL | trait Bar: ~const Foo {} | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs index 5994057b2db2e..3e98e131930af 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.rs @@ -1,8 +1,7 @@ -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] // revisions: yy yn ny nn -//[yy] known-bug: #110395 -//FIXME [yy] check-pass +//[yy] check-pass #[cfg_attr(any(yy, yn), const_trait)] trait Foo { diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr index 34f6515b572ec..dc08a8997389c 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yn.stderr @@ -1,17 +1,17 @@ error: `~const` is not allowed here - --> $DIR/super-traits-fail-3.rs:13:12 + --> $DIR/super-traits-fail-3.rs:12:12 | LL | trait Bar: ~const Foo {} | ^^^^^^ | note: this trait is not a `#[const_trait]`, so it cannot have `~const` trait bounds - --> $DIR/super-traits-fail-3.rs:13:1 + --> $DIR/super-traits-fail-3.rs:12:1 | LL | trait Bar: ~const Foo {} | ^^^^^^^^^^^^^^^^^^^^^^^^ error: ~const can only be applied to `#[const_trait]` traits - --> $DIR/super-traits-fail-3.rs:18:24 + --> $DIR/super-traits-fail-3.rs:17:24 | LL | const fn foo(x: &T) { | ^^^ diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr deleted file mode 100644 index 5cccc025161be..0000000000000 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits-fail-3.yy.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0015]: cannot call non-const fn `::a` in constant functions - --> $DIR/super-traits-fail-3.rs:20:7 - | -LL | x.a(); - | ^^^ - | - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs index 8d56295e73837..aa3b09ec9662a 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.rs @@ -1,7 +1,7 @@ // known-bug: #110395 #![feature(staged_api)] -#![feature(const_trait_impl)] +#![feature(const_trait_impl, effects)] #![feature(const_t_try)] #![feature(const_try)] #![feature(try_trait_v2)] diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr index deed05ae17982..62c4bc3b7ae60 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -1,29 +1,39 @@ -error[E0015]: `?` cannot determine the branch of `T` in constant functions - --> $DIR/trait-default-body-stability.rs:44:9 +error: const `impl` for trait `Try` which is not marked with `#[const_trait]` + --> $DIR/trait-default-body-stability.rs:18:12 | -LL | T? - | ^^ +LL | impl const Try for T { + | ^^^ | -note: impl defined here, but it is not `const` - --> $DIR/trait-default-body-stability.rs:18:1 + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `FromResidual` which is not marked with `#[const_trait]` + --> $DIR/trait-default-body-stability.rs:33:12 | -LL | impl const Try for T { - | ^^^^^^^^^^^^^^^^^^^^ - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants +LL | impl const FromResidual for T { + | ^^^^^^^^^^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change -error[E0015]: `?` cannot convert from residual of `T` in constant functions - --> $DIR/trait-default-body-stability.rs:44:9 +error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates + --> $DIR/trait-default-body-stability.rs:18:6 | -LL | T? - | ^^ +LL | impl const Try for T { + | ^^^^^ unconstrained const parameter | -note: impl defined here, but it is not `const` - --> $DIR/trait-default-body-stability.rs:33:1 + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates + --> $DIR/trait-default-body-stability.rs:33:6 | LL | impl const FromResidual for T { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants + | ^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0015`. +For more information about this error, try `rustc --explain E0207`. From 324ca878cec59b623fb6e4dbcfad1e94937d477a Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 19 Dec 2023 04:28:43 +0000 Subject: [PATCH 2/4] fix ICE when `~const` used on non-const trait --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 6f8e80172dd26..1603e2032057f 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -378,7 +378,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { assert!(self_ty.is_none()); } - let arg_count = check_generic_arg_count( + let mut arg_count = check_generic_arg_count( tcx, span, def_id, @@ -560,6 +560,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { inferred_params: vec![], infer_args, }; + if let ty::BoundConstness::ConstIfConst = constness + && generics.has_self + && !tcx.has_attr(def_id, sym::const_trait) + { + let e = tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span }); + arg_count.correct = + Err(GenericArgCountMismatch { reported: Some(e), invalid_args: vec![] }); + } let args = create_args_for_parent_generic_args( tcx, def_id, @@ -570,13 +578,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &mut args_ctx, ); - if let ty::BoundConstness::ConstIfConst = constness - && generics.has_self - && !tcx.has_attr(def_id, sym::const_trait) - { - tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span }); - } - (args, arg_count) } From df1a4c630dc8ea76f7dd01b3248689a2603b5da7 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 19 Dec 2023 04:28:56 +0000 Subject: [PATCH 3/4] clean up `check_consts` checks --- .../src/transform/check_consts/check.rs | 187 ++++-------------- 1 file changed, 40 insertions(+), 147 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index bb17602d3ba01..7a7a5ea8774f4 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -5,17 +5,15 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_index::bit_set::BitSet; use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::traits::{ImplSource, Obligation, ObligationCause}; +use rustc_infer::traits::ObligationCause; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; -use rustc_middle::traits::BuiltinImplSource; -use rustc_middle::ty::GenericArgs; -use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, InstanceDef, Ty, TyCtxt}; -use rustc_middle::ty::{TraitRef, TypeVisitableExt}; +use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt}; +use rustc_middle::ty::{Instance, InstanceDef, TypeVisitableExt}; use rustc_mir_dataflow::Analysis; use rustc_span::{sym, Span, Symbol}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt, SelectionContext}; +use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt}; use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitor}; use std::mem; @@ -752,143 +750,43 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { infcx.err_ctxt().report_fulfillment_errors(errors); } + let mut is_trait = false; // Attempting to call a trait method? - // FIXME(effects) do we need this? - if let Some(trait_id) = tcx.trait_of_item(callee) { + if tcx.trait_of_item(callee).is_some() { trace!("attempting to call a trait method"); - if !self.tcx.features().const_trait_impl { + // trait method calls are only permitted when `effects` is enabled. + // we don't error, since that is handled by typeck. We try to resolve + // the trait into the concrete method, and uses that for const stability + // checks. + // FIXME(effects) we might consider moving const stability checks to typeck as well. + if tcx.features().effects { + is_trait = true; + + if let Ok(Some(instance)) = + Instance::resolve(tcx, param_env, callee, fn_args) + && let InstanceDef::Item(def) = instance.def + { + // Resolve a trait method call to its concrete implementation, which may be in a + // `const` trait impl. This is only used for the const stability check below, since + // we want to look at the concrete impl's stability. + fn_args = instance.args; + callee = def; + } + } else { self.check_op(ops::FnCallNonConst { caller, callee, args: fn_args, span: *fn_span, call_source: *call_source, - feature: Some(sym::const_trait_impl), + feature: Some(if tcx.features().const_trait_impl { + sym::effects + } else { + sym::const_trait_impl + }), }); return; } - - let trait_ref = TraitRef::from_method(tcx, trait_id, fn_args); - let obligation = - Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref); - - let implsrc = { - let infcx = tcx.infer_ctxt().build(); - let mut selcx = SelectionContext::new(&infcx); - selcx.select(&obligation) - }; - - match implsrc { - Ok(Some(ImplSource::Param(_))) if tcx.features().effects => { - debug!( - "const_trait_impl: provided {:?} via where-clause in {:?}", - trait_ref, param_env - ); - return; - } - // Closure: Fn{Once|Mut} - Ok(Some(ImplSource::Builtin(BuiltinImplSource::Misc, _))) - if trait_ref.self_ty().is_closure() - && tcx.fn_trait_kind_from_def_id(trait_id).is_some() => - { - let ty::Closure(closure_def_id, fn_args) = *trait_ref.self_ty().kind() - else { - unreachable!() - }; - if !tcx.is_const_fn_raw(closure_def_id) { - self.check_op(ops::FnCallNonConst { - caller, - callee, - args: fn_args, - span: *fn_span, - call_source: *call_source, - feature: None, - }); - - return; - } - } - Ok(Some(ImplSource::UserDefined(data))) => { - let callee_name = tcx.item_name(callee); - - if let hir::Constness::NotConst = tcx.constness(data.impl_def_id) { - self.check_op(ops::FnCallNonConst { - caller, - callee, - args: fn_args, - span: *fn_span, - call_source: *call_source, - feature: None, - }); - return; - } - - if let Some(&did) = tcx - .associated_item_def_ids(data.impl_def_id) - .iter() - .find(|did| tcx.item_name(**did) == callee_name) - { - // using internal args is ok here, since this is only - // used for the `resolve` call below - fn_args = GenericArgs::identity_for_item(tcx, did); - callee = did; - } - } - _ if !tcx.is_const_fn_raw(callee) => { - // At this point, it is only legal when the caller is in a trait - // marked with #[const_trait], and the callee is in the same trait. - let mut nonconst_call_permission = false; - if let Some(callee_trait) = tcx.trait_of_item(callee) - && tcx.has_attr(callee_trait, sym::const_trait) - && Some(callee_trait) == tcx.trait_of_item(caller.to_def_id()) - // Can only call methods when it's `::f`. - && tcx.types.self_param == fn_args.type_at(0) - { - nonconst_call_permission = true; - } - - if !nonconst_call_permission { - let obligation = Obligation::new( - tcx, - ObligationCause::dummy_with_span(*fn_span), - param_env, - trait_ref, - ); - - // improve diagnostics by showing what failed. Our requirements are stricter this time - // as we are going to error again anyways. - let infcx = tcx.infer_ctxt().build(); - if let Err(e) = implsrc { - infcx.err_ctxt().report_selection_error( - obligation.clone(), - &obligation, - &e, - ); - } - - self.check_op(ops::FnCallNonConst { - caller, - callee, - args: fn_args, - span: *fn_span, - call_source: *call_source, - feature: None, - }); - return; - } - } - _ => {} - } - - // Resolve a trait method call to its concrete implementation, which may be in a - // `const` trait impl. - let instance = Instance::resolve(tcx, param_env, callee, fn_args); - debug!("Resolving ({:?}) -> {:?}", callee, instance); - if let Ok(Some(func)) = instance { - if let InstanceDef::Item(def) = func.def { - callee = def; - } - } } // At this point, we are calling a function, `callee`, whose `DefId` is known... @@ -921,21 +819,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { return; } - if !tcx.is_const_fn_raw(callee) { - if !tcx.is_const_default_method(callee) { - // To get to here we must have already found a const impl for the - // trait, but for it to still be non-const can be that the impl is - // using default method bodies. - self.check_op(ops::FnCallNonConst { - caller, - callee, - args: fn_args, - span: *fn_span, - call_source: *call_source, - feature: None, - }); - return; - } + if !tcx.is_const_fn_raw(callee) && !is_trait { + self.check_op(ops::FnCallNonConst { + caller, + callee, + args: fn_args, + span: *fn_span, + call_source: *call_source, + feature: None, + }); + return; } // If the `const fn` we are trying to call is not const-stable, ensure that we have From 1349d86c72fe4d57134edb025d64e0ddff804d77 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Fri, 22 Dec 2023 23:29:20 +0000 Subject: [PATCH 4/4] bool->enum for ast::PatKind::Struct presence of `..` See https://github.com/rust-lang/rust/blob/cee794ee98d49b45a55ba225680d98e0c4672736/compiler/rustc_parse/src/parser/pat.rs#L890-L897 for the only place this is constructed. --- compiler/rustc_ast/src/ast.rs | 12 ++++++++++-- compiler/rustc_ast_lowering/src/pat.rs | 2 +- compiler/rustc_ast_pretty/src/pprust/state.rs | 4 ++-- compiler/rustc_expand/src/build.rs | 2 +- compiler/rustc_parse/src/parser/pat.rs | 11 ++++++----- .../clippy/clippy_lints/src/unnested_or_patterns.rs | 2 +- src/tools/rustfmt/src/patterns.rs | 12 +++++++++--- 7 files changed, 30 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index a121b5a9bed3d..027b09b7f30b8 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -779,8 +779,7 @@ pub enum PatKind { Ident(BindingAnnotation, Ident, Option>), /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`). - /// The `bool` is `true` in the presence of a `..`. - Struct(Option>, Path, ThinVec, /* recovered */ bool), + Struct(Option>, Path, ThinVec, PatFieldsRest), /// A tuple struct/variant pattern (`Variant(x, y, .., z)`). TupleStruct(Option>, Path, ThinVec>), @@ -837,6 +836,15 @@ pub enum PatKind { MacCall(P), } +/// Whether the `..` is present in a struct fields pattern. +#[derive(Clone, Copy, Encodable, Decodable, Debug, PartialEq)] +pub enum PatFieldsRest { + /// `module::StructName { field, ..}` + Rest, + /// `module::StructName { field }` + None, +} + /// The kind of borrow in an `AddrOf` expression, /// e.g., `&place` or `&raw const place`. #[derive(Clone, Copy, PartialEq, Eq, Debug)] diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 017314ee4d14a..3ffa4f1f2e6eb 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -82,7 +82,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: self.lower_span(f.span), } })); - break hir::PatKind::Struct(qpath, fs, *etc); + break hir::PatKind::Struct(qpath, fs, *etc == ast::PatFieldsRest::Rest); } PatKind::Tuple(pats) => { let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple"); diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index d6c15ec35b603..619fd7a49ebe3 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1427,7 +1427,7 @@ impl<'a> State<'a> { } self.nbsp(); self.word("{"); - let empty = fields.is_empty() && !etc; + let empty = fields.is_empty() && *etc == ast::PatFieldsRest::None; if !empty { self.space(); } @@ -1445,7 +1445,7 @@ impl<'a> State<'a> { }, |f| f.pat.span, ); - if *etc { + if *etc == ast::PatFieldsRest::Rest { if !fields.is_empty() { self.word_space(","); } diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 86f555fa08bcf..c17d8472dcca3 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -488,7 +488,7 @@ impl<'a> ExtCtxt<'a> { path: ast::Path, field_pats: ThinVec, ) -> P { - self.pat(span, PatKind::Struct(None, path, field_pats, false)) + self.pat(span, PatKind::Struct(None, path, field_pats, ast::PatFieldsRest::None)) } pub fn pat_tuple(&self, span: Span, pats: ThinVec>) -> P { self.pat(span, PatKind::Tuple(pats)) diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 80233eddb9b7f..3fc4179af65ad 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -15,7 +15,7 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter}; use rustc_ast::{ self as ast, AttrVec, BindingAnnotation, ByRef, Expr, ExprKind, MacCall, Mutability, Pat, - PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax, + PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax, }; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult}; @@ -890,7 +890,8 @@ impl<'a> Parser<'a> { e.span_label(path.span, "while parsing the fields for this pattern"); e.emit(); self.recover_stmt(); - (ThinVec::new(), true) + // When recovering, pretend we had `Foo { .. }`, to avoid cascading errors. + (ThinVec::new(), PatFieldsRest::Rest) }); self.bump(); Ok(PatKind::Struct(qself, path, fields, etc)) @@ -964,9 +965,9 @@ impl<'a> Parser<'a> { } /// Parses the fields of a struct-like pattern. - fn parse_pat_fields(&mut self) -> PResult<'a, (ThinVec, bool)> { + fn parse_pat_fields(&mut self) -> PResult<'a, (ThinVec, PatFieldsRest)> { let mut fields = ThinVec::new(); - let mut etc = false; + let mut etc = PatFieldsRest::None; let mut ate_comma = true; let mut delayed_err: Option> = None; let mut first_etc_and_maybe_comma_span = None; @@ -1000,7 +1001,7 @@ impl<'a> Parser<'a> { || self.check_noexpect(&token::DotDotDot) || self.check_keyword(kw::Underscore) { - etc = true; + etc = PatFieldsRest::Rest; let mut etc_sp = self.token.span; if first_etc_and_maybe_comma_span.is_none() { if let Some(comma_tok) = self diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs index 65600009c1d79..77adcdd0e6bfb 100644 --- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs @@ -293,7 +293,7 @@ fn extend_with_struct_pat( qself1: &Option>, path1: &ast::Path, fps1: &mut [ast::PatField], - rest1: bool, + rest1: ast::PatFieldsRest, start: usize, alternatives: &mut ThinVec>, ) -> bool { diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs index 8504999b8ff51..0fa6edaa5d78b 100644 --- a/src/tools/rustfmt/src/patterns.rs +++ b/src/tools/rustfmt/src/patterns.rs @@ -259,9 +259,15 @@ impl Rewrite for Pat { None, None, ), - PatKind::Struct(ref qself, ref path, ref fields, ellipsis) => { - rewrite_struct_pat(qself, path, fields, ellipsis, self.span, context, shape) - } + PatKind::Struct(ref qself, ref path, ref fields, rest) => rewrite_struct_pat( + qself, + path, + fields, + rest == ast::PatFieldsRest::Rest, + self.span, + context, + shape, + ), PatKind::MacCall(ref mac) => { rewrite_macro(mac, None, context, shape, MacroPosition::Pat) }