From 30f5a039f07f830427fec693cdaff8724042cb12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:09:00 +0800 Subject: [PATCH 01/20] Move `tests/ui/associated-path-shl.rs` to `tests/ui/parser/` --- tests/ui/{ => parser}/associated-path-shl.rs | 0 tests/ui/{ => parser}/associated-path-shl.stderr | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{ => parser}/associated-path-shl.rs (100%) rename tests/ui/{ => parser}/associated-path-shl.stderr (100%) diff --git a/tests/ui/associated-path-shl.rs b/tests/ui/parser/associated-path-shl.rs similarity index 100% rename from tests/ui/associated-path-shl.rs rename to tests/ui/parser/associated-path-shl.rs diff --git a/tests/ui/associated-path-shl.stderr b/tests/ui/parser/associated-path-shl.stderr similarity index 100% rename from tests/ui/associated-path-shl.stderr rename to tests/ui/parser/associated-path-shl.stderr From 4ca2d9f7f5f158187e8ffcdfe82a1b1c39fc8733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:10:56 +0800 Subject: [PATCH 02/20] Move `tests/ui/attempted-access-non-fatal.rs` to `tests/ui/typeck/` --- tests/ui/{ => typeck}/attempted-access-non-fatal.rs | 0 tests/ui/{ => typeck}/attempted-access-non-fatal.stderr | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{ => typeck}/attempted-access-non-fatal.rs (100%) rename tests/ui/{ => typeck}/attempted-access-non-fatal.stderr (100%) diff --git a/tests/ui/attempted-access-non-fatal.rs b/tests/ui/typeck/attempted-access-non-fatal.rs similarity index 100% rename from tests/ui/attempted-access-non-fatal.rs rename to tests/ui/typeck/attempted-access-non-fatal.rs diff --git a/tests/ui/attempted-access-non-fatal.stderr b/tests/ui/typeck/attempted-access-non-fatal.stderr similarity index 100% rename from tests/ui/attempted-access-non-fatal.stderr rename to tests/ui/typeck/attempted-access-non-fatal.stderr From 0fc6be7898578e7d0c915f14f9ddb3ac71673796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:18:30 +0800 Subject: [PATCH 03/20] Adjust `tests/ui/attr-bad-crate-attr.rs` - Move `tests/ui/attr-bad-crate-attr.rs` to `tests/ui/attributes/`. - Briefly document test intent add link to relevant Reference docs. --- tests/ui/attr-bad-crate-attr.rs | 4 ---- tests/ui/attributes/attr-bad-crate-attr.rs | 9 +++++++++ tests/ui/{ => attributes}/attr-bad-crate-attr.stderr | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) delete mode 100644 tests/ui/attr-bad-crate-attr.rs create mode 100644 tests/ui/attributes/attr-bad-crate-attr.rs rename tests/ui/{ => attributes}/attr-bad-crate-attr.stderr (79%) diff --git a/tests/ui/attr-bad-crate-attr.rs b/tests/ui/attr-bad-crate-attr.rs deleted file mode 100644 index b9100ecfb67..00000000000 --- a/tests/ui/attr-bad-crate-attr.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ error-pattern: expected item - -#![attr = "val"] -#[attr = "val"] // Unterminated diff --git a/tests/ui/attributes/attr-bad-crate-attr.rs b/tests/ui/attributes/attr-bad-crate-attr.rs new file mode 100644 index 00000000000..9de0abca9a7 --- /dev/null +++ b/tests/ui/attributes/attr-bad-crate-attr.rs @@ -0,0 +1,9 @@ +//! Check that we permit a crate-level inner attribute but reject a dangling outer attribute which +//! does not have a following thing that it can target. +//! +//! See . + +//@ error-pattern: expected item + +#![attr = "val"] +#[attr = "val"] // Unterminated diff --git a/tests/ui/attr-bad-crate-attr.stderr b/tests/ui/attributes/attr-bad-crate-attr.stderr similarity index 79% rename from tests/ui/attr-bad-crate-attr.stderr rename to tests/ui/attributes/attr-bad-crate-attr.stderr index 9df991f71b3..69eabd32230 100644 --- a/tests/ui/attr-bad-crate-attr.stderr +++ b/tests/ui/attributes/attr-bad-crate-attr.stderr @@ -1,5 +1,5 @@ error: expected item after attributes - --> $DIR/attr-bad-crate-attr.rs:4:1 + --> $DIR/attr-bad-crate-attr.rs:9:1 | LL | #[attr = "val"] // Unterminated | ^^^^^^^^^^^^^^^ From 88f8bf7e560f5ea9c2efe2f587b2586f95984c4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:22:21 +0800 Subject: [PATCH 04/20] Adjust `tests/ui/attr-shebang.rs` - Move `tests/ui/attr-shebang.rs` to `tests/ui/attributes/`. - Downgrade test to `check-pass`, this would fail very early if the parser did not accept `#![..]` attributes. - Briefly document test intent. --- tests/ui/attr-shebang.rs | 5 ----- tests/ui/attributes/attr-shebang.rs | 7 +++++++ 2 files changed, 7 insertions(+), 5 deletions(-) delete mode 100644 tests/ui/attr-shebang.rs create mode 100644 tests/ui/attributes/attr-shebang.rs diff --git a/tests/ui/attr-shebang.rs b/tests/ui/attr-shebang.rs deleted file mode 100644 index 67c371aeaac..00000000000 --- a/tests/ui/attr-shebang.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ run-pass - -#![allow(stable_features)] -#![feature(rust1)] -pub fn main() { } diff --git a/tests/ui/attributes/attr-shebang.rs b/tests/ui/attributes/attr-shebang.rs new file mode 100644 index 00000000000..af446dc56e3 --- /dev/null +++ b/tests/ui/attributes/attr-shebang.rs @@ -0,0 +1,7 @@ +//! Check that we accept crate-level inner attributes with the `#![..]` shebang syntax. + +//@ check-pass + +#![allow(stable_features)] +#![feature(rust1)] +pub fn main() { } From 7424b898e94b019b49e0854ec061abfdc071e61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:29:14 +0800 Subject: [PATCH 05/20] Adjust `tests/ui/attr-usage-inline.rs` - Move `tests/ui/attr-usage-inline.rs` to `tests/ui/attributes/inline/`. - Briefly document test intent. - Drop unnecessary `#[allow(dead_code)]` as this is allowed-by-default for ui test suite. --- tests/ui/{ => attributes/inline}/attr-usage-inline.rs | 3 ++- tests/ui/{ => attributes/inline}/attr-usage-inline.stderr | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) rename tests/ui/{ => attributes/inline}/attr-usage-inline.rs (66%) rename tests/ui/{ => attributes/inline}/attr-usage-inline.stderr (84%) diff --git a/tests/ui/attr-usage-inline.rs b/tests/ui/attributes/inline/attr-usage-inline.rs similarity index 66% rename from tests/ui/attr-usage-inline.rs rename to tests/ui/attributes/inline/attr-usage-inline.rs index 674c12454cd..d8ca0fce163 100644 --- a/tests/ui/attr-usage-inline.rs +++ b/tests/ui/attributes/inline/attr-usage-inline.rs @@ -1,4 +1,5 @@ -#![allow(dead_code)] +//! Check that `#[inline]` attribute can only be applied to fn-like targets (e.g. function or +//! closure), and when misapplied to other targets an error is emitted. #[inline] fn f() {} diff --git a/tests/ui/attr-usage-inline.stderr b/tests/ui/attributes/inline/attr-usage-inline.stderr similarity index 84% rename from tests/ui/attr-usage-inline.stderr rename to tests/ui/attributes/inline/attr-usage-inline.stderr index 22a0bf47e20..2123438032c 100644 --- a/tests/ui/attr-usage-inline.stderr +++ b/tests/ui/attributes/inline/attr-usage-inline.stderr @@ -1,5 +1,5 @@ error[E0518]: attribute should be applied to function or closure - --> $DIR/attr-usage-inline.rs:6:1 + --> $DIR/attr-usage-inline.rs:7:1 | LL | #[inline] | ^^^^^^^^^ @@ -7,7 +7,7 @@ LL | struct S; | --------- not a function or closure error[E0518]: attribute should be applied to function or closure - --> $DIR/attr-usage-inline.rs:20:1 + --> $DIR/attr-usage-inline.rs:21:1 | LL | #[inline] | ^^^^^^^^^ not a function or closure From 836a0e00e5d29b845748cf42713445076418473b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:40:31 +0800 Subject: [PATCH 06/20] Adjust `tests/ui/attrs-resolution-errors.rs` - Move `tests/ui/attrs-resolution-errors.rs` to `tests/ui/resolve/`. - Document test intent. - Rename test to `attr-macros-positional-rejection.rs` to better reflect test intent. --- .../attr-macros-positional-rejection.rs} | 11 ++++++++++- .../attr-macros-positional-rejection.stderr} | 10 +++++----- 2 files changed, 15 insertions(+), 6 deletions(-) rename tests/ui/{attrs-resolution-errors.rs => resolve/attr-macros-positional-rejection.rs} (73%) rename tests/ui/{attrs-resolution-errors.stderr => resolve/attr-macros-positional-rejection.stderr} (73%) diff --git a/tests/ui/attrs-resolution-errors.rs b/tests/ui/resolve/attr-macros-positional-rejection.rs similarity index 73% rename from tests/ui/attrs-resolution-errors.rs rename to tests/ui/resolve/attr-macros-positional-rejection.rs index 8770fb1ded8..11382ff1399 100644 --- a/tests/ui/attrs-resolution-errors.rs +++ b/tests/ui/resolve/attr-macros-positional-rejection.rs @@ -1,3 +1,12 @@ +//! Check that certain positions (listed below) only permit *non-macro* attributes and reject +//! attribute macros: +//! +//! - Enum variants +//! - Struct fields +//! - Field in a struct pattern +//! - Match arm +//! - Field in struct initialization expression + enum FooEnum { #[test] //~^ ERROR expected non-macro attribute, found attribute macro @@ -32,7 +41,7 @@ fn main() { _ => {} } - let _another_foo_strunct = FooStruct { + let _another_foo_struct = FooStruct { #[test] //~^ ERROR expected non-macro attribute, found attribute macro bar: 1, diff --git a/tests/ui/attrs-resolution-errors.stderr b/tests/ui/resolve/attr-macros-positional-rejection.stderr similarity index 73% rename from tests/ui/attrs-resolution-errors.stderr rename to tests/ui/resolve/attr-macros-positional-rejection.stderr index 883f96e5c19..faea511f315 100644 --- a/tests/ui/attrs-resolution-errors.stderr +++ b/tests/ui/resolve/attr-macros-positional-rejection.stderr @@ -1,29 +1,29 @@ error: expected non-macro attribute, found attribute macro `test` - --> $DIR/attrs-resolution-errors.rs:2:7 + --> $DIR/attr-macros-positional-rejection.rs:11:7 | LL | #[test] | ^^^^ not a non-macro attribute error: expected non-macro attribute, found attribute macro `test` - --> $DIR/attrs-resolution-errors.rs:8:7 + --> $DIR/attr-macros-positional-rejection.rs:17:7 | LL | #[test] | ^^^^ not a non-macro attribute error: expected non-macro attribute, found attribute macro `test` - --> $DIR/attrs-resolution-errors.rs:23:15 + --> $DIR/attr-macros-positional-rejection.rs:32:15 | LL | #[test] bar | ^^^^ not a non-macro attribute error: expected non-macro attribute, found attribute macro `test` - --> $DIR/attrs-resolution-errors.rs:30:11 + --> $DIR/attr-macros-positional-rejection.rs:39:11 | LL | #[test] | ^^^^ not a non-macro attribute error: expected non-macro attribute, found attribute macro `test` - --> $DIR/attrs-resolution-errors.rs:36:11 + --> $DIR/attr-macros-positional-rejection.rs:45:11 | LL | #[test] | ^^^^ not a non-macro attribute From 47ad3b2be42790a54840f5aec9a3526244bedc55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= <39484203+jieyouxu@users.noreply.github.com> Date: Tue, 17 Dec 2024 19:43:05 +0800 Subject: [PATCH 07/20] Adjust `tests/ui/attrs-resolution.rs` - Move `tests/ui/attrs-resolution.rs` to `tests/ui/resolve/`. - Document test intent. - Rename test to `non-macro-attrs-accepted.rs` to better reflect test intent. --- .../non-macro-attrs-accepted.rs} | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) rename tests/ui/{attrs-resolution.rs => resolve/non-macro-attrs-accepted.rs} (66%) diff --git a/tests/ui/attrs-resolution.rs b/tests/ui/resolve/non-macro-attrs-accepted.rs similarity index 66% rename from tests/ui/attrs-resolution.rs rename to tests/ui/resolve/non-macro-attrs-accepted.rs index 38dd3812d68..76a04b2e837 100644 --- a/tests/ui/attrs-resolution.rs +++ b/tests/ui/resolve/non-macro-attrs-accepted.rs @@ -1,3 +1,11 @@ +//! Check that certain positions (listed below) permit *non-macro* attributes. +//! +//! - Enum variants +//! - Struct fields +//! - Field in a struct pattern +//! - Match arm +//! - Field in struct initialization expression + //@ check-pass enum FooEnum { @@ -30,7 +38,7 @@ fn main() { _ => {} } - let _another_foo_strunct = FooStruct { + let _another_foo_struct = FooStruct { #[rustfmt::skip] bar: 1, }; From bfd02d8b36914d222b2ee6ed185cbf6bdba7d9d9 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Tue, 22 Oct 2024 19:48:11 +0200 Subject: [PATCH 08/20] Improve testing coverage for `#[diagnostic::do_not_recommend]` This PR aims to improve the testing coverage for `#[diagnostic::do_not_recommend]`. It ensures that all tests are run for the old and new solver to verify that the behaviour is the same for both variants. It also adds two new tests: * A test with 4 traits having wild card impl for each other, with alternating `#[diagnostic::do_not_recommend]` attributse * A test with a lifetime dependend wild card impl, which is something that's not supported yet --- ...ibute_without_feature_flag.current.stderr} | 4 +- ...attribute_without_feature_flag.next.stderr | 21 ++++++++ ...ot_apply_attribute_without_feature_flag.rs | 3 ++ ...ture-gate-do_not_recommend.current.stderr} | 4 +- .../feature-gate-do_not_recommend.next.stderr | 17 ++++++ .../feature-gate-do_not_recommend.rs | 3 ++ ...err => incorrect-locations.current.stderr} | 16 +++--- .../incorrect-locations.next.stderr | 52 +++++++++++++++++++ .../do_not_recommend/incorrect-locations.rs | 3 ++ .../do_not_recommend/nested.current.stderr | 15 ++++++ .../do_not_recommend/nested.next.stderr | 15 ++++++ .../do_not_recommend/nested.rs | 25 +++++++++ ...stderr => unstable-feature.current.stderr} | 4 +- .../unstable-feature.next.stderr | 14 +++++ .../do_not_recommend/unstable-feature.rs | 3 ++ .../with_lifetime.current.stderr | 10 ++++ .../with_lifetime.next.stderr | 10 ++++ .../do_not_recommend/with_lifetime.rs | 25 +++++++++ 18 files changed, 230 insertions(+), 14 deletions(-) rename tests/ui/diagnostic_namespace/do_not_recommend/{do_not_apply_attribute_without_feature_flag.stderr => do_not_apply_attribute_without_feature_flag.current.stderr} (83%) create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.next.stderr rename tests/ui/diagnostic_namespace/do_not_recommend/{feature-gate-do_not_recommend.stderr => feature-gate-do_not_recommend.current.stderr} (79%) create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.next.stderr rename tests/ui/diagnostic_namespace/do_not_recommend/{incorrect-locations.stderr => incorrect-locations.current.stderr} (82%) create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/nested.current.stderr create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/nested.next.stderr create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/nested.rs rename tests/ui/diagnostic_namespace/do_not_recommend/{unstable-feature.stderr => unstable-feature.current.stderr} (81%) create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.next.stderr create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.current.stderr create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.next.stderr create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.current.stderr similarity index 83% rename from tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.stderr rename to tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.current.stderr index be17476524a..660fc7d2171 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/do_not_apply_attribute_without_feature_flag.rs:19:11 + --> $DIR/do_not_apply_attribute_without_feature_flag.rs:22:11 | LL | check(()); | ----- ^^ the trait `Foo` is not implemented for `()` @@ -11,7 +11,7 @@ LL | check(()); (A, B, C) (A,) note: required by a bound in `check` - --> $DIR/do_not_apply_attribute_without_feature_flag.rs:16:18 + --> $DIR/do_not_apply_attribute_without_feature_flag.rs:19:18 | LL | fn check(a: impl Foo) {} | ^^^ required by this bound in `check` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.next.stderr new file mode 100644 index 00000000000..1cd148186f1 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.next.stderr @@ -0,0 +1,21 @@ +error[E0277]: the trait bound `(): Foo` is not satisfied + --> $DIR/do_not_apply_attribute_without_feature_flag.rs:22:11 + | +LL | check(()); + | ----- ^^ the trait `Foo` is not implemented for `()` + | | + | required by a bound introduced by this call + | + = help: the following other types implement trait `Foo`: + (A, B) + (A, B, C) + (A,) +note: required by a bound in `check` + --> $DIR/do_not_apply_attribute_without_feature_flag.rs:19:18 + | +LL | fn check(a: impl Foo) {} + | ^^^ required by this bound in `check` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.rs b/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.rs index 5548fa2f52e..9c25069bc7d 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver #![allow(unknown_or_malformed_diagnostic_attributes)] trait Foo {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.current.stderr similarity index 79% rename from tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.stderr rename to tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.current.stderr index 3951231fa2e..d1deaa6a006 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `u8: Bar` is not satisfied - --> $DIR/feature-gate-do_not_recommend.rs:15:11 + --> $DIR/feature-gate-do_not_recommend.rs:18:11 | LL | stuff(1u8); | ^^^ the trait `Bar` is not implemented for `u8` | note: required by a bound in `stuff` - --> $DIR/feature-gate-do_not_recommend.rs:12:13 + --> $DIR/feature-gate-do_not_recommend.rs:15:13 | LL | fn stuff(_: T) {} | ^^^ required by this bound in `stuff` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.next.stderr new file mode 100644 index 00000000000..5bfcc60edc5 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.next.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `u8: Bar` is not satisfied + --> $DIR/feature-gate-do_not_recommend.rs:18:11 + | +LL | stuff(1u8); + | ----- ^^^ the trait `Bar` is not implemented for `u8` + | | + | required by a bound introduced by this call + | +note: required by a bound in `stuff` + --> $DIR/feature-gate-do_not_recommend.rs:15:13 + | +LL | fn stuff(_: T) {} + | ^^^ required by this bound in `stuff` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.rs b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.rs index 5a26d28188c..4adce112f15 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver #![feature(do_not_recommend)] pub trait Foo {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr similarity index 82% rename from tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.stderr rename to tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr index c83fd46db58..84ab0827ab6 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr @@ -1,5 +1,5 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:4:1 + --> $DIR/incorrect-locations.rs:7:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,43 +7,43 @@ LL | #[diagnostic::do_not_recommend] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:8:1 + --> $DIR/incorrect-locations.rs:11:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:12:1 + --> $DIR/incorrect-locations.rs:15:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:16:1 + --> $DIR/incorrect-locations.rs:19:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:20:1 + --> $DIR/incorrect-locations.rs:23:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:24:1 + --> $DIR/incorrect-locations.rs:27:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:28:1 + --> $DIR/incorrect-locations.rs:31:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:32:1 + --> $DIR/incorrect-locations.rs:35:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr new file mode 100644 index 00000000000..84ab0827ab6 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr @@ -0,0 +1,52 @@ +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:7:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:11:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:15:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:19:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:23:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:27:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:31:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:35:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 8 warnings emitted + diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs index 400ef83873e..daacf55ea79 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs @@ -1,4 +1,7 @@ //@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver #![feature(do_not_recommend)] #[diagnostic::do_not_recommend] diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/nested.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/nested.current.stderr new file mode 100644 index 00000000000..2e08a679360 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/nested.current.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `(): Root` is not satisfied + --> $DIR/nested.rs:23:18 + | +LL | needs_root::<()>(); + | ^^ the trait `Root` is not implemented for `()` + | +note: required by a bound in `needs_root` + --> $DIR/nested.rs:20:18 + | +LL | fn needs_root() {} + | ^^^^ required by this bound in `needs_root` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/nested.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/nested.next.stderr new file mode 100644 index 00000000000..2e08a679360 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/nested.next.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `(): Root` is not satisfied + --> $DIR/nested.rs:23:18 + | +LL | needs_root::<()>(); + | ^^ the trait `Root` is not implemented for `()` + | +note: required by a bound in `needs_root` + --> $DIR/nested.rs:20:18 + | +LL | fn needs_root() {} + | ^^^^ required by this bound in `needs_root` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/nested.rs b/tests/ui/diagnostic_namespace/do_not_recommend/nested.rs new file mode 100644 index 00000000000..d499cff9f56 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/nested.rs @@ -0,0 +1,25 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +#![feature(do_not_recommend)] + +trait Root {} +trait DontRecommend {} +trait Other {} +trait Child {} + +#[diagnostic::do_not_recommend] +impl Root for T where T: DontRecommend {} + +impl DontRecommend for T where T: Other {} + +#[diagnostic::do_not_recommend] +impl Other for T where T: Child {} + +fn needs_root() {} + +fn main() { + needs_root::<()>(); + //~^ ERROR the trait bound `(): Root` is not satisfied +} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.current.stderr similarity index 81% rename from tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.stderr rename to tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.current.stderr index d8332229d4f..fdea9eacae1 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.current.stderr @@ -1,11 +1,11 @@ error: unknown diagnostic attribute - --> $DIR/unstable-feature.rs:4:15 + --> $DIR/unstable-feature.rs:7:15 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/unstable-feature.rs:1:9 + --> $DIR/unstable-feature.rs:4:9 | LL | #![deny(unknown_or_malformed_diagnostic_attributes)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.next.stderr new file mode 100644 index 00000000000..fdea9eacae1 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.next.stderr @@ -0,0 +1,14 @@ +error: unknown diagnostic attribute + --> $DIR/unstable-feature.rs:7:15 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/unstable-feature.rs:4:9 + | +LL | #![deny(unknown_or_malformed_diagnostic_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.rs b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.rs index ccc687aa5b3..7a67f67b67f 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver #![deny(unknown_or_malformed_diagnostic_attributes)] trait Foo {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.current.stderr new file mode 100644 index 00000000000..c2874cf4594 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.current.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/with_lifetime.rs:19:5 + | +LL | fn foo<'a>(a: &'a ()) { + | -- lifetime `'a` defined here +LL | needs_root::<&'a ()>(); + | ^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to 1 previous error + diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.next.stderr new file mode 100644 index 00000000000..c2874cf4594 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.next.stderr @@ -0,0 +1,10 @@ +error: lifetime may not live long enough + --> $DIR/with_lifetime.rs:19:5 + | +LL | fn foo<'a>(a: &'a ()) { + | -- lifetime `'a` defined here +LL | needs_root::<&'a ()>(); + | ^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` + +error: aborting due to 1 previous error + diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs new file mode 100644 index 00000000000..9aaf7f33ecd --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs @@ -0,0 +1,25 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +#![feature(do_not_recommend)] + +trait Root {} +trait DontRecommend {} + +impl Root for T where T: DontRecommend {} + +// this has no effect yet for resolving the trait error below +#[diagnostic::do_not_recommend] +impl DontRecommend for &'static T {} + +fn needs_root() {} + +fn foo<'a>(a: &'a ()) { + needs_root::<&'a ()>(); + //~^ ERROR lifetime may not live long enough +} + +fn main() { + foo(&()); +} From ecb6fd8d3a98fb5d3c0347d1e15ac79032c63ef4 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Wed, 23 Oct 2024 07:48:57 +0200 Subject: [PATCH 09/20] Check `#[diagnostic::do_not_recommend]` for arguments This commit adds a check that verifies that no arguments are passed to `#[diagnostic::do_not_recommend]`. If we detect arguments we emit a warning. --- compiler/rustc_passes/messages.ftl | 3 +++ compiler/rustc_passes/src/check_attr.rs | 18 ++++++++++++-- compiler/rustc_passes/src/errors.rs | 4 ++++ .../does_not_acccept_args.current.stderr | 22 +++++++++++++++++ .../does_not_acccept_args.next.stderr | 22 +++++++++++++++++ .../do_not_recommend/does_not_acccept_args.rs | 24 +++++++++++++++++++ 6 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index fd133ba878e..9cc94b75624 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -357,6 +357,9 @@ passes_ignored_derived_impls = passes_implied_feature_not_exist = feature `{$implied_by}` implying `{$feature}` does not exist +passes_incorrect_do_not_recommend_args = + `#[diagnostic::do_not_recommend]` does not expect any arguments + passes_incorrect_do_not_recommend_location = `#[diagnostic::do_not_recommend]` can only be placed on trait implementations diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ce7947ad3ec..9879dfa9720 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -115,7 +115,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { for attr in attrs { match attr.path().as_slice() { [sym::diagnostic, sym::do_not_recommend, ..] => { - self.check_do_not_recommend(attr.span, hir_id, target) + self.check_do_not_recommend(attr.span, hir_id, target, attr) } [sym::diagnostic, sym::on_unimplemented, ..] => { self.check_diagnostic_on_unimplemented(attr.span, hir_id, target) @@ -348,7 +348,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } /// Checks if `#[diagnostic::do_not_recommend]` is applied on a trait impl. - fn check_do_not_recommend(&self, attr_span: Span, hir_id: HirId, target: Target) { + fn check_do_not_recommend( + &self, + attr_span: Span, + hir_id: HirId, + target: Target, + attr: &Attribute, + ) { if !matches!(target, Target::Impl) { self.tcx.emit_node_span_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, @@ -357,6 +363,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> { errors::IncorrectDoNotRecommendLocation, ); } + if !attr.is_word() { + self.tcx.emit_node_span_lint( + UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, + hir_id, + attr_span, + errors::DoNotRecommendDoesNotExpectArgs, + ); + } } /// Checks if `#[diagnostic::on_unimplemented]` is applied to a trait definition diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index f71d5284052..5e7bfa5e3bb 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -20,6 +20,10 @@ use crate::lang_items::Duplicate; #[diag(passes_incorrect_do_not_recommend_location)] pub(crate) struct IncorrectDoNotRecommendLocation; +#[derive(LintDiagnostic)] +#[diag(passes_incorrect_do_not_recommend_args)] +pub(crate) struct DoNotRecommendDoesNotExpectArgs; + #[derive(Diagnostic)] #[diag(passes_autodiff_attr)] pub(crate) struct AutoDiffAttr { diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr new file mode 100644 index 00000000000..3d004ca559e --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr @@ -0,0 +1,22 @@ +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/does_not_acccept_args.rs:12:1 + | +LL | #[diagnostic::do_not_recommend(not_accepted)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/does_not_acccept_args.rs:16:1 + | +LL | #[diagnostic::do_not_recommend(not_accepted = "foo")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/does_not_acccept_args.rs:20:1 + | +LL | #[diagnostic::do_not_recommend(not_accepted(42))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 3 warnings emitted + diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr new file mode 100644 index 00000000000..3d004ca559e --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr @@ -0,0 +1,22 @@ +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/does_not_acccept_args.rs:12:1 + | +LL | #[diagnostic::do_not_recommend(not_accepted)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default + +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/does_not_acccept_args.rs:16:1 + | +LL | #[diagnostic::do_not_recommend(not_accepted = "foo")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: `#[diagnostic::do_not_recommend]` does not expect any arguments + --> $DIR/does_not_acccept_args.rs:20:1 + | +LL | #[diagnostic::do_not_recommend(not_accepted(42))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 3 warnings emitted + diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs new file mode 100644 index 00000000000..f3295546f34 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs @@ -0,0 +1,24 @@ +//@ check-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +#![feature(do_not_recommend)] + +trait Foo {} +trait Bar {} +trait Baz {} + +#[diagnostic::do_not_recommend(not_accepted)] +//~^ WARNING `#[diagnostic::do_not_recommend]` does not expect any arguments +impl Foo for T where T: Send {} + +#[diagnostic::do_not_recommend(not_accepted = "foo")] +//~^ WARNING `#[diagnostic::do_not_recommend]` does not expect any arguments +impl Bar for T where T: Send {} + +#[diagnostic::do_not_recommend(not_accepted(42))] +//~^ WARNING `#[diagnostic::do_not_recommend]` does not expect any arguments +impl Baz for T where T: Send {} + +fn main() {} From dd31713c53bbd22915ecb0d43043923730726f20 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Wed, 23 Oct 2024 08:09:15 +0200 Subject: [PATCH 10/20] Stabilize `#[diagnostic::do_not_recommend]` This commit seeks to stabilize the `#[diagnostic::do_not_recommend]` attribute. This attribute was first proposed as `#[do_not_recommend`] attribute in RFC 2397 (https://github.com/rust-lang/rfcs/pull/2397). It gives the crate authors the ability to not suggest to the compiler to not show certain traits in it's error messages. With the presence of the `#[diagnostic]` tool attribute namespace it was decided to move the attribute there, as that lowers the amount of guarantees the compiler needs to give about the exact way this influences error messages. It turns the attribute into a hint which can be ignored. In addition to the original proposed functionality this attribute now also hides the marked trait in help messages ("This trait is implemented by: "). The attribute does not accept any argument and can only be placed on trait implementations. If it is placed somewhere else a lint warning is emitted and the attribute is otherwise ignored. If an argument is detected a lint warning is emitted and the argument is ignored. This follows the rules outlined by the diagnostic namespace. This attribute allows crates like diesel to improve their error messages drastically. The most common example here is the following error message: ``` error[E0277]: the trait bound `&str: Expression` is not satisfied --> /home/weiznich/Documents/rust/rust/tests/ui/diagnostic_namespace/do_not_recommend.rs:53:15 | LL | SelectInt.check("bar"); | ^^^^^ the trait `Expression` is not implemented for `&str`, which is required by `&str: AsExpression` | = help: the following other types implement trait `Expression`: Bound SelectInt note: required for `&str` to implement `AsExpression` --> /home/weiznich/Documents/rust/rust/tests/ui/diagnostic_namespace/do_not_recommend.rs:26:13 | LL | impl AsExpression for T | ^^^^^^^^^^^^^^^^ ^ LL | where LL | T: Expression, | ------------------------ unsatisfied trait bound introduced here ``` By applying the new attribute to the wild card trait implementation of `AsExpression` for `T: Expression` the error message becomes: ``` error[E0277]: the trait bound `&str: AsExpression` is not satisfied --> $DIR/as_expression.rs:55:15 | LL | SelectInt.check("bar"); | ^^^^^ the trait `AsExpression` is not implemented for `&str` | = help: the trait `AsExpression` is implemented for `&str` = help: for that trait implementation, expected `Text`, found `Integer` ``` which makes it much easier for users to understand that they are facing a type mismatch. Other explored example usages included * This standard library error message: https://github.com/rust-lang/rust/pull/128008 * That bevy derived example: https://github.com/rust-lang/rust/blob/e1f306899514ea80abc1d1c9f6a57762afb304a3/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs (No more tuple pyramids) Fixes #51992 --- compiler/rustc_feature/src/accepted.rs | 2 ++ compiler/rustc_feature/src/builtin_attrs.rs | 5 ++-- compiler/rustc_feature/src/unstable.rs | 2 -- compiler/rustc_resolve/src/macros.rs | 3 +-- library/core/src/lib.rs | 2 +- .../as_expression.current.stderr | 2 +- .../as_expression.next.stderr | 8 +++--- .../do_not_recommend/as_expression.rs | 2 -- ...ribute_without_feature_flag.current.stderr | 25 ------------------- ...attribute_without_feature_flag.next.stderr | 21 ---------------- ...ot_apply_attribute_without_feature_flag.rs | 24 ------------------ .../does_not_acccept_args.current.stderr | 6 ++--- .../does_not_acccept_args.next.stderr | 6 ++--- .../do_not_recommend/does_not_acccept_args.rs | 2 -- ...ature-gate-do_not_recommend.current.stderr | 15 ----------- .../feature-gate-do_not_recommend.next.stderr | 17 ------------- .../feature-gate-do_not_recommend.rs | 20 --------------- .../incorrect-locations.current.stderr | 16 ++++++------ .../incorrect-locations.next.stderr | 16 ++++++------ .../do_not_recommend/incorrect-locations.rs | 1 - .../do_not_recommend/nested.current.stderr | 4 +-- .../do_not_recommend/nested.next.stderr | 4 +-- .../do_not_recommend/nested.rs | 2 -- .../do_not_recommend/simple.current.stderr | 4 +-- .../do_not_recommend/simple.next.stderr | 4 +-- .../do_not_recommend/simple.rs | 2 -- .../do_not_recommend/stacked.current.stderr | 4 +-- .../do_not_recommend/stacked.next.stderr | 4 +-- .../do_not_recommend/stacked.rs | 2 -- ...supress_suggestions_in_help.current.stderr | 4 +-- .../supress_suggestions_in_help.next.stderr | 4 +-- .../supress_suggestions_in_help.rs | 2 -- .../type_mismatch.current.stderr | 4 +-- .../type_mismatch.next.stderr | 4 +-- .../do_not_recommend/type_mismatch.rs | 2 -- .../unstable-feature.current.stderr | 14 ----------- .../unstable-feature.next.stderr | 14 ----------- .../do_not_recommend/unstable-feature.rs | 11 -------- .../with_lifetime.current.stderr | 2 +- .../with_lifetime.next.stderr | 2 +- .../do_not_recommend/with_lifetime.rs | 2 -- 41 files changed, 55 insertions(+), 235 deletions(-) delete mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.current.stderr delete mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.next.stderr delete mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.rs delete mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.current.stderr delete mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.next.stderr delete mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.rs delete mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.current.stderr delete mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.next.stderr delete mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.rs diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs index 21fd11c1c5d..5a9b8c43e74 100644 --- a/compiler/rustc_feature/src/accepted.rs +++ b/compiler/rustc_feature/src/accepted.rs @@ -178,6 +178,8 @@ declare_features! ( (accepted, destructuring_assignment, "1.59.0", Some(71126)), /// Allows using the `#[diagnostic]` attribute tool namespace (accepted, diagnostic_namespace, "1.78.0", Some(111996)), + /// Controls errors in trait implementations. + (accepted, do_not_recommend, "CURRENT_RUSTC_VERSION", Some(51992)), /// Allows `#[doc(alias = "...")]`. (accepted, doc_alias, "1.48.0", Some(50146)), /// Allows `..` in tuple (struct) patterns. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index a065db7f7d0..4b9f62fa764 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -1187,10 +1187,9 @@ pub static BUILTIN_ATTRIBUTE_MAP: LazyLock> map }); -pub fn is_stable_diagnostic_attribute(sym: Symbol, features: &Features) -> bool { +pub fn is_stable_diagnostic_attribute(sym: Symbol, _features: &Features) -> bool { match sym { - sym::on_unimplemented => true, - sym::do_not_recommend => features.do_not_recommend(), + sym::on_unimplemented | sym::do_not_recommend => true, _ => false, } } diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 6570f9b565f..ebb07195a28 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -462,8 +462,6 @@ declare_features! ( (unstable, deprecated_suggestion, "1.61.0", Some(94785)), /// Allows deref patterns. (incomplete, deref_patterns, "1.79.0", Some(87121)), - /// Controls errors in trait implementations. - (unstable, do_not_recommend, "1.67.0", Some(51992)), /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`. (unstable, doc_auto_cfg, "1.58.0", Some(43781)), /// Allows `#[doc(cfg(...))]`. diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index edee19c280a..b24e343c58d 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -689,8 +689,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && let [namespace, attribute, ..] = &*path.segments && namespace.ident.name == sym::diagnostic && !(attribute.ident.name == sym::on_unimplemented - || (attribute.ident.name == sym::do_not_recommend - && self.tcx.features().do_not_recommend())) + || attribute.ident.name == sym::do_not_recommend) { let distance = edit_distance(attribute.ident.name.as_str(), sym::on_unimplemented.as_str(), 5); diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 922866f95dc..18bd9bb8118 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -108,12 +108,12 @@ // Library features: // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(coverage_attribute))] +#![cfg_attr(bootstrap, feature(do_not_recommend))] #![feature(array_ptr_get)] #![feature(asm_experimental_arch)] #![feature(const_eval_select)] #![feature(const_typed_swap)] #![feature(core_intrinsics)] -#![feature(do_not_recommend)] #![feature(internal_impls_macro)] #![feature(ip)] #![feature(is_ascii_octdigit)] diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr index 5d0c1826411..28e7975c7a2 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `&str: AsExpression` is not satisfied - --> $DIR/as_expression.rs:57:15 + --> $DIR/as_expression.rs:55:15 | LL | SelectInt.check("bar"); | ^^^^^ the trait `AsExpression` is not implemented for `&str` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr index 1e1eae852f9..1b76669ccb0 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.next.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `&str: AsExpression<::SqlType>` is not satisfied - --> $DIR/as_expression.rs:57:21 + --> $DIR/as_expression.rs:55:21 | LL | SelectInt.check("bar"); | ----- ^^^^^ the trait `AsExpression<::SqlType>` is not implemented for `&str` @@ -8,7 +8,7 @@ LL | SelectInt.check("bar"); | = help: the trait `AsExpression` is implemented for `&str` note: required by a bound in `Foo::check` - --> $DIR/as_expression.rs:48:12 + --> $DIR/as_expression.rs:46:12 | LL | fn check(&self, _: T) -> ::SqlType>>::Expression | ----- required by a bound in this associated function @@ -17,7 +17,7 @@ LL | T: AsExpression, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::check` error[E0277]: the trait bound `&str: AsExpression` is not satisfied - --> $DIR/as_expression.rs:57:15 + --> $DIR/as_expression.rs:55:15 | LL | SelectInt.check("bar"); | ^^^^^ the trait `AsExpression` is not implemented for `&str` @@ -27,7 +27,7 @@ LL | SelectInt.check("bar"); = help: for that trait implementation, expected `Text`, found `Integer` error[E0271]: type mismatch resolving `::SqlType == Text` - --> $DIR/as_expression.rs:57:5 + --> $DIR/as_expression.rs:55:5 | LL | SelectInt.check("bar"); | ^^^^^^^^^^^^^^^^^^^^^^ expected `Text`, found `Integer` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs index 37b4429f694..583b3c4675a 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/as_expression.rs @@ -2,8 +2,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(do_not_recommend)] - pub trait Expression { type SqlType; } diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.current.stderr deleted file mode 100644 index 660fc7d2171..00000000000 --- a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.current.stderr +++ /dev/null @@ -1,25 +0,0 @@ -error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/do_not_apply_attribute_without_feature_flag.rs:22:11 - | -LL | check(()); - | ----- ^^ the trait `Foo` is not implemented for `()` - | | - | required by a bound introduced by this call - | - = help: the following other types implement trait `Foo`: - (A, B) - (A, B, C) - (A,) -note: required by a bound in `check` - --> $DIR/do_not_apply_attribute_without_feature_flag.rs:19:18 - | -LL | fn check(a: impl Foo) {} - | ^^^ required by this bound in `check` -help: use a unary tuple instead - | -LL | check(((),)); - | + ++ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.next.stderr deleted file mode 100644 index 1cd148186f1..00000000000 --- a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.next.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/do_not_apply_attribute_without_feature_flag.rs:22:11 - | -LL | check(()); - | ----- ^^ the trait `Foo` is not implemented for `()` - | | - | required by a bound introduced by this call - | - = help: the following other types implement trait `Foo`: - (A, B) - (A, B, C) - (A,) -note: required by a bound in `check` - --> $DIR/do_not_apply_attribute_without_feature_flag.rs:19:18 - | -LL | fn check(a: impl Foo) {} - | ^^^ required by this bound in `check` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.rs b/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.rs deleted file mode 100644 index 9c25069bc7d..00000000000 --- a/tests/ui/diagnostic_namespace/do_not_recommend/do_not_apply_attribute_without_feature_flag.rs +++ /dev/null @@ -1,24 +0,0 @@ -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver -#![allow(unknown_or_malformed_diagnostic_attributes)] - -trait Foo {} - -#[diagnostic::do_not_recommend] -impl Foo for (A,) {} - -#[diagnostic::do_not_recommend] -impl Foo for (A, B) {} - -#[diagnostic::do_not_recommend] -impl Foo for (A, B, C) {} - -impl Foo for i32 {} - -fn check(a: impl Foo) {} - -fn main() { - check(()); - //~^ ERROR the trait bound `(): Foo` is not satisfied -} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr index 3d004ca559e..47597a5d405 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.current.stderr @@ -1,5 +1,5 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:12:1 + --> $DIR/does_not_acccept_args.rs:10:1 | LL | #[diagnostic::do_not_recommend(not_accepted)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,13 +7,13 @@ LL | #[diagnostic::do_not_recommend(not_accepted)] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:16:1 + --> $DIR/does_not_acccept_args.rs:14:1 | LL | #[diagnostic::do_not_recommend(not_accepted = "foo")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:20:1 + --> $DIR/does_not_acccept_args.rs:18:1 | LL | #[diagnostic::do_not_recommend(not_accepted(42))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr index 3d004ca559e..47597a5d405 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.next.stderr @@ -1,5 +1,5 @@ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:12:1 + --> $DIR/does_not_acccept_args.rs:10:1 | LL | #[diagnostic::do_not_recommend(not_accepted)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,13 +7,13 @@ LL | #[diagnostic::do_not_recommend(not_accepted)] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:16:1 + --> $DIR/does_not_acccept_args.rs:14:1 | LL | #[diagnostic::do_not_recommend(not_accepted = "foo")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` does not expect any arguments - --> $DIR/does_not_acccept_args.rs:20:1 + --> $DIR/does_not_acccept_args.rs:18:1 | LL | #[diagnostic::do_not_recommend(not_accepted(42))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs index f3295546f34..eeff5e2e6e8 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/does_not_acccept_args.rs @@ -3,8 +3,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(do_not_recommend)] - trait Foo {} trait Bar {} trait Baz {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.current.stderr deleted file mode 100644 index d1deaa6a006..00000000000 --- a/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.current.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0277]: the trait bound `u8: Bar` is not satisfied - --> $DIR/feature-gate-do_not_recommend.rs:18:11 - | -LL | stuff(1u8); - | ^^^ the trait `Bar` is not implemented for `u8` - | -note: required by a bound in `stuff` - --> $DIR/feature-gate-do_not_recommend.rs:15:13 - | -LL | fn stuff(_: T) {} - | ^^^ required by this bound in `stuff` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.next.stderr deleted file mode 100644 index 5bfcc60edc5..00000000000 --- a/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.next.stderr +++ /dev/null @@ -1,17 +0,0 @@ -error[E0277]: the trait bound `u8: Bar` is not satisfied - --> $DIR/feature-gate-do_not_recommend.rs:18:11 - | -LL | stuff(1u8); - | ----- ^^^ the trait `Bar` is not implemented for `u8` - | | - | required by a bound introduced by this call - | -note: required by a bound in `stuff` - --> $DIR/feature-gate-do_not_recommend.rs:15:13 - | -LL | fn stuff(_: T) {} - | ^^^ required by this bound in `stuff` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.rs b/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.rs deleted file mode 100644 index 4adce112f15..00000000000 --- a/tests/ui/diagnostic_namespace/do_not_recommend/feature-gate-do_not_recommend.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver -#![feature(do_not_recommend)] - -pub trait Foo {} - -impl Foo for i32 {} - -pub trait Bar {} - -#[diagnostic::do_not_recommend] -impl Bar for T {} - -fn stuff(_: T) {} - -fn main() { - stuff(1u8); - //~^ the trait bound `u8: Bar` is not satisfied -} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr index 84ab0827ab6..0b0dac32b39 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr @@ -1,5 +1,5 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:7:1 + --> $DIR/incorrect-locations.rs:6:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,43 +7,43 @@ LL | #[diagnostic::do_not_recommend] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:11:1 + --> $DIR/incorrect-locations.rs:10:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:15:1 + --> $DIR/incorrect-locations.rs:14:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:19:1 + --> $DIR/incorrect-locations.rs:18:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:23:1 + --> $DIR/incorrect-locations.rs:22:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:27:1 + --> $DIR/incorrect-locations.rs:26:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:31:1 + --> $DIR/incorrect-locations.rs:30:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:35:1 + --> $DIR/incorrect-locations.rs:34:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr index 84ab0827ab6..0b0dac32b39 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr @@ -1,5 +1,5 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:7:1 + --> $DIR/incorrect-locations.rs:6:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,43 +7,43 @@ LL | #[diagnostic::do_not_recommend] = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:11:1 + --> $DIR/incorrect-locations.rs:10:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:15:1 + --> $DIR/incorrect-locations.rs:14:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:19:1 + --> $DIR/incorrect-locations.rs:18:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:23:1 + --> $DIR/incorrect-locations.rs:22:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:27:1 + --> $DIR/incorrect-locations.rs:26:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:31:1 + --> $DIR/incorrect-locations.rs:30:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - --> $DIR/incorrect-locations.rs:35:1 + --> $DIR/incorrect-locations.rs:34:1 | LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs index daacf55ea79..014be580f61 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs @@ -2,7 +2,6 @@ //@ revisions: current next //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(do_not_recommend)] #[diagnostic::do_not_recommend] //~^WARN `#[diagnostic::do_not_recommend]` can only be placed diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/nested.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/nested.current.stderr index 2e08a679360..b14c68d6897 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/nested.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/nested.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `(): Root` is not satisfied - --> $DIR/nested.rs:23:18 + --> $DIR/nested.rs:21:18 | LL | needs_root::<()>(); | ^^ the trait `Root` is not implemented for `()` | note: required by a bound in `needs_root` - --> $DIR/nested.rs:20:18 + --> $DIR/nested.rs:18:18 | LL | fn needs_root() {} | ^^^^ required by this bound in `needs_root` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/nested.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/nested.next.stderr index 2e08a679360..b14c68d6897 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/nested.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/nested.next.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `(): Root` is not satisfied - --> $DIR/nested.rs:23:18 + --> $DIR/nested.rs:21:18 | LL | needs_root::<()>(); | ^^ the trait `Root` is not implemented for `()` | note: required by a bound in `needs_root` - --> $DIR/nested.rs:20:18 + --> $DIR/nested.rs:18:18 | LL | fn needs_root() {} | ^^^^ required by this bound in `needs_root` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/nested.rs b/tests/ui/diagnostic_namespace/do_not_recommend/nested.rs index d499cff9f56..6534157d1fb 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/nested.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/nested.rs @@ -2,8 +2,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(do_not_recommend)] - trait Root {} trait DontRecommend {} trait Other {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/simple.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/simple.current.stderr index 729cb5694e2..884b13c17b8 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/simple.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/simple.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `*mut (): Foo` is not satisfied - --> $DIR/simple.rs:17:17 + --> $DIR/simple.rs:15:17 | LL | needs_foo::<*mut ()>(); | ^^^^^^^ the trait `Foo` is not implemented for `*mut ()` | note: required by a bound in `needs_foo` - --> $DIR/simple.rs:12:17 + --> $DIR/simple.rs:10:17 | LL | fn needs_foo() {} | ^^^ required by this bound in `needs_foo` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/simple.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/simple.next.stderr index 729cb5694e2..884b13c17b8 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/simple.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/simple.next.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `*mut (): Foo` is not satisfied - --> $DIR/simple.rs:17:17 + --> $DIR/simple.rs:15:17 | LL | needs_foo::<*mut ()>(); | ^^^^^^^ the trait `Foo` is not implemented for `*mut ()` | note: required by a bound in `needs_foo` - --> $DIR/simple.rs:12:17 + --> $DIR/simple.rs:10:17 | LL | fn needs_foo() {} | ^^^ required by this bound in `needs_foo` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs b/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs index 780649b009c..6bca2b724d2 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/simple.rs @@ -2,8 +2,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(do_not_recommend)] - trait Foo {} #[diagnostic::do_not_recommend] diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.current.stderr index 41a10a61e1d..d8605806395 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `(): Root` is not satisfied - --> $DIR/stacked.rs:19:18 + --> $DIR/stacked.rs:17:18 | LL | needs_root::<()>(); | ^^ the trait `Root` is not implemented for `()` | note: required by a bound in `needs_root` - --> $DIR/stacked.rs:16:18 + --> $DIR/stacked.rs:14:18 | LL | fn needs_root() {} | ^^^^ required by this bound in `needs_root` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.next.stderr index 41a10a61e1d..d8605806395 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.next.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `(): Root` is not satisfied - --> $DIR/stacked.rs:19:18 + --> $DIR/stacked.rs:17:18 | LL | needs_root::<()>(); | ^^ the trait `Root` is not implemented for `()` | note: required by a bound in `needs_root` - --> $DIR/stacked.rs:16:18 + --> $DIR/stacked.rs:14:18 | LL | fn needs_root() {} | ^^^^ required by this bound in `needs_root` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs index fc355bdc4e2..842e04b9d90 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/stacked.rs @@ -2,8 +2,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(do_not_recommend)] - trait Root {} trait DontRecommend {} trait Other {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr index ca9a6ebc1c4..95ccbb92a89 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/supress_suggestions_in_help.rs:23:11 + --> $DIR/supress_suggestions_in_help.rs:21:11 | LL | check(()); | ----- ^^ the trait `Foo` is not implemented for `()` @@ -8,7 +8,7 @@ LL | check(()); | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `check` - --> $DIR/supress_suggestions_in_help.rs:20:18 + --> $DIR/supress_suggestions_in_help.rs:18:18 | LL | fn check(a: impl Foo) {} | ^^^ required by this bound in `check` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr index ca9a6ebc1c4..95ccbb92a89 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.next.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/supress_suggestions_in_help.rs:23:11 + --> $DIR/supress_suggestions_in_help.rs:21:11 | LL | check(()); | ----- ^^ the trait `Foo` is not implemented for `()` @@ -8,7 +8,7 @@ LL | check(()); | = help: the trait `Foo` is implemented for `i32` note: required by a bound in `check` - --> $DIR/supress_suggestions_in_help.rs:20:18 + --> $DIR/supress_suggestions_in_help.rs:18:18 | LL | fn check(a: impl Foo) {} | ^^^ required by this bound in `check` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs index ef6f255c351..2c7c1516123 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/supress_suggestions_in_help.rs @@ -2,8 +2,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(do_not_recommend)] - trait Foo {} #[diagnostic::do_not_recommend] diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr index bcede8a255f..b53febbb71a 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr @@ -1,11 +1,11 @@ error[E0277]: Very important message! - --> $DIR/type_mismatch.rs:25:14 + --> $DIR/type_mismatch.rs:23:14 | LL | verify::(); | ^^ the trait `TheImportantOne` is not implemented for `u8` | note: required by a bound in `verify` - --> $DIR/type_mismatch.rs:22:14 + --> $DIR/type_mismatch.rs:20:14 | LL | fn verify() {} | ^^^^^^^^^^^^^^^ required by this bound in `verify` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr index bcede8a255f..b53febbb71a 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr @@ -1,11 +1,11 @@ error[E0277]: Very important message! - --> $DIR/type_mismatch.rs:25:14 + --> $DIR/type_mismatch.rs:23:14 | LL | verify::(); | ^^ the trait `TheImportantOne` is not implemented for `u8` | note: required by a bound in `verify` - --> $DIR/type_mismatch.rs:22:14 + --> $DIR/type_mismatch.rs:20:14 | LL | fn verify() {} | ^^^^^^^^^^^^^^^ required by this bound in `verify` diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs index d6721ccc848..7f30fdb06c7 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs @@ -2,8 +2,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(do_not_recommend)] - #[diagnostic::on_unimplemented(message = "Very important message!")] trait TheImportantOne {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.current.stderr deleted file mode 100644 index fdea9eacae1..00000000000 --- a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.current.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: unknown diagnostic attribute - --> $DIR/unstable-feature.rs:7:15 - | -LL | #[diagnostic::do_not_recommend] - | ^^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/unstable-feature.rs:4:9 - | -LL | #![deny(unknown_or_malformed_diagnostic_attributes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.next.stderr deleted file mode 100644 index fdea9eacae1..00000000000 --- a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.next.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: unknown diagnostic attribute - --> $DIR/unstable-feature.rs:7:15 - | -LL | #[diagnostic::do_not_recommend] - | ^^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/unstable-feature.rs:4:9 - | -LL | #![deny(unknown_or_malformed_diagnostic_attributes)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 1 previous error - diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.rs b/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.rs deleted file mode 100644 index 7a67f67b67f..00000000000 --- a/tests/ui/diagnostic_namespace/do_not_recommend/unstable-feature.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ revisions: current next -//@ ignore-compare-mode-next-solver (explicit revisions) -//@[next] compile-flags: -Znext-solver -#![deny(unknown_or_malformed_diagnostic_attributes)] -trait Foo {} - -#[diagnostic::do_not_recommend] -//~^ ERROR unknown diagnostic attribute [unknown_or_malformed_diagnostic_attributes] -impl Foo for i32 {} - -fn main() {} diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.current.stderr index c2874cf4594..a8429ff60f8 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.current.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/with_lifetime.rs:19:5 + --> $DIR/with_lifetime.rs:17:5 | LL | fn foo<'a>(a: &'a ()) { | -- lifetime `'a` defined here diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.next.stderr index c2874cf4594..a8429ff60f8 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.next.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/with_lifetime.rs:19:5 + --> $DIR/with_lifetime.rs:17:5 | LL | fn foo<'a>(a: &'a ()) { | -- lifetime `'a` defined here diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs index 9aaf7f33ecd..6a67d83d5fe 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/with_lifetime.rs @@ -2,8 +2,6 @@ //@ ignore-compare-mode-next-solver (explicit revisions) //@[next] compile-flags: -Znext-solver -#![feature(do_not_recommend)] - trait Root {} trait DontRecommend {} From ad29947f02520878d6e60e6b26b3a55fae3b7982 Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Fri, 25 Oct 2024 08:54:05 +0200 Subject: [PATCH 11/20] Also warn against `#[diagnostic::do_not_recommend]` on plain impls --- compiler/rustc_passes/src/check_attr.rs | 11 +++++++++-- .../incorrect-locations.current.stderr | 8 +++++++- .../do_not_recommend/incorrect-locations.next.stderr | 8 +++++++- .../do_not_recommend/incorrect-locations.rs | 4 ++++ 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 9879dfa9720..2310dd9dc72 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -115,7 +115,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { for attr in attrs { match attr.path().as_slice() { [sym::diagnostic, sym::do_not_recommend, ..] => { - self.check_do_not_recommend(attr.span, hir_id, target, attr) + self.check_do_not_recommend(attr.span, hir_id, target, attr, item) } [sym::diagnostic, sym::on_unimplemented, ..] => { self.check_diagnostic_on_unimplemented(attr.span, hir_id, target) @@ -354,8 +354,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> { hir_id: HirId, target: Target, attr: &Attribute, + item: Option>, ) { - if !matches!(target, Target::Impl) { + if !matches!(target, Target::Impl) + || matches!( + item, + Some(ItemLike::Item(hir::Item { kind: hir::ItemKind::Impl(_impl),.. })) + if _impl.of_trait.is_none() + ) + { self.tcx.emit_node_span_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, hir_id, diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr index 0b0dac32b39..ee6ebabadd9 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.current.stderr @@ -48,5 +48,11 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implement LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 8 warnings emitted +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:38:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 9 warnings emitted diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr index 0b0dac32b39..ee6ebabadd9 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.next.stderr @@ -48,5 +48,11 @@ warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implement LL | #[diagnostic::do_not_recommend] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: 8 warnings emitted +warning: `#[diagnostic::do_not_recommend]` can only be placed on trait implementations + --> $DIR/incorrect-locations.rs:38:1 + | +LL | #[diagnostic::do_not_recommend] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +warning: 9 warnings emitted diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs index 014be580f61..1cf436aa2af 100644 --- a/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs +++ b/tests/ui/diagnostic_namespace/do_not_recommend/incorrect-locations.rs @@ -19,6 +19,10 @@ type Type = (); //~^WARN `#[diagnostic::do_not_recommend]` can only be placed enum Enum {} +#[diagnostic::do_not_recommend] +//~^WARN `#[diagnostic::do_not_recommend]` can only be placed +impl Enum {} + #[diagnostic::do_not_recommend] //~^WARN `#[diagnostic::do_not_recommend]` can only be placed extern "C" {} From 38ce73145c894399471c7a4bae588ac3c913b0a3 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 26 Nov 2024 09:29:01 +0100 Subject: [PATCH 12/20] canonicalizer: keep 'static in the param_env --- .../src/canonicalizer.rs | 119 ++++++++++++++---- .../src/solve/eval_ctxt/canonical.rs | 23 ++-- 2 files changed, 102 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs index 63608f9e856..2f7301d8fe5 100644 --- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs +++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs @@ -3,6 +3,7 @@ use std::cmp::Ordering; use rustc_type_ir::data_structures::HashMap; use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; +use rustc_type_ir::solve::{Goal, QueryInput}; use rustc_type_ir::visit::TypeVisitableExt; use rustc_type_ir::{ self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, InferCtxtLike, @@ -17,8 +18,11 @@ use crate::delegate::SolverDelegate; /// while canonicalizing the response happens in the context of the /// query. #[derive(Debug, Clone, Copy)] -pub enum CanonicalizeMode { - Input, +enum CanonicalizeMode { + /// When canonicalizing the `param_env`, we keep `'static` as merging + /// trait candidates relies on it when deciding whether a where-bound + /// is trivial. + Input { keep_static: bool }, /// FIXME: We currently return region constraints referring to /// placeholders and inference variables from a binder instantiated /// inside of the query. @@ -59,15 +63,15 @@ pub struct Canonicalizer<'a, D: SolverDelegate, I: Interner> { } impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { - pub fn canonicalize>( + pub fn canonicalize_response>( delegate: &'a D, - canonicalize_mode: CanonicalizeMode, + max_input_universe: ty::UniverseIndex, variables: &'a mut Vec, value: T, ) -> ty::Canonical { let mut canonicalizer = Canonicalizer { delegate, - canonicalize_mode, + canonicalize_mode: CanonicalizeMode::Response { max_input_universe }, variables, variable_lookup_table: Default::default(), @@ -80,9 +84,67 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { let value = value.fold_with(&mut canonicalizer); assert!(!value.has_infer(), "unexpected infer in {value:?}"); assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}"); - let (max_universe, variables) = canonicalizer.finalize(); + Canonical { max_universe, variables, value } + } + /// When canonicalizing query inputs, we keep `'static` in the `param_env` + /// but erase it everywhere else. We generally don't want to depend on region + /// identity, so while it should not matter whether `'static` is kept in the + /// value or opaque type storage as well, this prevents us from accidentally + /// relying on it in the future. + /// + /// We want to keep the option of canonicalizing `'static` to an existential + /// variable in the future by changing the way we detect global where-bounds. + pub fn canonicalize_input>( + delegate: &'a D, + variables: &'a mut Vec, + input: QueryInput, + ) -> ty::Canonical> { + // First canonicalize the `param_env` while keeping `'static` + let mut env_canonicalizer = Canonicalizer { + delegate, + canonicalize_mode: CanonicalizeMode::Input { keep_static: true }, + + variables, + variable_lookup_table: Default::default(), + primitive_var_infos: Vec::new(), + binder_index: ty::INNERMOST, + + cache: Default::default(), + }; + let param_env = input.goal.param_env.fold_with(&mut env_canonicalizer); + debug_assert_eq!(env_canonicalizer.binder_index, ty::INNERMOST); + // Then canonicalize the rest of the input without keeping `'static` + // while *mostly* reusing the canonicalizer from above. + let mut rest_canonicalizer = Canonicalizer { + delegate, + canonicalize_mode: CanonicalizeMode::Input { keep_static: false }, + + variables: env_canonicalizer.variables, + // We're able to reuse the `variable_lookup_table` as whether or not + // it already contains an entry for `'static` does not matter. + variable_lookup_table: env_canonicalizer.variable_lookup_table, + primitive_var_infos: env_canonicalizer.primitive_var_infos, + binder_index: ty::INNERMOST, + + // We do not reuse the cache as it may contain entries whose canonicalized + // value contains `'static`. While we could alternatively handle this by + // checking for `'static` when using cached entries, this does not + // feel worth the effort. I do not expect that a `ParamEnv` will ever + // contain large enough types for caching to be necessary. + cache: Default::default(), + }; + + let predicate = input.goal.predicate.fold_with(&mut rest_canonicalizer); + let goal = Goal { param_env, predicate }; + let predefined_opaques_in_body = + input.predefined_opaques_in_body.fold_with(&mut rest_canonicalizer); + let value = QueryInput { goal, predefined_opaques_in_body }; + + assert!(!value.has_infer(), "unexpected infer in {value:?}"); + assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}"); + let (max_universe, variables) = rest_canonicalizer.finalize(); Canonical { max_universe, variables, value } } @@ -126,7 +188,7 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { // all information which should not matter for the solver. // // For this we compress universes as much as possible. - CanonicalizeMode::Input => {} + CanonicalizeMode::Input { .. } => {} // When canonicalizing a response we map a universes already entered // by the caller to the root universe and only return useful universe // information for placeholders and inference variables created inside @@ -290,17 +352,15 @@ impl<'a, D: SolverDelegate, I: Interner> Canonicalizer<'a, D, I> { } }, ty::Placeholder(placeholder) => match self.canonicalize_mode { - CanonicalizeMode::Input => CanonicalVarKind::PlaceholderTy(PlaceholderLike::new( - placeholder.universe(), - self.variables.len().into(), - )), + CanonicalizeMode::Input { .. } => CanonicalVarKind::PlaceholderTy( + PlaceholderLike::new(placeholder.universe(), self.variables.len().into()), + ), CanonicalizeMode::Response { .. } => CanonicalVarKind::PlaceholderTy(placeholder), }, ty::Param(_) => match self.canonicalize_mode { - CanonicalizeMode::Input => CanonicalVarKind::PlaceholderTy(PlaceholderLike::new( - ty::UniverseIndex::ROOT, - self.variables.len().into(), - )), + CanonicalizeMode::Input { .. } => CanonicalVarKind::PlaceholderTy( + PlaceholderLike::new(ty::UniverseIndex::ROOT, self.variables.len().into()), + ), CanonicalizeMode::Response { .. } => panic!("param ty in response: {t:?}"), }, ty::Bool @@ -357,21 +417,30 @@ impl, I: Interner> TypeFolder for Canonicaliz let kind = match r.kind() { ty::ReBound(..) => return r, - // We may encounter `ReStatic` in item signatures or the hidden type - // of an opaque. `ReErased` should only be encountered in the hidden + // We don't canonicalize `ReStatic` in the `param_env` as we use it + // when checking whether a `ParamEnv` candidate is global. + ty::ReStatic => match self.canonicalize_mode { + CanonicalizeMode::Input { keep_static: false } => { + CanonicalVarKind::Region(ty::UniverseIndex::ROOT) + } + CanonicalizeMode::Input { keep_static: true } + | CanonicalizeMode::Response { .. } => return r, + }, + + // `ReErased` should only be encountered in the hidden // type of an opaque for regions that are ignored for the purposes of // captures. // // FIXME: We should investigate the perf implications of not uniquifying // `ReErased`. We may be able to short-circuit registering region // obligations if we encounter a `ReErased` on one side, for example. - ty::ReStatic | ty::ReErased | ty::ReError(_) => match self.canonicalize_mode { - CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), + ty::ReErased | ty::ReError(_) => match self.canonicalize_mode { + CanonicalizeMode::Input { .. } => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), CanonicalizeMode::Response { .. } => return r, }, ty::ReEarlyParam(_) | ty::ReLateParam(_) => match self.canonicalize_mode { - CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), + CanonicalizeMode::Input { .. } => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), CanonicalizeMode::Response { .. } => { panic!("unexpected region in response: {r:?}") } @@ -379,7 +448,7 @@ impl, I: Interner> TypeFolder for Canonicaliz ty::RePlaceholder(placeholder) => match self.canonicalize_mode { // We canonicalize placeholder regions as existentials in query inputs. - CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), + CanonicalizeMode::Input { .. } => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), CanonicalizeMode::Response { max_input_universe } => { // If we have a placeholder region inside of a query, it must be from // a new universe. @@ -397,7 +466,9 @@ impl, I: Interner> TypeFolder for Canonicaliz "region vid should have been resolved fully before canonicalization" ); match self.canonicalize_mode { - CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT), + CanonicalizeMode::Input { keep_static: _ } => { + CanonicalVarKind::Region(ty::UniverseIndex::ROOT) + } CanonicalizeMode::Response { .. } => { CanonicalVarKind::Region(self.delegate.universe_of_lt(vid).unwrap()) } @@ -434,7 +505,7 @@ impl, I: Interner> TypeFolder for Canonicaliz ty::InferConst::Fresh(_) => todo!(), }, ty::ConstKind::Placeholder(placeholder) => match self.canonicalize_mode { - CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst( + CanonicalizeMode::Input { .. } => CanonicalVarKind::PlaceholderConst( PlaceholderLike::new(placeholder.universe(), self.variables.len().into()), ), CanonicalizeMode::Response { .. } => { @@ -442,7 +513,7 @@ impl, I: Interner> TypeFolder for Canonicaliz } }, ty::ConstKind::Param(_) => match self.canonicalize_mode { - CanonicalizeMode::Input => CanonicalVarKind::PlaceholderConst( + CanonicalizeMode::Input { .. } => CanonicalVarKind::PlaceholderConst( PlaceholderLike::new(ty::UniverseIndex::ROOT, self.variables.len().into()), ), CanonicalizeMode::Response { .. } => panic!("param ty in response: {c:?}"), diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs index a143af13688..e99cd3d2727 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs @@ -18,7 +18,7 @@ use rustc_type_ir::relate::solver_relating::RelateExt; use rustc_type_ir::{self as ty, Canonical, CanonicalVarValues, InferCtxtLike, Interner}; use tracing::{debug, instrument, trace}; -use crate::canonicalizer::{CanonicalizeMode, Canonicalizer}; +use crate::canonicalizer::Canonicalizer; use crate::delegate::SolverDelegate; use crate::resolve::EagerResolver; use crate::solve::eval_ctxt::NestedGoals; @@ -60,17 +60,13 @@ where (goal, opaque_types).fold_with(&mut EagerResolver::new(self.delegate)); let mut orig_values = Default::default(); - let canonical = Canonicalizer::canonicalize( - self.delegate, - CanonicalizeMode::Input, - &mut orig_values, - QueryInput { + let canonical = + Canonicalizer::canonicalize_input(self.delegate, &mut orig_values, QueryInput { goal, predefined_opaques_in_body: self .cx() .mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }), - }, - ); + }); let query_input = ty::CanonicalQueryInput { canonical, typing_mode: self.typing_mode() }; (orig_values, query_input) } @@ -148,9 +144,9 @@ where .region_constraints .retain(|outlives| outlives.0.as_region().map_or(true, |re| re != outlives.1)); - let canonical = Canonicalizer::canonicalize( + let canonical = Canonicalizer::canonicalize_response( self.delegate, - CanonicalizeMode::Response { max_input_universe: self.max_input_universe }, + self.max_input_universe, &mut Default::default(), Response { var_values, @@ -428,12 +424,7 @@ where let var_values = CanonicalVarValues { var_values: delegate.cx().mk_args(var_values) }; let state = inspect::State { var_values, data }; let state = state.fold_with(&mut EagerResolver::new(delegate)); - Canonicalizer::canonicalize( - delegate, - CanonicalizeMode::Response { max_input_universe }, - &mut vec![], - state, - ) + Canonicalizer::canonicalize_response(delegate, max_input_universe, &mut vec![], state) } // FIXME: needs to be pub to be accessed by downstream From 6734a04c0a6aff674011c9b4cb1c89cba2636c4d Mon Sep 17 00:00:00 2001 From: acceptacross Date: Wed, 18 Dec 2024 23:23:44 +0800 Subject: [PATCH 13/20] chore: fix some typos Signed-off-by: acceptacross --- compiler/rustc_codegen_cranelift/src/compiler_builtins.rs | 2 +- compiler/rustc_codegen_gcc/src/intrinsic/mod.rs | 2 +- compiler/rustc_errors/src/emitter.rs | 2 +- compiler/rustc_errors/src/markdown/parse.rs | 2 +- compiler/rustc_resolve/src/late.rs | 2 +- compiler/rustc_trait_selection/src/traits/mod.rs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs b/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs index 4154a62234c..f8e3a034421 100644 --- a/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs +++ b/compiler/rustc_codegen_cranelift/src/compiler_builtins.rs @@ -3,7 +3,7 @@ use std::ffi::c_int; #[cfg(feature = "jit")] use std::ffi::c_void; -// FIXME replace with core::ffi::c_size_t once stablized +// FIXME replace with core::ffi::c_size_t once stabilized #[allow(non_camel_case_types)] #[cfg(feature = "jit")] type size_t = usize; diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs index 69326f409bb..78ec9741f57 100644 --- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs +++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs @@ -66,7 +66,7 @@ fn get_simple_intrinsic<'gcc, 'tcx>( sym::log2f64 => "log2", sym::fmaf32 => "fmaf", sym::fmaf64 => "fma", - // FIXME: calling `fma` from libc without FMA target feature uses expensive sofware emulation + // FIXME: calling `fma` from libc without FMA target feature uses expensive software emulation sym::fmuladdf32 => "fmaf", // TODO: use gcc intrinsic analogous to llvm.fmuladd.f32 sym::fmuladdf64 => "fma", // TODO: use gcc intrinsic analogous to llvm.fmuladd.f64 sym::fabsf32 => "fabsf", diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index ac2f91cdeb3..f63188402fe 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2523,7 +2523,7 @@ impl HumanEmitter { buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); } [] => { - // FIXME: needed? Doesn't get excercised in any test. + // FIXME: needed? Doesn't get exercised in any test. self.draw_col_separator_no_space(buffer, *row_num, max_line_num_len + 1); } _ => { diff --git a/compiler/rustc_errors/src/markdown/parse.rs b/compiler/rustc_errors/src/markdown/parse.rs index 8dd146c1c33..7a991a2ace7 100644 --- a/compiler/rustc_errors/src/markdown/parse.rs +++ b/compiler/rustc_errors/src/markdown/parse.rs @@ -346,7 +346,7 @@ fn parse_with_end_pat<'a>( None } -/// Resturn `(match, residual)` to end of line. The EOL is returned with the +/// Return `(match, residual)` to end of line. The EOL is returned with the /// residual. fn parse_to_newline(buf: &[u8]) -> (&[u8], &[u8]) { buf.iter().position(|ch| *ch == b'\n').map_or((buf, &[]), |pos| buf.split_at(pos)) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index a48a2865228..7324d3fe786 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4325,7 +4325,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { #[inline] /// If we're actually rustdoc then avoid giving a name resolution error for `cfg()` items or - // an invalid `use foo::*;` was found, which can cause unbounded ammounts of "item not found" + // an invalid `use foo::*;` was found, which can cause unbounded amounts of "item not found" // errors. We silence them all. fn should_report_errs(&self) -> bool { !(self.r.tcx.sess.opts.actually_rustdoc && self.in_func_body) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 069d42d4018..1dcd0d0dfb8 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -599,7 +599,7 @@ pub fn try_evaluate_const<'tcx>( // even though it is not something we should ever actually encounter. // // Array repeat expr counts are allowed to syntactically use generic parameters - // but must not actually depend on them in order to evalaute succesfully. This means + // but must not actually depend on them in order to evalaute successfully. This means // that it is actually fine to evalaute them in their own environment rather than with // the actually provided generic arguments. tcx.dcx().delayed_bug( From d5a0c5cfdbebc1366c8c801b3b7f9348f0197296 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 26 Nov 2024 12:09:42 +0100 Subject: [PATCH 14/20] update new solver candidate assembly --- compiler/rustc_middle/src/ty/mod.rs | 2 +- .../src/solve/assembly/mod.rs | 134 ++++++++---------- .../src/solve/effect_goals.rs | 8 +- .../src/solve/eval_ctxt/mod.rs | 2 +- .../rustc_next_trait_solver/src/solve/mod.rs | 25 ++-- .../src/solve/normalizes_to/mod.rs | 11 +- .../src/solve/trait_goals.rs | 93 +++++++++++- compiler/rustc_type_ir/src/inherent.rs | 2 +- ...-method-resolution-opaque-type.next.stderr | 9 -- ...e-method-resolution-opaque-type.old.stderr | 4 +- ...rm-before-method-resolution-opaque-type.rs | 2 +- 11 files changed, 187 insertions(+), 105 deletions(-) delete mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 25d0d7b71da..830ae7dd00a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -971,7 +971,7 @@ pub struct ParamEnv<'tcx> { } impl<'tcx> rustc_type_ir::inherent::ParamEnv> for ParamEnv<'tcx> { - fn caller_bounds(self) -> impl IntoIterator> { + fn caller_bounds(self) -> impl inherent::SliceLike> { self.caller_bounds() } } diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 198ccb000f3..02f6439b77f 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -11,6 +11,7 @@ use rustc_type_ir::visit::TypeVisitableExt as _; use rustc_type_ir::{self as ty, Interner, TypingMode, Upcast as _, elaborate}; use tracing::{debug, instrument}; +use super::trait_goals::TraitGoalProvenVia; use crate::delegate::SolverDelegate; use crate::solve::inspect::ProbeKind; use crate::solve::{ @@ -337,15 +338,6 @@ where self.assemble_param_env_candidates(goal, &mut candidates); - match self.typing_mode() { - TypingMode::Coherence => {} - TypingMode::Analysis { .. } - | TypingMode::PostBorrowckAnalysis { .. } - | TypingMode::PostAnalysis => { - self.discard_impls_shadowed_by_env(goal, &mut candidates); - } - } - candidates } @@ -500,7 +492,7 @@ where goal: Goal, candidates: &mut Vec>, ) { - for (i, assumption) in goal.param_env.caller_bounds().into_iter().enumerate() { + for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() { candidates.extend(G::probe_and_consider_implied_clause( self, CandidateSource::ParamEnv(i), @@ -733,72 +725,64 @@ where }) } - /// If there's a where-bound for the current goal, do not use any impl candidates - /// to prove the current goal. Most importantly, if there is a where-bound which does - /// not specify any associated types, we do not allow normalizing the associated type - /// by using an impl, even if it would apply. + /// We sadly can't simply take all possible candidates for normalization goals + /// and check whether they result in the same constraints. We want to make sure + /// that trying to normalize an alias doesn't result in constraints which aren't + /// otherwise required. /// - /// - // FIXME(@lcnr): The current structure here makes me unhappy and feels ugly. idk how - // to improve this however. However, this should make it fairly straightforward to refine - // the filtering going forward, so it seems alright-ish for now. - #[instrument(level = "debug", skip(self, goal))] - fn discard_impls_shadowed_by_env>( - &mut self, - goal: Goal, - candidates: &mut Vec>, - ) { - let cx = self.cx(); - let trait_goal: Goal> = - goal.with(cx, goal.predicate.trait_ref(cx)); - - let mut trait_candidates_from_env = vec![]; - self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| { - ecx.assemble_param_env_candidates(trait_goal, &mut trait_candidates_from_env); - ecx.assemble_alias_bound_candidates(trait_goal, &mut trait_candidates_from_env); - }); - - if !trait_candidates_from_env.is_empty() { - let trait_env_result = self.merge_candidates(trait_candidates_from_env); - match trait_env_result.unwrap().value.certainty { - // If proving the trait goal succeeds by using the env, - // we freely drop all impl candidates. - // - // FIXME(@lcnr): It feels like this could easily hide - // a forced ambiguity candidate added earlier. - // This feels dangerous. - Certainty::Yes => { - candidates.retain(|c| match c.source { - CandidateSource::Impl(_) | CandidateSource::BuiltinImpl(_) => { - debug!(?c, "discard impl candidate"); - false - } - CandidateSource::ParamEnv(_) | CandidateSource::AliasBound => true, - CandidateSource::CoherenceUnknowable => panic!("uh oh"), - }); - } - // If it is still ambiguous we instead just force the whole goal - // to be ambig and wait for inference constraints. See - // tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs - Certainty::Maybe(cause) => { - debug!(?cause, "force ambiguity"); - *candidates = self.forced_ambiguity(cause).into_iter().collect(); - } - } - } - } - - /// If there are multiple ways to prove a trait or projection goal, we have - /// to somehow try to merge the candidates into one. If that fails, we return - /// ambiguity. + /// Most notably, when proving a trait goal by via a where-bound, we should not + /// normalize via impls which have stricter region constraints than the where-bound: + /// + /// ```rust + /// trait Trait<'a> { + /// type Assoc; + /// } + /// + /// impl<'a, T: 'a> Trait<'a> for T { + /// type Assoc = u32; + /// } + /// + /// fn with_bound<'a, T: Trait<'a>>(_value: T::Assoc) {} + /// ``` + /// + /// The where-bound of `with_bound` doesn't specify the associated type, so we would + /// only be able to normalize `>::Assoc` by using the impl. This impl + /// adds a `T: 'a` bound however, which would result in a region error. Given that the + /// user explicitly wrote that `T: Trait<'a>` holds, this is undesirable and we instead + /// treat the alias as rigid. + /// + /// See trait-system-refactor-initiative#124 for more details. #[instrument(level = "debug", skip(self), ret)] - pub(super) fn merge_candidates(&mut self, candidates: Vec>) -> QueryResult { - // First try merging all candidates. This is complete and fully sound. - let responses = candidates.iter().map(|c| c.result).collect::>(); - if let Some(result) = self.try_merge_responses(&responses) { - return Ok(result); - } else { - self.flounder(&responses) - } + pub(super) fn merge_candidates( + &mut self, + proven_via: Option, + candidates: Vec>, + ) -> QueryResult { + let Some(proven_via) = proven_via else { + // We don't care about overflow. If proving the trait goal overflowed, then + // it's enough to report an overflow error for that, we don't also have to + // overflow during normalization. + return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Ambiguity)); + }; + + let responses: Vec<_> = match proven_via { + // Even when a trait bound has been proven using a where-bound, we + // still need to consider alias-bounds for normalization, see + // tests/ui/next-solver/alias-bound-shadowed-by-env.rs. + // + // FIXME(const_trait_impl): should this behavior also be used by + // constness checking. Doing so is *at least theoretically* breaking, + // see github.com/rust-lang/rust/issues/133044#issuecomment-2500709754 + TraitGoalProvenVia::ParamEnv | TraitGoalProvenVia::AliasBound => candidates + .iter() + .filter(|c| { + matches!(c.source, CandidateSource::AliasBound | CandidateSource::ParamEnv(_)) + }) + .map(|c| c.result) + .collect(), + TraitGoalProvenVia::Misc => candidates.iter().map(|c| c.result).collect(), + }; + + self.try_merge_responses(&responses).map_or_else(|| self.flounder(&responses), Ok) } } diff --git a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs index 81b5199002b..ce7552e30f0 100644 --- a/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/effect_goals.rs @@ -4,6 +4,7 @@ use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::inspect::ProbeKind; use rustc_type_ir::{self as ty, Interner, elaborate}; use tracing::instrument; @@ -391,6 +392,11 @@ where goal: Goal>, ) -> QueryResult { let candidates = self.assemble_and_evaluate_candidates(goal); - self.merge_candidates(candidates) + let (_, proven_via) = self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| { + let trait_goal: Goal> = + goal.with(ecx.cx(), goal.predicate.trait_ref); + ecx.compute_trait_goal(trait_goal) + })?; + self.merge_candidates(proven_via, candidates) } } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 70ceb22bfea..8c74490e0e0 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -440,7 +440,7 @@ where if let Some(kind) = kind.no_bound_vars() { match kind { ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => { - self.compute_trait_goal(Goal { param_env, predicate }) + self.compute_trait_goal(Goal { param_env, predicate }).map(|(r, _via)| r) } ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => { self.compute_host_effect_goal(Goal { param_env, predicate }) diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs index ebf1013db1e..37678bfd880 100644 --- a/compiler/rustc_next_trait_solver/src/solve/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs @@ -243,22 +243,27 @@ where .copied() } + fn bail_with_ambiguity(&mut self, responses: &[CanonicalResponse]) -> CanonicalResponse { + debug_assert!(!responses.is_empty()); + if let Certainty::Maybe(maybe_cause) = + responses.iter().fold(Certainty::AMBIGUOUS, |certainty, response| { + certainty.unify_with(response.value.certainty) + }) + { + self.make_ambiguous_response_no_constraints(maybe_cause) + } else { + panic!("expected flounder response to be ambiguous") + } + } + /// If we fail to merge responses we flounder and return overflow or ambiguity. #[instrument(level = "trace", skip(self), ret)] fn flounder(&mut self, responses: &[CanonicalResponse]) -> QueryResult { if responses.is_empty() { return Err(NoSolution); + } else { + Ok(self.bail_with_ambiguity(responses)) } - - let Certainty::Maybe(maybe_cause) = - responses.iter().fold(Certainty::AMBIGUOUS, |certainty, response| { - certainty.unify_with(response.value.certainty) - }) - else { - panic!("expected flounder response to be ambiguous") - }; - - Ok(self.make_ambiguous_response_no_constraints(maybe_cause)) } /// Normalize a type for when it is structurally matched on. diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 63dbee2640b..b8867192225 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -88,10 +88,17 @@ where /// returns `NoSolution`. #[instrument(level = "trace", skip(self), ret)] fn normalize_at_least_one_step(&mut self, goal: Goal>) -> QueryResult { - match goal.predicate.alias.kind(self.cx()) { + let cx = self.cx(); + match goal.predicate.alias.kind(cx) { ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => { let candidates = self.assemble_and_evaluate_candidates(goal); - self.merge_candidates(candidates) + let (_, proven_via) = + self.probe(|_| ProbeKind::ShadowedEnvProbing).enter(|ecx| { + let trait_goal: Goal> = + goal.with(cx, goal.predicate.alias.trait_ref(cx)); + ecx.compute_trait_goal(trait_goal) + })?; + self.merge_candidates(proven_via, candidates) } ty::AliasTermKind::InherentTy => self.normalize_inherent_associated_type(goal), ty::AliasTermKind::OpaqueTy => self.normalize_opaque_type(goal), diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index 12df35d30b8..886cdec0345 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -5,6 +5,7 @@ use rustc_type_ir::data_structures::IndexSet; use rustc_type_ir::fast_reject::DeepRejectCtxt; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; +use rustc_type_ir::solve::CanonicalResponse; use rustc_type_ir::visit::TypeVisitableExt as _; use rustc_type_ir::{self as ty, Interner, TraitPredicate, TypingMode, Upcast as _, elaborate}; use tracing::{instrument, trace}; @@ -1147,13 +1148,101 @@ where ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } +} + +/// How we've proven this trait goal. +/// +/// This is used by `NormalizesTo` goals to only normalize +/// by using the same 'kind of candidate' we've used to prove +/// its corresponding trait goal. Most notably, we do not +/// normalize by using an impl if the trait goal has been +/// proven via a `ParamEnv` candidate. +/// +/// This is necessary to avoid unnecessary region constraints, +/// see trait-system-refactor-initiative#125 for more details. +#[derive(Debug, Clone, Copy)] +pub(super) enum TraitGoalProvenVia { + /// We've proven the trait goal by something which is + /// is not a non-global where-bound or an alias-bound. + /// + /// This means we don't disable any candidates during + /// normalization. + Misc, + ParamEnv, + AliasBound, +} + +impl EvalCtxt<'_, D> +where + D: SolverDelegate, + I: Interner, +{ + pub(super) fn merge_trait_candidates( + &mut self, + goal: Goal>, + candidates: Vec>, + ) -> Result<(CanonicalResponse, Option), NoSolution> { + if let TypingMode::Coherence = self.typing_mode() { + let all_candidates: Vec<_> = candidates.into_iter().map(|c| c.result).collect(); + return if let Some(response) = self.try_merge_responses(&all_candidates) { + Ok((response, Some(TraitGoalProvenVia::Misc))) + } else { + self.flounder(&all_candidates).map(|r| (r, None)) + }; + } + + // FIXME: prefer trivial builtin impls + + // If there are non-global where-bounds, prefer where-bounds + // (including global ones) over everything else. + let has_non_global_where_bounds = candidates.iter().any(|c| match c.source { + CandidateSource::ParamEnv(idx) => { + let where_bound = goal.param_env.caller_bounds().get(idx); + where_bound.has_bound_vars() || !where_bound.is_global() + } + _ => false, + }); + if has_non_global_where_bounds { + let where_bounds: Vec<_> = candidates + .iter() + .filter(|c| matches!(c.source, CandidateSource::ParamEnv(_))) + .map(|c| c.result) + .collect(); + + return if let Some(response) = self.try_merge_responses(&where_bounds) { + Ok((response, Some(TraitGoalProvenVia::ParamEnv))) + } else { + Ok((self.bail_with_ambiguity(&where_bounds), None)) + }; + } + + if candidates.iter().any(|c| matches!(c.source, CandidateSource::AliasBound)) { + let alias_bounds: Vec<_> = candidates + .iter() + .filter(|c| matches!(c.source, CandidateSource::AliasBound)) + .map(|c| c.result) + .collect(); + return if let Some(response) = self.try_merge_responses(&alias_bounds) { + Ok((response, Some(TraitGoalProvenVia::AliasBound))) + } else { + Ok((self.bail_with_ambiguity(&alias_bounds), None)) + }; + } + + let all_candidates: Vec<_> = candidates.into_iter().map(|c| c.result).collect(); + if let Some(response) = self.try_merge_responses(&all_candidates) { + Ok((response, Some(TraitGoalProvenVia::Misc))) + } else { + self.flounder(&all_candidates).map(|r| (r, None)) + } + } #[instrument(level = "trace", skip(self))] pub(super) fn compute_trait_goal( &mut self, goal: Goal>, - ) -> QueryResult { + ) -> Result<(CanonicalResponse, Option), NoSolution> { let candidates = self.assemble_and_evaluate_candidates(goal); - self.merge_candidates(candidates) + self.merge_trait_candidates(goal, candidates) } } diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index f45c94127bd..2db40accda3 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -543,7 +543,7 @@ pub trait AdtDef: Copy + Debug + Hash + Eq { } pub trait ParamEnv: Copy + Debug + Hash + Eq + TypeFoldable { - fn caller_bounds(self) -> impl IntoIterator; + fn caller_bounds(self) -> impl SliceLike; } pub trait Features: Copy { diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr deleted file mode 100644 index 9e04e90a98a..00000000000 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.next.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0284]: type annotations needed: cannot satisfy `Foo == _` - --> $DIR/norm-before-method-resolution-opaque-type.rs:15:19 - | -LL | fn weird_bound(x: &>::Out) -> X - | ^ cannot satisfy `Foo == _` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr index 479f5984355..57cbe169118 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.old.stderr @@ -1,12 +1,12 @@ error: item does not constrain `Foo::{opaque#0}`, but has it in its signature - --> $DIR/norm-before-method-resolution-opaque-type.rs:15:4 + --> $DIR/norm-before-method-resolution-opaque-type.rs:16:4 | LL | fn weird_bound(x: &>::Out) -> X | ^^^^^^^^^^^ | = note: consider moving the opaque type's declaration and defining uses into a separate module note: this opaque type is in the signature - --> $DIR/norm-before-method-resolution-opaque-type.rs:13:12 + --> $DIR/norm-before-method-resolution-opaque-type.rs:14:12 | LL | type Foo = impl Sized; | ^^^^^^^^^^ diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs index ffbfc622bb0..43207d89276 100644 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs +++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution-opaque-type.rs @@ -1,5 +1,6 @@ //@ revisions: old next //@[next] compile-flags: -Znext-solver +//@[next] check-pass #![feature(type_alias_impl_trait)] trait Trait<'a> { @@ -14,7 +15,6 @@ type Foo = impl Sized; fn weird_bound(x: &>::Out) -> X //[old]~^ ERROR: item does not constrain -//[next]~^^ ERROR: cannot satisfy `Foo == _` where for<'a> X: Trait<'a>, for<'a> >::Out<()>: Copy, From f0ae48d1065b6d017df75dc2d70a7c56b272b54d Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 29 Nov 2024 18:43:55 +0100 Subject: [PATCH 15/20] add tests --- tests/crashes/133639.rs | 33 ------------------- .../specialization-fuzzing-ice-133639.rs | 19 +++++++++++ .../specialization-fuzzing-ice-133639.stderr | 11 +++++++ .../param-env-eager-norm-dedup.rs | 3 ++ .../winnowing/global-non-global-env-1.rs | 3 ++ .../winnowing/global-non-global-env-2.rs | 3 ++ .../winnowing/global-non-global-env-3.rs | 3 ++ .../winnowing/global-non-global-env-4.rs | 3 ++ 8 files changed, 45 insertions(+), 33 deletions(-) delete mode 100644 tests/crashes/133639.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.rs create mode 100644 tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.stderr diff --git a/tests/crashes/133639.rs b/tests/crashes/133639.rs deleted file mode 100644 index d522b0730cf..00000000000 --- a/tests/crashes/133639.rs +++ /dev/null @@ -1,33 +0,0 @@ -//@ known-bug: #133639 - -#![feature(with_negative_coherence)] -#![feature(min_specialization)] -#![feature(generic_const_exprs)] - -#![crate_type = "lib"] -use std::str::FromStr; - -struct a; - -trait c {} - -impl FromStr for e -where - a<{ d <= 2 }>: c, -{ - type Err = (); - fn from_str(f: &str) -> Result { - unimplemented!() - } -} -struct e; - -impl FromStr for e -where - a<{ d <= 2 }>: c, -{ - type Err = (); - fn from_str(f: &str) -> Result { - unimplemented!() - } -} diff --git a/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.rs b/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.rs new file mode 100644 index 00000000000..d3ae863bee9 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.rs @@ -0,0 +1,19 @@ +//@ check-pass + +// Regression test for #133639. + +#![feature(with_negative_coherence)] +#![feature(min_specialization)] +#![feature(generic_const_exprs)] +//~^ WARNING the feature `generic_const_exprs` is incomplete + +#![crate_type = "lib"] +trait Trait {} +struct A; + +trait C {} + +impl Trait for E where A<{ D <= 2 }>: C {} +struct E; + +impl Trait for E where A<{ D <= 2 }>: C {} diff --git a/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.stderr b/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.stderr new file mode 100644 index 00000000000..f17b248d856 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/specialization-fuzzing-ice-133639.stderr @@ -0,0 +1,11 @@ +warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/specialization-fuzzing-ice-133639.rs:7:12 + | +LL | #![feature(generic_const_exprs)] + | ^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #76560 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/const-generics/min_const_generics/param-env-eager-norm-dedup.rs b/tests/ui/const-generics/min_const_generics/param-env-eager-norm-dedup.rs index 9600b3875ba..2e97e3fe004 100644 --- a/tests/ui/const-generics/min_const_generics/param-env-eager-norm-dedup.rs +++ b/tests/ui/const-generics/min_const_generics/param-env-eager-norm-dedup.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver //@ check-pass // This caused a regression in a crater run in #132325. diff --git a/tests/ui/traits/winnowing/global-non-global-env-1.rs b/tests/ui/traits/winnowing/global-non-global-env-1.rs index d232d32dddf..75c184b65bf 100644 --- a/tests/ui/traits/winnowing/global-non-global-env-1.rs +++ b/tests/ui/traits/winnowing/global-non-global-env-1.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver //@ check-pass // A regression test for an edge case of candidate selection diff --git a/tests/ui/traits/winnowing/global-non-global-env-2.rs b/tests/ui/traits/winnowing/global-non-global-env-2.rs index c73d0f06cd9..128ec2a40da 100644 --- a/tests/ui/traits/winnowing/global-non-global-env-2.rs +++ b/tests/ui/traits/winnowing/global-non-global-env-2.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver //@ check-pass // A regression test for an edge case of candidate selection diff --git a/tests/ui/traits/winnowing/global-non-global-env-3.rs b/tests/ui/traits/winnowing/global-non-global-env-3.rs index 008d07e4144..7e5dbd4ba8e 100644 --- a/tests/ui/traits/winnowing/global-non-global-env-3.rs +++ b/tests/ui/traits/winnowing/global-non-global-env-3.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver //@ check-pass // A regression test for an edge case of candidate selection diff --git a/tests/ui/traits/winnowing/global-non-global-env-4.rs b/tests/ui/traits/winnowing/global-non-global-env-4.rs index 74793620c9e..2dc082be45c 100644 --- a/tests/ui/traits/winnowing/global-non-global-env-4.rs +++ b/tests/ui/traits/winnowing/global-non-global-env-4.rs @@ -1,3 +1,6 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver //@ check-pass // A regression test for an edge case of candidate selection From 5fa4b093f59e4be0847ee00628ae5439fad51cfc Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 18 Dec 2024 16:31:44 +0100 Subject: [PATCH 16/20] resolve FIXME --- .../next-solver/generalize/occurs-check-nested-alias.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs index 00dc7a9d337..fbf4cadc678 100644 --- a/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs +++ b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs @@ -37,9 +37,4 @@ fn foo() { // result in a cyclic type. However, we can still unify these types by first // normalizing the inner associated type. Emitting an error here would be incomplete. drop::(t); - - // FIXME(-Znext-solver): This line is necessary due to an unrelated solver bug - // and should get removed in the future. - // https://github.com/rust-lang/trait-system-refactor-initiative/issues/96 - drop::::Assoc>>(u); } From 19e44f4db48e21832d17378a32739a70db29cf30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 18 Dec 2024 19:27:44 +0000 Subject: [PATCH 17/20] Point at lint name instead of whole attr for gated lints ``` warning: unknown lint: `test_unstable_lint` --> $DIR/warn-unknown-unstable-lint-inline.rs:4:10 | LL | #![allow(test_unstable_lint, another_unstable_lint)] | ^^^^^^^^^^^^^^^^^^ | = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date note: the lint level is defined here --> $DIR/warn-unknown-unstable-lint-inline.rs:3:9 | LL | #![warn(unknown_lints)] | ^^^^^^^^^^^^^ warning: unknown lint: `test_unstable_lint` --> $DIR/warn-unknown-unstable-lint-inline.rs:4:29 | LL | #![allow(test_unstable_lint, another_unstable_lint)] | ^^^^^^^^^^^^^^^^^^^^^ | = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date note: the lint level is defined here --> $DIR/warn-unknown-unstable-lint-inline.rs:3:9 | LL | #![warn(unknown_lints)] | ^^^^^^^^^^^^^ ``` This is particularly relevant when there are multiple lints in the same `warn` attribute. Pointing at the smaller span makes it clearer which one the warning is complaining about. --- compiler/rustc_lint/src/levels.rs | 2 +- ...e-rustdoc_missing_doc_code_examples.stderr | 4 ++-- ...gate-multiple_supertrait_upcastable.stderr | 8 +++---- ...on_exhaustive_omitted_patterns_lint.stderr | 24 +++++++++---------- ...eature-gate-strict_provenance_lints.stderr | 8 +++---- .../feature-gate-test_unstable_lint.stderr | 4 ++-- ...ture-gate-unqualified-local-imports.stderr | 4 ++-- tests/ui/lint/must_not_suspend/gated.stderr | 4 ++-- .../deny-unstable-lint-inline.stderr | 4 ++-- .../warn-unknown-unstable-lint-inline.stderr | 4 ++-- 10 files changed, 33 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 7ea6c63dbe6..7f4aa60fa0b 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -915,7 +915,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { let src = LintLevelSource::Node { name, span: sp, reason }; for &id in ids { - if self.check_gated_lint(id, attr.span(), false) { + if self.check_gated_lint(id, sp, false) { self.insert_spec(id, (level, src)); } } diff --git a/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr index 67540949f4d..e017b1f34a1 100644 --- a/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr +++ b/tests/rustdoc-ui/lints/feature-gate-rustdoc_missing_doc_code_examples.stderr @@ -1,8 +1,8 @@ error: unknown lint: `rustdoc::missing_doc_code_examples` - --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:4:1 + --> $DIR/feature-gate-rustdoc_missing_doc_code_examples.rs:4:10 | LL | #![allow(rustdoc::missing_doc_code_examples)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `rustdoc::missing_doc_code_examples` lint is unstable = note: see issue #101730 for more information diff --git a/tests/ui/feature-gates/feature-gate-multiple_supertrait_upcastable.stderr b/tests/ui/feature-gates/feature-gate-multiple_supertrait_upcastable.stderr index 8a43d615963..0c7e68a599c 100644 --- a/tests/ui/feature-gates/feature-gate-multiple_supertrait_upcastable.stderr +++ b/tests/ui/feature-gates/feature-gate-multiple_supertrait_upcastable.stderr @@ -1,8 +1,8 @@ warning: unknown lint: `multiple_supertrait_upcastable` - --> $DIR/feature-gate-multiple_supertrait_upcastable.rs:3:1 + --> $DIR/feature-gate-multiple_supertrait_upcastable.rs:3:9 | LL | #![deny(multiple_supertrait_upcastable)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `multiple_supertrait_upcastable` lint is unstable = help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable @@ -10,10 +10,10 @@ LL | #![deny(multiple_supertrait_upcastable)] = note: `#[warn(unknown_lints)]` on by default warning: unknown lint: `multiple_supertrait_upcastable` - --> $DIR/feature-gate-multiple_supertrait_upcastable.rs:5:1 + --> $DIR/feature-gate-multiple_supertrait_upcastable.rs:5:9 | LL | #![warn(multiple_supertrait_upcastable)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `multiple_supertrait_upcastable` lint is unstable = help: add `#![feature(multiple_supertrait_upcastable)]` to the crate attributes to enable diff --git a/tests/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr b/tests/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr index 41764c8e018..7a453521590 100644 --- a/tests/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr +++ b/tests/ui/feature-gates/feature-gate-non_exhaustive_omitted_patterns_lint.stderr @@ -1,8 +1,8 @@ warning: unknown lint: `non_exhaustive_omitted_patterns` - --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:3:1 + --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:3:9 | LL | #![deny(non_exhaustive_omitted_patterns)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 for more information @@ -11,10 +11,10 @@ LL | #![deny(non_exhaustive_omitted_patterns)] = note: `#[warn(unknown_lints)]` on by default warning: unknown lint: `non_exhaustive_omitted_patterns` - --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:5:1 + --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:5:10 | LL | #![allow(non_exhaustive_omitted_patterns)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 for more information @@ -22,10 +22,10 @@ LL | #![allow(non_exhaustive_omitted_patterns)] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date warning: unknown lint: `non_exhaustive_omitted_patterns` - --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:15:5 + --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:15:13 | LL | #[allow(non_exhaustive_omitted_patterns)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 for more information @@ -33,10 +33,10 @@ LL | #[allow(non_exhaustive_omitted_patterns)] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date warning: unknown lint: `non_exhaustive_omitted_patterns` - --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:15:5 + --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:15:13 | LL | #[allow(non_exhaustive_omitted_patterns)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 for more information @@ -45,10 +45,10 @@ LL | #[allow(non_exhaustive_omitted_patterns)] = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` warning: unknown lint: `non_exhaustive_omitted_patterns` - --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:24:5 + --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:24:12 | LL | #[warn(non_exhaustive_omitted_patterns)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 for more information @@ -56,10 +56,10 @@ LL | #[warn(non_exhaustive_omitted_patterns)] = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date warning: unknown lint: `non_exhaustive_omitted_patterns` - --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:24:5 + --> $DIR/feature-gate-non_exhaustive_omitted_patterns_lint.rs:24:12 | LL | #[warn(non_exhaustive_omitted_patterns)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `non_exhaustive_omitted_patterns` lint is unstable = note: see issue #89554 for more information diff --git a/tests/ui/feature-gates/feature-gate-strict_provenance_lints.stderr b/tests/ui/feature-gates/feature-gate-strict_provenance_lints.stderr index 15428cbd4be..3f3b49bc606 100644 --- a/tests/ui/feature-gates/feature-gate-strict_provenance_lints.stderr +++ b/tests/ui/feature-gates/feature-gate-strict_provenance_lints.stderr @@ -1,8 +1,8 @@ warning: unknown lint: `fuzzy_provenance_casts` - --> $DIR/feature-gate-strict_provenance_lints.rs:3:1 + --> $DIR/feature-gate-strict_provenance_lints.rs:3:9 | LL | #![deny(fuzzy_provenance_casts)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ | = note: the `fuzzy_provenance_casts` lint is unstable = note: see issue #130351 for more information @@ -11,10 +11,10 @@ LL | #![deny(fuzzy_provenance_casts)] = note: `#[warn(unknown_lints)]` on by default warning: unknown lint: `lossy_provenance_casts` - --> $DIR/feature-gate-strict_provenance_lints.rs:5:1 + --> $DIR/feature-gate-strict_provenance_lints.rs:5:9 | LL | #![deny(lossy_provenance_casts)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^ | = note: the `lossy_provenance_casts` lint is unstable = note: see issue #130351 for more information diff --git a/tests/ui/feature-gates/feature-gate-test_unstable_lint.stderr b/tests/ui/feature-gates/feature-gate-test_unstable_lint.stderr index 5dc303da742..e460688e5fc 100644 --- a/tests/ui/feature-gates/feature-gate-test_unstable_lint.stderr +++ b/tests/ui/feature-gates/feature-gate-test_unstable_lint.stderr @@ -1,8 +1,8 @@ warning: unknown lint: `test_unstable_lint` - --> $DIR/feature-gate-test_unstable_lint.rs:4:1 + --> $DIR/feature-gate-test_unstable_lint.rs:4:10 | LL | #![allow(test_unstable_lint)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ | = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable diff --git a/tests/ui/feature-gates/feature-gate-unqualified-local-imports.stderr b/tests/ui/feature-gates/feature-gate-unqualified-local-imports.stderr index 22cd3bf4c6f..bc8edd847cc 100644 --- a/tests/ui/feature-gates/feature-gate-unqualified-local-imports.stderr +++ b/tests/ui/feature-gates/feature-gate-unqualified-local-imports.stderr @@ -1,8 +1,8 @@ warning: unknown lint: `unqualified_local_imports` - --> $DIR/feature-gate-unqualified-local-imports.rs:3:1 + --> $DIR/feature-gate-unqualified-local-imports.rs:3:10 | LL | #![allow(unqualified_local_imports)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: the `unqualified_local_imports` lint is unstable = help: add `#![feature(unqualified_local_imports)]` to the crate attributes to enable diff --git a/tests/ui/lint/must_not_suspend/gated.stderr b/tests/ui/lint/must_not_suspend/gated.stderr index aff1b6a2ac4..8ec3202c5af 100644 --- a/tests/ui/lint/must_not_suspend/gated.stderr +++ b/tests/ui/lint/must_not_suspend/gated.stderr @@ -1,8 +1,8 @@ warning: unknown lint: `must_not_suspend` - --> $DIR/gated.rs:4:1 + --> $DIR/gated.rs:4:9 | LL | #![deny(must_not_suspend)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ | = note: the `must_not_suspend` lint is unstable = note: see issue #83310 for more information diff --git a/tests/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr b/tests/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr index e486f04f273..4ff90945397 100644 --- a/tests/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr +++ b/tests/ui/unknown-unstable-lints/deny-unstable-lint-inline.stderr @@ -1,8 +1,8 @@ error: unknown lint: `test_unstable_lint` - --> $DIR/deny-unstable-lint-inline.rs:4:1 + --> $DIR/deny-unstable-lint-inline.rs:4:10 | LL | #![allow(test_unstable_lint)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ | = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable diff --git a/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr b/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr index 981d3b1a874..7d56b360837 100644 --- a/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr +++ b/tests/ui/unknown-unstable-lints/warn-unknown-unstable-lint-inline.stderr @@ -1,8 +1,8 @@ warning: unknown lint: `test_unstable_lint` - --> $DIR/warn-unknown-unstable-lint-inline.rs:4:1 + --> $DIR/warn-unknown-unstable-lint-inline.rs:4:10 | LL | #![allow(test_unstable_lint)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^ | = note: the `test_unstable_lint` lint is unstable = help: add `#![feature(test_unstable_lint)]` to the crate attributes to enable From 007586966cfae4e076d6335bc2aaf7eedd56aa20 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 19 Dec 2024 07:41:00 +1100 Subject: [PATCH 18/20] Add nnethercote to the `triagebot.toml` vacation list. --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 214fc2a21c4..eefb87aa298 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -996,6 +996,7 @@ contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" users_on_vacation = [ "jyn514", "celinval", + "nnethercote", ] [[assign.warn_non_default_branch.exceptions]] From 983930635228c36045dd8013dc3251578989ea14 Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:00:54 -0500 Subject: [PATCH 19/20] Update books --- src/doc/book | 2 +- src/doc/edition-guide | 2 +- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-dev-guide | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/doc/book b/src/doc/book index 9900d976bbf..ad2011d3bca 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 9900d976bbfecf4e8124da54351a9ad85ee3c7f3 +Subproject commit ad2011d3bcad9f152d034faf7635c22506839d58 diff --git a/src/doc/edition-guide b/src/doc/edition-guide index 128669297c8..bc4ce51e1d4 160000 --- a/src/doc/edition-guide +++ b/src/doc/edition-guide @@ -1 +1 @@ -Subproject commit 128669297c8a7fdf771042eaec18b8adfaeaf0cd +Subproject commit bc4ce51e1d4dacb9350a92e95f6159a42de2f8c6 diff --git a/src/doc/nomicon b/src/doc/nomicon index 0674321898c..97e84a38c94 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 0674321898cd454764ab69702819d39a919afd68 +Subproject commit 97e84a38c94bf9362b11284c20b2cb4adaa1e868 diff --git a/src/doc/reference b/src/doc/reference index ede56d1bbe1..9f41bc11342 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit ede56d1bbe132bac476b5029cd6d7508ca9572e9 +Subproject commit 9f41bc11342d46544ae0732caf14ec0bcaf27376 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index e1d1f2cdcee..76406337f41 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit e1d1f2cdcee4d52b9a01ff7c448be4372a377b70 +Subproject commit 76406337f4131253443aea0ed7e7f451b464117c diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index b21d99b770f..7f7ba48f04a 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit b21d99b770f9aceb0810c843847c52f86f45d2ed +Subproject commit 7f7ba48f04abc2ad25e52f30b5e2bffa286b019f From f8cd8c1c37892378974766b4ce2eebd138ee70d9 Mon Sep 17 00:00:00 2001 From: leejaehong Date: Thu, 19 Dec 2024 10:37:19 +0900 Subject: [PATCH 20/20] fix typo in ptr/mod.rs Signed-off-by: leejaehong --- library/core/src/ptr/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 51ab2054b3b..1423e7ea8d1 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -84,7 +84,7 @@ // ^ we use this term instead of saying that the produced reference must // be valid, as the validity of a reference is easily confused for the // validity of the thing it refers to, and while the two concepts are -// closly related, they are not identical. +// closely related, they are not identical. //! //! These rules apply even if the result is unused! //! (The part about being initialized is not yet fully decided, but until