From 6773fd1a9a9aae8da53596e15eb2098e0efbb9a2 Mon Sep 17 00:00:00 2001 From: Arlie Davis Date: Wed, 22 Nov 2023 09:10:53 -0800 Subject: [PATCH 01/11] suppress warnings on msvc --- compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h | 2 ++ compiler/rustc_llvm/llvm-wrapper/Linker.cpp | 1 + .../rustc_llvm/llvm-wrapper/SuppressLLVMWarnings.h | 13 +++++++++++++ compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp | 1 + 4 files changed, 17 insertions(+) create mode 100644 compiler/rustc_llvm/llvm-wrapper/SuppressLLVMWarnings.h diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h index 142384e6d0ca2..0520d4150fabd 100644 --- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h +++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h @@ -1,3 +1,5 @@ +#include "SuppressLLVMWarnings.h" + #include "llvm-c/BitReader.h" #include "llvm-c/Core.h" #include "llvm-c/Object.h" diff --git a/compiler/rustc_llvm/llvm-wrapper/Linker.cpp b/compiler/rustc_llvm/llvm-wrapper/Linker.cpp index 8766e96f086d2..533df0f75f8f5 100644 --- a/compiler/rustc_llvm/llvm-wrapper/Linker.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/Linker.cpp @@ -1,3 +1,4 @@ +#include "SuppressLLVMWarnings.h" #include "llvm/Linker/Linker.h" #include "LLVMWrapper.h" diff --git a/compiler/rustc_llvm/llvm-wrapper/SuppressLLVMWarnings.h b/compiler/rustc_llvm/llvm-wrapper/SuppressLLVMWarnings.h new file mode 100644 index 0000000000000..74cd024ca223a --- /dev/null +++ b/compiler/rustc_llvm/llvm-wrapper/SuppressLLVMWarnings.h @@ -0,0 +1,13 @@ +#ifndef _rustc_llvm_SuppressLLVMWarnings_h +#define _rustc_llvm_SuppressLLVMWarnings_h + +// LLVM currently generates many warnings when compiled using MSVC. These warnings make it difficult +// to diagnose real problems when working on C++ code, so we suppress them. + +#ifdef _MSC_VER +#pragma warning(disable:4530) // C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc +#pragma warning(disable:4624) // 'xxx': destructor was implicitly defined as deleted +#pragma warning(disable:4244) // 'initializing': conversion from 'xxx' to 'yyy', possible loss of data +#endif + +#endif // _rustc_llvm_SuppressLLVMWarnings_h diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp index bf00d11edf6d8..91f84692df8f5 100644 --- a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp @@ -7,6 +7,7 @@ // * https://github.com/llvm/llvm-project/blob/8ef3e895ad8ab1724e2b87cabad1dacdc7a397a3/llvm/include/llvm/Object/ArchiveWriter.h // * https://github.com/llvm/llvm-project/blob/8ef3e895ad8ab1724e2b87cabad1dacdc7a397a3/llvm/lib/Object/ArchiveWriter.cpp +#include "SuppressLLVMWarnings.h" #include "llvm/ADT/SmallString.h" #include "llvm/IR/LLVMContext.h" #include "llvm/Object/ObjectFile.h" From 84bc8f037afa470232b3171c5e547744c322be2b Mon Sep 17 00:00:00 2001 From: Arlie Davis Date: Wed, 22 Nov 2023 10:17:50 -0800 Subject: [PATCH 02/11] fix long lines --- compiler/rustc_llvm/llvm-wrapper/SuppressLLVMWarnings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/SuppressLLVMWarnings.h b/compiler/rustc_llvm/llvm-wrapper/SuppressLLVMWarnings.h index 74cd024ca223a..56964e4eaa702 100644 --- a/compiler/rustc_llvm/llvm-wrapper/SuppressLLVMWarnings.h +++ b/compiler/rustc_llvm/llvm-wrapper/SuppressLLVMWarnings.h @@ -5,9 +5,9 @@ // to diagnose real problems when working on C++ code, so we suppress them. #ifdef _MSC_VER -#pragma warning(disable:4530) // C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc +#pragma warning(disable:4530) // C++ exception handler used, but unwind semantics are not enabled. #pragma warning(disable:4624) // 'xxx': destructor was implicitly defined as deleted -#pragma warning(disable:4244) // 'initializing': conversion from 'xxx' to 'yyy', possible loss of data +#pragma warning(disable:4244) // conversion from 'xxx' to 'yyy', possible loss of data #endif #endif // _rustc_llvm_SuppressLLVMWarnings_h From d1009a42d820ded1d446c62d3acb69dffc5117c8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 30 Nov 2023 02:24:11 +0000 Subject: [PATCH 03/11] Enforce must_use on associated types and RPITITs --- compiler/rustc_lint/src/unused.rs | 2 +- .../lint/unused/assoc-types.assoc_ty.stderr | 15 ++++++++++++ .../ui/lint/unused/assoc-types.rpitit.stderr | 15 ++++++++++++ tests/ui/lint/unused/assoc-types.rs | 23 +++++++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 tests/ui/lint/unused/assoc-types.assoc_ty.stderr create mode 100644 tests/ui/lint/unused/assoc-types.rpitit.stderr create mode 100644 tests/ui/lint/unused/assoc-types.rs diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index 0a167b0893c59..c492e7c6fbfb8 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -291,7 +291,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { .map(|inner| MustUsePath::Pinned(Box::new(inner))) } ty::Adt(def, _) => is_def_must_use(cx, def.did(), span), - ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { + ty::Alias(ty::Opaque | ty::Projection, ty::AliasTy { def_id: def, .. }) => { elaborate( cx.tcx, cx.tcx.explicit_item_bounds(def).instantiate_identity_iter_copied(), diff --git a/tests/ui/lint/unused/assoc-types.assoc_ty.stderr b/tests/ui/lint/unused/assoc-types.assoc_ty.stderr new file mode 100644 index 0000000000000..190c4ef0cea0d --- /dev/null +++ b/tests/ui/lint/unused/assoc-types.assoc_ty.stderr @@ -0,0 +1,15 @@ +error: unused implementer of `Future` that must be used + --> $DIR/assoc-types.rs:19:5 + | +LL | T::foo(); + | ^^^^^^^^ + | + = note: futures do nothing unless you `.await` or poll them +note: the lint level is defined here + --> $DIR/assoc-types.rs:4:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/unused/assoc-types.rpitit.stderr b/tests/ui/lint/unused/assoc-types.rpitit.stderr new file mode 100644 index 0000000000000..190c4ef0cea0d --- /dev/null +++ b/tests/ui/lint/unused/assoc-types.rpitit.stderr @@ -0,0 +1,15 @@ +error: unused implementer of `Future` that must be used + --> $DIR/assoc-types.rs:19:5 + | +LL | T::foo(); + | ^^^^^^^^ + | + = note: futures do nothing unless you `.await` or poll them +note: the lint level is defined here + --> $DIR/assoc-types.rs:4:9 + | +LL | #![deny(unused_must_use)] + | ^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/lint/unused/assoc-types.rs b/tests/ui/lint/unused/assoc-types.rs new file mode 100644 index 0000000000000..cebb9b4090ce9 --- /dev/null +++ b/tests/ui/lint/unused/assoc-types.rs @@ -0,0 +1,23 @@ +// edition: 2021 +// revisions: rpitit assoc_ty + +#![deny(unused_must_use)] + +use std::future::Future; + +pub trait Tr { + type Fut: Future; + + #[cfg(rpitit)] + fn foo() -> impl Future; + + #[cfg(assoc_ty)] + fn foo() -> Self::Fut; +} + +pub async fn bar() { + T::foo(); + //~^ ERROR unused implementer of `Future` that must be used +} + +fn main() {} From 801bc561bc9c2ff73ce9c15c6636e6dd5d060bf3 Mon Sep 17 00:00:00 2001 From: Urgau Date: Tue, 5 Dec 2023 13:24:58 +0100 Subject: [PATCH 04/11] Update bootstrap libc to 0.2.150 Version 0.2.150 include support for the new check-cfg syntax --- src/bootstrap/Cargo.lock | 4 ++-- src/bootstrap/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 57113b0ec62c6..f452b944e75be 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -370,9 +370,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.149" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "linux-raw-sys" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index e4d359141cec1..24951cf20fa08 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -42,7 +42,7 @@ filetime = "0.2" hex = "0.4" home = "0.5.4" ignore = "0.4.10" -libc = "0.2" +libc = "0.2.150" object = { version = "0.32.0", default-features = false, features = ["archive", "coff", "read_core", "unaligned"] } once_cell = "1.7.2" opener = "0.5" From 9b4fe38903997a7d873a3064d1eda4f2b1d3357b Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 16 Nov 2023 19:00:38 +0100 Subject: [PATCH 05/11] Use new check-cfg syntax in rustc_llvm build script --- compiler/rustc_llvm/build.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index ed1e87713237b..4b0c1229da134 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -102,7 +102,7 @@ fn output(cmd: &mut Command) -> String { fn main() { for component in REQUIRED_COMPONENTS.iter().chain(OPTIONAL_COMPONENTS.iter()) { - println!("cargo:rustc-check-cfg=values(llvm_component,\"{component}\")"); + println!("cargo:rustc-check-cfg=cfg(llvm_component,values(\"{component}\"))"); } if tracked_env_var_os("RUST_CHECK").is_some() { From 9a942390bfad01ce379b98c211e7b8210681d5b0 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 16 Nov 2023 19:01:06 +0100 Subject: [PATCH 06/11] Update unexpected_cfgs lint definition with new syntax and diagnostics --- compiler/rustc_lint_defs/src/builtin.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a2243817df95f..fc2b2192febb6 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3135,7 +3135,7 @@ declare_lint! { /// ### Example /// /// ```text - /// rustc --check-cfg 'names()' + /// rustc --check-cfg 'cfg()' /// ``` /// /// ```rust,ignore (needs command line option) @@ -3146,7 +3146,7 @@ declare_lint! { /// This will produce: /// /// ```text - /// warning: unknown condition name used + /// warning: unexpected `cfg` condition name: `widnows` /// --> lint_example.rs:1:7 /// | /// 1 | #[cfg(widnows)] @@ -3157,9 +3157,10 @@ declare_lint! { /// /// ### Explanation /// - /// This lint is only active when a `--check-cfg='names(...)'` option has been passed - /// to the compiler and triggers whenever an unknown condition name or value is used. - /// The known condition include names or values passed in `--check-cfg`, `--cfg`, and some + /// This lint is only active when `--check-cfg` arguments are being passed + /// to the compiler and triggers whenever an unexpected condition name or value is used. + /// + /// The known condition include names or values passed in `--check-cfg`, and some /// well-knows names and values built into the compiler. pub UNEXPECTED_CFGS, Warn, From 3f0369e0f2e8c196d8e0324eb300fd8ee2ed51e1 Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 16 Nov 2023 18:41:45 +0100 Subject: [PATCH 07/11] Remove deprecated --check-cfg names() and values() syntax --- compiler/rustc_interface/src/interface.rs | 240 ++++++------------ .../src/compiler-flags/check-cfg.md | 67 ----- .../exhaustive-names-values.empty_cfg.stderr | 8 +- .../exhaustive-names-values.feature.stderr | 6 +- .../exhaustive-names-values.full.stderr | 6 +- tests/ui/check-cfg/exhaustive-names-values.rs | 3 +- tests/ui/check-cfg/exhaustive-names.rs | 4 +- ...y_names.stderr => exhaustive-names.stderr} | 2 +- .../exhaustive-values.empty_cfg.stderr | 2 +- .../exhaustive-values.empty_values.stderr | 13 - tests/ui/check-cfg/exhaustive-values.rs | 3 +- .../exhaustive-values.without_names.stderr | 2 +- ...nvalid-arguments.names_simple_ident.stderr | 2 - tests/ui/check-cfg/invalid-arguments.rs | 5 +- ...valid-arguments.values_simple_ident.stderr | 2 - ...id-arguments.values_string_literals.stderr | 2 - tests/ui/check-cfg/mix.rs | 9 +- .../{mix.names_values.stderr => mix.stderr} | 54 ++-- .../check-cfg/no-expected-values.empty.stderr | 4 +- .../check-cfg/no-expected-values.mixed.stderr | 4 +- tests/ui/check-cfg/no-expected-values.rs | 3 +- .../no-expected-values.simple.stderr | 4 +- .../no-expected-values.values.stderr | 23 -- .../order-independant.names_after.stderr | 19 -- .../order-independant.names_before.stderr | 19 -- tests/ui/check-cfg/order-independant.rs | 11 +- .../order-independant.values_after.stderr | 11 + .../order-independant.values_before.stderr | 11 + .../unexpected-cfg-name.exhaustive.stderr | 10 - tests/ui/check-cfg/unexpected-cfg-name.rs | 5 +- ...ames.stderr => unexpected-cfg-name.stderr} | 2 +- tests/ui/check-cfg/unexpected-cfg-value.rs | 6 +- ...ues.stderr => unexpected-cfg-value.stderr} | 4 +- tests/ui/check-cfg/values-target-json.rs | 2 +- .../feature-gates/feature-gate-check-cfg.rs | 2 +- 35 files changed, 173 insertions(+), 397 deletions(-) rename tests/ui/check-cfg/{exhaustive-names.empty_names.stderr => exhaustive-names.stderr} (94%) delete mode 100644 tests/ui/check-cfg/exhaustive-values.empty_values.stderr delete mode 100644 tests/ui/check-cfg/invalid-arguments.names_simple_ident.stderr delete mode 100644 tests/ui/check-cfg/invalid-arguments.values_simple_ident.stderr delete mode 100644 tests/ui/check-cfg/invalid-arguments.values_string_literals.stderr rename tests/ui/check-cfg/{mix.names_values.stderr => mix.stderr} (81%) delete mode 100644 tests/ui/check-cfg/no-expected-values.values.stderr delete mode 100644 tests/ui/check-cfg/order-independant.names_after.stderr delete mode 100644 tests/ui/check-cfg/order-independant.names_before.stderr create mode 100644 tests/ui/check-cfg/order-independant.values_after.stderr create mode 100644 tests/ui/check-cfg/order-independant.values_before.stderr delete mode 100644 tests/ui/check-cfg/unexpected-cfg-name.exhaustive.stderr rename tests/ui/check-cfg/{unexpected-cfg-name.names.stderr => unexpected-cfg-name.stderr} (86%) rename tests/ui/check-cfg/{unexpected-cfg-value.values.stderr => unexpected-cfg-value.stderr} (87%) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 8a6d8d3d42e28..4be47f93eb4ce 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -10,8 +10,8 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::registry::Registry; use rustc_errors::{ErrorGuaranteed, Handler}; use rustc_lint::LintStore; +use rustc_middle::ty; use rustc_middle::util::Providers; -use rustc_middle::{bug, ty}; use rustc_parse::maybe_new_parser_from_source_str; use rustc_query_impl::QueryCtxt; use rustc_query_system::query::print_query_stack; @@ -104,7 +104,6 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) - let exhaustive_values = !specs.is_empty(); let mut check_cfg = CheckCfg { exhaustive_names, exhaustive_values, ..CheckCfg::default() }; - let mut old_syntax = None; for s in specs { let sess = ParseSess::with_silent_emitter(Some(format!( "this error occurred on the command line: `--check-cfg={s}`" @@ -142,174 +141,101 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec) - expected_error(); }; - let mut set_old_syntax = || { - // 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 meta_item.has_name(sym::names) { - set_old_syntax(); - - check_cfg.exhaustive_names = true; - for arg in args { - if arg.is_word() - && let Some(ident) = arg.ident() - { - check_cfg.expecteds.entry(ident.name).or_insert(ExpectedValues::Any); - } else { - error!("`names()` arguments must be simple identifiers"); - } - } - } else if meta_item.has_name(sym::values) { - set_old_syntax(); - - if let Some((name, values)) = args.split_first() { - if name.is_word() - && let Some(ident) = name.ident() - { - let expected_values = check_cfg - .expecteds - .entry(ident.name) - .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())); + if !meta_item.has_name(sym::cfg) { + expected_error(); + } - let ExpectedValues::Some(expected_values) = expected_values else { - bug!("`expected_values` should be a list a values") - }; + let mut names = Vec::new(); + let mut values: FxHashSet<_> = Default::default(); - for val in values { - if let Some(LitKind::Str(s, _)) = val.lit().map(|lit| &lit.kind) { - expected_values.insert(Some(*s)); - } else { - error!("`values()` arguments must be string literals"); - } - } + let mut any_specified = false; + let mut values_specified = false; + let mut values_any_specified = false; - if values.is_empty() { - expected_values.insert(None); - } - } else { - error!("`values()` first argument must be a simple identifier"); + for arg in args { + if arg.is_word() + && let Some(ident) = arg.ident() + { + if values_specified { + error!("`cfg()` names cannot be after values"); } - } 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)); - } 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()`"); + 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)); + } 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(...)`" - ); } + } else { + error!("`cfg()` arguments must be simple identifiers, `any()` or `values(...)`"); } + } - 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 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_specified - && !values_any_specified - { - check_cfg.exhaustive_names = false; - } else { - error!("`cfg(any())` can only be provided in isolation"); - } + if any_specified { + if names.is_empty() && values.is_empty() && !values_specified && !values_any_specified { + check_cfg.exhaustive_names = false; } else { - for name in names { - check_cfg - .expecteds - .entry(name.name) - .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()) - } - }); - } + error!("`cfg(any())` can only be provided in isolation"); } } else { - expected_error(); + for name in names { + check_cfg + .expecteds + .entry(name.name) + .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()) + } + }); + } } } 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 bcfab79047897..a5b9169c9f3d1 100644 --- a/src/doc/unstable-book/src/compiler-flags/check-cfg.md +++ b/src/doc/unstable-book/src/compiler-flags/check-cfg.md @@ -190,70 +190,3 @@ fn shoot_lasers() {} // the cfg(feature) list fn write_shakespeare() {} ``` - -## The deprecated `names(...)` form - -The `names(...)` form enables checking the names. This form uses a named list: - -```bash -rustc --check-cfg 'names(name1, name2, ... nameN)' -``` - -where each `name` is a bare identifier (has no quotes). The order of the names is not significant. - -If `--check-cfg names(...)` is specified at least once, then `rustc` will check all references to -condition names. `rustc` will check every `#[cfg]` attribute, `#[cfg_attr]` attribute, `cfg` clause -inside `#[link]` attribute and `cfg!(...)` call against the provided list of expected condition -names. If a name is not present in this list, then `rustc` will report an `unexpected_cfgs` lint -diagnostic. The default diagnostic level for this lint is `Warn`. - -If `--check-cfg names(...)` is not specified, then `rustc` will not check references to condition -names. - -`--check-cfg names(...)` may be specified more than once. The result is that the list of valid -condition names is merged across all options. It is legal for a condition name to be specified -more than once; redundantly specifying a condition name has no effect. - -To enable checking condition names with an empty set of valid condition names, use the following -form. The parentheses are required. - -```bash -rustc --check-cfg 'names()' -``` - -Note that `--check-cfg 'names()'` is _not_ equivalent to omitting the option entirely. -The first form enables checking condition names, while specifying that there are no valid -condition names (outside of the set of well-known names defined by `rustc`). Omitting the -`--check-cfg 'names(...)'` option does not enable checking condition names. - -## The deprecated `values(...)` form - -The `values(...)` form enables checking the values within list-valued conditions. It has this -form: - -```bash -rustc --check-cfg `values(name, "value1", "value2", ... "valueN")' -``` - -where `name` is a bare identifier (has no quotes) and each `"value"` term is a quoted literal -string. `name` specifies the name of the condition, such as `feature` or `target_os`. - -When the `values(...)` option is specified, `rustc` will check every `#[cfg(name = "value")]` -attribute, `#[cfg_attr(name = "value")]` attribute, `#[link(name = "a", cfg(name = "value"))]` -and `cfg!(name = "value")` call. It will check that the `"value"` specified is present in the -list of expected values. If `"value"` is not in it, then `rustc` will report an `unexpected_cfgs` -lint diagnostic. The default diagnostic level for this lint is `Warn`. - -To enable checking of values, but to provide an empty set of valid values, use this form: - -```bash -rustc --check-cfg `values(name)` -``` - -The `--check-cfg values(...)` option can be repeated, both for the same condition name and for -different names. If it is repeated for the same condition name, then the sets of values for that -condition are merged together. - -If `values()` is specified, then `rustc` will enable the checking of well-known values defined -by itself. Note that it's necessary to specify the `values()` form to enable the checking of -well known values, specifying the other forms doesn't implicitly enable it. diff --git a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr index 971abb1a21a41..9efc77fb43f1b 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `unknown_key` - --> $DIR/exhaustive-names-values.rs:11:7 + --> $DIR/exhaustive-names-values.rs:10:7 | LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #[cfg(unknown_key = "value")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-names-values.rs:15:7 + --> $DIR/exhaustive-names-values.rs:14:7 | LL | #[cfg(test = "value")] | ^^^^---------- @@ -18,13 +18,13 @@ LL | #[cfg(test = "value")] = note: no expected value for `test` warning: unexpected `cfg` condition name: `feature` - --> $DIR/exhaustive-names-values.rs:19:7 + --> $DIR/exhaustive-names-values.rs:18:7 | LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ warning: unexpected `cfg` condition name: `feature` - --> $DIR/exhaustive-names-values.rs:26:7 + --> $DIR/exhaustive-names-values.rs:25:7 | LL | #[cfg(feature = "std")] | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr index d71ca09589488..4549482abcb91 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.feature.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.feature.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `unknown_key` - --> $DIR/exhaustive-names-values.rs:11:7 + --> $DIR/exhaustive-names-values.rs:10:7 | LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #[cfg(unknown_key = "value")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-names-values.rs:15:7 + --> $DIR/exhaustive-names-values.rs:14:7 | LL | #[cfg(test = "value")] | ^^^^---------- @@ -18,7 +18,7 @@ LL | #[cfg(test = "value")] = note: no expected value for `test` warning: unexpected `cfg` condition value: `unk` - --> $DIR/exhaustive-names-values.rs:19:7 + --> $DIR/exhaustive-names-values.rs:18:7 | LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/exhaustive-names-values.full.stderr b/tests/ui/check-cfg/exhaustive-names-values.full.stderr index d71ca09589488..4549482abcb91 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.full.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.full.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `unknown_key` - --> $DIR/exhaustive-names-values.rs:11:7 + --> $DIR/exhaustive-names-values.rs:10:7 | LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #[cfg(unknown_key = "value")] = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-names-values.rs:15:7 + --> $DIR/exhaustive-names-values.rs:14:7 | LL | #[cfg(test = "value")] | ^^^^---------- @@ -18,7 +18,7 @@ LL | #[cfg(test = "value")] = note: no expected value for `test` warning: unexpected `cfg` condition value: `unk` - --> $DIR/exhaustive-names-values.rs:19:7 + --> $DIR/exhaustive-names-values.rs:18:7 | LL | #[cfg(feature = "unk")] | ^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/exhaustive-names-values.rs b/tests/ui/check-cfg/exhaustive-names-values.rs index ceb4831e22d39..956992a1e777d 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.rs +++ b/tests/ui/check-cfg/exhaustive-names-values.rs @@ -1,9 +1,8 @@ // Check warning for unexpected cfg in the code. // // check-pass -// revisions: empty_names_values empty_cfg feature full +// revisions: empty_cfg feature full // compile-flags: -Z unstable-options -// [empty_names_values]compile-flags: --check-cfg=names() --check-cfg=values() // [empty_cfg]compile-flags: --check-cfg=cfg() // [feature]compile-flags: --check-cfg=cfg(feature,values("std")) // [full]compile-flags: --check-cfg=cfg(feature,values("std")) --check-cfg=cfg() diff --git a/tests/ui/check-cfg/exhaustive-names.rs b/tests/ui/check-cfg/exhaustive-names.rs index b86a7f84eb4b3..8066802069957 100644 --- a/tests/ui/check-cfg/exhaustive-names.rs +++ b/tests/ui/check-cfg/exhaustive-names.rs @@ -1,9 +1,7 @@ // Check warning for unexpected cfg // // check-pass -// revisions: empty_names exhaustive_names -// [empty_names]compile-flags: --check-cfg=names() -Z unstable-options -// [exhaustive_names]compile-flags: --check-cfg=cfg() -Z unstable-options +// compile-flags: --check-cfg=cfg() -Z unstable-options #[cfg(unknown_key = "value")] //~^ WARNING unexpected `cfg` condition name diff --git a/tests/ui/check-cfg/exhaustive-names.empty_names.stderr b/tests/ui/check-cfg/exhaustive-names.stderr similarity index 94% rename from tests/ui/check-cfg/exhaustive-names.empty_names.stderr rename to tests/ui/check-cfg/exhaustive-names.stderr index 7d01c73cc09b5..866595b1213cb 100644 --- a/tests/ui/check-cfg/exhaustive-names.empty_names.stderr +++ b/tests/ui/check-cfg/exhaustive-names.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `unknown_key` - --> $DIR/exhaustive-names.rs:8:7 + --> $DIR/exhaustive-names.rs:6:7 | LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr index 77ddc35100ae3..745646bda1c9f 100644 --- a/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr +++ b/tests/ui/check-cfg/exhaustive-values.empty_cfg.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-values.rs:9:7 + --> $DIR/exhaustive-values.rs:8:7 | LL | #[cfg(test = "value")] | ^^^^---------- diff --git a/tests/ui/check-cfg/exhaustive-values.empty_values.stderr b/tests/ui/check-cfg/exhaustive-values.empty_values.stderr deleted file mode 100644 index 77ddc35100ae3..0000000000000 --- a/tests/ui/check-cfg/exhaustive-values.empty_values.stderr +++ /dev/null @@ -1,13 +0,0 @@ -warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-values.rs:9:7 - | -LL | #[cfg(test = "value")] - | ^^^^---------- - | | - | help: remove the value - | - = note: no expected value for `test` - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/check-cfg/exhaustive-values.rs b/tests/ui/check-cfg/exhaustive-values.rs index 8a1689ba86b5f..430d3b89e7abd 100644 --- a/tests/ui/check-cfg/exhaustive-values.rs +++ b/tests/ui/check-cfg/exhaustive-values.rs @@ -1,8 +1,7 @@ // Check warning for unexpected cfg value // // check-pass -// revisions: empty_values empty_cfg without_names -// [empty_values]compile-flags: --check-cfg=values() -Z unstable-options +// revisions: empty_cfg without_names // [empty_cfg]compile-flags: --check-cfg=cfg() -Z unstable-options // [without_names]compile-flags: --check-cfg=cfg(any()) -Z unstable-options diff --git a/tests/ui/check-cfg/exhaustive-values.without_names.stderr b/tests/ui/check-cfg/exhaustive-values.without_names.stderr index 77ddc35100ae3..745646bda1c9f 100644 --- a/tests/ui/check-cfg/exhaustive-values.without_names.stderr +++ b/tests/ui/check-cfg/exhaustive-values.without_names.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `value` - --> $DIR/exhaustive-values.rs:9:7 + --> $DIR/exhaustive-values.rs:8:7 | LL | #[cfg(test = "value")] | ^^^^---------- diff --git a/tests/ui/check-cfg/invalid-arguments.names_simple_ident.stderr b/tests/ui/check-cfg/invalid-arguments.names_simple_ident.stderr deleted file mode 100644 index 8fadcc1f9f06c..0000000000000 --- a/tests/ui/check-cfg/invalid-arguments.names_simple_ident.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: invalid `--check-cfg` argument: `names("NOT_IDENT")` (`names()` arguments must be simple identifiers) - diff --git a/tests/ui/check-cfg/invalid-arguments.rs b/tests/ui/check-cfg/invalid-arguments.rs index a56f48e0af93d..90c62fa38070d 100644 --- a/tests/ui/check-cfg/invalid-arguments.rs +++ b/tests/ui/check-cfg/invalid-arguments.rs @@ -1,7 +1,7 @@ // Check that invalid --check-cfg are rejected // // check-fail -// revisions: anything_else names_simple_ident values_simple_ident values_string_literals +// revisions: anything_else // revisions: string_for_name_1 string_for_name_2 multiple_any multiple_values // revisions: multiple_values_any not_empty_any not_empty_values_any // revisions: values_any_missing_values values_any_before_ident ident_in_values_1 @@ -10,9 +10,6 @@ // // compile-flags: -Z unstable-options // [anything_else]compile-flags: --check-cfg=anything_else(...) -// [names_simple_ident]compile-flags: --check-cfg=names("NOT_IDENT") -// [values_simple_ident]compile-flags: --check-cfg=values("NOT_IDENT") -// [values_string_literals]compile-flags: --check-cfg=values(test,12) // [string_for_name_1]compile-flags: --check-cfg=cfg("NOT_IDENT") // [string_for_name_2]compile-flags: --check-cfg=cfg(foo,"NOT_IDENT",bar) // [multiple_any]compile-flags: --check-cfg=cfg(any(),any()) diff --git a/tests/ui/check-cfg/invalid-arguments.values_simple_ident.stderr b/tests/ui/check-cfg/invalid-arguments.values_simple_ident.stderr deleted file mode 100644 index 061d3f0e971c3..0000000000000 --- a/tests/ui/check-cfg/invalid-arguments.values_simple_ident.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: invalid `--check-cfg` argument: `values("NOT_IDENT")` (`values()` first argument must be a simple identifier) - diff --git a/tests/ui/check-cfg/invalid-arguments.values_string_literals.stderr b/tests/ui/check-cfg/invalid-arguments.values_string_literals.stderr deleted file mode 100644 index 5853b4741a642..0000000000000 --- a/tests/ui/check-cfg/invalid-arguments.values_string_literals.stderr +++ /dev/null @@ -1,2 +0,0 @@ -error: invalid `--check-cfg` argument: `values(test,12)` (`values()` arguments must be string literals) - diff --git a/tests/ui/check-cfg/mix.rs b/tests/ui/check-cfg/mix.rs index d7b3b4953b7a4..a6c3efee61167 100644 --- a/tests/ui/check-cfg/mix.rs +++ b/tests/ui/check-cfg/mix.rs @@ -1,13 +1,10 @@ -// This test checks the combination of well known names, their activation via names(), -// the usage of values(), and that no implicit is done with --cfg while also testing that +// This test checks the combination of well known names, the usage of cfg(), +// and that no implicit cfgs is added from --cfg while also testing that // we correctly lint on the `cfg!` macro and `cfg_attr` attribute. // // 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") -// [cfg]compile-flags: --check-cfg=cfg(feature,values("foo")) +// compile-flags: --check-cfg=cfg(feature,values("foo")) #[cfg(windows)] fn do_windows_stuff() {} diff --git a/tests/ui/check-cfg/mix.names_values.stderr b/tests/ui/check-cfg/mix.stderr similarity index 81% rename from tests/ui/check-cfg/mix.names_values.stderr rename to tests/ui/check-cfg/mix.stderr index 21c0c7da1dd3d..eefdbd6af30ed 100644 --- a/tests/ui/check-cfg/mix.names_values.stderr +++ b/tests/ui/check-cfg/mix.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `widnows` - --> $DIR/mix.rs:15:7 + --> $DIR/mix.rs:12: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:16: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:23: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:27:7 | LL | #[cfg(feature = "zebra")] | ^^^^^^^^^^^^^^^^^ @@ -31,21 +31,21 @@ 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:31:12 | LL | #[cfg_attr(uu, test)] | ^^ | - = help: expected names are: `cfg`, `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `names_values`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` warning: unexpected `cfg` condition name: `widnows` - --> $DIR/mix.rs:43:10 + --> $DIR/mix.rs:40: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:43:10 | LL | cfg!(feature = "bar"); | ^^^^^^^^^^^^^^^ @@ -53,7 +53,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:45:10 | LL | cfg!(feature = "zebra"); | ^^^^^^^^^^^^^^^^^ @@ -61,25 +61,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:47:10 | LL | cfg!(xxx = "foo"); | ^^^^^^^^^^^ warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:52:10 + --> $DIR/mix.rs:49:10 | LL | cfg!(xxx); | ^^^ warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:54:14 + --> $DIR/mix.rs:51:14 | LL | cfg!(any(xxx, windows)); | ^^^ warning: unexpected `cfg` condition value: `bad` - --> $DIR/mix.rs:56:14 + --> $DIR/mix.rs:53:14 | LL | cfg!(any(feature = "bad", windows)); | ^^^^^^^^^^^^^^^ @@ -87,43 +87,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:55:23 | LL | cfg!(any(windows, xxx)); | ^^^ warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:60:20 + --> $DIR/mix.rs:57:20 | LL | cfg!(all(unix, xxx)); | ^^^ warning: unexpected `cfg` condition name: `aa` - --> $DIR/mix.rs:62:14 + --> $DIR/mix.rs:59:14 | LL | cfg!(all(aa, bb)); | ^^ warning: unexpected `cfg` condition name: `bb` - --> $DIR/mix.rs:62:18 + --> $DIR/mix.rs:59:18 | LL | cfg!(all(aa, bb)); | ^^ warning: unexpected `cfg` condition name: `aa` - --> $DIR/mix.rs:65:14 + --> $DIR/mix.rs:62:14 | LL | cfg!(any(aa, bb)); | ^^ warning: unexpected `cfg` condition name: `bb` - --> $DIR/mix.rs:65:18 + --> $DIR/mix.rs:62:18 | LL | cfg!(any(aa, bb)); | ^^ warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:68:20 + --> $DIR/mix.rs:65:20 | LL | cfg!(any(unix, feature = "zebra")); | ^^^^^^^^^^^^^^^^^ @@ -131,13 +131,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:67:14 | LL | cfg!(any(xxx, feature = "zebra")); | ^^^ warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:70:19 + --> $DIR/mix.rs:67:19 | LL | cfg!(any(xxx, feature = "zebra")); | ^^^^^^^^^^^^^^^^^ @@ -145,19 +145,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:70:14 | LL | cfg!(any(xxx, unix, xxx)); | ^^^ warning: unexpected `cfg` condition name: `xxx` - --> $DIR/mix.rs:73:25 + --> $DIR/mix.rs:70:25 | LL | cfg!(any(xxx, unix, xxx)); | ^^^ warning: unexpected `cfg` condition value: `zebra` - --> $DIR/mix.rs:76:14 + --> $DIR/mix.rs:73:14 | LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ @@ -165,7 +165,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:73:33 | 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:52 + --> $DIR/mix.rs:73:52 | LL | cfg!(all(feature = "zebra", feature = "zebra", feature = "zebra")); | ^^^^^^^^^^^^^^^^^ 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..9f34c019ea534 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) // [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/order-independant.names_after.stderr b/tests/ui/check-cfg/order-independant.names_after.stderr deleted file mode 100644 index a308358e48587..0000000000000 --- a/tests/ui/check-cfg/order-independant.names_after.stderr +++ /dev/null @@ -1,19 +0,0 @@ -warning: unexpected `cfg` condition value: (none) - --> $DIR/order-independant.rs:8:7 - | -LL | #[cfg(a)] - | ^- help: specify a config value: `= "b"` - | - = note: expected values for `a` are: `b` - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: unexpected `cfg` condition value: `unk` - --> $DIR/order-independant.rs:12:7 - | -LL | #[cfg(a = "unk")] - | ^^^^^^^^^ - | - = note: expected values for `a` are: `b` - -warning: 2 warnings emitted - diff --git a/tests/ui/check-cfg/order-independant.names_before.stderr b/tests/ui/check-cfg/order-independant.names_before.stderr deleted file mode 100644 index a308358e48587..0000000000000 --- a/tests/ui/check-cfg/order-independant.names_before.stderr +++ /dev/null @@ -1,19 +0,0 @@ -warning: unexpected `cfg` condition value: (none) - --> $DIR/order-independant.rs:8:7 - | -LL | #[cfg(a)] - | ^- help: specify a config value: `= "b"` - | - = note: expected values for `a` are: `b` - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: unexpected `cfg` condition value: `unk` - --> $DIR/order-independant.rs:12:7 - | -LL | #[cfg(a = "unk")] - | ^^^^^^^^^ - | - = note: expected values for `a` are: `b` - -warning: 2 warnings emitted - diff --git a/tests/ui/check-cfg/order-independant.rs b/tests/ui/check-cfg/order-independant.rs index ce056b8dcd6f8..86e3cfa1d9bfd 100644 --- a/tests/ui/check-cfg/order-independant.rs +++ b/tests/ui/check-cfg/order-independant.rs @@ -1,12 +1,13 @@ // check-pass -// revisions: names_before names_after +// +// revisions: values_before values_after // compile-flags: -Z unstable-options -// compile-flags: --check-cfg=names(names_before,names_after) -// [names_before]compile-flags: --check-cfg=names(a) --check-cfg=values(a,"b") -// [names_after]compile-flags: --check-cfg=values(a,"b") --check-cfg=names(a) +// compile-flags: --check-cfg=cfg(values_before,values_after) +// +// [values_before]compile-flags: --check-cfg=cfg(a,values("b")) --check-cfg=cfg(a) +// [values_after]compile-flags: --check-cfg=cfg(a) --check-cfg=cfg(a,values("b")) #[cfg(a)] -//~^ WARNING unexpected `cfg` condition value fn my_cfg() {} #[cfg(a = "unk")] diff --git a/tests/ui/check-cfg/order-independant.values_after.stderr b/tests/ui/check-cfg/order-independant.values_after.stderr new file mode 100644 index 0000000000000..ed162fb5489d4 --- /dev/null +++ b/tests/ui/check-cfg/order-independant.values_after.stderr @@ -0,0 +1,11 @@ +warning: unexpected `cfg` condition value: `unk` + --> $DIR/order-independant.rs:13:7 + | +LL | #[cfg(a = "unk")] + | ^^^^^^^^^ + | + = note: expected values for `a` are: (none), `b` + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/check-cfg/order-independant.values_before.stderr b/tests/ui/check-cfg/order-independant.values_before.stderr new file mode 100644 index 0000000000000..ed162fb5489d4 --- /dev/null +++ b/tests/ui/check-cfg/order-independant.values_before.stderr @@ -0,0 +1,11 @@ +warning: unexpected `cfg` condition value: `unk` + --> $DIR/order-independant.rs:13:7 + | +LL | #[cfg(a = "unk")] + | ^^^^^^^^^ + | + = note: expected values for `a` are: (none), `b` + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/check-cfg/unexpected-cfg-name.exhaustive.stderr b/tests/ui/check-cfg/unexpected-cfg-name.exhaustive.stderr deleted file mode 100644 index 513f7ac7fd18e..0000000000000 --- a/tests/ui/check-cfg/unexpected-cfg-name.exhaustive.stderr +++ /dev/null @@ -1,10 +0,0 @@ -warning: unexpected `cfg` condition name: `widnows` - --> $DIR/unexpected-cfg-name.rs:9:7 - | -LL | #[cfg(widnows)] - | ^^^^^^^ help: there is a config with a similar name: `windows` - | - = note: `#[warn(unexpected_cfgs)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/check-cfg/unexpected-cfg-name.rs b/tests/ui/check-cfg/unexpected-cfg-name.rs index 15c3aa6e08122..9fc0e28a8fec0 100644 --- a/tests/ui/check-cfg/unexpected-cfg-name.rs +++ b/tests/ui/check-cfg/unexpected-cfg-name.rs @@ -1,10 +1,7 @@ // Check warning for unexpected configuration name // // 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: --check-cfg=cfg() -Z unstable-options #[cfg(widnows)] //~^ WARNING unexpected `cfg` condition name diff --git a/tests/ui/check-cfg/unexpected-cfg-name.names.stderr b/tests/ui/check-cfg/unexpected-cfg-name.stderr similarity index 86% rename from tests/ui/check-cfg/unexpected-cfg-name.names.stderr rename to tests/ui/check-cfg/unexpected-cfg-name.stderr index 513f7ac7fd18e..0874ccfc4617a 100644 --- a/tests/ui/check-cfg/unexpected-cfg-name.names.stderr +++ b/tests/ui/check-cfg/unexpected-cfg-name.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition name: `widnows` - --> $DIR/unexpected-cfg-name.rs:9:7 + --> $DIR/unexpected-cfg-name.rs:6:7 | LL | #[cfg(widnows)] | ^^^^^^^ help: there is a config with a similar name: `windows` diff --git a/tests/ui/check-cfg/unexpected-cfg-value.rs b/tests/ui/check-cfg/unexpected-cfg-value.rs index 1b8ead956bef0..54dce0f0de407 100644 --- a/tests/ui/check-cfg/unexpected-cfg-value.rs +++ b/tests/ui/check-cfg/unexpected-cfg-value.rs @@ -1,10 +1,8 @@ // Check for unexpected configuration value in the code. // // check-pass -// revisions: values cfg -// compile-flags: -Z unstable-options -// [values]compile-flags: --check-cfg=values(feature,"serde","full") -// [cfg]compile-flags: --check-cfg=cfg(feature,values("serde","full")) +// compile-flags: --cfg=feature="rand" -Z unstable-options +// compile-flags: --check-cfg=cfg(feature,values("serde","full")) #[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.stderr similarity index 87% rename from tests/ui/check-cfg/unexpected-cfg-value.values.stderr rename to tests/ui/check-cfg/unexpected-cfg-value.stderr index 2855aa75966bc..31c473a08cb2b 100644 --- a/tests/ui/check-cfg/unexpected-cfg-value.values.stderr +++ b/tests/ui/check-cfg/unexpected-cfg-value.stderr @@ -1,5 +1,5 @@ warning: unexpected `cfg` condition value: `sedre` - --> $DIR/unexpected-cfg-value.rs:9:7 + --> $DIR/unexpected-cfg-value.rs:7: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:16:7 + --> $DIR/unexpected-cfg-value.rs:14:7 | LL | #[cfg(feature = "rand")] | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/check-cfg/values-target-json.rs b/tests/ui/check-cfg/values-target-json.rs index 2ef5a44592b81..e4c1b54ccccfd 100644 --- a/tests/ui/check-cfg/values-target-json.rs +++ b/tests/ui/check-cfg/values-target-json.rs @@ -2,7 +2,7 @@ // // check-pass // needs-llvm-components: x86 -// compile-flags: --crate-type=lib --check-cfg=values() --target={{src-base}}/check-cfg/my-awesome-platform.json -Z unstable-options +// compile-flags: --crate-type=lib --check-cfg=cfg() --target={{src-base}}/check-cfg/my-awesome-platform.json -Z unstable-options #![feature(lang_items, no_core, auto_traits)] #![no_core] diff --git a/tests/ui/feature-gates/feature-gate-check-cfg.rs b/tests/ui/feature-gates/feature-gate-check-cfg.rs index 4012a3b04b522..953b8e3ffcebc 100644 --- a/tests/ui/feature-gates/feature-gate-check-cfg.rs +++ b/tests/ui/feature-gates/feature-gate-check-cfg.rs @@ -1,3 +1,3 @@ -// compile-flags: --check-cfg "names()" +// compile-flags: --check-cfg "cfg()" fn main() {} From 92bf40ffe30832ba459e50d6f51d9e9a1cde9cd2 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 5 Dec 2023 17:33:16 -0800 Subject: [PATCH 08/11] rustc_arena: add `alloc_str` Two places called `from_utf8_unchecked` for strings from `alloc_slice`, and one's SAFETY comment said this was for lack of `alloc_str` -- so let's just add that instead! --- compiler/rustc_arena/src/lib.rs | 22 ++++++++++++++++++++++ compiler/rustc_middle/src/ty/mod.rs | 4 +--- compiler/rustc_span/src/symbol.rs | 6 +----- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 756af7269f293..621516af9c053 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -484,6 +484,20 @@ impl DroplessArena { } } + /// Allocates a string slice that is copied into the `DroplessArena`, returning a + /// reference to it. Will panic if passed an empty string. + /// + /// Panics: + /// + /// - Zero-length string + #[inline] + pub fn alloc_str(&self, string: &str) -> &str { + let slice = self.alloc_slice(string.as_bytes()); + + // SAFETY: the result has a copy of the same valid UTF-8 bytes. + unsafe { std::str::from_utf8_unchecked(slice) } + } + /// # Safety /// /// The caller must ensure that `mem` is valid for writes up to `size_of::() * len`, and that @@ -655,6 +669,14 @@ pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*]) { self.dropless.alloc_slice(value) } + #[inline] + pub fn alloc_str(&self, string: &str) -> &str { + if string.is_empty() { + return ""; + } + self.dropless.alloc_str(string) + } + #[allow(clippy::mut_from_ref)] pub fn alloc_from_iter, C>( &self, diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 9feda4d205e9c..bedb8050e6bb9 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2614,9 +2614,7 @@ pub struct SymbolName<'tcx> { impl<'tcx> SymbolName<'tcx> { pub fn new(tcx: TyCtxt<'tcx>, name: &str) -> SymbolName<'tcx> { - SymbolName { - name: unsafe { str::from_utf8_unchecked(tcx.arena.alloc_slice(name.as_bytes())) }, - } + SymbolName { name: tcx.arena.alloc_str(name) } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index d7e822382ef92..3190ccaf7b485 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2118,11 +2118,7 @@ impl Interner { return Symbol::new(idx as u32); } - // SAFETY: we convert from `&str` to `&[u8]`, clone it into the arena, - // and immediately convert the clone back to `&[u8]`, all because there - // is no `inner.arena.alloc_str()` method. This is clearly safe. - let string: &str = - unsafe { str::from_utf8_unchecked(inner.arena.alloc_slice(string.as_bytes())) }; + let string: &str = inner.arena.alloc_str(string); // SAFETY: we can extend the arena allocation to `'static` because we // only access these while the arena is still alive. From 0f14e8ea7421c791690e81e6a484eed81be7e7e1 Mon Sep 17 00:00:00 2001 From: bohan Date: Sun, 26 Nov 2023 22:05:13 +0800 Subject: [PATCH 09/11] tip for define macro name after `macro_rules!` --- compiler/rustc_resolve/messages.ftl | 2 ++ compiler/rustc_resolve/src/diagnostics.rs | 13 +++++++++---- compiler/rustc_resolve/src/errors.rs | 7 +++++++ tests/ui/resolve/issue-118295.rs | 5 +++++ tests/ui/resolve/issue-118295.stderr | 14 ++++++++++++++ 5 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 tests/ui/resolve/issue-118295.rs create mode 100644 tests/ui/resolve/issue-118295.stderr diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index a5faaaab639a3..3f8df16e03f77 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -181,6 +181,8 @@ resolve_method_not_member_of_trait = method `{$method}` is not a member of trait `{$trait_}` .label = not a member of trait `{$trait_}` +resolve_missing_macro_rules_name = maybe you have forgotten to define a name for this `macro_rules!` + resolve_module_only = visibility must resolve to a module diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 444110c7e7ebd..542aff69e3459 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -27,10 +27,8 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Span, SyntaxContext}; use thin_vec::{thin_vec, ThinVec}; -use crate::errors::{ - AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion, ConsiderAddingADerive, - ExplicitUnsafeTraits, -}; +use crate::errors::{AddedMacroUse, ChangeImportBinding, ChangeImportBindingSuggestion}; +use crate::errors::{ConsiderAddingADerive, ExplicitUnsafeTraits, MaybeMissingMacroRulesName}; use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; use crate::path_names_to_string; @@ -1421,14 +1419,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { "", ); + if macro_kind == MacroKind::Bang && ident.name == sym::macro_rules { + err.subdiagnostic(MaybeMissingMacroRulesName { span: ident.span }); + return; + } + if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) { err.subdiagnostic(ExplicitUnsafeTraits { span: ident.span, ident }); return; } + if self.macro_names.contains(&ident.normalize_to_macros_2_0()) { err.subdiagnostic(AddedMacroUse); return; } + if ident.name == kw::Default && let ModuleKind::Def(DefKind::Enum, def_id, _) = parent_scope.module.kind { diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 72ff959bbd632..1fdb193e571f1 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -665,6 +665,13 @@ pub(crate) struct ExplicitUnsafeTraits { pub(crate) ident: Ident, } +#[derive(Subdiagnostic)] +#[note(resolve_missing_macro_rules_name)] +pub(crate) struct MaybeMissingMacroRulesName { + #[primary_span] + pub(crate) span: Span, +} + #[derive(Subdiagnostic)] #[help(resolve_added_macro_use)] pub(crate) struct AddedMacroUse; diff --git a/tests/ui/resolve/issue-118295.rs b/tests/ui/resolve/issue-118295.rs new file mode 100644 index 0000000000000..b97681d956341 --- /dev/null +++ b/tests/ui/resolve/issue-118295.rs @@ -0,0 +1,5 @@ +macro_rules! {} +//~^ ERROR cannot find macro `macro_rules` in this scope +//~| NOTE maybe you have forgotten to define a name for this `macro_rules!` + +fn main() {} diff --git a/tests/ui/resolve/issue-118295.stderr b/tests/ui/resolve/issue-118295.stderr new file mode 100644 index 0000000000000..d60d7d9185db4 --- /dev/null +++ b/tests/ui/resolve/issue-118295.stderr @@ -0,0 +1,14 @@ +error: cannot find macro `macro_rules` in this scope + --> $DIR/issue-118295.rs:1:1 + | +LL | macro_rules! {} + | ^^^^^^^^^^^ + | +note: maybe you have forgotten to define a name for this `macro_rules!` + --> $DIR/issue-118295.rs:1:1 + | +LL | macro_rules! {} + | ^^^^^^^^^^^ + +error: aborting due to 1 previous error + From 1bcd162465dc98a2264138d145ecf3033d7e2108 Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Wed, 6 Dec 2023 10:48:18 -0800 Subject: [PATCH 10/11] Fix `is_foreign_item` for StableMIR instance Change the implementation of `Instance::is_foreign_item` to directly query the compiler for the instance `def_id` instead of incorrectly relying on the conversion to `CrateItem`. Background: - In pull https://github.com/rust-lang/rust/pull/118524, I fixed the conversion from Instance to CrateItem to avoid the conversion if the instance didn't have a body available. This broke the `is_foreign_item`. --- compiler/rustc_smir/src/rustc_smir/context.rs | 4 ++-- compiler/stable_mir/src/compiler_interface.rs | 2 +- compiler/stable_mir/src/lib.rs | 2 +- compiler/stable_mir/src/mir/mono.rs | 3 +-- tests/ui-fulldeps/stable-mir/check_instance.rs | 3 ++- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index 0bd640ee1e3b0..301ba79bfbe55 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -187,9 +187,9 @@ impl<'tcx> Context for TablesWrapper<'tcx> { new_item_kind(tables.tcx.def_kind(tables[item.0])) } - fn is_foreign_item(&self, item: CrateItem) -> bool { + fn is_foreign_item(&self, item: DefId) -> bool { let tables = self.0.borrow(); - tables.tcx.is_foreign_item(tables[item.0]) + tables.tcx.is_foreign_item(tables[item]) } fn adt_kind(&self, def: AdtDef) -> AdtKind { diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs index daf4465963edd..1bbcc257dfc4e 100644 --- a/compiler/stable_mir/src/compiler_interface.rs +++ b/compiler/stable_mir/src/compiler_interface.rs @@ -60,7 +60,7 @@ pub trait Context { fn item_kind(&self, item: CrateItem) -> ItemKind; /// Returns whether this is a foreign item. - fn is_foreign_item(&self, item: CrateItem) -> bool; + fn is_foreign_item(&self, item: DefId) -> bool; /// Returns the kind of a given algebraic data type fn adt_kind(&self, def: AdtDef) -> AdtKind; diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 2099c485c6f8f..1e7495009d8de 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -120,7 +120,7 @@ impl CrateItem { } pub fn is_foreign_item(&self) -> bool { - with(|cx| cx.is_foreign_item(*self)) + with(|cx| cx.is_foreign_item(self.0)) } pub fn dump(&self, w: &mut W) -> io::Result<()> { diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs index 10270c82e6323..541a8376a62ea 100644 --- a/compiler/stable_mir/src/mir/mono.rs +++ b/compiler/stable_mir/src/mir/mono.rs @@ -40,8 +40,7 @@ impl Instance { } pub fn is_foreign_item(&self) -> bool { - let item = CrateItem::try_from(*self); - item.as_ref().is_ok_and(CrateItem::is_foreign_item) + with(|cx| cx.is_foreign_item(self.def.def_id())) } /// Get the instance type with generic substitutions applied and lifetimes erased. diff --git a/tests/ui-fulldeps/stable-mir/check_instance.rs b/tests/ui-fulldeps/stable-mir/check_instance.rs index 976dfee774b27..2b590d2eff7a2 100644 --- a/tests/ui-fulldeps/stable-mir/check_instance.rs +++ b/tests/ui-fulldeps/stable-mir/check_instance.rs @@ -65,7 +65,8 @@ fn test_body(body: mir::Body) { let instance = Instance::resolve(def, &args).unwrap(); let mangled_name = instance.mangled_name(); let body = instance.body(); - assert!(body.is_some() || mangled_name == "setpwent", "Failed: {func:?}"); + assert!(body.is_some() || (mangled_name == "setpwent"), "Failed: {func:?}"); + assert!(body.is_some() ^ instance.is_foreign_item()); } Goto { .. } | Assert { .. } | SwitchInt { .. } | Return | Drop { .. } => { /* Do nothing */ From 4a75d1893eb65baa5d65c0e1eb511daa8247c85e Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Wed, 6 Dec 2023 11:00:30 -0800 Subject: [PATCH 11/11] Also add an API to check if an instance has body This is much cheaper than building a body just for the purpose of checking if the body exists. --- compiler/stable_mir/src/mir/mono.rs | 8 ++++++++ tests/ui-fulldeps/stable-mir/check_instance.rs | 9 ++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs index 541a8376a62ea..11b849868e009 100644 --- a/compiler/stable_mir/src/mir/mono.rs +++ b/compiler/stable_mir/src/mir/mono.rs @@ -39,6 +39,14 @@ impl Instance { with(|context| context.instance_body(self.def)) } + /// Check whether this instance has a body available. + /// + /// This call is much cheaper than `instance.body().is_some()`, since it doesn't try to build + /// the StableMIR body. + pub fn has_body(&self) -> bool { + with(|cx| cx.has_body(self.def.def_id())) + } + pub fn is_foreign_item(&self) -> bool { with(|cx| cx.is_foreign_item(self.def.def_id())) } diff --git a/tests/ui-fulldeps/stable-mir/check_instance.rs b/tests/ui-fulldeps/stable-mir/check_instance.rs index 2b590d2eff7a2..5cb07eabf41d3 100644 --- a/tests/ui-fulldeps/stable-mir/check_instance.rs +++ b/tests/ui-fulldeps/stable-mir/check_instance.rs @@ -64,9 +64,12 @@ fn test_body(body: mir::Body) { let RigidTy::FnDef(def, args) = ty else { unreachable!() }; let instance = Instance::resolve(def, &args).unwrap(); let mangled_name = instance.mangled_name(); - let body = instance.body(); - assert!(body.is_some() || (mangled_name == "setpwent"), "Failed: {func:?}"); - assert!(body.is_some() ^ instance.is_foreign_item()); + assert!(instance.has_body() || (mangled_name == "setpwent"), "Failed: {func:?}"); + assert!(instance.has_body() ^ instance.is_foreign_item()); + if instance.has_body() { + let body = instance.body().unwrap(); + assert!(!body.locals().is_empty(), "Body must at least have a return local"); + } } Goto { .. } | Assert { .. } | SwitchInt { .. } | Return | Drop { .. } => { /* Do nothing */