From 6642b4b1e2f2edec71cdf3fabef8fcdc8b8517a7 Mon Sep 17 00:00:00 2001 From: Havard Eidnes Date: Wed, 25 Oct 2023 15:23:34 +0000 Subject: [PATCH 1/9] Add support for i586-unknown-netbsd as target. This restricts instructions to those offered by Pentium, to support e.g. AMD Geode. There is already an entry for this target in the NetBSD platform support page at src/doc/rustc/src/platform-support/netbsd.md ...so this should forestall its removal. Additional fixes are needed for some vendored modules, this is the changes in the rust compiler core itself. --- compiler/rustc_llvm/build.rs | 6 +++++ .../src/spec/i586_unknown_netbsd.rs | 22 +++++++++++++++++++ compiler/rustc_target/src/spec/mod.rs | 1 + 3 files changed, 29 insertions(+) create mode 100644 compiler/rustc_target/src/spec/i586_unknown_netbsd.rs diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index f606fa483caf0..acb1d9607a4f5 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -258,6 +258,12 @@ fn main() { { println!("cargo:rustc-link-lib=z"); } else if target.contains("netbsd") { + // Building for i586 or i686, we need -latomic for 64-bit atomics + if target.starts_with("i586") + || target.starts_with("i686") + { + println!("cargo:rustc-link-lib=atomic"); + } println!("cargo:rustc-link-lib=z"); println!("cargo:rustc-link-lib=execinfo"); } diff --git a/compiler/rustc_target/src/spec/i586_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i586_unknown_netbsd.rs new file mode 100644 index 0000000000000..9b36a3c28d35c --- /dev/null +++ b/compiler/rustc_target/src/spec/i586_unknown_netbsd.rs @@ -0,0 +1,22 @@ +use crate::spec::{Cc, Lld, LinkerFlavor, StackProbeType, Target, TargetOptions}; + +pub fn target() -> Target { + let mut base = super::netbsd_base::opts(); + base.cpu = "pentium".into(); + base.max_atomic_width = Some(64); + base.pre_link_args + .entry(LinkerFlavor::Gnu(Cc::Yes, Lld::No)) + .or_default() + .push("-m32".into()); + base.stack_probes = StackProbeType::Call; + + Target { + llvm_target: "i586-unknown-netbsdelf".into(), + pointer_width: 32, + data_layout: "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ + f64:32:64-f80:32-n8:16:32-S128" + .into(), + arch: "x86".into(), + options: TargetOptions { mcount: "__mcount".into(), ..base }, + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index f1c7513d88560..73e5c6c858b9e 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1426,6 +1426,7 @@ supported_targets! { ("aarch64_be-unknown-netbsd", aarch64_be_unknown_netbsd), ("armv6-unknown-netbsd-eabihf", armv6_unknown_netbsd_eabihf), ("armv7-unknown-netbsd-eabihf", armv7_unknown_netbsd_eabihf), + ("i586-unknown-netbsd", i586_unknown_netbsd), ("i686-unknown-netbsd", i686_unknown_netbsd), ("powerpc-unknown-netbsd", powerpc_unknown_netbsd), ("riscv64gc-unknown-netbsd", riscv64gc_unknown_netbsd), From 391b472a370a5d35c43bd0a26182076cf0c17ca9 Mon Sep 17 00:00:00 2001 From: Havard Eidnes Date: Thu, 26 Oct 2023 17:10:16 +0000 Subject: [PATCH 2/9] rustc_llvm/build.rs: improve comment for NetBSD/i386 targets ...explaining why we need -latomic (gcc & g++ built for i486, and LLVM insisting on use of 64-bit atomics). --- compiler/rustc_llvm/build.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index acb1d9607a4f5..e4412132136bf 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -258,7 +258,9 @@ fn main() { { println!("cargo:rustc-link-lib=z"); } else if target.contains("netbsd") { - // Building for i586 or i686, we need -latomic for 64-bit atomics + // On NetBSD/i386, gcc and g++ is built for i486 (to maximize backward compat) + // However, LLVM insists on using 64-bit atomics. + // This gives rise to a need to link rust itself with -latomic for these targets if target.starts_with("i586") || target.starts_with("i686") { From 4392230c08f04c7168e3502e8e075bb19d709a47 Mon Sep 17 00:00:00 2001 From: NAHO <90870942+trueNAHO@users.noreply.github.com> Date: Thu, 26 Oct 2023 19:28:48 +0200 Subject: [PATCH 3/9] Fix documentation typo in std::iter::Iterator::collect_into --- library/core/src/iter/traits/iterator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 166d04e078d90..6adea444214eb 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2142,7 +2142,7 @@ pub trait Iterator { /// passed collection. The collection is then returned, so the call chain /// can be continued. /// - /// This is useful when you already have a collection and wants to add + /// This is useful when you already have a collection and want to add /// the iterator items to it. /// /// This method is a convenience method to call [Extend::extend](trait.Extend.html), From 27919ceba717cd5be7f7ebcb2f5e5f5afa955035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 18 Oct 2023 00:24:21 +0000 Subject: [PATCH 4/9] Tweak suggestion spans for invalid crate-level inner attribute CC #89566. --- compiler/rustc_passes/messages.ftl | 3 + compiler/rustc_passes/src/check_attr.rs | 22 ++++- compiler/rustc_passes/src/errors.rs | 20 +++- .../unix_sigpipe/unix_sigpipe-crate.stderr | 8 +- tests/ui/derives/issue-36617.stderr | 40 ++++++-- .../issue-43106-gating-of-bench.stderr | 6 +- ...sue-43106-gating-of-builtin-attrs-error.rs | 6 ++ ...43106-gating-of-builtin-attrs-error.stderr | 96 ++++++++++++------- .../issue-43106-gating-of-test.stderr | 6 +- tests/ui/imports/issue-28134.stderr | 5 +- .../ui/span/issue-43927-non-ADT-derive.stderr | 8 +- 11 files changed, 160 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 84d3b84e13f60..026186cbe6cd3 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -393,6 +393,9 @@ passes_invalid_attr_at_crate_level = `{$name}` attribute cannot be used at crate level .suggestion = perhaps you meant to use an outer attribute +passes_invalid_attr_at_crate_level_item = + the inner attribute doesn't annotate this {$kind} + passes_invalid_deprecation_version = invalid deprecation version found .label = invalid deprecation version diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index dfe75ea5e8e13..a8a27e761cb3f 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2534,10 +2534,30 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { if attr.style == AttrStyle::Inner { for attr_to_check in ATTRS_TO_CHECK { if attr.has_name(*attr_to_check) { + let item = tcx + .hir() + .items() + .map(|id| tcx.hir().item(id)) + .find(|item| !item.span.is_dummy()) // Skip prelude `use`s + .map(|item| errors::ItemFollowingInnerAttr { + span: item.ident.span, + kind: item.kind.descr(), + }); tcx.sess.emit_err(errors::InvalidAttrAtCrateLevel { span: attr.span, - snippet: tcx.sess.source_map().span_to_snippet(attr.span).ok(), + sugg_span: tcx + .sess + .source_map() + .span_to_snippet(attr.span) + .ok() + .filter(|src| src.starts_with("#![")) + .map(|_| { + attr.span + .with_lo(attr.span.lo() + BytePos(1)) + .with_hi(attr.span.lo() + BytePos(2)) + }), name: *attr_to_check, + item, }); } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 6e840f24c6983..eca0fb7748b15 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -856,8 +856,15 @@ pub struct UnknownLangItem { pub struct InvalidAttrAtCrateLevel { pub span: Span, - pub snippet: Option, + pub sugg_span: Option, pub name: Symbol, + pub item: Option, +} + +#[derive(Clone, Copy)] +pub struct ItemFollowingInnerAttr { + pub span: Span, + pub kind: &'static str, } impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel { @@ -871,15 +878,18 @@ impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel { diag.set_arg("name", self.name); // Only emit an error with a suggestion if we can create a string out // of the attribute span - if let Some(src) = self.snippet { - let replacement = src.replace("#!", "#"); + if let Some(span) = self.sugg_span { diag.span_suggestion_verbose( - self.span, + span, fluent::passes_suggestion, - replacement, + String::new(), rustc_errors::Applicability::MachineApplicable, ); } + if let Some(item) = self.item { + diag.set_arg("kind", item.kind); + diag.span_label(item.span, fluent::passes_invalid_attr_at_crate_level_item); + } diag } } diff --git a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr index a1fb4d6787cef..225b8e8f32fb0 100644 --- a/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr +++ b/tests/ui/attributes/unix_sigpipe/unix_sigpipe-crate.stderr @@ -3,11 +3,15 @@ error: `unix_sigpipe` attribute cannot be used at crate level | LL | #![unix_sigpipe = "inherit"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | fn main() {} + | ---- the inner attribute doesn't annotate this function | help: perhaps you meant to use an outer attribute | -LL | #[unix_sigpipe = "inherit"] - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - #![unix_sigpipe = "inherit"] +LL + #[unix_sigpipe = "inherit"] + | error: aborting due to previous error diff --git a/tests/ui/derives/issue-36617.stderr b/tests/ui/derives/issue-36617.stderr index 9cc0a29b0651d..98be7963e5ef9 100644 --- a/tests/ui/derives/issue-36617.stderr +++ b/tests/ui/derives/issue-36617.stderr @@ -43,55 +43,75 @@ error: `derive` attribute cannot be used at crate level | LL | #![derive(Copy)] | ^^^^^^^^^^^^^^^^ +... +LL | fn main() {} + | ---- the inner attribute doesn't annotate this function | help: perhaps you meant to use an outer attribute | -LL | #[derive(Copy)] - | ~~~~~~~~~~~~~~~ +LL - #![derive(Copy)] +LL + #[derive(Copy)] + | error: `test` attribute cannot be used at crate level --> $DIR/issue-36617.rs:4:1 | LL | #![test] | ^^^^^^^^ +... +LL | fn main() {} + | ---- the inner attribute doesn't annotate this function | help: perhaps you meant to use an outer attribute | -LL | #[test] - | ~~~~~~~ +LL - #![test] +LL + #[test] + | error: `test_case` attribute cannot be used at crate level --> $DIR/issue-36617.rs:7:1 | LL | #![test_case] | ^^^^^^^^^^^^^ +... +LL | fn main() {} + | ---- the inner attribute doesn't annotate this function | help: perhaps you meant to use an outer attribute | -LL | #[test_case] - | ~~~~~~~~~~~~ +LL - #![test_case] +LL + #[test_case] + | error: `bench` attribute cannot be used at crate level --> $DIR/issue-36617.rs:10:1 | LL | #![bench] | ^^^^^^^^^ +... +LL | fn main() {} + | ---- the inner attribute doesn't annotate this function | help: perhaps you meant to use an outer attribute | -LL | #[bench] - | ~~~~~~~~ +LL - #![bench] +LL + #[bench] + | error: `global_allocator` attribute cannot be used at crate level --> $DIR/issue-36617.rs:13:1 | LL | #![global_allocator] | ^^^^^^^^^^^^^^^^^^^^ +... +LL | fn main() {} + | ---- the inner attribute doesn't annotate this function | help: perhaps you meant to use an outer attribute | -LL | #[global_allocator] - | ~~~~~~~~~~~~~~~~~~~ +LL - #![global_allocator] +LL + #[global_allocator] + | error: aborting due to 10 previous errors diff --git a/tests/ui/feature-gates/issue-43106-gating-of-bench.stderr b/tests/ui/feature-gates/issue-43106-gating-of-bench.stderr index 6b33221194221..8270d46d492a9 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-bench.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-bench.stderr @@ -11,10 +11,14 @@ error: `bench` attribute cannot be used at crate level | LL | #![bench = "4100"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn main() {} + | ---- the inner attribute doesn't annotate this function | help: perhaps you meant to use an outer attribute | -LL | #[bench = "4100"] +LL - #![bench = "4100"] +LL + #[bench = "4100"] | error: aborting due to 2 previous errors diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs index 1fe133ac2bc98..0f833f793bd85 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs @@ -32,6 +32,12 @@ //~^ ERROR attribute should be applied to function or closure mod inline { //~^ NOTE not a function or closure + //~| NOTE the inner attribute doesn't annotate this module + //~| NOTE the inner attribute doesn't annotate this module + //~| NOTE the inner attribute doesn't annotate this module + //~| NOTE the inner attribute doesn't annotate this module + //~| NOTE the inner attribute doesn't annotate this module + //~| NOTE the inner attribute doesn't annotate this module mod inner { #![inline] } //~^ ERROR attribute should be applied to function or closure diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index 7876704042188..f01153dcb96c0 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr @@ -7,7 +7,7 @@ LL | #![rustc_main] = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable error: attribute must be of the form `#[inline]` or `#[inline(always|never)]` - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:40:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:46:5 | LL | #[inline = "2100"] fn f() { } | ^^^^^^^^^^^^^^^^^^ @@ -17,31 +17,31 @@ LL | #[inline = "2100"] fn f() { } = note: `#[deny(ill_formed_attribute_input)]` on by default error: `start` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:119:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:125:1 | LL | #[start] | ^^^^^^^^ error: `start` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:122:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:128:17 | LL | mod inner { #![start] } | ^^^^^^^^^ error: `start` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:127:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:133:5 | LL | #[start] struct S; | ^^^^^^^^ error: `start` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:130:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:136:5 | LL | #[start] type T = S; | ^^^^^^^^ error: `start` attribute can only be used on functions - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:133:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:139:5 | LL | #[start] impl S { } | ^^^^^^^^ @@ -55,14 +55,14 @@ LL | LL | / mod inline { LL | | LL | | -LL | | mod inner { #![inline] } +LL | | ... | LL | | LL | | } | |_- not a function or closure error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:59:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:65:1 | LL | #[no_link] | ^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | | } | |_- not an `extern crate` item error: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:85:1 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:91:1 | LL | #[export_name = "2200"] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -92,7 +92,7 @@ LL | | } | |_- not a free function, impl method or static error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:137:8 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:143:8 | LL | #[repr(C)] | ^ @@ -129,10 +129,14 @@ error: `macro_export` attribute cannot be used at crate level | LL | #![macro_export] | ^^^^^^^^^^^^^^^^ +... +LL | mod inline { + | ------ the inner attribute doesn't annotate this module | help: perhaps you meant to use an outer attribute | -LL | #[macro_export] +LL - #![macro_export] +LL + #[macro_export] | error: `rustc_main` attribute cannot be used at crate level @@ -140,21 +144,29 @@ error: `rustc_main` attribute cannot be used at crate level | LL | #![rustc_main] | ^^^^^^^^^^^^^^ +... +LL | mod inline { + | ------ the inner attribute doesn't annotate this module | help: perhaps you meant to use an outer attribute | -LL | #[rustc_main] - | ~~~~~~~~~~~~~ +LL - #![rustc_main] +LL + #[rustc_main] + | error: `start` attribute cannot be used at crate level --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:16:1 | LL | #![start] | ^^^^^^^^^ +... +LL | mod inline { + | ------ the inner attribute doesn't annotate this module | help: perhaps you meant to use an outer attribute | -LL | #[start] +LL - #![start] +LL + #[start] | error: `repr` attribute cannot be used at crate level @@ -162,10 +174,14 @@ error: `repr` attribute cannot be used at crate level | LL | #![repr()] | ^^^^^^^^^^ +... +LL | mod inline { + | ------ the inner attribute doesn't annotate this module | help: perhaps you meant to use an outer attribute | -LL | #[repr()] +LL - #![repr()] +LL + #[repr()] | error: `path` attribute cannot be used at crate level @@ -173,10 +189,14 @@ error: `path` attribute cannot be used at crate level | LL | #![path = "3800"] | ^^^^^^^^^^^^^^^^^ +... +LL | mod inline { + | ------ the inner attribute doesn't annotate this module | help: perhaps you meant to use an outer attribute | -LL | #[path = "3800"] +LL - #![path = "3800"] +LL + #[path = "3800"] | error: `automatically_derived` attribute cannot be used at crate level @@ -184,122 +204,126 @@ error: `automatically_derived` attribute cannot be used at crate level | LL | #![automatically_derived] | ^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | mod inline { + | ------ the inner attribute doesn't annotate this module | help: perhaps you meant to use an outer attribute | -LL | #[automatically_derived] +LL - #![automatically_derived] +LL + #[automatically_derived] | error[E0518]: attribute should be applied to function or closure - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:36:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:42:17 | LL | mod inner { #![inline] } | ------------^^^^^^^^^^-- not a function or closure error[E0518]: attribute should be applied to function or closure - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:46:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:52:5 | LL | #[inline] struct S; | ^^^^^^^^^ --------- not a function or closure error[E0518]: attribute should be applied to function or closure - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:50:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:56:5 | LL | #[inline] type T = S; | ^^^^^^^^^ ----------- not a function or closure error[E0518]: attribute should be applied to function or closure - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:54:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:60:5 | LL | #[inline] impl S { } | ^^^^^^^^^ ---------- not a function or closure error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:64:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:70:17 | LL | mod inner { #![no_link] } | ------------^^^^^^^^^^^-- not an `extern crate` item error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:68:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:74:5 | LL | #[no_link] fn f() { } | ^^^^^^^^^^ ---------- not an `extern crate` item error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:72:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:78:5 | LL | #[no_link] struct S; | ^^^^^^^^^^ --------- not an `extern crate` item error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:76:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:82:5 | LL | #[no_link]type T = S; | ^^^^^^^^^^----------- not an `extern crate` item error: attribute should be applied to an `extern crate` item - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:80:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:86:5 | LL | #[no_link] impl S { } | ^^^^^^^^^^ ---------- not an `extern crate` item error: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:90:17 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:96:17 | LL | mod inner { #![export_name="2200"] } | ------------^^^^^^^^^^^^^^^^^^^^^^-- not a free function, impl method or static error: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:96:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:102:5 | LL | #[export_name = "2200"] struct S; | ^^^^^^^^^^^^^^^^^^^^^^^ --------- not a free function, impl method or static error: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:100:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:106:5 | LL | #[export_name = "2200"] type T = S; | ^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a free function, impl method or static error: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:104:5 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:110:5 | LL | #[export_name = "2200"] impl S { } | ^^^^^^^^^^^^^^^^^^^^^^^ ---------- not a free function, impl method or static error: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:109:9 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:115:9 | LL | #[export_name = "2200"] fn foo(); | ^^^^^^^^^^^^^^^^^^^^^^^ --------- not a free function, impl method or static error: attribute should be applied to a free function, impl method or static - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:113:9 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:119:9 | LL | #[export_name = "2200"] fn bar() {} | ^^^^^^^^^^^^^^^^^^^^^^^ ----------- not a free function, impl method or static error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:141:25 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:147:25 | LL | mod inner { #![repr(C)] } | --------------------^---- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:145:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:151:12 | LL | #[repr(C)] fn f() { } | ^ ---------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:151:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:157:12 | LL | #[repr(C)] type T = S; | ^ ----------- not a struct, enum, or union error[E0517]: attribute should be applied to a struct, enum, or union - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:155:12 + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:161:12 | LL | #[repr(C)] impl S { } | ^ ---------- not a struct, enum, or union diff --git a/tests/ui/feature-gates/issue-43106-gating-of-test.stderr b/tests/ui/feature-gates/issue-43106-gating-of-test.stderr index 300a9966dd880..922c9861aa3c1 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-test.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-test.stderr @@ -11,10 +11,14 @@ error: `test` attribute cannot be used at crate level | LL | #![test = "4200"] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | fn main() {} + | ---- the inner attribute doesn't annotate this function | help: perhaps you meant to use an outer attribute | -LL | #[test = "4200"] +LL - #![test = "4200"] +LL + #[test = "4200"] | error: aborting due to 2 previous errors diff --git a/tests/ui/imports/issue-28134.stderr b/tests/ui/imports/issue-28134.stderr index 33cb53f202a30..5315c2e9fee9c 100644 --- a/tests/ui/imports/issue-28134.stderr +++ b/tests/ui/imports/issue-28134.stderr @@ -14,8 +14,9 @@ LL | #![test] | help: perhaps you meant to use an outer attribute | -LL | #[test] - | ~~~~~~~ +LL - #![test] +LL + #[test] + | error: aborting due to 2 previous errors diff --git a/tests/ui/span/issue-43927-non-ADT-derive.stderr b/tests/ui/span/issue-43927-non-ADT-derive.stderr index e3ae37e368937..a22a4d2b40a8e 100644 --- a/tests/ui/span/issue-43927-non-ADT-derive.stderr +++ b/tests/ui/span/issue-43927-non-ADT-derive.stderr @@ -11,11 +11,15 @@ error: `derive` attribute cannot be used at crate level | LL | #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | struct DerivedOn; + | --------- the inner attribute doesn't annotate this struct | help: perhaps you meant to use an outer attribute | -LL | #[derive(Debug, PartialEq, Eq)] // should be an outer attribute! - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LL - #![derive(Debug, PartialEq, Eq)] // should be an outer attribute! +LL + #[derive(Debug, PartialEq, Eq)] // should be an outer attribute! + | error: aborting due to 2 previous errors From 828f069c12b356631ef2f7b707d51708861a788d Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 20 Oct 2023 19:33:22 +0200 Subject: [PATCH 5/9] Remove most indentation in check-cfg impl --- compiler/rustc_interface/src/interface.rs | 381 ++++++++++------------ 1 file changed, 181 insertions(+), 200 deletions(-) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index d2ce77ad53511..2218892538212 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -139,7 +139,7 @@ pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -> Check let filename = FileName::cfg_spec_source_code(&s); macro_rules! error { - ($reason: expr) => { + ($reason:expr) => { handler.early_error(format!( concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"), s @@ -147,217 +147,198 @@ pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -> Check }; } - let expected_error = - || error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`"); - - match maybe_new_parser_from_source_str(&sess, filename, s.to_string()) { - Ok(mut parser) => match parser.parse_meta_item() { - Ok(meta_item) if parser.token == token::Eof => { - if let Some(args) = meta_item.meta_item_list() { - if meta_item.has_name(sym::names) { - // defaults are flipped for the old syntax - if old_syntax == None { - check_cfg.exhaustive_names = false; - check_cfg.exhaustive_values = false; - } - old_syntax = Some(true); - - check_cfg.exhaustive_names = true; - for arg in args { - if arg.is_word() && arg.ident().is_some() { - let ident = arg.ident().expect("multi-segment cfg key"); - check_cfg - .expecteds - .entry(ident.name.to_string()) - .or_insert(ExpectedValues::Any); - } else { - error!("`names()` arguments must be simple identifiers"); - } - } - } else if meta_item.has_name(sym::values) { - // defaults are flipped for the old syntax - if old_syntax == None { - check_cfg.exhaustive_names = false; - check_cfg.exhaustive_values = false; - } - old_syntax = Some(true); - - if let Some((name, values)) = args.split_first() { - if name.is_word() && name.ident().is_some() { - let ident = name.ident().expect("multi-segment cfg key"); - let expected_values = check_cfg - .expecteds - .entry(ident.name.to_string()) - .and_modify(|expected_values| match expected_values { - ExpectedValues::Some(_) => {} - ExpectedValues::Any => { - // handle the case where names(...) was done - // before values by changing to a list - *expected_values = - ExpectedValues::Some(FxHashSet::default()); - } - }) - .or_insert_with(|| { - ExpectedValues::Some(FxHashSet::default()) - }); - - let ExpectedValues::Some(expected_values) = expected_values - else { - bug!("`expected_values` should be a list a values") - }; - - for val in values { - if let Some(LitKind::Str(s, _)) = - val.lit().map(|lit| &lit.kind) - { - expected_values.insert(Some(s.to_string())); - } else { - error!( - "`values()` arguments must be string literals" - ); - } - } - - if values.is_empty() { - expected_values.insert(None); - } - } else { - error!( - "`values()` first argument must be a simple identifier" - ); - } - } else if args.is_empty() { - check_cfg.exhaustive_values = true; - } else { - expected_error(); - } - } else if meta_item.has_name(sym::cfg) { - old_syntax = Some(false); - - let mut names = Vec::new(); - let mut values: FxHashSet<_> = Default::default(); - - let mut any_specified = false; - let mut values_specified = false; - let mut values_any_specified = false; - - for arg in args { - if arg.is_word() && let Some(ident) = arg.ident() { - if values_specified { - error!("`cfg()` names cannot be after values"); - } - names.push(ident); - } else if arg.has_name(sym::any) - && let Some(args) = arg.meta_item_list() - { - if any_specified { - error!("`any()` cannot be specified multiple times"); - } - any_specified = true; - if !args.is_empty() { - error!("`any()` must be empty"); - } - } else if arg.has_name(sym::values) - && let Some(args) = arg.meta_item_list() - { - if names.is_empty() { - error!( - "`values()` cannot be specified before the names" - ); - } else if values_specified { - error!( - "`values()` cannot be specified multiple times" - ); - } - values_specified = true; - - for arg in args { - if let Some(LitKind::Str(s, _)) = - arg.lit().map(|lit| &lit.kind) - { - values.insert(Some(s.to_string())); - } else if arg.has_name(sym::any) - && let Some(args) = arg.meta_item_list() - { - if values_any_specified { - error!( - "`any()` in `values()` cannot be specified multiple times" - ); - } - values_any_specified = true; - if !args.is_empty() { - error!("`any()` must be empty"); - } - } else { - error!( - "`values()` arguments must be string literals or `any()`" - ); - } - } - } else { - error!( - "`cfg()` arguments must be simple identifiers, `any()` or `values(...)`" - ); - } + let expected_error = || -> ! { + error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`") + }; + + let Ok(mut parser) = maybe_new_parser_from_source_str(&sess, filename, s.to_string()) + else { + expected_error(); + }; + + let meta_item = match parser.parse_meta_item() { + Ok(meta_item) if parser.token == token::Eof => meta_item, + Ok(..) => expected_error(), + Err(err) => { + err.cancel(); + expected_error(); + } + }; + + let Some(args) = meta_item.meta_item_list() else { + expected_error(); + }; + + if meta_item.has_name(sym::names) { + // defaults are flipped for the old syntax + if old_syntax == None { + check_cfg.exhaustive_names = false; + check_cfg.exhaustive_values = false; + } + old_syntax = Some(true); + + check_cfg.exhaustive_names = true; + for arg in args { + if arg.is_word() && arg.ident().is_some() { + let ident = arg.ident().expect("multi-segment cfg key"); + check_cfg + .expecteds + .entry(ident.name.to_string()) + .or_insert(ExpectedValues::Any); + } else { + error!("`names()` arguments must be simple identifiers"); + } + } + } else if meta_item.has_name(sym::values) { + // defaults are flipped for the old syntax + if old_syntax == None { + check_cfg.exhaustive_names = false; + check_cfg.exhaustive_values = false; + } + old_syntax = Some(true); + + if let Some((name, values)) = args.split_first() { + if name.is_word() && name.ident().is_some() { + let ident = name.ident().expect("multi-segment cfg key"); + let expected_values = check_cfg + .expecteds + .entry(ident.name.to_string()) + .and_modify(|expected_values| match expected_values { + ExpectedValues::Some(_) => {} + ExpectedValues::Any => { + // handle the case where names(...) was done + // before values by changing to a list + *expected_values = ExpectedValues::Some(FxHashSet::default()); } + }) + .or_insert_with(|| ExpectedValues::Some(FxHashSet::default())); + + let ExpectedValues::Some(expected_values) = expected_values else { + bug!("`expected_values` should be a list a values") + }; - if values.is_empty() && !values_any_specified && !any_specified { - values.insert(None); - } else if !values.is_empty() && values_any_specified { + for val in values { + if let Some(LitKind::Str(s, _)) = val.lit().map(|lit| &lit.kind) { + expected_values.insert(Some(s.to_string())); + } else { + error!("`values()` arguments must be string literals"); + } + } + + if values.is_empty() { + expected_values.insert(None); + } + } else { + error!("`values()` first argument must be a simple identifier"); + } + } else if args.is_empty() { + check_cfg.exhaustive_values = true; + } else { + expected_error(); + } + } else if meta_item.has_name(sym::cfg) { + old_syntax = Some(false); + + let mut names = Vec::new(); + let mut values: FxHashSet<_> = Default::default(); + + let mut any_specified = false; + let mut values_specified = false; + let mut values_any_specified = false; + + for arg in args { + if arg.is_word() && let Some(ident) = arg.ident() { + if values_specified { + error!("`cfg()` names cannot be after values"); + } + names.push(ident); + } else if arg.has_name(sym::any) + && let Some(args) = arg.meta_item_list() + { + if any_specified { + error!("`any()` cannot be specified multiple times"); + } + any_specified = true; + if !args.is_empty() { + error!("`any()` must be empty"); + } + } else if arg.has_name(sym::values) + && let Some(args) = arg.meta_item_list() + { + if names.is_empty() { + error!("`values()` cannot be specified before the names"); + } else if values_specified { + error!("`values()` cannot be specified multiple times"); + } + values_specified = true; + + for arg in args { + if let Some(LitKind::Str(s, _)) = + arg.lit().map(|lit| &lit.kind) + { + values.insert(Some(s.to_string())); + } else if arg.has_name(sym::any) + && let Some(args) = arg.meta_item_list() + { + if values_any_specified { error!( - "`values()` arguments cannot specify string literals and `any()` at the same time" + "`any()` in `values()` cannot be specified multiple times" ); } - - if any_specified { - if !names.is_empty() - || !values.is_empty() - || values_any_specified - { - error!("`cfg(any())` can only be provided in isolation"); - } - - check_cfg.exhaustive_names = false; - } else { - for name in names { - check_cfg - .expecteds - .entry(name.to_string()) - .and_modify(|v| match v { - ExpectedValues::Some(v) - if !values_any_specified => - { - v.extend(values.clone()) - } - ExpectedValues::Some(_) => *v = ExpectedValues::Any, - ExpectedValues::Any => {} - }) - .or_insert_with(|| { - if values_any_specified { - ExpectedValues::Any - } else { - ExpectedValues::Some(values.clone()) - } - }); - } + values_any_specified = true; + if !args.is_empty() { + error!("`any()` must be empty"); } } else { - expected_error(); + error!( + "`values()` arguments must be string literals or `any()`" + ); } - } else { - expected_error(); } + } else { + error!( + "`cfg()` arguments must be simple identifiers, `any()` or `values(...)`" + ); } - Ok(..) => expected_error(), - Err(err) => { - err.cancel(); - expected_error(); + } + + if values.is_empty() && !values_any_specified && !any_specified { + values.insert(None); + } else if !values.is_empty() && values_any_specified { + error!( + "`values()` arguments cannot specify string literals and `any()` at the same time" + ); + } + + if any_specified { + if !names.is_empty() || !values.is_empty() || values_any_specified { + error!("`cfg(any())` can only be provided in isolation"); + } + + check_cfg.exhaustive_names = false; + } else { + for name in names { + check_cfg + .expecteds + .entry(name.to_string()) + .and_modify(|v| match v { + ExpectedValues::Some(v) if !values_any_specified => { + v.extend(values.clone()) + } + ExpectedValues::Some(_) => *v = ExpectedValues::Any, + ExpectedValues::Any => {} + }) + .or_insert_with(|| { + if values_any_specified { + ExpectedValues::Any + } else { + ExpectedValues::Some(values.clone()) + } + }); } - }, - Err(errs) => { - drop(errs); - expected_error(); } + } else { + expected_error(); } } From 1ef96a9e06124ca3ce95f9ceb3be6f24d0e7154a Mon Sep 17 00:00:00 2001 From: Urgau Date: Fri, 20 Oct 2023 19:34:45 +0200 Subject: [PATCH 6/9] Fix residual (never merged) check-cfg syntax in doc --- src/doc/unstable-book/src/compiler-flags/check-cfg.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/unstable-book/src/compiler-flags/check-cfg.md b/src/doc/unstable-book/src/compiler-flags/check-cfg.md index 7a3ef5e9e2be6..0e15c79076fa4 100644 --- a/src/doc/unstable-book/src/compiler-flags/check-cfg.md +++ b/src/doc/unstable-book/src/compiler-flags/check-cfg.md @@ -139,7 +139,7 @@ fn do_mumble_frotz() {} ```bash # This turns on checking for feature values, but not for condition names. -rustc --check-cfg 'configure(feature, values("zapping", "lasers"))' \ +rustc --check-cfg 'cfg(feature, values("zapping", "lasers"))' \ --check-cfg 'cfg(any())' \ --cfg 'feature="zapping"' -Z unstable-options ``` From 351ca152ef633ed0037e6a4cdcaf68d40ec40c43 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 21 Oct 2023 18:45:48 +0200 Subject: [PATCH 7/9] Prevent mixing deprecated check-cfg syntax with new one --- compiler/rustc_interface/src/interface.rs | 13 +++++ tests/ui/check-cfg/mix.cfg.stderr | 52 +++++++++---------- tests/ui/check-cfg/mix.names_values.stderr | 52 +++++++++---------- tests/ui/check-cfg/mix.rs | 3 +- .../check-cfg/no-expected-values.empty.stderr | 4 +- .../check-cfg/no-expected-values.mixed.stderr | 4 +- tests/ui/check-cfg/no-expected-values.rs | 5 +- .../no-expected-values.simple.stderr | 4 +- .../no-expected-values.values.stderr | 23 -------- tests/ui/check-cfg/unexpected-cfg-name.rs | 6 +-- .../check-cfg/unexpected-cfg-value.cfg.stderr | 4 +- tests/ui/check-cfg/unexpected-cfg-value.rs | 5 +- .../unexpected-cfg-value.values.stderr | 4 +- 13 files changed, 84 insertions(+), 95 deletions(-) delete mode 100644 tests/ui/check-cfg/no-expected-values.values.stderr diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 2218892538212..758db80dd4a00 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -147,6 +147,12 @@ pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -> Check }; } + let cannot_mix_error = || { + error!( + "cannot mix `cfg(...)` with deprecated syntax `names(...)` and `values(...)`" + ) + }; + let expected_error = || -> ! { error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`") }; @@ -174,6 +180,8 @@ pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -> Check if old_syntax == None { check_cfg.exhaustive_names = false; check_cfg.exhaustive_values = false; + } else if old_syntax == Some(false) { + cannot_mix_error(); } old_syntax = Some(true); @@ -194,6 +202,8 @@ pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -> Check if old_syntax == None { check_cfg.exhaustive_names = false; check_cfg.exhaustive_values = false; + } else if old_syntax == Some(false) { + cannot_mix_error(); } old_syntax = Some(true); @@ -237,6 +247,9 @@ pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -> Check expected_error(); } } else if meta_item.has_name(sym::cfg) { + if old_syntax == Some(true) { + cannot_mix_error(); + } old_syntax = Some(false); let mut names = Vec::new(); diff --git a/tests/ui/check-cfg/mix.cfg.stderr b/tests/ui/check-cfg/mix.cfg.stderr index daa200440cc94..e619b222446b6 100644 --- a/tests/ui/check-cfg/mix.cfg.stderr +++ b/tests/ui/check-cfg/mix.cfg.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `widnows` - --> $DIR/mix.rs:15:7 + --> $DIR/mix.rs:16:7 | LL | #[cfg(widnows)] | ^^^^^^^ help: there is a config with a similar name: `windows` @@ -7,7 +7,7 @@ LL | #[cfg(widnows)] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: (none) - --> $DIR/mix.rs:19:7 + --> $DIR/mix.rs:20:7 | LL | #[cfg(feature)] | ^^^^^^^- help: specify a config value: `= "foo"` @@ -15,7 +15,7 @@ LL | #[cfg(feature)] = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value: `bar` - --> $DIR/mix.rs:26:7 + --> $DIR/mix.rs:27:7 | LL | #[cfg(feature = "bar")] | ^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | #[cfg(feature = "bar")] = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:30:7 + --> $DIR/mix.rs:31:7 | LL | #[cfg(feature = "zebra")] | ^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | #[cfg(feature = "zebra")] = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name: `uu` - --> $DIR/mix.rs:34:12 + --> $DIR/mix.rs:35:12 | LL | #[cfg_attr(uu, test)] | ^^ @@ -47,13 +47,13 @@ warning: unexpected `unknown_name` as condition name = help: was set with `--cfg` but isn't in the `--check-cfg` expected names warning: unexpected `cfg` condition name: `widnows` - --> $DIR/mix.rs:43:10 + --> $DIR/mix.rs:44:10 | LL | cfg!(widnows); | ^^^^^^^ help: there is a config with a similar name: `windows` warning: unexpected `cfg` condition value: `bar` - --> $DIR/mix.rs:46:10 + --> $DIR/mix.rs:47:10 | LL | cfg!(feature = "bar"); | ^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | cfg!(feature = "bar"); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:48:10 + --> $DIR/mix.rs:49:10 | LL | cfg!(feature = "zebra"); | ^^^^^^^^^^^^^^^^^ @@ -69,25 +69,25 @@ LL | cfg!(feature = "zebra"); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:50:10 + --> $DIR/mix.rs:51:10 | LL | cfg!(xxx = "foo"); | ^^^^^^^^^^^ warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:52:10 + --> $DIR/mix.rs:53:10 | LL | cfg!(xxx); | ^^^ warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:54:14 + --> $DIR/mix.rs:55:14 | LL | cfg!(any(xxx, windows)); | ^^^ warning: unexpected `cfg` condition value: `bad` - --> $DIR/mix.rs:56:14 + --> $DIR/mix.rs:57:14 | LL | cfg!(any(feature = "bad", windows)); | ^^^^^^^^^^^^^^^ @@ -95,43 +95,43 @@ LL | cfg!(any(feature = "bad", windows)); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:58:23 + --> $DIR/mix.rs:59:23 | LL | cfg!(any(windows, xxx)); | ^^^ warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:60:20 + --> $DIR/mix.rs:61:20 | LL | cfg!(all(unix, xxx)); | ^^^ warning: unexpected `cfg` condition name: `aa` - --> $DIR/mix.rs:62:14 + --> $DIR/mix.rs:63:14 | LL | cfg!(all(aa, bb)); | ^^ warning: unexpected `cfg` condition name: `bb` - --> $DIR/mix.rs:62:18 + --> $DIR/mix.rs:63:18 | LL | cfg!(all(aa, bb)); | ^^ warning: unexpected `cfg` condition name: `aa` - --> $DIR/mix.rs:65:14 + --> $DIR/mix.rs:66:14 | LL | cfg!(any(aa, bb)); | ^^ warning: unexpected `cfg` condition name: `bb` - --> $DIR/mix.rs:65:18 + --> $DIR/mix.rs:66:18 | LL | cfg!(any(aa, bb)); | ^^ warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:68:20 + --> $DIR/mix.rs:69:20 | LL | cfg!(any(unix, feature = "zebra")); | ^^^^^^^^^^^^^^^^^ @@ -139,13 +139,13 @@ LL | cfg!(any(unix, feature = "zebra")); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:70:14 + --> $DIR/mix.rs:71:14 | LL | cfg!(any(xxx, feature = "zebra")); | ^^^ warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:70:19 + --> $DIR/mix.rs:71:19 | LL | cfg!(any(xxx, feature = "zebra")); | ^^^^^^^^^^^^^^^^^ @@ -153,19 +153,19 @@ LL | cfg!(any(xxx, feature = "zebra")); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:73:14 + --> $DIR/mix.rs:74:14 | LL | cfg!(any(xxx, unix, xxx)); | ^^^ warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:73:25 + --> $DIR/mix.rs:74:25 | LL | cfg!(any(xxx, unix, xxx)); | ^^^ warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:76:14 + --> $DIR/mix.rs:77:14 | LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ @@ -173,7 +173,7 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:76:33 + --> $DIR/mix.rs:77:33 | LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:76:52 + --> $DIR/mix.rs:77:52 | LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/mix.names_values.stderr b/tests/ui/check-cfg/mix.names_values.stderr index daa200440cc94..e619b222446b6 100644 --- a/tests/ui/check-cfg/mix.names_values.stderr +++ b/tests/ui/check-cfg/mix.names_values.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `widnows` - --> $DIR/mix.rs:15:7 + --> $DIR/mix.rs:16:7 | LL | #[cfg(widnows)] | ^^^^^^^ help: there is a config with a similar name: `windows` @@ -7,7 +7,7 @@ LL | #[cfg(widnows)] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: (none) - --> $DIR/mix.rs:19:7 + --> $DIR/mix.rs:20:7 | LL | #[cfg(feature)] | ^^^^^^^- help: specify a config value: `= "foo"` @@ -15,7 +15,7 @@ LL | #[cfg(feature)] = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value: `bar` - --> $DIR/mix.rs:26:7 + --> $DIR/mix.rs:27:7 | LL | #[cfg(feature = "bar")] | ^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ LL | #[cfg(feature = "bar")] = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:30:7 + --> $DIR/mix.rs:31:7 | LL | #[cfg(feature = "zebra")] | ^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | #[cfg(feature = "zebra")] = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name: `uu` - --> $DIR/mix.rs:34:12 + --> $DIR/mix.rs:35:12 | LL | #[cfg_attr(uu, test)] | ^^ @@ -47,13 +47,13 @@ warning: unexpected `unknown_name` as condition name = help: was set with `--cfg` but isn't in the `--check-cfg` expected names warning: unexpected `cfg` condition name: `widnows` - --> $DIR/mix.rs:43:10 + --> $DIR/mix.rs:44:10 | LL | cfg!(widnows); | ^^^^^^^ help: there is a config with a similar name: `windows` warning: unexpected `cfg` condition value: `bar` - --> $DIR/mix.rs:46:10 + --> $DIR/mix.rs:47:10 | LL | cfg!(feature = "bar"); | ^^^^^^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | cfg!(feature = "bar"); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:48:10 + --> $DIR/mix.rs:49:10 | LL | cfg!(feature = "zebra"); | ^^^^^^^^^^^^^^^^^ @@ -69,25 +69,25 @@ LL | cfg!(feature = "zebra"); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:50:10 + --> $DIR/mix.rs:51:10 | LL | cfg!(xxx = "foo"); | ^^^^^^^^^^^ warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:52:10 + --> $DIR/mix.rs:53:10 | LL | cfg!(xxx); | ^^^ warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:54:14 + --> $DIR/mix.rs:55:14 | LL | cfg!(any(xxx, windows)); | ^^^ warning: unexpected `cfg` condition value: `bad` - --> $DIR/mix.rs:56:14 + --> $DIR/mix.rs:57:14 | LL | cfg!(any(feature = "bad", windows)); | ^^^^^^^^^^^^^^^ @@ -95,43 +95,43 @@ LL | cfg!(any(feature = "bad", windows)); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:58:23 + --> $DIR/mix.rs:59:23 | LL | cfg!(any(windows, xxx)); | ^^^ warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:60:20 + --> $DIR/mix.rs:61:20 | LL | cfg!(all(unix, xxx)); | ^^^ warning: unexpected `cfg` condition name: `aa` - --> $DIR/mix.rs:62:14 + --> $DIR/mix.rs:63:14 | LL | cfg!(all(aa, bb)); | ^^ warning: unexpected `cfg` condition name: `bb` - --> $DIR/mix.rs:62:18 + --> $DIR/mix.rs:63:18 | LL | cfg!(all(aa, bb)); | ^^ warning: unexpected `cfg` condition name: `aa` - --> $DIR/mix.rs:65:14 + --> $DIR/mix.rs:66:14 | LL | cfg!(any(aa, bb)); | ^^ warning: unexpected `cfg` condition name: `bb` - --> $DIR/mix.rs:65:18 + --> $DIR/mix.rs:66:18 | LL | cfg!(any(aa, bb)); | ^^ warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:68:20 + --> $DIR/mix.rs:69:20 | LL | cfg!(any(unix, feature = "zebra")); | ^^^^^^^^^^^^^^^^^ @@ -139,13 +139,13 @@ LL | cfg!(any(unix, feature = "zebra")); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:70:14 + --> $DIR/mix.rs:71:14 | LL | cfg!(any(xxx, feature = "zebra")); | ^^^ warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:70:19 + --> $DIR/mix.rs:71:19 | LL | cfg!(any(xxx, feature = "zebra")); | ^^^^^^^^^^^^^^^^^ @@ -153,19 +153,19 @@ LL | cfg!(any(xxx, feature = "zebra")); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:73:14 + --> $DIR/mix.rs:74:14 | LL | cfg!(any(xxx, unix, xxx)); | ^^^ warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:73:25 + --> $DIR/mix.rs:74:25 | LL | cfg!(any(xxx, unix, xxx)); | ^^^ warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:76:14 + --> $DIR/mix.rs:77:14 | LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ @@ -173,7 +173,7 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:76:33 + --> $DIR/mix.rs:77:33 | LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); = note: expected values for `feature` are: `foo` warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:76:52 + --> $DIR/mix.rs:77:52 | LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/mix.rs b/tests/ui/check-cfg/mix.rs index d7b3b4953b7a4..17247fb4c491d 100644 --- a/tests/ui/check-cfg/mix.rs +++ b/tests/ui/check-cfg/mix.rs @@ -5,8 +5,9 @@ // check-pass // revisions: names_values cfg // compile-flags: --cfg feature="bar" --cfg unknown_name -Z unstable-options -// compile-flags: --check-cfg=cfg(names_values,cfg) // [names_values]compile-flags: --check-cfg=names() --check-cfg=values(feature,"foo") +// [names_values]compile-flags: --check-cfg=names(names_values,cfg) +// [cfg]compile-flags: --check-cfg=cfg(names_values,cfg) // [cfg]compile-flags: --check-cfg=cfg(feature,values("foo")) #[cfg(windows)] diff --git a/tests/ui/check-cfg/no-expected-values.empty.stderr b/tests/ui/check-cfg/no-expected-values.empty.stderr index 5d261b2a5e63e..0969d61dd40e9 100644 --- a/tests/ui/check-cfg/no-expected-values.empty.stderr +++ b/tests/ui/check-cfg/no-expected-values.empty.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:12:7 + --> $DIR/no-expected-values.rs:11:7 | LL | #[cfg(feature = "foo")] | ^^^^^^^-------- @@ -10,7 +10,7 @@ LL | #[cfg(feature = "foo")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:16:7 + --> $DIR/no-expected-values.rs:15:7 | LL | #[cfg(test = "foo")] | ^^^^-------- diff --git a/tests/ui/check-cfg/no-expected-values.mixed.stderr b/tests/ui/check-cfg/no-expected-values.mixed.stderr index 5d261b2a5e63e..0969d61dd40e9 100644 --- a/tests/ui/check-cfg/no-expected-values.mixed.stderr +++ b/tests/ui/check-cfg/no-expected-values.mixed.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:12:7 + --> $DIR/no-expected-values.rs:11:7 | LL | #[cfg(feature = "foo")] | ^^^^^^^-------- @@ -10,7 +10,7 @@ LL | #[cfg(feature = "foo")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:16:7 + --> $DIR/no-expected-values.rs:15:7 | LL | #[cfg(test = "foo")] | ^^^^-------- diff --git a/tests/ui/check-cfg/no-expected-values.rs b/tests/ui/check-cfg/no-expected-values.rs index 9e2a9f09aedcd..a07f688c620a8 100644 --- a/tests/ui/check-cfg/no-expected-values.rs +++ b/tests/ui/check-cfg/no-expected-values.rs @@ -1,10 +1,9 @@ // Check that we detect unexpected value when none are allowed // // check-pass -// revisions: values simple mixed empty +// revisions: simple mixed empty // compile-flags: -Z unstable-options -// compile-flags: --check-cfg=cfg(values,simple,mixed,empty) -// [values]compile-flags: --check-cfg=values(test) --check-cfg=values(feature) +// compile-flags: --check-cfg=cfg(simple,mixed,empty) // [simple]compile-flags: --check-cfg=cfg(test) --check-cfg=cfg(feature) // [mixed]compile-flags: --check-cfg=cfg(test,feature) // [empty]compile-flags: --check-cfg=cfg(test,feature,values()) diff --git a/tests/ui/check-cfg/no-expected-values.simple.stderr b/tests/ui/check-cfg/no-expected-values.simple.stderr index 5d261b2a5e63e..0969d61dd40e9 100644 --- a/tests/ui/check-cfg/no-expected-values.simple.stderr +++ b/tests/ui/check-cfg/no-expected-values.simple.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:12:7 + --> $DIR/no-expected-values.rs:11:7 | LL | #[cfg(feature = "foo")] | ^^^^^^^-------- @@ -10,7 +10,7 @@ LL | #[cfg(feature = "foo")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:16:7 + --> $DIR/no-expected-values.rs:15:7 | LL | #[cfg(test = "foo")] | ^^^^-------- diff --git a/tests/ui/check-cfg/no-expected-values.values.stderr b/tests/ui/check-cfg/no-expected-values.values.stderr deleted file mode 100644 index 5d261b2a5e63e..0000000000000 --- a/tests/ui/check-cfg/no-expected-values.values.stderr +++ /dev/null @@ -1,23 +0,0 @@ -warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:12:7 - | -LL | #[cfg(feature = "foo")] - | ^^^^^^^-------- - | | - | help: remove the value - | - = note: no expected value for `feature` - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: unexpected `cfg` condition value: `foo` - --> $DIR/no-expected-values.rs:16:7 - | -LL | #[cfg(test = "foo")] - | ^^^^-------- - | | - | help: remove the value - | - = note: no expected value for `test` - -warning: 2 warnings emitted - diff --git a/tests/ui/check-cfg/unexpected-cfg-name.rs b/tests/ui/check-cfg/unexpected-cfg-name.rs index 15c3aa6e08122..6a3dd0cba3732 100644 --- a/tests/ui/check-cfg/unexpected-cfg-name.rs +++ b/tests/ui/check-cfg/unexpected-cfg-name.rs @@ -2,9 +2,9 @@ // // check-pass // revisions: names exhaustive -// compile-flags: --check-cfg=cfg(names,exhaustive) -// [names]compile-flags: --check-cfg=names() -Z unstable-options -// [exhaustive]compile-flags: --check-cfg=cfg() -Z unstable-options +// compile-flags: -Z unstable-options +// [names]compile-flags: --check-cfg=names() --check-cfg=names(names,exhaustive) +// [exhaustive]compile-flags: --check-cfg=cfg() --check-cfg=cfg(names,exhaustive) #[cfg(widnows)] //~^ WARNING unexpected `cfg` condition name diff --git a/tests/ui/check-cfg/unexpected-cfg-value.cfg.stderr b/tests/ui/check-cfg/unexpected-cfg-value.cfg.stderr index 2ed7f9005573f..a094f52bcb29e 100644 --- a/tests/ui/check-cfg/unexpected-cfg-value.cfg.stderr +++ b/tests/ui/check-cfg/unexpected-cfg-value.cfg.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `sedre` - --> $DIR/unexpected-cfg-value.rs:11:7 + --> $DIR/unexpected-cfg-value.rs:10:7 | LL | #[cfg(feature = "sedre")] | ^^^^^^^^^^------- @@ -10,7 +10,7 @@ LL | #[cfg(feature = "sedre")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `rand` - --> $DIR/unexpected-cfg-value.rs:18:7 + --> $DIR/unexpected-cfg-value.rs:17:7 | LL | #[cfg(feature = "rand")] | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/unexpected-cfg-value.rs b/tests/ui/check-cfg/unexpected-cfg-value.rs index a84458071de84..480f35f565a88 100644 --- a/tests/ui/check-cfg/unexpected-cfg-value.rs +++ b/tests/ui/check-cfg/unexpected-cfg-value.rs @@ -4,9 +4,8 @@ // check-pass // revisions: values cfg // compile-flags: --cfg=feature="rand" -Z unstable-options -// compile-flags: --check-cfg=cfg(values,cfg) -// [values]compile-flags: --check-cfg=values(feature,"serde","full") -// [cfg]compile-flags: --check-cfg=cfg(feature,values("serde","full")) +// [values]compile-flags: --check-cfg=values(feature,"serde","full") --check-cfg=names(values,cfg) +// [cfg]compile-flags: --check-cfg=cfg(feature,values("serde","full")) --check-cfg=cfg(values,cfg) #[cfg(feature = "sedre")] //~^ WARNING unexpected `cfg` condition value diff --git a/tests/ui/check-cfg/unexpected-cfg-value.values.stderr b/tests/ui/check-cfg/unexpected-cfg-value.values.stderr index 2ed7f9005573f..a094f52bcb29e 100644 --- a/tests/ui/check-cfg/unexpected-cfg-value.values.stderr +++ b/tests/ui/check-cfg/unexpected-cfg-value.values.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `sedre` - --> $DIR/unexpected-cfg-value.rs:11:7 + --> $DIR/unexpected-cfg-value.rs:10:7 | LL | #[cfg(feature = "sedre")] | ^^^^^^^^^^------- @@ -10,7 +10,7 @@ LL | #[cfg(feature = "sedre")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `rand` - --> $DIR/unexpected-cfg-value.rs:18:7 + --> $DIR/unexpected-cfg-value.rs:17:7 | LL | #[cfg(feature = "rand")] | ^^^^^^^^^^^^^^^^ From e2122e76551225c169c27035560653627c600406 Mon Sep 17 00:00:00 2001 From: Urgau Date: Sat, 21 Oct 2023 19:11:24 +0200 Subject: [PATCH 8/9] Better guard against wrong input with check-cfg any() --- compiler/rustc_interface/src/interface.rs | 10 +++++++--- tests/ui/check-cfg/invalid-arguments.any_values.stderr | 2 ++ tests/ui/check-cfg/invalid-arguments.rs | 4 +++- .../ui/check-cfg/invalid-arguments.unterminated.stderr | 2 ++ 4 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 tests/ui/check-cfg/invalid-arguments.any_values.stderr create mode 100644 tests/ui/check-cfg/invalid-arguments.unterminated.stderr diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 758db80dd4a00..573b8ffb1699b 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -324,11 +324,15 @@ pub fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) -> Check } if any_specified { - if !names.is_empty() || !values.is_empty() || values_any_specified { + if names.is_empty() + && values.is_empty() + && !values_specified + && !values_any_specified + { + check_cfg.exhaustive_names = false; + } else { error!("`cfg(any())` can only be provided in isolation"); } - - check_cfg.exhaustive_names = false; } else { for name in names { check_cfg diff --git a/tests/ui/check-cfg/invalid-arguments.any_values.stderr b/tests/ui/check-cfg/invalid-arguments.any_values.stderr new file mode 100644 index 0000000000000..f9a9c4a6e1328 --- /dev/null +++ b/tests/ui/check-cfg/invalid-arguments.any_values.stderr @@ -0,0 +1,2 @@ +error: invalid `--check-cfg` argument: `cfg(any(),values())` (`values()` cannot be specified before the names) + diff --git a/tests/ui/check-cfg/invalid-arguments.rs b/tests/ui/check-cfg/invalid-arguments.rs index 79bef89c95740..a56f48e0af93d 100644 --- a/tests/ui/check-cfg/invalid-arguments.rs +++ b/tests/ui/check-cfg/invalid-arguments.rs @@ -6,7 +6,7 @@ // revisions: multiple_values_any not_empty_any not_empty_values_any // revisions: values_any_missing_values values_any_before_ident ident_in_values_1 // revisions: ident_in_values_2 unknown_meta_item_1 unknown_meta_item_2 unknown_meta_item_3 -// revisions: mixed_values_any mixed_any giberich +// revisions: mixed_values_any mixed_any any_values giberich unterminated // // compile-flags: -Z unstable-options // [anything_else]compile-flags: --check-cfg=anything_else(...) @@ -29,6 +29,8 @@ // [unknown_meta_item_3]compile-flags: --check-cfg=cfg(foo,values(test())) // [mixed_values_any]compile-flags: --check-cfg=cfg(foo,values("bar",any())) // [mixed_any]compile-flags: --check-cfg=cfg(any(),values(any())) +// [any_values]compile-flags: --check-cfg=cfg(any(),values()) // [giberich]compile-flags: --check-cfg=cfg(...) +// [unterminated]compile-flags: --check-cfg=cfg( fn main() {} diff --git a/tests/ui/check-cfg/invalid-arguments.unterminated.stderr b/tests/ui/check-cfg/invalid-arguments.unterminated.stderr new file mode 100644 index 0000000000000..80161a6aa0fc8 --- /dev/null +++ b/tests/ui/check-cfg/invalid-arguments.unterminated.stderr @@ -0,0 +1,2 @@ +error: invalid `--check-cfg` argument: `cfg(` (expected `cfg(name, values("value1", "value2", ... "valueN"))`) + From 87dc85d3222743aeb82848537ad77c2ece746ef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 17 Oct 2023 19:29:43 +0000 Subject: [PATCH 9/9] Suggest assoc fn `new` when trying to build tuple struct with private fields Fix #22488. --- .../rustc_resolve/src/late/diagnostics.rs | 21 ++++++++++++++++++- tests/ui/privacy/suggest-box-new.fixed | 15 +++++++++++++ tests/ui/privacy/suggest-box-new.rs | 15 +++++++++++++ tests/ui/privacy/suggest-box-new.stderr | 20 ++++++++++++++++++ 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 tests/ui/privacy/suggest-box-new.fixed create mode 100644 tests/ui/privacy/suggest-box-new.rs create mode 100644 tests/ui/privacy/suggest-box-new.stderr diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a5f8f61f3db50..fd5d6fabf021d 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1570,7 +1570,26 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { err.set_primary_message( "cannot initialize a tuple struct which contains private fields", ); - + if !def_id.is_local() + && self + .r + .tcx + .inherent_impls(def_id) + .iter() + .flat_map(|impl_def_id| { + self.r.tcx.provided_trait_methods(*impl_def_id) + }) + .any(|assoc| !assoc.fn_has_self_parameter && assoc.name == sym::new) + { + // FIXME: look for associated functions with Self return type, + // instead of relying only on the name and lack of self receiver. + err.span_suggestion_verbose( + span.shrink_to_hi(), + "you might have meant to use the `new` associated function", + "::new".to_string(), + Applicability::MaybeIncorrect, + ); + } // Use spans of the tuple struct definition. self.r.field_def_ids(def_id).map(|field_ids| { field_ids diff --git a/tests/ui/privacy/suggest-box-new.fixed b/tests/ui/privacy/suggest-box-new.fixed new file mode 100644 index 0000000000000..f5ae5c2abfd99 --- /dev/null +++ b/tests/ui/privacy/suggest-box-new.fixed @@ -0,0 +1,15 @@ +// run-rustfix +#![allow(dead_code)] +struct U { + wtf: Option>>, + x: T, +} +fn main() { + U { + wtf: Some(Box::new(U { //~ ERROR cannot initialize a tuple struct which contains private fields + wtf: None, + x: (), + })), + x: () + }; +} diff --git a/tests/ui/privacy/suggest-box-new.rs b/tests/ui/privacy/suggest-box-new.rs new file mode 100644 index 0000000000000..2e18dba8b9fb2 --- /dev/null +++ b/tests/ui/privacy/suggest-box-new.rs @@ -0,0 +1,15 @@ +// run-rustfix +#![allow(dead_code)] +struct U { + wtf: Option>>, + x: T, +} +fn main() { + U { + wtf: Some(Box(U { //~ ERROR cannot initialize a tuple struct which contains private fields + wtf: None, + x: (), + })), + x: () + }; +} diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr new file mode 100644 index 0000000000000..ed7fa036408a4 --- /dev/null +++ b/tests/ui/privacy/suggest-box-new.stderr @@ -0,0 +1,20 @@ +error[E0423]: cannot initialize a tuple struct which contains private fields + --> $DIR/suggest-box-new.rs:9:19 + | +LL | wtf: Some(Box(U { + | ^^^ + | +note: constructor is not visible here due to private fields + --> $SRC_DIR/alloc/src/boxed.rs:LL:COL + | + = note: private field + | + = note: private field +help: you might have meant to use the `new` associated function + | +LL | wtf: Some(Box::new(U { + | +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0423`.