From 356027b7097abb90538a5794da30af16326518d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Wed, 17 Apr 2024 19:21:11 +0000 Subject: [PATCH 01/22] ast_passes/validation: update module docs - Syntax extensions are replaced by proc macros. - Add rationale for why AST validation pass need to be run post-expansion and why the pass is needed in the first place. --- compiler/rustc_ast_passes/src/ast_validation.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 495e90e967b93..0592837e42caa 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1,10 +1,13 @@ -// Validate AST before lowering it to HIR. -// -// This pass is supposed to catch things that fit into AST data structures, -// but not permitted by the language. It runs after expansion when AST is frozen, -// so it can check for erroneous constructions produced by syntax extensions. -// This pass is supposed to perform only simple checks not requiring name resolution -// or type checking or some other kind of complex analysis. +//! Validate AST before lowering it to HIR. +//! +//! This pass intends to check that the constructed AST is *syntactically valid* to allow the rest +//! of the compiler to assume that the AST is valid. These checks cannot be performed during parsing +//! because attribute macros are allowed to accept certain pieces of invalid syntax such as `async +//! fn` within a trait (before async-fn-in-trait was introduced). +//! +//! These checks are run post-expansion, after AST is frozen, to be able to check for erroneous +//! constructions produced by proc macros. This pass is only intended for simple checks that do not +//! require name resolution or type checking, or other kinds of complex analysis. use itertools::{Either, Itertools}; use rustc_ast::ptr::P; From 0e3521605dff967199347565dde4d4daeb36fe6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Wed, 17 Apr 2024 19:37:27 +0000 Subject: [PATCH 02/22] ast_passes/validation: update attribute macro example --- compiler/rustc_ast_passes/src/ast_validation.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 0592837e42caa..eadfd3b98e24a 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -2,8 +2,15 @@ //! //! This pass intends to check that the constructed AST is *syntactically valid* to allow the rest //! of the compiler to assume that the AST is valid. These checks cannot be performed during parsing -//! because attribute macros are allowed to accept certain pieces of invalid syntax such as `async -//! fn` within a trait (before async-fn-in-trait was introduced). +//! because attribute macros are allowed to accept certain pieces of invalid syntax such as a +//! function without body outside of a trait definition: +//! +//! ```ignore (illustrative) +//! #[my_attribute] +//! mod foo { +//! fn missing_body(); +//! } +//! ``` //! //! These checks are run post-expansion, after AST is frozen, to be able to check for erroneous //! constructions produced by proc macros. This pass is only intended for simple checks that do not From 9aec5c5bcecad566a76fc7dbb819aa0e58a23671 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 9 Apr 2024 23:17:45 +0000 Subject: [PATCH 03/22] Add test for fn pointer duplication. --- tests/ui/mir/auxiliary/static_fnptr.rs | 10 ++++++++++ tests/ui/mir/static_fnptr.rs | 14 ++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/ui/mir/auxiliary/static_fnptr.rs create mode 100644 tests/ui/mir/static_fnptr.rs diff --git a/tests/ui/mir/auxiliary/static_fnptr.rs b/tests/ui/mir/auxiliary/static_fnptr.rs new file mode 100644 index 0000000000000..a48ee6c012105 --- /dev/null +++ b/tests/ui/mir/auxiliary/static_fnptr.rs @@ -0,0 +1,10 @@ +//@ compile-flags:-O + +fn foo() {} + +pub static ADDR: fn() = foo; + +#[inline(always)] +pub fn bar(x: fn()) -> bool { + x == ADDR +} diff --git a/tests/ui/mir/static_fnptr.rs b/tests/ui/mir/static_fnptr.rs new file mode 100644 index 0000000000000..571dcf4463e12 --- /dev/null +++ b/tests/ui/mir/static_fnptr.rs @@ -0,0 +1,14 @@ +//@ run-pass +//@ compile-flags:-Cno-prepopulate-passes -Copt-level=0 +//@ aux-build:static_fnptr.rs + +extern crate static_fnptr; +use static_fnptr::{ADDR, bar}; + +fn baz() -> bool { + bar(ADDR) +} + +fn main() { + assert!(baz()) +} From d223ba6233455544818e0998d3352de8e237c896 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 10 Apr 2024 10:15:26 +0000 Subject: [PATCH 04/22] Document test. --- tests/ui/mir/static_fnptr.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/ui/mir/static_fnptr.rs b/tests/ui/mir/static_fnptr.rs index 571dcf4463e12..6b1ec021629b8 100644 --- a/tests/ui/mir/static_fnptr.rs +++ b/tests/ui/mir/static_fnptr.rs @@ -1,3 +1,10 @@ +//! Verify that we correctly handle fn pointer provenance in MIR optimizations. +//! By asking to inline `static_fnptr::bar`, we have two copies of `static_fnptr::foo`, one in the +//! auxiliary crate and one in the local crate CGU. +//! `baz` must only consider the versions from upstream crate, and not try to compare with the +//! address of the CGU-local copy. +//! Related issue: #123670 + //@ run-pass //@ compile-flags:-Cno-prepopulate-passes -Copt-level=0 //@ aux-build:static_fnptr.rs From 4c779d75bff7c7c83f4955c3f448198f6dd3c1db Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 4 May 2024 19:27:27 +0000 Subject: [PATCH 05/22] Mark `foo` as explicitly inline. --- tests/ui/mir/auxiliary/static_fnptr.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/mir/auxiliary/static_fnptr.rs b/tests/ui/mir/auxiliary/static_fnptr.rs index a48ee6c012105..8c7347175f4b8 100644 --- a/tests/ui/mir/auxiliary/static_fnptr.rs +++ b/tests/ui/mir/auxiliary/static_fnptr.rs @@ -1,5 +1,6 @@ //@ compile-flags:-O +#[inline] fn foo() {} pub static ADDR: fn() = foo; From 11acf83159edc94edeeafd75eff458d9d584b822 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 14 Jun 2024 09:45:02 +0300 Subject: [PATCH 06/22] bootstrap: exclude cargo from package metadata Signed-off-by: onur-ozkan --- src/bootstrap/src/core/metadata.rs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs index 08a96407a6917..12867cb46b811 100644 --- a/src/bootstrap/src/core/metadata.rs +++ b/src/bootstrap/src/core/metadata.rs @@ -66,9 +66,6 @@ pub fn build(build: &mut Build) { } /// Invokes `cargo metadata` to get package metadata of each workspace member. -/// -/// Note that `src/tools/cargo` is no longer a workspace member but we still -/// treat it as one here, by invoking an additional `cargo metadata` command. fn workspace_members(build: &Build) -> impl Iterator { let collect_metadata = |manifest_path| { let mut cargo = Command::new(&build.initial_cargo); @@ -89,12 +86,8 @@ fn workspace_members(build: &Build) -> impl Iterator { // Collects `metadata.packages` from all workspaces. let packages = collect_metadata("Cargo.toml"); - let cargo_packages = collect_metadata("src/tools/cargo/Cargo.toml"); let ra_packages = collect_metadata("src/tools/rust-analyzer/Cargo.toml"); let bootstrap_packages = collect_metadata("src/bootstrap/Cargo.toml"); - // We only care about the root package from `src/tool/cargo` workspace. - let cargo_package = cargo_packages.into_iter().find(|pkg| pkg.name == "cargo").into_iter(); - - packages.into_iter().chain(cargo_package).chain(ra_packages).chain(bootstrap_packages) + packages.into_iter().chain(ra_packages).chain(bootstrap_packages) } From 457ac5d570f1897ac4c59b3db5f86f26a17d14bb Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 14 Jun 2024 09:45:59 +0300 Subject: [PATCH 07/22] don't fetch/sync cargo submodule by default Signed-off-by: onur-ozkan --- src/bootstrap/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index dfc30298c28d2..afba907ee92b4 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -469,8 +469,7 @@ impl Build { // Make sure we update these before gathering metadata so we don't get an error about missing // Cargo.toml files. - let rust_submodules = - ["src/tools/cargo", "src/doc/book", "library/backtrace", "library/stdarch"]; + let rust_submodules = ["src/doc/book", "library/backtrace", "library/stdarch"]; for s in rust_submodules { build.update_submodule(Path::new(s)); } From 8c3ebf7a4dced401e58f544f1af187f8c41d3472 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 14 Jun 2024 09:49:28 +0300 Subject: [PATCH 08/22] refactor `tool_doc` macro in bootstrap Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/doc.rs | 42 ++++++++++------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 6748625f1323d..87c700dad063d 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -888,12 +888,11 @@ impl Step for Rustc { macro_rules! tool_doc { ( $tool: ident, - $should_run: literal, $path: literal, $(rustc_tool = $rustc_tool:literal, )? - $(in_tree = $in_tree:literal ,)? $(is_library = $is_library:expr,)? $(crates = $crates:expr)? + $(, submodule $(= $submodule:literal)? )? ) => { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct $tool { @@ -907,7 +906,7 @@ macro_rules! tool_doc { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; - run.crate_or_deps($should_run).default_condition(builder.config.compiler_docs) + run.path($path).default_condition(builder.config.compiler_docs) } fn make_run(run: RunConfig<'_>) { @@ -921,6 +920,15 @@ macro_rules! tool_doc { /// we do not merge it with the other documentation from std, test and /// proc_macros. This is largely just a wrapper around `cargo doc`. fn run(self, builder: &Builder<'_>) { + let source_type = SourceType::InTree; + $( + let _ = source_type; // silence the "unused variable" warning + let source_type = SourceType::Submodule; + + let path = Path::new(submodule_helper!( $path, submodule $( = $submodule )? )); + builder.update_submodule(&path); + )? + let stage = builder.top_stage; let target = self.target; @@ -941,12 +949,6 @@ macro_rules! tool_doc { builder.ensure(compile::Rustc::new(compiler, target)); } - let source_type = if true $(&& $in_tree)? { - SourceType::InTree - } else { - SourceType::Submodule - }; - // Build cargo command. let mut cargo = prepare_tool_cargo( builder, @@ -1008,21 +1010,14 @@ macro_rules! tool_doc { } } -tool_doc!(Rustdoc, "rustdoc-tool", "src/tools/rustdoc", crates = ["rustdoc", "rustdoc-json-types"]); -tool_doc!( - Rustfmt, - "rustfmt-nightly", - "src/tools/rustfmt", - crates = ["rustfmt-nightly", "rustfmt-config_proc_macro"] -); -tool_doc!(Clippy, "clippy", "src/tools/clippy", crates = ["clippy_config", "clippy_utils"]); -tool_doc!(Miri, "miri", "src/tools/miri", crates = ["miri"]); +tool_doc!(Rustdoc, "src/tools/rustdoc", crates = ["rustdoc", "rustdoc-json-types"]); +tool_doc!(Rustfmt, "src/tools/rustfmt", crates = ["rustfmt-nightly", "rustfmt-config_proc_macro"]); +tool_doc!(Clippy, "src/tools/clippy", crates = ["clippy_config", "clippy_utils"]); +tool_doc!(Miri, "src/tools/miri", crates = ["miri"]); tool_doc!( Cargo, - "cargo", "src/tools/cargo", rustc_tool = false, - in_tree = false, crates = [ "cargo", "cargo-credential", @@ -1034,12 +1029,12 @@ tool_doc!( "crates-io", "mdman", "rustfix", - ] + ], + submodule = "src/tools/cargo" ); -tool_doc!(Tidy, "tidy", "src/tools/tidy", rustc_tool = false, crates = ["tidy"]); +tool_doc!(Tidy, "src/tools/tidy", rustc_tool = false, crates = ["tidy"]); tool_doc!( Bootstrap, - "bootstrap", "src/bootstrap", rustc_tool = false, is_library = true, @@ -1047,7 +1042,6 @@ tool_doc!( ); tool_doc!( RunMakeSupport, - "run_make_support", "src/tools/run-make-support", rustc_tool = false, is_library = true, From 51f6e68559bdef1a1b16b3d026552eab51b5f389 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Fri, 14 Jun 2024 12:32:34 +0300 Subject: [PATCH 09/22] handle cargo submodule in a lazy-load way Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/test.rs | 3 +++ src/bootstrap/src/core/build_steps/tool.rs | 2 ++ src/bootstrap/src/core/build_steps/vendor.rs | 5 ++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index efc09c41bf429..1ef5af7cc2daf 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2983,6 +2983,9 @@ impl Step for Bootstrap { let compiler = builder.compiler(0, host); let _guard = builder.msg(Kind::Test, 0, "bootstrap", host, host); + // Some tests require cargo submodule to be present. + builder.build.update_submodule(Path::new("src/tools/cargo")); + let mut check_bootstrap = Command::new(builder.python()); check_bootstrap .args(["-m", "unittest", "bootstrap_test.py"]) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 850c8bfe2f8b9..d909a39b60a61 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -654,6 +654,8 @@ impl Step for Cargo { } fn run(self, builder: &Builder<'_>) -> PathBuf { + builder.build.update_submodule(Path::new("src/tools/cargo")); + builder.ensure(ToolBuild { compiler: self.compiler, target: self.target, diff --git a/src/bootstrap/src/core/build_steps/vendor.rs b/src/bootstrap/src/core/build_steps/vendor.rs index 68f1b1bef3f39..e92ab57619b6a 100644 --- a/src/bootstrap/src/core/build_steps/vendor.rs +++ b/src/bootstrap/src/core/build_steps/vendor.rs @@ -1,5 +1,5 @@ use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::Command; #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -34,6 +34,9 @@ impl Step for Vendor { cmd.arg("--versioned-dirs"); } + // cargo submodule must be present for `x vendor` to work. + builder.build.update_submodule(Path::new("src/tools/cargo")); + // Sync these paths by default. for p in [ "src/tools/cargo/Cargo.toml", From ac7595fdb1ee2aafecdd99cd8a3e56192639ada6 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Tue, 12 Dec 2023 13:32:43 -0800 Subject: [PATCH 10/22] Support for -Z patchable-function-entry `-Z patchable-function-entry` works like `-fpatchable-function-entry` on clang/gcc. The arguments are total nop count and function offset. See MCP rust-lang/compiler-team#704 --- compiler/rustc_codegen_llvm/src/attributes.rs | 26 +++++++++++++++++ compiler/rustc_interface/src/tests.rs | 1 + .../src/middle/codegen_fn_attrs.rs | 23 +++++++++++++++ compiler/rustc_session/src/config.rs | 29 ++++++++++++++++++- compiler/rustc_session/src/options.rs | 29 +++++++++++++++++++ .../patchable-function-entry.md | 24 +++++++++++++++ tests/codegen/patchable-function-entry.rs | 8 +++++ 7 files changed, 139 insertions(+), 1 deletion(-) create mode 100644 src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md create mode 100644 tests/codegen/patchable-function-entry.rs diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 48693895da13e..7cf789ab5d72e 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -53,6 +53,31 @@ fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll } } +#[inline] +fn patchable_function_entry_attrs<'ll>( + cx: &CodegenCx<'ll, '_>, +) -> SmallVec<[&'ll Attribute; 2]> { + let mut attrs = SmallVec::new(); + let patchable_spec = cx.tcx.sess.opts.unstable_opts.patchable_function_entry; + let entry = patchable_spec.entry(); + let prefix = patchable_spec.prefix(); + if entry > 0 { + attrs.push(llvm::CreateAttrStringValue( + cx.llcx, + "patchable-function-entry", + &format!("{}", entry), + )); + } + if prefix > 0 { + attrs.push(llvm::CreateAttrStringValue( + cx.llcx, + "patchable-function-prefix", + &format!("{}", prefix), + )); + } + attrs +} + /// Get LLVM sanitize attributes. #[inline] pub fn sanitize_attrs<'ll>( @@ -421,6 +446,7 @@ pub fn from_fn_attrs<'ll, 'tcx>( llvm::set_alignment(llfn, align); } to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize)); + to_add.extend(patchable_function_entry_attrs(cx)); // Always annotate functions with the target-cpu they are compiled for. // Without this, ThinLTO won't inline Rust functions into Clang generated diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 6ffc518097ef0..e4b50e7f5ff26 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -813,6 +813,7 @@ fn test_unstable_options_tracking_hash() { tracked!(packed_bundled_libs, true); tracked!(panic_abort_tests, true); tracked!(panic_in_drop, PanicStrategy::Abort); + tracked!(patchable_function_entry, PatchableFunctionEntry::from_nop_count_and_offset(3, 4)); tracked!(plt, Some(true)); tracked!(polonius, Polonius::Legacy); tracked!(precise_enum_drop_elaboration, false); diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 3fa5054baed1e..0fce26dcbbdbb 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -47,6 +47,29 @@ pub struct CodegenFnAttrs { pub alignment: Option, } +#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] +pub struct PatchableFunctionEntry { + /// Nops to prepend to the function + prefix: u8, + /// Nops after entry, but before body + entry: u8, +} + +impl PatchableFunctionEntry { + pub fn from_config(config: rustc_session::config::PatchableFunctionEntry) -> Self { + Self { prefix: config.prefix(), entry: config.entry() } + } + pub fn from_prefix_and_entry(prefix: u8, entry: u8) -> Self { + Self { prefix, entry } + } + pub fn prefix(&self) -> u8 { + self.prefix + } + pub fn entry(&self) -> u8 { + self.entry + } +} + #[derive(Clone, Copy, PartialEq, Eq, TyEncodable, TyDecodable, HashStable)] pub struct CodegenFnAttrFlags(u32); bitflags::bitflags! { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 839cc51efcea8..2534152267e14 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2963,7 +2963,7 @@ pub(crate) mod dep_tracking { CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, - Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, + PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, }; use crate::lint; @@ -3071,6 +3071,7 @@ pub(crate) mod dep_tracking { OomStrategy, LanguageIdentifier, NextSolverConfig, + PatchableFunctionEntry, Polonius, InliningThreshold, FunctionReturn, @@ -3248,6 +3249,32 @@ impl DumpMonoStatsFormat { } } +/// `-Z patchable-function-entry` representation - how many nops to put before and after function +/// entry. +#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)] +pub struct PatchableFunctionEntry { + /// Nops before the entry + prefix: u8, + /// Nops after the entry + entry: u8, +} + +impl PatchableFunctionEntry { + pub fn from_nop_count_and_offset(nop_count: u8, offset: u8) -> Option { + if nop_count < offset { + None + } else { + Some(Self { prefix: offset, entry: nop_count - offset }) + } + } + pub fn prefix(&self) -> u8 { + self.prefix + } + pub fn entry(&self) -> u8 { + self.entry + } +} + /// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy, /// or future prototype. #[derive(Clone, Copy, PartialEq, Hash, Debug, Default)] diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 9a10adeb6d1a1..f4f8a16662d75 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -379,6 +379,8 @@ mod desc { pub const parse_passes: &str = "a space-separated list of passes, or `all`"; pub const parse_panic_strategy: &str = "either `unwind` or `abort`"; pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`"; + pub const parse_patchable_function_entry: &str = + "nop_count,entry_offset or nop_count (defaulting entry_offset=0)"; pub const parse_opt_panic_strategy: &str = parse_panic_strategy; pub const parse_oom_strategy: &str = "either `panic` or `abort`"; pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; @@ -723,6 +725,7 @@ mod parse { true } + pub(crate) fn parse_on_broken_pipe(slot: &mut OnBrokenPipe, v: Option<&str>) -> bool { match v { // OnBrokenPipe::Default can't be explicitly specified @@ -734,6 +737,30 @@ mod parse { true } + pub(crate) fn parse_patchable_function_entry( + slot: &mut PatchableFunctionEntry, + v: Option<&str>, + ) -> bool { + let mut nop_count = 0; + let mut offset = 0; + + if !parse_number(&mut nop_count, v) { + let parts = v.and_then(|v| v.split_once(',')).unzip(); + if !parse_number(&mut nop_count, parts.0) { + return false; + } + if !parse_number(&mut offset, parts.1) { + return false; + } + } + + if let Some(pfe) = PatchableFunctionEntry::from_nop_count_and_offset(nop_count, offset) { + *slot = pfe; + return true; + } + false + } + pub(crate) fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool { match v { Some("panic") => *slot = OomStrategy::Panic, @@ -1859,6 +1886,8 @@ options! { "panic strategy for panics in drops"), parse_only: bool = (false, parse_bool, [UNTRACKED], "parse only; do not compile, assemble, or link (default: no)"), + patchable_function_entry: PatchableFunctionEntry = (PatchableFunctionEntry::default(), parse_patchable_function_entry, [TRACKED], + "nop padding at function entry"), plt: Option = (None, parse_opt_bool, [TRACKED], "whether to use the PLT when calling into shared libraries; only has effect for PIC code on systems with ELF binaries diff --git a/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md b/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md new file mode 100644 index 0000000000000..a701b9e37719c --- /dev/null +++ b/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md @@ -0,0 +1,24 @@ +# `patchable-function-entry` + +-------------------- + +The `-Z patchable-function-entry=M,N` or `-Z patchable-function-entry=M` +compiler flag enables nop padding of function entries with M nops, with +an offset for the entry of the function at N nops. In the second form, +N defaults to 0. + +As an illustrative example, `-Z patchable-function-entry=3,2` would produce: + +``` +nop +nop +function_label: +nop +//Actual function code begins here +``` + +This flag is used for hotpatching, especially in the Linux kernel. The flag +arguments are modeled after hte `-fpatchable-function-entry` flag as defined +for both [Clang](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fpatchable-function-entry) +and [gcc](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fpatchable-function-entry) +and is intended to provide the same effect. diff --git a/tests/codegen/patchable-function-entry.rs b/tests/codegen/patchable-function-entry.rs new file mode 100644 index 0000000000000..f06739303d2e2 --- /dev/null +++ b/tests/codegen/patchable-function-entry.rs @@ -0,0 +1,8 @@ +// compile-flags: -Z patchable-function-entry=15,10 + +#![crate_type = "lib"] + +#[no_mangle] +pub fn foo() {} +// CHECK: @foo() unnamed_addr #0 +// CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-prefix"="10" {{.*}} } From 9b0ae75ecc485d668232c9c85f0090fb85668312 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Tue, 12 Dec 2023 13:37:04 -0800 Subject: [PATCH 11/22] Support `#[patchable_function_entries]` See [RFC](https://github.com/maurer/rust-rfcs/blob/patchable-function-entry/text/0000-patchable-function-entry.md) (yet to be numbered) TODO before submission: * Needs an RFC * Improve error reporting for malformed attributes --- compiler/rustc_codegen_llvm/src/attributes.rs | 9 ++++--- .../rustc_codegen_ssa/src/codegen_attrs.rs | 26 ++++++++++++++++++- compiler/rustc_feature/src/builtin_attrs.rs | 7 +++++ compiler/rustc_feature/src/unstable.rs | 3 +++ .../src/middle/codegen_fn_attrs.rs | 4 +++ compiler/rustc_span/src/symbol.rs | 3 +++ tests/codegen/patchable-function-entry.rs | 20 ++++++++++++++ .../feature-gate-patchable-function-entry.rs | 3 +++ ...ature-gate-patchable-function-entry.stderr | 12 +++++++++ 9 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-patchable-function-entry.rs create mode 100644 tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 7cf789ab5d72e..cd82894af18eb 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -2,7 +2,7 @@ use rustc_codegen_ssa::traits::*; use rustc_hir::def_id::DefId; -use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry}; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::config::{FunctionReturn, OptLevel}; use rustc_span::symbol::sym; @@ -56,9 +56,12 @@ fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll #[inline] fn patchable_function_entry_attrs<'ll>( cx: &CodegenCx<'ll, '_>, + attr: Option, ) -> SmallVec<[&'ll Attribute; 2]> { let mut attrs = SmallVec::new(); - let patchable_spec = cx.tcx.sess.opts.unstable_opts.patchable_function_entry; + let patchable_spec = attr.unwrap_or_else(|| { + PatchableFunctionEntry::from_config(cx.tcx.sess.opts.unstable_opts.patchable_function_entry) + }); let entry = patchable_spec.entry(); let prefix = patchable_spec.prefix(); if entry > 0 { @@ -446,7 +449,7 @@ pub fn from_fn_attrs<'ll, 'tcx>( llvm::set_alignment(llfn, align); } to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize)); - to_add.extend(patchable_function_entry_attrs(cx)); + to_add.extend(patchable_function_entry_attrs(cx, codegen_fn_attrs.patchable_function_entry)); // Always annotate functions with the target-cpu they are compiled for. // Without this, ThinLTO won't inline Rust functions into Clang generated diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index fb71cdaa8ff2a..8924ddb2aedd3 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -5,7 +5,9 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::{lang_items, weak_lang_items::WEAK_LANG_ITEMS, LangItem}; -use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; +use rustc_middle::middle::codegen_fn_attrs::{ + CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, +}; use rustc_middle::mir::mono::Linkage; use rustc_middle::query::Providers; use rustc_middle::ty::{self as ty, TyCtxt}; @@ -463,6 +465,28 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { None }; } + sym::patchable_function_entry => { + codegen_fn_attrs.patchable_function_entry = attr.meta_item_list().and_then(|l| { + let mut prefix = 0; + let mut entry = 0; + for item in l { + if let Some((sym, lit)) = item.name_value_literal() { + let val = match lit.kind { + // FIXME emit error if too many nops requested + rustc_ast::LitKind::Int(i, _) => i as u8, + _ => continue, + }; + match sym { + sym::prefix => prefix = val, + sym::entry => entry = val, + // FIXME possibly emit error here? + _ => continue, + } + } + } + Some(PatchableFunctionEntry::from_prefix_and_entry(prefix, entry)) + }) + } _ => {} } } diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index c53bf96513951..b5f9f2c715f4f 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -584,6 +584,13 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ pointee, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee) ), + + // FIXME RFC + // `#[patchable_function_entry(prefix(n), entry(n))]` + gated!( + patchable_function_entry, Normal, template!(List: "prefix(n), entry(n)"), ErrorPreceding, + experimental!(patchable_function_entry) + ), // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 2dfaac8f6e731..796475e766f6b 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -565,6 +565,9 @@ declare_features! ( (unstable, offset_of_slice, "CURRENT_RUSTC_VERSION", Some(126151)), /// Allows using `#[optimize(X)]`. (unstable, optimize_attribute, "1.34.0", Some(54882)), + /// Allows specifying nop padding on functions for dynamic patching. + // FIXME this needs an RFC # + (unstable, patchable_function_entry, "CURRENT_RUSTC_VERSION", Some(9999)), /// Allows postfix match `expr.match { ... }` (unstable, postfix_match, "1.79.0", Some(121618)), /// Allows `use<'a, 'b, A, B>` in `impl Trait + use<...>` for precise capture of generic args. diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index 0fce26dcbbdbb..23fe72c537a1c 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -45,6 +45,9 @@ pub struct CodegenFnAttrs { /// The `#[repr(align(...))]` attribute. Indicates the value of which the function should be /// aligned to. pub alignment: Option, + /// The `#[patchable_function_entry(...)]` attribute. Indicates how many nops should be around + /// the function entry. + pub patchable_function_entry: Option, } #[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)] @@ -147,6 +150,7 @@ impl CodegenFnAttrs { no_sanitize: SanitizerSet::empty(), instruction_set: None, alignment: None, + patchable_function_entry: None, } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6d4a8c29bc902..ea7fe7e76c412 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -768,6 +768,7 @@ symbols! { enable, encode, end, + entry, enumerate_method, env, env_CFG_RELEASE: env!("CFG_RELEASE"), @@ -1383,6 +1384,7 @@ symbols! { passes, pat, pat_param, + patchable_function_entry, path, pattern_complexity, pattern_parentheses, @@ -1421,6 +1423,7 @@ symbols! { prefetch_read_instruction, prefetch_write_data, prefetch_write_instruction, + prefix, preg, prelude, prelude_import, diff --git a/tests/codegen/patchable-function-entry.rs b/tests/codegen/patchable-function-entry.rs index f06739303d2e2..dc20c0a2c6dad 100644 --- a/tests/codegen/patchable-function-entry.rs +++ b/tests/codegen/patchable-function-entry.rs @@ -1,8 +1,28 @@ +#![feature(patchable_function_entry)] // compile-flags: -Z patchable-function-entry=15,10 #![crate_type = "lib"] +// This should have the default, as set by the compile flags #[no_mangle] pub fn foo() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix(1), entry(2))] +pub fn bar() {} + +// If we override an attribute to 0 or unset, the attribute should go away +#[no_mangle] +#[patchable_function_entry(entry(0))] +pub fn baz() {} + // CHECK: @foo() unnamed_addr #0 +// CHECK: @bar() unnamed_addr #1 +// CHECK: @baz() unnamed_addr #2 + // CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-prefix"="10" {{.*}} } +// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} } +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } +// CHECK: attributes #2 = { {{.*}} } diff --git a/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs b/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs new file mode 100644 index 0000000000000..0e16e873a1eaa --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs @@ -0,0 +1,3 @@ +#[patchable_function_entry(entry(1), prefix(1))] +//~^ ERROR: the `#[patchable_function_entry]` attribute is an experimental feature +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr b/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr new file mode 100644 index 0000000000000..c4d57d774e35d --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr @@ -0,0 +1,12 @@ +error[E0658]: the `#[patchable_function_entry]` attribute is an experimental feature + --> $DIR/feature-gate-patchable-function-entry.rs:1:1 + | +LL | #[patchable_function_entry(entry(1), prefix(1))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #9999 for more information + = help: add `#![feature(patchable_function_entry)]` to the crate attributes to enable + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0658`. From 7c56398e912ea9e81d8e56b2ca7459b4e62b6636 Mon Sep 17 00:00:00 2001 From: Florian Schmiderer Date: Thu, 2 May 2024 23:19:02 +0200 Subject: [PATCH 12/22] Updated code for changes to RFC, added additional error handling, added tests --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 62 ++++++++++++----- compiler/rustc_feature/src/builtin_attrs.rs | 10 +-- compiler/rustc_feature/src/unstable.rs | 3 +- compiler/rustc_interface/src/tests.rs | 9 ++- compiler/rustc_session/src/config.rs | 14 ++-- compiler/rustc_session/src/options.rs | 18 ++--- compiler/rustc_span/src/symbol.rs | 4 +- .../patchable-function-entry.md | 12 ++-- tests/codegen/patchable-function-entry.rs | 28 -------- .../patchable-function-entry-both-flags.rs | 64 ++++++++++++++++++ .../patchable-function-entry-no-flag.rs | 39 +++++++++++ .../patchable-function-entry-one-flag.rs | 66 +++++++++++++++++++ .../feature-gate-patchable-function-entry.rs | 2 +- ...ature-gate-patchable-function-entry.stderr | 7 +- .../patchable-function-entry-attribute.rs | 17 +++++ .../patchable-function-entry-attribute.stderr | 32 +++++++++ .../patchable-function-entry-flags.rs | 2 + .../patchable-function-entry-flags.stderr | 2 + 18 files changed, 312 insertions(+), 79 deletions(-) delete mode 100644 tests/codegen/patchable-function-entry.rs create mode 100644 tests/codegen/patchable-function-entry/patchable-function-entry-both-flags.rs create mode 100644 tests/codegen/patchable-function-entry/patchable-function-entry-no-flag.rs create mode 100644 tests/codegen/patchable-function-entry/patchable-function-entry-one-flag.rs create mode 100644 tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs create mode 100644 tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr create mode 100644 tests/ui/patchable-function-entry/patchable-function-entry-flags.rs create mode 100644 tests/ui/patchable-function-entry/patchable-function-entry-flags.stderr diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 8924ddb2aedd3..84041811bbbf2 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -1,5 +1,6 @@ use rustc_ast::{ast, attr, MetaItemKind, NestedMetaItem}; use rustc_attr::{list_contains_name, InlineAttr, InstructionSetAttr, OptimizeAttr}; +use rustc_data_structures::packed::Pu128; use rustc_errors::{codes::*, struct_span_code_err}; use rustc_hir as hir; use rustc_hir::def::DefKind; @@ -467,24 +468,55 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { } sym::patchable_function_entry => { codegen_fn_attrs.patchable_function_entry = attr.meta_item_list().and_then(|l| { - let mut prefix = 0; - let mut entry = 0; + let mut prefix = None; + let mut entry = None; for item in l { - if let Some((sym, lit)) = item.name_value_literal() { - let val = match lit.kind { - // FIXME emit error if too many nops requested - rustc_ast::LitKind::Int(i, _) => i as u8, - _ => continue, - }; - match sym { - sym::prefix => prefix = val, - sym::entry => entry = val, - // FIXME possibly emit error here? - _ => continue, + let Some(meta_item) = item.meta_item() else { + tcx.dcx().span_err(item.span(), "Expected name value pair."); + continue; + }; + + let Some(name_value_lit) = meta_item.name_value_literal() else { + tcx.dcx().span_err(item.span(), "Expected name value pair."); + continue; + }; + + let attrib_to_write = match meta_item.name_or_empty() { + sym::prefix_nops => &mut prefix, + sym::entry_nops => &mut entry, + _ => { + tcx.dcx().span_err( + item.span(), + format!( + "Unexpected parameter name. Allowed names: {}, {}", + sym::prefix_nops, + sym::entry_nops + ), + ); + continue; } - } + }; + + let rustc_ast::LitKind::Int(Pu128(val @ 0..=255), _) = name_value_lit.kind + else { + tcx.dcx().span_err( + name_value_lit.span, + "Expected integer value between 0 and 255.", + ); + continue; + }; + + *attrib_to_write = Some(val.try_into().unwrap()); } - Some(PatchableFunctionEntry::from_prefix_and_entry(prefix, entry)) + + if let (None, None) = (prefix, entry) { + tcx.dcx().span_err(attr.span, "Must specify at least one parameter."); + } + + Some(PatchableFunctionEntry::from_prefix_and_entry( + prefix.unwrap_or(0), + entry.unwrap_or(0), + )) }) } _ => {} diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index b5f9f2c715f4f..9371a288f09f7 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -584,12 +584,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ pointee, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee) ), - - // FIXME RFC - // `#[patchable_function_entry(prefix(n), entry(n))]` + + // RFC 3543 + // `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` gated!( - patchable_function_entry, Normal, template!(List: "prefix(n), entry(n)"), ErrorPreceding, - experimental!(patchable_function_entry) + patchable_function_entry, Normal, template!(List: "prefix_nops = m, entry_nops = n"), ErrorPreceding, + EncodeCrossCrate::Yes, experimental!(patchable_function_entry) ), // ========================================================================== diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 796475e766f6b..29c28b4efd2f8 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -566,8 +566,7 @@ declare_features! ( /// Allows using `#[optimize(X)]`. (unstable, optimize_attribute, "1.34.0", Some(54882)), /// Allows specifying nop padding on functions for dynamic patching. - // FIXME this needs an RFC # - (unstable, patchable_function_entry, "CURRENT_RUSTC_VERSION", Some(9999)), + (unstable, patchable_function_entry, "CURRENT_RUSTC_VERSION", Some(123115)), /// Allows postfix match `expr.match { ... }` (unstable, postfix_match, "1.79.0", Some(121618)), /// Allows `use<'a, 'b, A, B>` in `impl Trait + use<...>` for precise capture of generic args. diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index e4b50e7f5ff26..e23d556ad4610 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -8,8 +8,8 @@ use rustc_session::config::{ ErrorOutputType, ExternEntry, ExternLocation, Externs, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName, OutputType, OutputTypes, PAuthKey, - PacRet, Passes, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, - SymbolManglingVersion, WasiExecModel, + PacRet, Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, + SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, }; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; @@ -813,7 +813,10 @@ fn test_unstable_options_tracking_hash() { tracked!(packed_bundled_libs, true); tracked!(panic_abort_tests, true); tracked!(panic_in_drop, PanicStrategy::Abort); - tracked!(patchable_function_entry, PatchableFunctionEntry::from_nop_count_and_offset(3, 4)); + tracked!( + patchable_function_entry, + PatchableFunctionEntry::from_total_and_prefix_nops(10, 5).expect("total >= prefix") + ); tracked!(plt, Some(true)); tracked!(polonius, Polonius::Legacy); tracked!(precise_enum_drop_elaboration, false); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 2534152267e14..e716abedf0733 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2963,8 +2963,9 @@ pub(crate) mod dep_tracking { CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, - PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks, SourceFileHashAlgorithm, - SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel, + PatchableFunctionEntry, Polonius, RemapPathScopeComponents, ResolveDocLinks, + SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, + WasiExecModel, }; use crate::lint; use crate::utils::NativeLib; @@ -3260,11 +3261,14 @@ pub struct PatchableFunctionEntry { } impl PatchableFunctionEntry { - pub fn from_nop_count_and_offset(nop_count: u8, offset: u8) -> Option { - if nop_count < offset { + pub fn from_total_and_prefix_nops( + total_nops: u8, + prefix_nops: u8, + ) -> Option { + if total_nops < prefix_nops { None } else { - Some(Self { prefix: offset, entry: nop_count - offset }) + Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops }) } } pub fn prefix(&self) -> u8 { diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index f4f8a16662d75..80f7ca544f3c5 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -379,8 +379,7 @@ mod desc { pub const parse_passes: &str = "a space-separated list of passes, or `all`"; pub const parse_panic_strategy: &str = "either `unwind` or `abort`"; pub const parse_on_broken_pipe: &str = "either `kill`, `error`, or `inherit`"; - pub const parse_patchable_function_entry: &str = - "nop_count,entry_offset or nop_count (defaulting entry_offset=0)"; + pub const parse_patchable_function_entry: &str = "either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops)"; pub const parse_opt_panic_strategy: &str = parse_panic_strategy; pub const parse_oom_strategy: &str = "either `panic` or `abort`"; pub const parse_relro_level: &str = "one of: `full`, `partial`, or `off`"; @@ -725,7 +724,6 @@ mod parse { true } - pub(crate) fn parse_on_broken_pipe(slot: &mut OnBrokenPipe, v: Option<&str>) -> bool { match v { // OnBrokenPipe::Default can't be explicitly specified @@ -741,20 +739,22 @@ mod parse { slot: &mut PatchableFunctionEntry, v: Option<&str>, ) -> bool { - let mut nop_count = 0; - let mut offset = 0; + let mut total_nops = 0; + let mut prefix_nops = 0; - if !parse_number(&mut nop_count, v) { + if !parse_number(&mut total_nops, v) { let parts = v.and_then(|v| v.split_once(',')).unzip(); - if !parse_number(&mut nop_count, parts.0) { + if !parse_number(&mut total_nops, parts.0) { return false; } - if !parse_number(&mut offset, parts.1) { + if !parse_number(&mut prefix_nops, parts.1) { return false; } } - if let Some(pfe) = PatchableFunctionEntry::from_nop_count_and_offset(nop_count, offset) { + if let Some(pfe) = + PatchableFunctionEntry::from_total_and_prefix_nops(total_nops, prefix_nops) + { *slot = pfe; return true; } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index ea7fe7e76c412..3b6147c4c0f64 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -768,7 +768,7 @@ symbols! { enable, encode, end, - entry, + entry_nops, enumerate_method, env, env_CFG_RELEASE: env!("CFG_RELEASE"), @@ -1423,7 +1423,7 @@ symbols! { prefetch_read_instruction, prefetch_write_data, prefetch_write_instruction, - prefix, + prefix_nops, preg, prelude, prelude_import, diff --git a/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md b/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md index a701b9e37719c..4a9bf47a29011 100644 --- a/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md +++ b/src/doc/unstable-book/src/compiler-flags/patchable-function-entry.md @@ -2,14 +2,14 @@ -------------------- -The `-Z patchable-function-entry=M,N` or `-Z patchable-function-entry=M` -compiler flag enables nop padding of function entries with M nops, with -an offset for the entry of the function at N nops. In the second form, -N defaults to 0. +The `-Z patchable-function-entry=total_nops,prefix_nops` or `-Z patchable-function-entry=total_nops` +compiler flag enables nop padding of function entries with 'total_nops' nops, with +an offset for the entry of the function at 'prefix_nops' nops. In the second form, +'prefix_nops' defaults to 0. As an illustrative example, `-Z patchable-function-entry=3,2` would produce: -``` +```text nop nop function_label: @@ -18,7 +18,7 @@ nop ``` This flag is used for hotpatching, especially in the Linux kernel. The flag -arguments are modeled after hte `-fpatchable-function-entry` flag as defined +arguments are modeled after the `-fpatchable-function-entry` flag as defined for both [Clang](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fpatchable-function-entry) and [gcc](https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fpatchable-function-entry) and is intended to provide the same effect. diff --git a/tests/codegen/patchable-function-entry.rs b/tests/codegen/patchable-function-entry.rs deleted file mode 100644 index dc20c0a2c6dad..0000000000000 --- a/tests/codegen/patchable-function-entry.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![feature(patchable_function_entry)] -// compile-flags: -Z patchable-function-entry=15,10 - -#![crate_type = "lib"] - -// This should have the default, as set by the compile flags -#[no_mangle] -pub fn foo() {} - -// The attribute should override the compile flags -#[no_mangle] -#[patchable_function_entry(prefix(1), entry(2))] -pub fn bar() {} - -// If we override an attribute to 0 or unset, the attribute should go away -#[no_mangle] -#[patchable_function_entry(entry(0))] -pub fn baz() {} - -// CHECK: @foo() unnamed_addr #0 -// CHECK: @bar() unnamed_addr #1 -// CHECK: @baz() unnamed_addr #2 - -// CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-prefix"="10" {{.*}} } -// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } -// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} } -// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } -// CHECK: attributes #2 = { {{.*}} } diff --git a/tests/codegen/patchable-function-entry/patchable-function-entry-both-flags.rs b/tests/codegen/patchable-function-entry/patchable-function-entry-both-flags.rs new file mode 100644 index 0000000000000..72204c78a4906 --- /dev/null +++ b/tests/codegen/patchable-function-entry/patchable-function-entry-both-flags.rs @@ -0,0 +1,64 @@ +//@ compile-flags: -Z patchable-function-entry=15,10 + +#![feature(patchable_function_entry)] +#![crate_type = "lib"] + +// This should have the default, as set by the compile flags +#[no_mangle] +pub fn fun0() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 1, entry_nops = 2)] +pub fn fun1() {} + +// If we override an attribute to 0 or unset, the attribute should go away +#[no_mangle] +#[patchable_function_entry(entry_nops = 0)] +pub fn fun2() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 20, entry_nops = 1)] +pub fn fun3() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 2, entry_nops = 19)] +pub fn fun4() {} + +// The attribute should override patchable-function-entry to 3 and +// patchable-function-prefix to the default of 0, clearing it entirely +#[no_mangle] +#[patchable_function_entry(entry_nops = 3)] +pub fn fun5() {} + +// The attribute should override patchable-function-prefix to 4 +// and patchable-function-entry to the default of 0, clearing it entirely +#[no_mangle] +#[patchable_function_entry(prefix_nops = 4)] +pub fn fun6() {} + +// CHECK: @fun0() unnamed_addr #0 +// CHECK: @fun1() unnamed_addr #1 +// CHECK: @fun2() unnamed_addr #2 +// CHECK: @fun3() unnamed_addr #3 +// CHECK: @fun4() unnamed_addr #4 +// CHECK: @fun5() unnamed_addr #5 +// CHECK: @fun6() unnamed_addr #6 + +// CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-prefix"="10" {{.*}} } +// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } + +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} } +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } +// CHECK: attributes #2 = { {{.*}} } + +// CHECK: attributes #3 = { {{.*}}"patchable-function-entry"="1"{{.*}}"patchable-function-prefix"="20" {{.*}} } +// CHECK: attributes #4 = { {{.*}}"patchable-function-entry"="19"{{.*}}"patchable-function-prefix"="2" {{.*}} } + +// CHECK: attributes #5 = { {{.*}}"patchable-function-entry"="3"{{.*}} } +// CHECK-NOT: attributes #5 = { {{.*}}patchable-function-prefix{{.*}} } + +// CHECK: attributes #6 = { {{.*}}"patchable-function-prefix"="4"{{.*}} } +// CHECK-NOT: attributes #6 = { {{.*}}patchable-function-entry{{.*}} } diff --git a/tests/codegen/patchable-function-entry/patchable-function-entry-no-flag.rs b/tests/codegen/patchable-function-entry/patchable-function-entry-no-flag.rs new file mode 100644 index 0000000000000..3a7078fe55107 --- /dev/null +++ b/tests/codegen/patchable-function-entry/patchable-function-entry-no-flag.rs @@ -0,0 +1,39 @@ +#![feature(patchable_function_entry)] +#![crate_type = "lib"] + +// No patchable function entry should be set +#[no_mangle] +pub fn fun0() {} + +// The attribute should work even without compiler flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 1, entry_nops = 2)] +pub fn fun1() {} + +// The attribute should work even without compiler flags +// and only set patchable-function-entry to 3. +#[no_mangle] +#[patchable_function_entry(entry_nops = 3)] +pub fn fun2() {} + +// The attribute should work even without compiler flags +// and only set patchable-function-prefix to 4. +#[no_mangle] +#[patchable_function_entry(prefix_nops = 4)] +pub fn fun3() {} + +// CHECK: @fun0() unnamed_addr #0 +// CHECK: @fun1() unnamed_addr #1 +// CHECK: @fun2() unnamed_addr #2 +// CHECK: @fun3() unnamed_addr #3 + +// CHECK-NOT: attributes #0 = { {{.*}}patchable-function-entry{{.*}} } +// CHECK-NOT: attributes #0 = { {{.*}}patchable-function-prefix{{.*}} } + +// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } + +// CHECK: attributes #2 = { {{.*}}"patchable-function-entry"="3"{{.*}} } +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } + +// CHECK: attributes #3 = { {{.*}}"patchable-function-prefix"="4"{{.*}} } +// CHECK-NOT: attributes #3 = { {{.*}}patchable-function-entry{{.*}} } diff --git a/tests/codegen/patchable-function-entry/patchable-function-entry-one-flag.rs b/tests/codegen/patchable-function-entry/patchable-function-entry-one-flag.rs new file mode 100644 index 0000000000000..8bdd61e461b81 --- /dev/null +++ b/tests/codegen/patchable-function-entry/patchable-function-entry-one-flag.rs @@ -0,0 +1,66 @@ +//@ compile-flags: -Z patchable-function-entry=15 + +#![feature(patchable_function_entry)] +#![crate_type = "lib"] + +// This should have the default, as set by the compile flags +#[no_mangle] +pub fn fun0() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 1, entry_nops = 2)] +pub fn fun1() {} + +// If we override an attribute to 0 or unset, the attribute should go away +#[no_mangle] +#[patchable_function_entry(entry_nops = 0)] +pub fn fun2() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 20, entry_nops = 1)] +pub fn fun3() {} + +// The attribute should override the compile flags +#[no_mangle] +#[patchable_function_entry(prefix_nops = 2, entry_nops = 19)] +pub fn fun4() {} + +// The attribute should override patchable-function-entry to 3 +// and patchable-function-prefix to the default of 0, clearing it entirely +#[no_mangle] +#[patchable_function_entry(entry_nops = 3)] +pub fn fun5() {} + +// The attribute should override patchable-function-prefix to 4 +// and patchable-function-entry to the default of 0, clearing it entirely +#[no_mangle] +#[patchable_function_entry(prefix_nops = 4)] +pub fn fun6() {} + +// CHECK: @fun0() unnamed_addr #0 +// CHECK: @fun1() unnamed_addr #1 +// CHECK: @fun2() unnamed_addr #2 +// CHECK: @fun3() unnamed_addr #3 +// CHECK: @fun4() unnamed_addr #4 +// CHECK: @fun5() unnamed_addr #5 +// CHECK: @fun6() unnamed_addr #6 + +// CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="15" {{.*}} } +// CHECK-NOT: attributes #0 = { {{.*}}patchable-function-prefix{{.*}} } + +// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} } + +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} } +// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} } +// CHECK: attributes #2 = { {{.*}} } + +// CHECK: attributes #3 = { {{.*}}"patchable-function-entry"="1"{{.*}}"patchable-function-prefix"="20" {{.*}} } +// CHECK: attributes #4 = { {{.*}}"patchable-function-entry"="19"{{.*}}"patchable-function-prefix"="2" {{.*}} } + +// CHECK: attributes #5 = { {{.*}}"patchable-function-entry"="3"{{.*}} } +// CHECK-NOT: attributes #5 = { {{.*}}patchable-function-prefix{{.*}} } + +// CHECK: attributes #6 = { {{.*}}"patchable-function-prefix"="4"{{.*}} } +// CHECK-NOT: attributes #6 = { {{.*}}patchable-function-entry{{.*}} } diff --git a/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs b/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs index 0e16e873a1eaa..b9642c7bfd4a6 100644 --- a/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs +++ b/tests/ui/feature-gates/feature-gate-patchable-function-entry.rs @@ -1,3 +1,3 @@ -#[patchable_function_entry(entry(1), prefix(1))] +#[patchable_function_entry(prefix_nops = 1, entry_nops = 1)] //~^ ERROR: the `#[patchable_function_entry]` attribute is an experimental feature fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr b/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr index c4d57d774e35d..55fcdb4f7291e 100644 --- a/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr +++ b/tests/ui/feature-gates/feature-gate-patchable-function-entry.stderr @@ -1,11 +1,12 @@ error[E0658]: the `#[patchable_function_entry]` attribute is an experimental feature --> $DIR/feature-gate-patchable-function-entry.rs:1:1 | -LL | #[patchable_function_entry(entry(1), prefix(1))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[patchable_function_entry(prefix_nops = 1, entry_nops = 1)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #9999 for more information + = note: see issue #123115 for more information = help: add `#![feature(patchable_function_entry)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date error: aborting due to 1 previous error diff --git a/tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs new file mode 100644 index 0000000000000..d7231ef416077 --- /dev/null +++ b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.rs @@ -0,0 +1,17 @@ +#![feature(patchable_function_entry)] +fn main() {} + +#[patchable_function_entry(prefix_nops = 256, entry_nops = 0)]//~error: Expected integer value between 0 and 255. +pub fn too_high_pnops() {} + +#[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)]//~error: Expected integer value between 0 and 255. +pub fn non_int_nop() {} + +#[patchable_function_entry]//~error: malformed `patchable_function_entry` attribute input +pub fn malformed_attribute() {} + +#[patchable_function_entry(prefix_nops = 10, something = 0)]//~error: Unexpected parameter name. Allowed names: prefix_nops, entry_nops +pub fn unexpected_parameter_name() {} + +#[patchable_function_entry()]//~error: Must specify at least one parameter. +pub fn no_parameters_given() {} diff --git a/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr new file mode 100644 index 0000000000000..a270106925f44 --- /dev/null +++ b/tests/ui/patchable-function-entry/patchable-function-entry-attribute.stderr @@ -0,0 +1,32 @@ +error: malformed `patchable_function_entry` attribute input + --> $DIR/patchable-function-entry-attribute.rs:10:1 + | +LL | #[patchable_function_entry] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]` + +error: Expected integer value between 0 and 255. + --> $DIR/patchable-function-entry-attribute.rs:4:42 + | +LL | #[patchable_function_entry(prefix_nops = 256, entry_nops = 0)] + | ^^^ + +error: Expected integer value between 0 and 255. + --> $DIR/patchable-function-entry-attribute.rs:7:42 + | +LL | #[patchable_function_entry(prefix_nops = "stringvalue", entry_nops = 0)] + | ^^^^^^^^^^^^^ + +error: Unexpected parameter name. Allowed names: prefix_nops, entry_nops + --> $DIR/patchable-function-entry-attribute.rs:13:46 + | +LL | #[patchable_function_entry(prefix_nops = 10, something = 0)] + | ^^^^^^^^^^^^^ + +error: Must specify at least one parameter. + --> $DIR/patchable-function-entry-attribute.rs:16:1 + | +LL | #[patchable_function_entry()] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/tests/ui/patchable-function-entry/patchable-function-entry-flags.rs b/tests/ui/patchable-function-entry/patchable-function-entry-flags.rs new file mode 100644 index 0000000000000..cb5bc62b6b347 --- /dev/null +++ b/tests/ui/patchable-function-entry/patchable-function-entry-flags.rs @@ -0,0 +1,2 @@ +//@ compile-flags: -Z patchable-function-entry=1,2 +fn main() {} diff --git a/tests/ui/patchable-function-entry/patchable-function-entry-flags.stderr b/tests/ui/patchable-function-entry/patchable-function-entry-flags.stderr new file mode 100644 index 0000000000000..b09af94a61541 --- /dev/null +++ b/tests/ui/patchable-function-entry/patchable-function-entry-flags.stderr @@ -0,0 +1,2 @@ +error: incorrect value `1,2` for unstable option `patchable-function-entry` - either two comma separated integers (total_nops,prefix_nops), with prefix_nops <= total_nops, or one integer (total_nops) was expected + From d5ff4f4f657766ca03d7b96553baae6aca053596 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 25 Jun 2024 22:34:40 +0200 Subject: [PATCH 13/22] Simplify `str::clone_into` Removes an `unsafe` in favor of just using `String` methods. --- library/alloc/src/str.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index 3e23612d0c13c..3bb808a6c73ab 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -206,15 +206,16 @@ impl BorrowMut for String { #[stable(feature = "rust1", since = "1.0.0")] impl ToOwned for str { type Owned = String; + #[inline] fn to_owned(&self) -> String { unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) } } + #[inline] fn clone_into(&self, target: &mut String) { - let mut b = mem::take(target).into_bytes(); - self.as_bytes().clone_into(&mut b); - *target = unsafe { String::from_utf8_unchecked(b) } + target.clear(); + target.push_str(self); } } From 414ebeaeea13d37bcd59473d11660169286b7cd5 Mon Sep 17 00:00:00 2001 From: Stephen Skeirik Date: Mon, 17 Jun 2024 17:01:38 -0400 Subject: [PATCH 14/22] add serde derive Serialize to stable_mir --- Cargo.lock | 1 + compiler/stable_mir/Cargo.toml | 1 + compiler/stable_mir/src/abi.rs | 35 ++--- compiler/stable_mir/src/crate_def.rs | 3 +- compiler/stable_mir/src/lib.rs | 10 +- compiler/stable_mir/src/mir/alloc.rs | 5 +- compiler/stable_mir/src/mir/body.rs | 81 +++++------ compiler/stable_mir/src/mir/mono.rs | 10 +- compiler/stable_mir/src/target.rs | 7 +- compiler/stable_mir/src/ty.rs | 153 ++++++++++++--------- tests/ui-fulldeps/stable-mir/smir_serde.rs | 75 ++++++++++ 11 files changed, 242 insertions(+), 139 deletions(-) create mode 100644 tests/ui-fulldeps/stable-mir/smir_serde.rs diff --git a/Cargo.lock b/Cargo.lock index 241a37588b409..24caf5cd3e67f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5254,6 +5254,7 @@ name = "stable_mir" version = "0.1.0-preview" dependencies = [ "scoped-tls", + "serde", ] [[package]] diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml index 4ed6115273653..2edb3f140d7ac 100644 --- a/compiler/stable_mir/Cargo.toml +++ b/compiler/stable_mir/Cargo.toml @@ -5,3 +5,4 @@ edition = "2021" [dependencies] scoped-tls = "1.0" +serde = { version = "1.0.125", features = [ "derive" ] } diff --git a/compiler/stable_mir/src/abi.rs b/compiler/stable_mir/src/abi.rs index e1c14fe0b380b..c003ec1fbc920 100644 --- a/compiler/stable_mir/src/abi.rs +++ b/compiler/stable_mir/src/abi.rs @@ -5,12 +5,13 @@ use crate::target::{MachineInfo, MachineSize as Size}; use crate::ty::{Align, IndexedVal, Ty, VariantIdx}; use crate::Error; use crate::Opaque; +use serde::Serialize; use std::fmt::{self, Debug}; use std::num::NonZero; use std::ops::RangeInclusive; /// A function ABI definition. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub struct FnAbi { /// The types of each argument. pub args: Vec, @@ -31,7 +32,7 @@ pub struct FnAbi { } /// Information about the ABI of a function's argument, or return value. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub struct ArgAbi { pub ty: Ty, pub layout: Layout, @@ -39,7 +40,7 @@ pub struct ArgAbi { } /// How a function argument should be passed in to the target function. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum PassMode { /// Ignore the argument. /// @@ -60,14 +61,14 @@ pub enum PassMode { } /// The layout of a type, alongside the type itself. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub struct TyAndLayout { pub ty: Ty, pub layout: Layout, } /// The layout of a type in memory. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub struct LayoutShape { /// The fields location withing the layout pub fields: FieldsShape, @@ -108,7 +109,7 @@ impl LayoutShape { } } -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub struct Layout(usize); impl Layout { @@ -127,7 +128,7 @@ impl IndexedVal for Layout { } /// Describes how the fields of a type are shaped in memory. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum FieldsShape { /// Scalar primitives and `!`, which never have fields. Primitive, @@ -177,7 +178,7 @@ impl FieldsShape { } } -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum VariantsShape { /// Single enum variants, structs/tuples, unions, and all non-ADTs. Single { index: VariantIdx }, @@ -196,7 +197,7 @@ pub enum VariantsShape { }, } -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum TagEncoding { /// The tag directly stores the discriminant, but possibly with a smaller layout /// (so converting the tag to the discriminant can require sign extension). @@ -221,7 +222,7 @@ pub enum TagEncoding { /// Describes how values of the type are passed by target ABIs, /// in terms of categories of C types there are ABI rules for. -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum ValueAbi { Uninhabited, Scalar(Scalar), @@ -250,7 +251,7 @@ impl ValueAbi { } /// Information about one scalar component of a Rust type. -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize)] pub enum Scalar { Initialized { /// The primitive type used to represent this value. @@ -280,7 +281,7 @@ impl Scalar { } /// Fundamental unit of memory access and layout. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Serialize)] pub enum Primitive { /// The `bool` is the signedness of the `Integer` type. /// @@ -310,7 +311,7 @@ impl Primitive { } /// Enum representing the existing integer lengths. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)] pub enum IntegerLength { I8, I16, @@ -320,7 +321,7 @@ pub enum IntegerLength { } /// Enum representing the existing float lengths. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)] pub enum FloatLength { F16, F32, @@ -354,7 +355,7 @@ impl FloatLength { /// An identifier that specifies the address space that some operation /// should operate on. Special address spaces have an effect on code generation, /// depending on the target and the address spaces it implements. -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)] pub struct AddressSpace(pub u32); impl AddressSpace { @@ -369,7 +370,7 @@ impl AddressSpace { /// sequence: /// /// 254 (-2), 255 (-1), 0, 1, 2 -#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)] pub struct WrappingRange { pub start: u128, pub end: u128, @@ -420,7 +421,7 @@ impl Debug for WrappingRange { } /// General language calling conventions. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum CallConvention { C, Rust, diff --git a/compiler/stable_mir/src/crate_def.rs b/compiler/stable_mir/src/crate_def.rs index 67752a5e629f3..a7cebc4c132ba 100644 --- a/compiler/stable_mir/src/crate_def.rs +++ b/compiler/stable_mir/src/crate_def.rs @@ -3,9 +3,10 @@ use crate::ty::{GenericArgs, Span, Ty}; use crate::{with, Crate, Symbol}; +use serde::Serialize; /// A unique identification number for each item accessible for the current compilation unit. -#[derive(Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)] pub struct DefId(pub(crate) usize); /// A trait for retrieving information about a particular definition. diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 8385856ae532d..fe745326d819a 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -27,6 +27,7 @@ pub use crate::error::*; use crate::mir::Body; use crate::mir::Mutability; use crate::ty::{ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty}; +use serde::Serialize; pub mod abi; #[macro_use] @@ -74,7 +75,7 @@ pub type TraitDecls = Vec; pub type ImplTraitDecls = Vec; /// Holds information about a crate. -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug, Serialize)] pub struct Crate { pub id: CrateNum, pub name: Symbol, @@ -98,7 +99,7 @@ impl Crate { } } -#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)] pub enum ItemKind { Fn, Static, @@ -106,7 +107,7 @@ pub enum ItemKind { Ctor(CtorKind), } -#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)] pub enum CtorKind { Const, Fn, @@ -116,6 +117,7 @@ pub type Filename = String; crate_def_with_ty! { /// Holds information about an item in a crate. + #[derive(Serialize)] pub CrateItem; } @@ -188,7 +190,7 @@ pub fn all_trait_impls() -> ImplTraitDecls { } /// A type that provides internal information but that can still be used for debug purpose. -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Clone, PartialEq, Eq, Hash, Serialize)] pub struct Opaque(String); impl std::fmt::Display for Opaque { diff --git a/compiler/stable_mir/src/mir/alloc.rs b/compiler/stable_mir/src/mir/alloc.rs index ef1568151f2e6..9e0cac67f0aa3 100644 --- a/compiler/stable_mir/src/mir/alloc.rs +++ b/compiler/stable_mir/src/mir/alloc.rs @@ -4,11 +4,12 @@ use crate::mir::mono::{Instance, StaticDef}; use crate::target::{Endian, MachineInfo}; use crate::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty}; use crate::{with, Error}; +use serde::Serialize; use std::io::Read; /// An allocation in the SMIR global memory can be either a function pointer, /// a static, or a "real" allocation with some data in it. -#[derive(Debug, Clone, Eq, PartialEq)] +#[derive(Debug, Clone, Eq, PartialEq, Serialize)] pub enum GlobalAlloc { /// The alloc ID is used as a function pointer. Function(Instance), @@ -41,7 +42,7 @@ impl GlobalAlloc { } /// A unique identification number for each provenance -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)] pub struct AllocId(usize); impl IndexedVal for AllocId { diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index e0f9e7ae67a0f..f7457ecd38f4c 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -5,10 +5,11 @@ use crate::ty::{ TyConst, TyKind, VariantIdx, }; use crate::{Error, Opaque, Span, Symbol}; +use serde::Serialize; use std::io; /// The SMIR representation of a single function. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Serialize)] pub struct Body { pub blocks: Vec, @@ -104,20 +105,20 @@ impl Body { type LocalDecls = Vec; -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct LocalDecl { pub ty: Ty, pub span: Span, pub mutability: Mutability, } -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug, Serialize)] pub struct BasicBlock { pub statements: Vec, pub terminator: Terminator, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct Terminator { pub kind: TerminatorKind, pub span: Span, @@ -131,7 +132,7 @@ impl Terminator { pub type Successors = Vec; -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum TerminatorKind { Goto { target: BasicBlockIdx, @@ -221,7 +222,7 @@ impl TerminatorKind { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct InlineAsmOperand { pub in_value: Option, pub out_place: Option, @@ -230,7 +231,7 @@ pub struct InlineAsmOperand { pub raw_rpr: String, } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] pub enum UnwindAction { Continue, Unreachable, @@ -238,7 +239,7 @@ pub enum UnwindAction { Cleanup(BasicBlockIdx), } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum AssertMessage { BoundsCheck { len: Operand, index: Operand }, Overflow(BinOp, Operand, Operand), @@ -307,7 +308,7 @@ impl AssertMessage { } } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] pub enum BinOp { Add, AddUnchecked, @@ -342,7 +343,7 @@ impl BinOp { } } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] pub enum UnOp { Not, Neg, @@ -357,20 +358,20 @@ impl UnOp { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum CoroutineKind { Desugared(CoroutineDesugaring, CoroutineSource), Coroutine(Movability), } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] pub enum CoroutineSource { Block, Closure, Fn, } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] pub enum CoroutineDesugaring { Async, @@ -386,7 +387,7 @@ pub(crate) type LocalDefId = Opaque; pub(crate) type Coverage = Opaque; /// The FakeReadCause describes the type of pattern why a FakeRead statement exists. -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum FakeReadCause { ForMatchGuard, ForMatchedPlace(LocalDefId), @@ -396,7 +397,7 @@ pub enum FakeReadCause { } /// Describes what kind of retag is to be performed -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)] pub enum RetagKind { FnEntry, TwoPhase, @@ -404,7 +405,7 @@ pub enum RetagKind { Default, } -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)] pub enum Variance { Covariant, Invariant, @@ -412,26 +413,26 @@ pub enum Variance { Bivariant, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct CopyNonOverlapping { pub src: Operand, pub dst: Operand, pub count: Operand, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum NonDivergingIntrinsic { Assume(Operand), CopyNonOverlapping(CopyNonOverlapping), } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct Statement { pub kind: StatementKind, pub span: Span, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum StatementKind { Assign(Place, Rvalue), FakeRead(FakeReadCause, Place), @@ -448,7 +449,7 @@ pub enum StatementKind { Nop, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum Rvalue { /// Creates a pointer with the indicated mutability to the place. /// @@ -622,7 +623,7 @@ impl Rvalue { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum AggregateKind { Array(Ty), Tuple, @@ -633,14 +634,14 @@ pub enum AggregateKind { RawPtr(Ty, Mutability), } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum Operand { Copy(Place), Move(Place), Constant(ConstOperand), } -#[derive(Clone, Eq, PartialEq)] +#[derive(Clone, Eq, PartialEq, Serialize)] pub struct Place { pub local: Local, /// projection out of a place (access a field, deref a pointer, etc) @@ -653,7 +654,7 @@ impl From for Place { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct ConstOperand { pub span: Span, pub user_ty: Option, @@ -661,7 +662,7 @@ pub struct ConstOperand { } /// Debug information pertaining to a user variable. -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct VarDebugInfo { /// The variable name. pub name: Symbol, @@ -703,19 +704,19 @@ impl VarDebugInfo { pub type SourceScope = u32; -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct SourceInfo { pub span: Span, pub scope: SourceScope, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct VarDebugInfoFragment { pub ty: Ty, pub projection: Vec, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum VarDebugInfoContents { Place(Place), Const(ConstOperand), @@ -726,7 +727,7 @@ pub enum VarDebugInfoContents { // ProjectionElem) and user-provided type annotations (for which the projection elements // are of type ProjectionElem<(), ()>). In SMIR we don't need this generality, so we just use // ProjectionElem for Places. -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum ProjectionElem { /// Dereference projections (e.g. `*_1`) project to the address referenced by the base place. Deref, @@ -800,7 +801,7 @@ pub enum ProjectionElem { Subtype(Ty), } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct UserTypeProjection { pub base: UserTypeAnnotationIndex, @@ -830,7 +831,7 @@ pub type FieldIdx = usize; type UserTypeAnnotationIndex = usize; /// The possible branch sites of a [TerminatorKind::SwitchInt]. -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct SwitchTargets { /// The conditional branches where the first element represents the value that guards this /// branch, and the second element is the branch target. @@ -867,7 +868,7 @@ impl SwitchTargets { } } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] pub enum BorrowKind { /// Data must be immutable and is aliasable. Shared, @@ -894,14 +895,14 @@ impl BorrowKind { } } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] pub enum MutBorrowKind { Default, TwoPhaseBorrow, ClosureCapture, } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] pub enum FakeBorrowKind { /// A shared (deep) borrow. Data must be immutable and is aliasable. Deep, @@ -912,19 +913,19 @@ pub enum FakeBorrowKind { Shallow, } -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum Mutability { Not, Mut, } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] pub enum Safety { Safe, Unsafe, } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] pub enum PointerCoercion { /// Go from a fn-item type to a fn-pointer type. ReifyFnPointer, @@ -951,7 +952,7 @@ pub enum PointerCoercion { Unsize, } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] pub enum CastKind { // FIXME(smir-rename): rename this to PointerExposeProvenance PointerExposeAddress, @@ -967,7 +968,7 @@ pub enum CastKind { Transmute, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum NullOp { /// Returns the size of a value of that type. SizeOf, diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs index 572f1499c5a5c..c23293388f933 100644 --- a/compiler/stable_mir/src/mir/mono.rs +++ b/compiler/stable_mir/src/mir/mono.rs @@ -3,17 +3,18 @@ use crate::crate_def::CrateDef; use crate::mir::Body; use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty}; use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque, Symbol}; +use serde::Serialize; use std::fmt::{Debug, Formatter}; use std::io; -#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum MonoItem { Fn(Instance), Static(StaticDef), GlobalAsm(Opaque), } -#[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize)] pub struct Instance { /// The type of instance. pub kind: InstanceKind, @@ -22,7 +23,7 @@ pub struct Instance { pub def: InstanceDef, } -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)] pub enum InstanceKind { /// A user defined item. Item, @@ -240,7 +241,7 @@ impl From for CrateItem { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] pub struct InstanceDef(usize); impl CrateDef for InstanceDef { @@ -251,6 +252,7 @@ impl CrateDef for InstanceDef { crate_def! { /// Holds information about a static variable definition. + #[derive(Serialize)] pub StaticDef; } diff --git a/compiler/stable_mir/src/target.rs b/compiler/stable_mir/src/target.rs index e00a418c54039..9fb5e046abc3c 100644 --- a/compiler/stable_mir/src/target.rs +++ b/compiler/stable_mir/src/target.rs @@ -1,9 +1,10 @@ //! Provide information about the machine that this is being compiled into. use crate::compiler_interface::with; +use serde::Serialize; /// The properties of the target machine being compiled into. -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, PartialEq, Eq, Serialize)] pub struct MachineInfo { pub endian: Endian, pub pointer_width: MachineSize, @@ -23,14 +24,14 @@ impl MachineInfo { } } -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Copy, Clone, PartialEq, Eq, Serialize)] pub enum Endian { Little, Big, } /// Represent the size of a component. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)] pub struct MachineSize { num_bits: usize, } diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index 8c120a96e75b1..9c8921da52ff9 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -8,10 +8,11 @@ use crate::mir::alloc::{read_target_int, read_target_uint, AllocId}; use crate::mir::mono::StaticDef; use crate::target::MachineInfo; use crate::{Filename, Opaque}; +use serde::Serialize; use std::fmt::{self, Debug, Display, Formatter}; use std::ops::Range; -#[derive(Copy, Clone, Eq, PartialEq, Hash)] +#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)] pub struct Ty(usize); impl Debug for Ty { @@ -100,13 +101,13 @@ impl Ty { } /// Represents a pattern in the type system -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum Pattern { Range { start: Option, end: Option, include_end: bool }, } /// Represents a constant in the type system -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct TyConst { pub(crate) kind: TyConstKind, pub id: TyConstId, @@ -133,7 +134,7 @@ impl TyConst { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum TyConstKind { Param(ParamConst), Bound(DebruijnIndex, BoundVar), @@ -144,11 +145,11 @@ pub enum TyConstKind { ZSTValue(Ty), } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)] pub struct TyConstId(usize); /// Represents a constant in MIR -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct MirConst { /// The constant kind. pub(crate) kind: ConstantKind, @@ -205,17 +206,17 @@ impl MirConst { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)] pub struct MirConstId(usize); type Ident = Opaque; -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct Region { pub kind: RegionKind, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum RegionKind { ReEarlyParam(EarlyParamRegion), ReBound(DebruijnIndex, BoundRegion), @@ -226,7 +227,7 @@ pub enum RegionKind { pub(crate) type DebruijnIndex = u32; -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct EarlyParamRegion { pub index: u32, pub name: Symbol, @@ -234,7 +235,7 @@ pub struct EarlyParamRegion { pub(crate) type BoundVar = u32; -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct BoundRegion { pub var: BoundVar, pub kind: BoundRegionKind, @@ -242,13 +243,13 @@ pub struct BoundRegion { pub(crate) type UniverseIndex = u32; -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct Placeholder { pub universe: UniverseIndex, pub bound: T, } -#[derive(Clone, Copy, PartialEq, Eq)] +#[derive(Clone, Copy, PartialEq, Eq, Serialize)] pub struct Span(usize); impl Debug for Span { @@ -272,7 +273,7 @@ impl Span { } } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, Serialize)] /// Information you get from `Span` in a struct form. /// Line and col start from 1. pub struct LineInfo { @@ -282,7 +283,7 @@ pub struct LineInfo { pub end_col: usize, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum TyKind { RigidTy(RigidTy), Alias(AliasKind, AliasTy), @@ -521,7 +522,7 @@ pub struct TypeAndMut { pub mutability: Mutability, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum RigidTy { Bool, Char, @@ -560,7 +561,7 @@ impl From for TyKind { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)] pub enum IntTy { Isize, I8, @@ -583,7 +584,7 @@ impl IntTy { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)] pub enum UintTy { Usize, U8, @@ -606,19 +607,20 @@ impl UintTy { } } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)] pub enum FloatTy { F32, F64, } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)] pub enum Movability { Static, Movable, } crate_def! { + #[derive(Serialize)] pub ForeignModuleDef; } @@ -641,6 +643,7 @@ impl ForeignModule { crate_def_with_ty! { /// Hold information about a ForeignItem in a crate. + #[derive(Serialize)] pub ForeignDef; } @@ -650,7 +653,7 @@ impl ForeignDef { } } -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)] pub enum ForeignItemKind { Fn(FnDef), Static(StaticDef), @@ -659,6 +662,7 @@ pub enum ForeignItemKind { crate_def_with_ty! { /// Hold information about a function definition in a crate. + #[derive(Serialize)] pub FnDef; } @@ -692,6 +696,7 @@ impl FnDef { } crate_def_with_ty! { + #[derive(Serialize)] pub IntrinsicDef; } @@ -716,26 +721,31 @@ impl From for FnDef { } crate_def! { + #[derive(Serialize)] pub ClosureDef; } crate_def! { + #[derive(Serialize)] pub CoroutineDef; } crate_def! { + #[derive(Serialize)] pub ParamDef; } crate_def! { + #[derive(Serialize)] pub BrNamedDef; } -crate_def_with_ty! { +crate_def! { + #[derive(Serialize)] pub AdtDef; } -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)] pub enum AdtKind { Enum, Union, @@ -789,7 +799,7 @@ impl AdtDef { } /// Definition of a variant, which can be either a struct / union field or an enum variant. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] pub struct VariantDef { /// The variant index. /// @@ -818,7 +828,7 @@ impl VariantDef { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct FieldDef { /// The field definition. /// @@ -869,11 +879,13 @@ impl AdtKind { } crate_def! { + #[derive(Serialize)] pub AliasDef; } crate_def! { /// A trait's definition. + #[derive(Serialize)] pub TraitDef; } @@ -884,15 +896,18 @@ impl TraitDef { } crate_def! { + #[derive(Serialize)] pub GenericDef; } crate_def_with_ty! { + #[derive(Serialize)] pub ConstDef; } crate_def! { /// A trait impl definition. + #[derive(Serialize)] pub ImplDef; } @@ -904,15 +919,17 @@ impl ImplDef { } crate_def! { + #[derive(Serialize)] pub RegionDef; } crate_def! { + #[derive(Serialize)] pub CoroutineWitnessDef; } /// A list of generic arguments. -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct GenericArgs(pub Vec); impl std::ops::Index for GenericArgs { @@ -931,7 +948,7 @@ impl std::ops::Index for GenericArgs { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum GenericArgKind { Lifetime(Region), Type(Ty), @@ -968,13 +985,13 @@ impl GenericArgKind { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum TermKind { Type(Ty), Const(TyConst), } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum AliasKind { Projection, Inherent, @@ -982,13 +999,13 @@ pub enum AliasKind { Weak, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct AliasTy { pub def_id: AliasDef, pub args: GenericArgs, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct AliasTerm { pub def_id: AliasDef, pub args: GenericArgs, @@ -1006,7 +1023,7 @@ impl PolyFnSig { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct FnSig { pub inputs_and_output: Vec, pub c_variadic: bool, @@ -1024,7 +1041,7 @@ impl FnSig { } } -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug, Serialize)] pub enum Abi { Rust, C { unwind: bool }, @@ -1054,7 +1071,7 @@ pub enum Abi { } /// A binder represents a possibly generic type and its bound vars. -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct Binder { pub value: T, pub bound_vars: Vec, @@ -1094,38 +1111,38 @@ impl Binder { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct EarlyBinder { pub value: T, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum BoundVariableKind { Ty(BoundTyKind), Region(BoundRegionKind), Const, } -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug, Serialize)] pub enum BoundTyKind { Anon, Param(ParamDef, String), } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum BoundRegionKind { BrAnon, BrNamed(BrNamedDef, String), BrEnv, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum DynKind { Dyn, DynStar, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum ExistentialPredicate { Trait(ExistentialTraitRef), Projection(ExistentialProjection), @@ -1135,7 +1152,7 @@ pub enum ExistentialPredicate { /// An existential reference to a trait where `Self` is not included. /// /// The `generic_args` will include any other known argument. -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct ExistentialTraitRef { pub def_id: TraitDef, pub generic_args: GenericArgs, @@ -1153,20 +1170,20 @@ impl ExistentialTraitRef { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct ExistentialProjection { pub def_id: TraitDef, pub generic_args: GenericArgs, pub term: TermKind, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct ParamTy { pub index: u32, pub name: String, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct BoundTy { pub var: usize, pub kind: BoundTyKind, @@ -1177,7 +1194,7 @@ pub type Bytes = Vec>; /// Size in bytes. pub type Size = usize; -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)] pub struct Prov(pub AllocId); pub type Align = u64; @@ -1185,14 +1202,14 @@ pub type Promoted = u32; pub type InitMaskMaterialized = Vec; /// Stores the provenance information of pointers stored in memory. -#[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)] pub struct ProvenanceMap { /// Provenance in this map applies from the given offset for an entire pointer-size worth of /// bytes. Two entries in this map are always at least a pointer size apart. pub ptrs: Vec<(Size, Prov)>, } -#[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)] pub struct Allocation { pub bytes: Bytes, pub provenance: ProvenanceMap, @@ -1268,7 +1285,7 @@ impl Allocation { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum ConstantKind { Ty(TyConst), Allocated(Allocation), @@ -1279,27 +1296,27 @@ pub enum ConstantKind { ZeroSized, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct ParamConst { pub index: u32, pub name: String, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct UnevaluatedConst { pub def: ConstDef, pub args: GenericArgs, pub promoted: Option, } -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)] pub enum TraitSpecializationKind { None, Marker, AlwaysApplicable, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct TraitDecl { pub def_id: TraitDef, pub safety: Safety, @@ -1332,7 +1349,7 @@ impl TraitDecl { pub type ImplTrait = EarlyBinder; /// A complete reference to a trait, i.e., one where `Self` is known. -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct TraitRef { pub def_id: TraitDef, /// The generic arguments for this definition. @@ -1366,7 +1383,7 @@ impl TraitRef { } } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct Generics { pub parent: Option, pub parent_count: usize, @@ -1377,14 +1394,14 @@ pub struct Generics { pub host_effect_index: Option, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum GenericParamDefKind { Lifetime, Type { has_default: bool, synthetic: bool }, Const { has_default: bool }, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct GenericParamDef { pub name: super::Symbol, pub def_id: GenericDef, @@ -1398,7 +1415,7 @@ pub struct GenericPredicates { pub predicates: Vec<(PredicateKind, Span)>, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum PredicateKind { Clause(ClauseKind), ObjectSafe(TraitDef), @@ -1409,7 +1426,7 @@ pub enum PredicateKind { AliasRelate(TermKind, TermKind, AliasRelationDirection), } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum ClauseKind { Trait(TraitPredicate), RegionOutlives(RegionOutlivesPredicate), @@ -1420,57 +1437,57 @@ pub enum ClauseKind { ConstEvaluatable(TyConst), } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum ClosureKind { Fn, FnMut, FnOnce, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct SubtypePredicate { pub a: Ty, pub b: Ty, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct CoercePredicate { pub a: Ty, pub b: Ty, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum AliasRelationDirection { Equate, Subtype, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct TraitPredicate { pub trait_ref: TraitRef, pub polarity: PredicatePolarity, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct OutlivesPredicate(pub A, pub B); pub type RegionOutlivesPredicate = OutlivesPredicate; pub type TypeOutlivesPredicate = OutlivesPredicate; -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct ProjectionPredicate { pub projection_term: AliasTerm, pub term: TermKind, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum ImplPolarity { Positive, Negative, Reservation, } -#[derive(Clone, Debug, Eq, PartialEq)] +#[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub enum PredicatePolarity { Positive, Negative, @@ -1513,7 +1530,7 @@ index_impl!(Span); /// `a` is in the variant with the `VariantIdx` of `0`, /// `c` is in the variant with the `VariantIdx` of `1`, and /// `g` is in the variant with the `VariantIdx` of `0`. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] pub struct VariantIdx(usize); index_impl!(VariantIdx); diff --git a/tests/ui-fulldeps/stable-mir/smir_serde.rs b/tests/ui-fulldeps/stable-mir/smir_serde.rs new file mode 100644 index 0000000000000..957d840f7a241 --- /dev/null +++ b/tests/ui-fulldeps/stable-mir/smir_serde.rs @@ -0,0 +1,75 @@ +//@ run-pass +//! Test that users are able to use serialize stable MIR constructs. + +//@ ignore-stage1 +//@ ignore-cross-compile +//@ ignore-remote +//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837 +//@ edition: 2021 + +#![feature(rustc_private)] +#![feature(assert_matches)] +#![feature(control_flow_enum)] + +#[macro_use] +extern crate rustc_smir; +extern crate rustc_driver; +extern crate rustc_interface; +extern crate rustc_middle; +extern crate stable_mir; +extern crate serde; +extern crate serde_json; + +use rustc_middle::ty::TyCtxt; +use rustc_smir::rustc_internal; +use stable_mir::mir::Body; +use std::io::{Write, BufWriter}; +use std::ops::ControlFlow; +use serde_json::to_string; + + +const CRATE_NAME: &str = "input"; + +fn serialize_to_json(_tcx: TyCtxt<'_>) -> ControlFlow<()> { + let path = "output.json"; + let mut writer = BufWriter::new(std::fs::File::create(path) + .expect("Failed to create path")); + let local_crate = stable_mir::local_crate(); + let items: Vec = stable_mir::all_local_items() + .iter() + .map(|item| { item.body() }) + .collect(); + let crate_data = ( local_crate.name, items ); + writer.write_all(to_string(&crate_data) + .expect("serde_json failed") + .as_bytes()).expect("JSON serialization failed"); + ControlFlow::Continue(()) +} + +/// This test will generate and analyze a dummy crate using the stable mir. +/// For that, it will first write the dummy crate into a file. +/// Then it will create a `StableMir` using custom arguments and then +/// it will run the compiler. +fn main() { + let path = "internal_input.rs"; + generate_input(&path).unwrap(); + let args = vec![ + "rustc".to_string(), + "--crate-name".to_string(), + CRATE_NAME.to_string(), + path.to_string(), + ]; + run_with_tcx!(args, serialize_to_json).unwrap(); +} + +fn generate_input(path: &str) -> std::io::Result<()> { + let mut file = std::fs::File::create(path)?; + write!( + file, + r#" + pub fn main() {{ + }} + "# + )?; + Ok(()) +} From 315be7d483bd4bad3e5541376ebf1d926c21f4f2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Jun 2024 00:04:23 +0200 Subject: [PATCH 15/22] Update browser-ui-test version to `0.18.0` --- .../host-x86_64/x86_64-gnu-tools/browser-ui-test.version | 2 +- tests/rustdoc-gui/label-next-to-symbol.goml | 3 +++ tests/rustdoc-gui/sidebar-source-code-display.goml | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index 50c2e5e29f0b8..47d04a528837e 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.17.2 \ No newline at end of file +0.18.0 \ No newline at end of file diff --git a/tests/rustdoc-gui/label-next-to-symbol.goml b/tests/rustdoc-gui/label-next-to-symbol.goml index 9a7de60bf38e1..0582bd2cad36e 100644 --- a/tests/rustdoc-gui/label-next-to-symbol.goml +++ b/tests/rustdoc-gui/label-next-to-symbol.goml @@ -1,7 +1,10 @@ // These tests verify that labels like "UNIX" and "Deprecated" stay on the same line as their symbol. // It also verifies the staggered layout on mobile. +include: "utils.goml" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" +call-function: ("switch-theme", {"theme": "light"}) + // Desktop view set-window-size: (1080, 600) assert: (".stab.deprecated") diff --git a/tests/rustdoc-gui/sidebar-source-code-display.goml b/tests/rustdoc-gui/sidebar-source-code-display.goml index 7ce3be8a5b355..67152afbbaa33 100644 --- a/tests/rustdoc-gui/sidebar-source-code-display.goml +++ b/tests/rustdoc-gui/sidebar-source-code-display.goml @@ -141,14 +141,15 @@ click: "#sidebar-button" wait-for-css: (".src .sidebar > *", {"visibility": "hidden"}) // We scroll to line 117 to change the scroll position. scroll-to: '//*[@id="117"]' -assert-window-property: {"pageYOffset": "2516"} +store-value: (y_offset, "2493") +assert-window-property: {"pageYOffset": |y_offset|} // Expanding the sidebar... click: "#sidebar-button" wait-for-css: (".sidebar", {"left": "0px"}) click: "#sidebar-button" wait-for-css: (".sidebar", {"left": "-1000px"}) // The "scrollTop" property should be the same. -assert-window-property: {"pageYOffset": "2516"} +assert-window-property: {"pageYOffset": |y_offset|} // We now check that opening the sidebar and clicking a link will close it. // The behavior here on mobile is different than the behavior on desktop, From 0c0dfb88eeefbbaa4c10cfa4a7f0e16541e086eb Mon Sep 17 00:00:00 2001 From: Urgau Date: Thu, 27 Jun 2024 08:05:07 +0200 Subject: [PATCH 16/22] Switch back `non_local_definitions` lint to allow-by-default as request T-lang is requesting some major changes in the lint inner workings in #126768#issuecomment-2192634762 --- compiler/rustc_lint/src/non_local_def.rs | 2 +- tests/rustdoc-ui/doctest/non_local_defs.rs | 2 + .../rustdoc-ui/doctest/non_local_defs.stderr | 8 ++- .../rustdoc-ui/doctest/non_local_defs.stdout | 2 +- tests/ui/lint/non-local-defs/cargo-update.rs | 2 + .../lint/non-local-defs/cargo-update.stderr | 8 ++- tests/ui/lint/non-local-defs/consts.rs | 2 + tests/ui/lint/non-local-defs/consts.stderr | 22 ++++--- .../lint/non-local-defs/exhaustive-trait.rs | 2 + .../non-local-defs/exhaustive-trait.stderr | 18 +++--- tests/ui/lint/non-local-defs/exhaustive.rs | 2 + .../ui/lint/non-local-defs/exhaustive.stderr | 58 ++++++++++--------- .../non-local-defs/from-local-for-global.rs | 2 + .../from-local-for-global.stderr | 24 ++++---- tests/ui/lint/non-local-defs/generics.rs | 2 + tests/ui/lint/non-local-defs/generics.stderr | 36 +++++++----- .../lint/non-local-defs/inside-macro_rules.rs | 2 + .../non-local-defs/inside-macro_rules.stderr | 8 ++- tests/ui/lint/non-local-defs/local.rs | 2 + tests/ui/lint/non-local-defs/macro_rules.rs | 2 + .../ui/lint/non-local-defs/macro_rules.stderr | 14 +++-- .../non-local-defs/suggest-moving-inner.rs | 2 + .../suggest-moving-inner.stderr | 10 +++- .../trait-solver-overflow-123573.rs | 2 + .../trait-solver-overflow-123573.stderr | 10 +++- tests/ui/lint/non-local-defs/weird-exprs.rs | 2 + .../ui/lint/non-local-defs/weird-exprs.stderr | 18 +++--- 27 files changed, 169 insertions(+), 95 deletions(-) diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index 300dac442d564..17429ed061f25 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -50,7 +50,7 @@ declare_lint! { /// All nested bodies (functions, enum discriminant, array length, consts) (expect for /// `const _: Ty = { ... }` in top-level module, which is still undecided) are checked. pub NON_LOCAL_DEFINITIONS, - Warn, + Allow, "checks for non-local definitions", report_in_external_macro } diff --git a/tests/rustdoc-ui/doctest/non_local_defs.rs b/tests/rustdoc-ui/doctest/non_local_defs.rs index aa166c343b2b0..d8cfe5637ae02 100644 --- a/tests/rustdoc-ui/doctest/non_local_defs.rs +++ b/tests/rustdoc-ui/doctest/non_local_defs.rs @@ -4,6 +4,8 @@ //@ normalize-stderr-test: "tests/rustdoc-ui/doctest" -> "$$DIR" //@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME" +#![doc(test(attr(warn(non_local_definitions))))] + //! ``` //! #[macro_export] //! macro_rules! a_macro { () => {} } diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stderr b/tests/rustdoc-ui/doctest/non_local_defs.stderr index 2b47e6b5bc4d5..13cd2558793f8 100644 --- a/tests/rustdoc-ui/doctest/non_local_defs.stderr +++ b/tests/rustdoc-ui/doctest/non_local_defs.stderr @@ -1,5 +1,5 @@ warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/non_local_defs.rs:9:1 + --> $DIR/non_local_defs.rs:11:1 | LL | macro_rules! a_macro { () => {} } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,11 @@ LL | macro_rules! a_macro { () => {} } = help: remove the `#[macro_export]` or make this doc-test a standalone test with its own `fn main() { ... }` = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/non_local_defs.rs:8:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/rustdoc-ui/doctest/non_local_defs.stdout b/tests/rustdoc-ui/doctest/non_local_defs.stdout index bee195fcdd772..61b4074886e4b 100644 --- a/tests/rustdoc-ui/doctest/non_local_defs.stdout +++ b/tests/rustdoc-ui/doctest/non_local_defs.stdout @@ -1,6 +1,6 @@ running 1 test -test $DIR/non_local_defs.rs - (line 7) ... ok +test $DIR/non_local_defs.rs - (line 9) ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME diff --git a/tests/ui/lint/non-local-defs/cargo-update.rs b/tests/ui/lint/non-local-defs/cargo-update.rs index 8b8c15795d376..3c62a655a9f61 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.rs +++ b/tests/ui/lint/non-local-defs/cargo-update.rs @@ -10,6 +10,8 @@ // of the `cargo update` suggestion we assert it here. //@ error-pattern: `cargo update -p non_local_macro` +#![warn(non_local_definitions)] + extern crate non_local_macro; struct LocalStruct; diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr index bccf8622bac66..4dd41519455c6 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.stderr +++ b/tests/ui/lint/non-local-defs/cargo-update.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/cargo-update.rs:17:1 + --> $DIR/cargo-update.rs:19:1 | LL | non_local_macro::non_local_impl!(LocalStruct); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -14,7 +14,11 @@ LL | non_local_macro::non_local_impl!(LocalStruct); = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/cargo-update.rs:13:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ = note: this warning originates in the macro `non_local_macro::non_local_impl` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 1 warning emitted diff --git a/tests/ui/lint/non-local-defs/consts.rs b/tests/ui/lint/non-local-defs/consts.rs index d8a497e43e502..e7ee611529b96 100644 --- a/tests/ui/lint/non-local-defs/consts.rs +++ b/tests/ui/lint/non-local-defs/consts.rs @@ -2,6 +2,8 @@ //@ edition:2021 //@ rustc-env:CARGO_CRATE_NAME=non_local_def +#![warn(non_local_definitions)] + struct Test; trait Uto {} diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr index 9f70119e0f8c9..ed7bd56fe4a54 100644 --- a/tests/ui/lint/non-local-defs/consts.stderr +++ b/tests/ui/lint/non-local-defs/consts.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:13:5 + --> $DIR/consts.rs:15:5 | LL | const Z: () = { | ----------- @@ -17,10 +17,14 @@ LL | impl Uto for &Test {} = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/consts.rs:5:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:24:5 + --> $DIR/consts.rs:26:5 | LL | static A: u32 = { | ------------- move the `impl` block outside of this static `A` @@ -36,7 +40,7 @@ LL | impl Uto2 for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:32:5 + --> $DIR/consts.rs:34:5 | LL | const B: u32 = { | ------------ move the `impl` block outside of this constant `B` @@ -52,7 +56,7 @@ LL | impl Uto3 for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:43:5 + --> $DIR/consts.rs:45:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -65,7 +69,7 @@ LL | impl Test { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:50:9 + --> $DIR/consts.rs:52:9 | LL | const { | ___________- @@ -84,7 +88,7 @@ LL | | }; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:59:9 + --> $DIR/consts.rs:61:9 | LL | const _: u32 = { | ------------ move the `impl` block outside of this constant `_` and up 2 bodies @@ -98,7 +102,7 @@ LL | impl Test { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:72:9 + --> $DIR/consts.rs:74:9 | LL | let _a = || { | -- move the `impl` block outside of this closure `` and up 2 bodies @@ -113,7 +117,7 @@ LL | impl Uto9 for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/consts.rs:79:9 + --> $DIR/consts.rs:81:9 | LL | type A = [u32; { | ____________________- diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.rs b/tests/ui/lint/non-local-defs/exhaustive-trait.rs index 40d2314460f86..79f8cc4620b97 100644 --- a/tests/ui/lint/non-local-defs/exhaustive-trait.rs +++ b/tests/ui/lint/non-local-defs/exhaustive-trait.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + struct Dog; fn main() { diff --git a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr index 67df0e31d5bdf..24c9a6b4f01e2 100644 --- a/tests/ui/lint/non-local-defs/exhaustive-trait.stderr +++ b/tests/ui/lint/non-local-defs/exhaustive-trait.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:7:5 + --> $DIR/exhaustive-trait.rs:9:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -12,10 +12,14 @@ LL | impl PartialEq<()> for Dog { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/exhaustive-trait.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:14:5 + --> $DIR/exhaustive-trait.rs:16:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -31,7 +35,7 @@ LL | impl PartialEq<()> for &Dog { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:21:5 + --> $DIR/exhaustive-trait.rs:23:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -47,7 +51,7 @@ LL | impl PartialEq for () { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:28:5 + --> $DIR/exhaustive-trait.rs:30:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -63,7 +67,7 @@ LL | impl PartialEq<&Dog> for () { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:35:5 + --> $DIR/exhaustive-trait.rs:37:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -79,7 +83,7 @@ LL | impl PartialEq for &Dog { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive-trait.rs:42:5 + --> $DIR/exhaustive-trait.rs:44:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` diff --git a/tests/ui/lint/non-local-defs/exhaustive.rs b/tests/ui/lint/non-local-defs/exhaustive.rs index 2fb30f4344abb..f59a85c7ed94f 100644 --- a/tests/ui/lint/non-local-defs/exhaustive.rs +++ b/tests/ui/lint/non-local-defs/exhaustive.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + use std::fmt::Display; trait Trait {} diff --git a/tests/ui/lint/non-local-defs/exhaustive.stderr b/tests/ui/lint/non-local-defs/exhaustive.stderr index 1e0d5caec3830..6d8c2ec0bc7cf 100644 --- a/tests/ui/lint/non-local-defs/exhaustive.stderr +++ b/tests/ui/lint/non-local-defs/exhaustive.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:10:5 + --> $DIR/exhaustive.rs:12:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -10,10 +10,14 @@ LL | impl Test { | = note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/exhaustive.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:15:5 + --> $DIR/exhaustive.rs:17:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -29,7 +33,7 @@ LL | impl Display for Test { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:22:5 + --> $DIR/exhaustive.rs:24:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -43,7 +47,7 @@ LL | impl dyn Trait {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:25:5 + --> $DIR/exhaustive.rs:27:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -59,7 +63,7 @@ LL | impl Trait for Vec { } = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:28:5 + --> $DIR/exhaustive.rs:30:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -75,7 +79,7 @@ LL | impl Trait for &dyn Trait {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:31:5 + --> $DIR/exhaustive.rs:33:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -91,7 +95,7 @@ LL | impl Trait for *mut Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:34:5 + --> $DIR/exhaustive.rs:36:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -107,7 +111,7 @@ LL | impl Trait for *mut [Test] {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:37:5 + --> $DIR/exhaustive.rs:39:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -123,7 +127,7 @@ LL | impl Trait for [Test; 8] {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:40:5 + --> $DIR/exhaustive.rs:42:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -139,7 +143,7 @@ LL | impl Trait for (Test,) {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:43:5 + --> $DIR/exhaustive.rs:45:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -155,7 +159,7 @@ LL | impl Trait for fn(Test) -> () {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:46:5 + --> $DIR/exhaustive.rs:48:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -171,7 +175,7 @@ LL | impl Trait for fn() -> Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:50:9 + --> $DIR/exhaustive.rs:52:9 | LL | let _a = || { | -- move the `impl` block outside of this closure `` and up 2 bodies @@ -186,7 +190,7 @@ LL | impl Trait for Test {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:58:5 + --> $DIR/exhaustive.rs:60:5 | LL | impl Trait for *mut InsideMain {} | ^^^^^-----^^^^^--------------- @@ -198,7 +202,7 @@ LL | impl Trait for *mut InsideMain {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -208,7 +212,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:60:5 + --> $DIR/exhaustive.rs:62:5 | LL | impl Trait for *mut [InsideMain] {} | ^^^^^-----^^^^^----------------- @@ -219,7 +223,7 @@ LL | impl Trait for *mut [InsideMain] {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -229,7 +233,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:62:5 + --> $DIR/exhaustive.rs:64:5 | LL | impl Trait for [InsideMain; 8] {} | ^^^^^-----^^^^^--------------- @@ -240,7 +244,7 @@ LL | impl Trait for [InsideMain; 8] {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -250,7 +254,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:64:5 + --> $DIR/exhaustive.rs:66:5 | LL | impl Trait for (InsideMain,) {} | ^^^^^-----^^^^^------------- @@ -261,7 +265,7 @@ LL | impl Trait for (InsideMain,) {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -271,7 +275,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:66:5 + --> $DIR/exhaustive.rs:68:5 | LL | impl Trait for fn(InsideMain) -> () {} | ^^^^^-----^^^^^-------------------- @@ -282,7 +286,7 @@ LL | impl Trait for fn(InsideMain) -> () {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -292,7 +296,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:68:5 + --> $DIR/exhaustive.rs:70:5 | LL | impl Trait for fn() -> InsideMain {} | ^^^^^-----^^^^^------------------ @@ -303,7 +307,7 @@ LL | impl Trait for fn() -> InsideMain {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/exhaustive.rs:9:1 + --> $DIR/exhaustive.rs:11:1 | LL | fn main() { | ^^^^^^^^^ @@ -313,7 +317,7 @@ LL | struct InsideMain; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:72:9 + --> $DIR/exhaustive.rs:74:9 | LL | fn inside_inside() { | ------------------ move the `impl` block outside of this function `inside_inside` and up 2 bodies @@ -328,7 +332,7 @@ LL | impl Display for InsideMain { = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/exhaustive.rs:79:9 + --> $DIR/exhaustive.rs:81:9 | LL | fn inside_inside() { | ------------------ move the `impl` block outside of this function `inside_inside` and up 2 bodies diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.rs b/tests/ui/lint/non-local-defs/from-local-for-global.rs index fea9679d7375d..1d8f4845c2860 100644 --- a/tests/ui/lint/non-local-defs/from-local-for-global.rs +++ b/tests/ui/lint/non-local-defs/from-local-for-global.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + struct Cat; struct Wrap(T); diff --git a/tests/ui/lint/non-local-defs/from-local-for-global.stderr b/tests/ui/lint/non-local-defs/from-local-for-global.stderr index 67fd937d134cc..04eba8435fc04 100644 --- a/tests/ui/lint/non-local-defs/from-local-for-global.stderr +++ b/tests/ui/lint/non-local-defs/from-local-for-global.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:8:5 + --> $DIR/from-local-for-global.rs:10:5 | LL | fn main() { | --------- move the `impl` block outside of this function `main` @@ -12,10 +12,14 @@ LL | impl From for () { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/from-local-for-global.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:18:5 + --> $DIR/from-local-for-global.rs:20:5 | LL | impl From>> for () { | ^^^^^----^^^^^^^^^^^^^^^^^^^^^^^^^^^-- @@ -25,7 +29,7 @@ LL | impl From>> for () { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/from-local-for-global.rs:7:1 + --> $DIR/from-local-for-global.rs:9:1 | LL | fn main() { | ^^^^^^^^^ @@ -35,7 +39,7 @@ LL | struct Elephant; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:32:5 + --> $DIR/from-local-for-global.rs:34:5 | LL | impl StillNonLocal for &Foo {} | ^^^^^-------------^^^^^---- @@ -47,7 +51,7 @@ LL | impl StillNonLocal for &Foo {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `only_global` - --> $DIR/from-local-for-global.rs:30:1 + --> $DIR/from-local-for-global.rs:32:1 | LL | fn only_global() { | ^^^^^^^^^^^^^^^^ @@ -56,7 +60,7 @@ LL | struct Foo; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:40:5 + --> $DIR/from-local-for-global.rs:42:5 | LL | impl From for GlobalSameFunction { | ^^^^^----^^^^^^^^^^^^^------------------ @@ -67,7 +71,7 @@ LL | impl From for GlobalSameFunction { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `same_function` - --> $DIR/from-local-for-global.rs:38:1 + --> $DIR/from-local-for-global.rs:40:1 | LL | fn same_function() { | ^^^^^^^^^^^^^^^^^^ @@ -76,7 +80,7 @@ LL | struct Local1(GlobalSameFunction); = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/from-local-for-global.rs:48:5 + --> $DIR/from-local-for-global.rs:50:5 | LL | impl From for GlobalSameFunction { | ^^^^^----^^^^^^^^^^^^^------------------ @@ -87,7 +91,7 @@ LL | impl From for GlobalSameFunction { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `same_function` - --> $DIR/from-local-for-global.rs:38:1 + --> $DIR/from-local-for-global.rs:40:1 | LL | fn same_function() { | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/non-local-defs/generics.rs b/tests/ui/lint/non-local-defs/generics.rs index 0f526526dba21..13e392c510c64 100644 --- a/tests/ui/lint/non-local-defs/generics.rs +++ b/tests/ui/lint/non-local-defs/generics.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + trait Global {} fn main() { diff --git a/tests/ui/lint/non-local-defs/generics.stderr b/tests/ui/lint/non-local-defs/generics.stderr index ed2f87a4ed2d2..35366ed8ecf94 100644 --- a/tests/ui/lint/non-local-defs/generics.stderr +++ b/tests/ui/lint/non-local-defs/generics.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:9:5 + --> $DIR/generics.rs:11:5 | LL | impl Global for Vec { } | ^^^^^^^^^^^^^^^------^^^^^---^^^ @@ -10,17 +10,21 @@ LL | impl Global for Vec { } = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/generics.rs:6:1 + --> $DIR/generics.rs:8:1 | LL | fn main() { | ^^^^^^^^^ LL | trait Local {}; | ----------- may need to be moved as well = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/generics.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:20:5 + --> $DIR/generics.rs:22:5 | LL | impl Uto7 for Test where Local: std::any::Any {} | ^^^^^----^^^^^---- @@ -31,7 +35,7 @@ LL | impl Uto7 for Test where Local: std::any::Any {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `bad` - --> $DIR/generics.rs:18:1 + --> $DIR/generics.rs:20:1 | LL | fn bad() { | ^^^^^^^^ @@ -40,7 +44,7 @@ LL | struct Local; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:23:5 + --> $DIR/generics.rs:25:5 | LL | fn bad() { | -------- move the `impl` block outside of this function `bad` @@ -56,7 +60,7 @@ LL | impl Uto8 for T {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:32:5 + --> $DIR/generics.rs:34:5 | LL | impl Default for UwU { | ^^^^^-------^^^^^---^^^^^ @@ -67,7 +71,7 @@ LL | impl Default for UwU { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `fun` - --> $DIR/generics.rs:29:1 + --> $DIR/generics.rs:31:1 | LL | fn fun() { | ^^^^^^^^ @@ -77,7 +81,7 @@ LL | struct OwO; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:43:5 + --> $DIR/generics.rs:45:5 | LL | impl AsRef for () { | ^^^^^-----^^^^^^^^^^-- @@ -88,7 +92,7 @@ LL | impl AsRef for () { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `meow` - --> $DIR/generics.rs:40:1 + --> $DIR/generics.rs:42:1 | LL | fn meow() { | ^^^^^^^^^ @@ -98,7 +102,7 @@ LL | struct Cat; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:54:5 + --> $DIR/generics.rs:56:5 | LL | impl PartialEq for G { | ^^^^^---------^^^^^^^^- @@ -109,7 +113,7 @@ LL | impl PartialEq for G { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `fun2` - --> $DIR/generics.rs:51:1 + --> $DIR/generics.rs:53:1 | LL | fn fun2() { | ^^^^^^^^^ @@ -119,7 +123,7 @@ LL | struct B; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:69:5 + --> $DIR/generics.rs:71:5 | LL | impl From>> for () { | ^^^^^----^^^^^^^^^^^^^^^^^^^^^^^-- @@ -129,7 +133,7 @@ LL | impl From>> for () { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `rawr` - --> $DIR/generics.rs:66:1 + --> $DIR/generics.rs:68:1 | LL | fn rawr() { | ^^^^^^^^^ @@ -138,7 +142,7 @@ LL | struct Lion; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/generics.rs:76:5 + --> $DIR/generics.rs:78:5 | LL | impl From<()> for Wrap { | ^^^^^----^^^^^^^^^----^^^^^^ @@ -149,7 +153,7 @@ LL | impl From<()> for Wrap { = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `rawr` - --> $DIR/generics.rs:66:1 + --> $DIR/generics.rs:68:1 | LL | fn rawr() { | ^^^^^^^^^ diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.rs b/tests/ui/lint/non-local-defs/inside-macro_rules.rs index 9f21cc89852e2..744a1f7a6f1ab 100644 --- a/tests/ui/lint/non-local-defs/inside-macro_rules.rs +++ b/tests/ui/lint/non-local-defs/inside-macro_rules.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + macro_rules! m { () => { trait MacroTrait {} diff --git a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr index fa9ba2cb785d9..89835372c8a53 100644 --- a/tests/ui/lint/non-local-defs/inside-macro_rules.stderr +++ b/tests/ui/lint/non-local-defs/inside-macro_rules.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/inside-macro_rules.rs:9:13 + --> $DIR/inside-macro_rules.rs:11:13 | LL | fn my_func() { | ------------ move the `impl` block outside of this function `my_func` @@ -16,7 +16,11 @@ LL | m!(); = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/inside-macro_rules.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) warning: 1 warning emitted diff --git a/tests/ui/lint/non-local-defs/local.rs b/tests/ui/lint/non-local-defs/local.rs index 166ee88c0210c..e9dbff1300f28 100644 --- a/tests/ui/lint/non-local-defs/local.rs +++ b/tests/ui/lint/non-local-defs/local.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + use std::fmt::Debug; trait GlobalTrait {} diff --git a/tests/ui/lint/non-local-defs/macro_rules.rs b/tests/ui/lint/non-local-defs/macro_rules.rs index ed30a24903d01..20672cf0a3225 100644 --- a/tests/ui/lint/non-local-defs/macro_rules.rs +++ b/tests/ui/lint/non-local-defs/macro_rules.rs @@ -3,6 +3,8 @@ //@ aux-build:non_local_macro.rs //@ rustc-env:CARGO_CRATE_NAME=non_local_def +#![warn(non_local_definitions)] + extern crate non_local_macro; const B: u32 = { diff --git a/tests/ui/lint/non-local-defs/macro_rules.stderr b/tests/ui/lint/non-local-defs/macro_rules.stderr index 4e86fc7b987e6..f9995bf82183c 100644 --- a/tests/ui/lint/non-local-defs/macro_rules.stderr +++ b/tests/ui/lint/non-local-defs/macro_rules.stderr @@ -1,5 +1,5 @@ warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/macro_rules.rs:10:5 + --> $DIR/macro_rules.rs:12:5 | LL | macro_rules! m0 { () => { } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,10 +7,14 @@ LL | macro_rules! m0 { () => { } }; = help: remove the `#[macro_export]` or move this `macro_rules!` outside the of the current constant `B` = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/macro_rules.rs:6:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/macro_rules.rs:16:1 + --> $DIR/macro_rules.rs:18:1 | LL | non_local_macro::non_local_macro_rules!(my_macro); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +26,7 @@ LL | non_local_macro::non_local_macro_rules!(my_macro); = note: this warning originates in the macro `non_local_macro::non_local_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info) warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/macro_rules.rs:21:5 + --> $DIR/macro_rules.rs:23:5 | LL | macro_rules! m { () => { } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -32,7 +36,7 @@ LL | macro_rules! m { () => { } }; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module - --> $DIR/macro_rules.rs:29:13 + --> $DIR/macro_rules.rs:31:13 | LL | macro_rules! m2 { () => { } }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lint/non-local-defs/suggest-moving-inner.rs b/tests/ui/lint/non-local-defs/suggest-moving-inner.rs index 61b32e5bad9fe..9360ace4d805b 100644 --- a/tests/ui/lint/non-local-defs/suggest-moving-inner.rs +++ b/tests/ui/lint/non-local-defs/suggest-moving-inner.rs @@ -1,5 +1,7 @@ //@ check-pass +#![warn(non_local_definitions)] + trait Trait {} fn main() { diff --git a/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr b/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr index f0de0f72e74f6..a214415316f84 100644 --- a/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr +++ b/tests/ui/lint/non-local-defs/suggest-moving-inner.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/suggest-moving-inner.rs:12:5 + --> $DIR/suggest-moving-inner.rs:14:5 | LL | impl Trait for &Vec> | ^^^^^^^^-----^^^^^^^^^^^^^^^^^---------------------------------- @@ -10,7 +10,7 @@ LL | impl Trait for &Vec> = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/suggest-moving-inner.rs:5:1 + --> $DIR/suggest-moving-inner.rs:7:1 | LL | fn main() { | ^^^^^^^^^ @@ -23,7 +23,11 @@ LL | struct InsideMain; LL | trait HasFoo {} | ------------ may need to be moved as well = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/suggest-moving-inner.rs:3:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.rs b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.rs index 4291426e046a8..b726398bf9c9a 100644 --- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.rs +++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.rs @@ -3,6 +3,8 @@ // https://github.com/rust-lang/rust/issues/123573#issue-2229428739 +#![warn(non_local_definitions)] + pub trait Test {} impl<'a, T: 'a> Test for &[T] where &'a T: Test {} diff --git a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr index 80930ce1bcdf3..2eb71cecacaaf 100644 --- a/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr +++ b/tests/ui/lint/non-local-defs/trait-solver-overflow-123573.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/trait-solver-overflow-123573.rs:12:5 + --> $DIR/trait-solver-overflow-123573.rs:14:5 | LL | impl Test for &Local {} | ^^^^^----^^^^^------ @@ -11,14 +11,18 @@ LL | impl Test for &Local {} = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` help: move the `impl` block outside of this function `main` - --> $DIR/trait-solver-overflow-123573.rs:10:1 + --> $DIR/trait-solver-overflow-123573.rs:12:1 | LL | fn main() { | ^^^^^^^^^ LL | struct Local {} | ------------ may need to be moved as well = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/trait-solver-overflow-123573.rs:6:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/ui/lint/non-local-defs/weird-exprs.rs b/tests/ui/lint/non-local-defs/weird-exprs.rs index 1d9cecea0c971..fbf1fd941eecb 100644 --- a/tests/ui/lint/non-local-defs/weird-exprs.rs +++ b/tests/ui/lint/non-local-defs/weird-exprs.rs @@ -1,6 +1,8 @@ //@ check-pass //@ edition:2021 +#![warn(non_local_definitions)] + trait Uto {} struct Test; diff --git a/tests/ui/lint/non-local-defs/weird-exprs.stderr b/tests/ui/lint/non-local-defs/weird-exprs.stderr index cd414d636d34b..49aba904ebb0e 100644 --- a/tests/ui/lint/non-local-defs/weird-exprs.stderr +++ b/tests/ui/lint/non-local-defs/weird-exprs.stderr @@ -1,5 +1,5 @@ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:8:5 + --> $DIR/weird-exprs.rs:10:5 | LL | type A = [u32; { | ________________- @@ -16,10 +16,14 @@ LL | | }]; = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue - = note: `#[warn(non_local_definitions)]` on by default +note: the lint level is defined here + --> $DIR/weird-exprs.rs:4:9 + | +LL | #![warn(non_local_definitions)] + | ^^^^^^^^^^^^^^^^^^^^^ warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:16:9 + --> $DIR/weird-exprs.rs:18:9 | LL | Discr = { | _____________- @@ -38,7 +42,7 @@ LL | | } = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:25:9 + --> $DIR/weird-exprs.rs:27:9 | LL | let _array = [0i32; { | _________________________- @@ -57,7 +61,7 @@ LL | | }]; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:34:9 + --> $DIR/weird-exprs.rs:36:9 | LL | type A = [u32; { | ____________________- @@ -76,7 +80,7 @@ LL | | }]; = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:41:9 + --> $DIR/weird-exprs.rs:43:9 | LL | fn a(_: [u32; { | ___________________- @@ -95,7 +99,7 @@ LL | | }]) {} = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item - --> $DIR/weird-exprs.rs:48:9 + --> $DIR/weird-exprs.rs:50:9 | LL | fn b() -> [u32; { | _____________________- From 648cb1692050ecbcb5dfbb21623debbf5244ff15 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 13 Jun 2024 08:11:16 -0500 Subject: [PATCH 17/22] Enable const casting for `f16` and `f128` --- .../rustc_const_eval/src/interpret/cast.rs | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs index a13630ce084d5..83b61ab17492c 100644 --- a/compiler/rustc_const_eval/src/interpret/cast.rs +++ b/compiler/rustc_const_eval/src/interpret/cast.rs @@ -1,6 +1,6 @@ use std::assert_matches::assert_matches; -use rustc_apfloat::ieee::{Double, Single}; +use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_apfloat::{Float, FloatConvert}; use rustc_middle::mir::interpret::{InterpResult, PointerArithmetic, Scalar}; use rustc_middle::mir::CastKind; @@ -187,10 +187,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { bug!("FloatToFloat/FloatToInt cast: source type {} is not a float type", src.layout.ty) }; let val = match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => self.cast_from_float(src.to_scalar().to_f16()?, cast_to.ty), FloatTy::F32 => self.cast_from_float(src.to_scalar().to_f32()?, cast_to.ty), FloatTy::F64 => self.cast_from_float(src.to_scalar().to_f64()?, cast_to.ty), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => self.cast_from_float(src.to_scalar().to_f128()?, cast_to.ty), }; Ok(ImmTy::from_scalar(val, cast_to)) } @@ -296,18 +296,18 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { Float(fty) if signed => { let v = v as i128; match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => Scalar::from_f16(Half::from_i128(v).value), FloatTy::F32 => Scalar::from_f32(Single::from_i128(v).value), FloatTy::F64 => Scalar::from_f64(Double::from_i128(v).value), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => Scalar::from_f128(Quad::from_i128(v).value), } } // unsigned int -> float Float(fty) => match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => Scalar::from_f16(Half::from_u128(v).value), FloatTy::F32 => Scalar::from_f32(Single::from_u128(v).value), FloatTy::F64 => Scalar::from_f64(Double::from_u128(v).value), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => Scalar::from_f128(Quad::from_u128(v).value), }, // u8 -> char @@ -321,7 +321,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { /// Low-level cast helper function. Converts an apfloat `f` into int or float types. fn cast_from_float(&self, f: F, dest_ty: Ty<'tcx>) -> Scalar where - F: Float + Into> + FloatConvert + FloatConvert, + F: Float + + Into> + + FloatConvert + + FloatConvert + + FloatConvert + + FloatConvert, { use rustc_type_ir::TyKind::*; @@ -358,10 +363,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } // float -> float Float(fty) => match fty { - FloatTy::F16 => unimplemented!("f16_f128"), + FloatTy::F16 => Scalar::from_f16(adjust_nan(self, f, f.convert(&mut false).value)), FloatTy::F32 => Scalar::from_f32(adjust_nan(self, f, f.convert(&mut false).value)), FloatTy::F64 => Scalar::from_f64(adjust_nan(self, f, f.convert(&mut false).value)), - FloatTy::F128 => unimplemented!("f16_f128"), + FloatTy::F128 => { + Scalar::from_f128(adjust_nan(self, f, f.convert(&mut false).value)) + } }, // That's it. _ => span_bug!(self.cur_span(), "invalid float to {} cast", dest_ty), From 4a11ab0b343239c38d7760c973f5be65dddeadc2 Mon Sep 17 00:00:00 2001 From: WANG Xuerui Date: Thu, 27 Jun 2024 16:45:56 +0800 Subject: [PATCH 18/22] Fix Markdown tables in platform-support.md These table entries have wrong number of columns so the "notes" field is missing from the rendered page. Fix by removing excess empty columns. --- src/doc/rustc/src/platform-support.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 71dc8c4ca0f92..f5cd4bd217a32 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -168,12 +168,12 @@ target | std | notes `i686-unknown-freebsd` | ✓ | 32-bit FreeBSD [^x86_32-floats-return-ABI] `i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 [^x86_32-floats-return-ABI] [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 32-bit UEFI -[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64D ABI) -[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64S ABI) +[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64D ABI) +[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64S ABI) [`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs] [`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA) [`riscv32i-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32I ISA) -[`riscv32im-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IM ISA) +[`riscv32im-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IM ISA) [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) [`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) @@ -193,7 +193,7 @@ target | std | notes `wasm32-unknown-unknown` | ✓ | WebAssembly `wasm32-wasi` | ✓ | WebAssembly with WASI (undergoing a [rename to `wasm32-wasip1`][wasi-rename]) [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASI -[`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | | WebAssembly with WASI Preview 1 and threads +[`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads [`x86_64-apple-ios`](platform-support/apple-ios.md) | ✓ | 64-bit x86 iOS [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX `x86_64-fuchsia` | ✓ | Alias for `x86_64-unknown-fuchsia` From 3457ecc776e87550bc1b1bd4bb686bde8bd5c504 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 27 Jun 2024 13:06:10 +0300 Subject: [PATCH 19/22] remove unnecessary packages from `metadata::workspace_members` Currently bootstrap doesn't use any inner paths from rust-analyzer and bootstrap with `ShouldRun::create_or_deps`. Signed-off-by: onur-ozkan --- src/bootstrap/src/core/metadata.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs index 12867cb46b811..220eb5ba126e4 100644 --- a/src/bootstrap/src/core/metadata.rs +++ b/src/bootstrap/src/core/metadata.rs @@ -66,7 +66,10 @@ pub fn build(build: &mut Build) { } /// Invokes `cargo metadata` to get package metadata of each workspace member. -fn workspace_members(build: &Build) -> impl Iterator { +/// +/// This is used to resolve specific crate paths in `fn should_run` to compile +/// particular crate (e.g., `x build sysroot` to build library/sysroot). +fn workspace_members(build: &Build) -> Vec { let collect_metadata = |manifest_path| { let mut cargo = Command::new(&build.initial_cargo); cargo @@ -85,9 +88,5 @@ fn workspace_members(build: &Build) -> impl Iterator { }; // Collects `metadata.packages` from all workspaces. - let packages = collect_metadata("Cargo.toml"); - let ra_packages = collect_metadata("src/tools/rust-analyzer/Cargo.toml"); - let bootstrap_packages = collect_metadata("src/bootstrap/Cargo.toml"); - - packages.into_iter().chain(ra_packages).chain(bootstrap_packages) + collect_metadata("Cargo.toml") } From ae645147972435e725aa383ce614bb9a2ca20798 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Jun 2024 16:15:08 +0200 Subject: [PATCH 20/22] Migrate `run-make/override-aliased-flags` to `rmake.rs` --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/override-aliased-flags/Makefile | 23 ------------------ .../run-make/override-aliased-flags/rmake.rs | 24 +++++++++++++++++++ 3 files changed, 24 insertions(+), 24 deletions(-) delete mode 100644 tests/run-make/override-aliased-flags/Makefile create mode 100644 tests/run-make/override-aliased-flags/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index cb68589d8a4c2..b3dcfed5ce8b0 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -118,7 +118,6 @@ run-make/obey-crate-type-flag/Makefile run-make/optimization-remarks-dir-pgo/Makefile run-make/optimization-remarks-dir/Makefile run-make/output-type-permutations/Makefile -run-make/override-aliased-flags/Makefile run-make/overwrite-input/Makefile run-make/panic-abort-eh_frame/Makefile run-make/pass-linker-flags-flavor/Makefile diff --git a/tests/run-make/override-aliased-flags/Makefile b/tests/run-make/override-aliased-flags/Makefile deleted file mode 100644 index db1ff1ff98161..0000000000000 --- a/tests/run-make/override-aliased-flags/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# FIXME: it would be good to check that it's actually the rightmost flags -# that are used when multiple flags are specified, but I can't think of a -# reliable way to check this. - -all: - # Test that `-O` and `-C opt-level` can be specified multiple times. - # The rightmost flag will be used over any previous flags. - $(RUSTC) -O -O main.rs - $(RUSTC) -O -C opt-level=0 main.rs - $(RUSTC) -C opt-level=0 -O main.rs - $(RUSTC) -C opt-level=0 -C opt-level=2 main.rs - $(RUSTC) -C opt-level=2 -C opt-level=0 main.rs - - # Test that `-g` and `-C debuginfo` can be specified multiple times. - # The rightmost flag will be used over any previous flags. - $(RUSTC) -g -g main.rs - $(RUSTC) -g -C debuginfo=0 main.rs - $(RUSTC) -C debuginfo=0 -g main.rs - $(RUSTC) -C debuginfo=0 -C debuginfo=2 main.rs - $(RUSTC) -C debuginfo=2 -C debuginfo=0 main.rs diff --git a/tests/run-make/override-aliased-flags/rmake.rs b/tests/run-make/override-aliased-flags/rmake.rs new file mode 100644 index 0000000000000..e610c04651e95 --- /dev/null +++ b/tests/run-make/override-aliased-flags/rmake.rs @@ -0,0 +1,24 @@ +//@ ignore-cross-compile + +use run_make_support::rustc; + +// FIXME: it would be good to check that it's actually the rightmost flags +// that are used when multiple flags are specified, but I can't think of a +// reliable way to check this. +fn main() { + // Test that `-O` and `-C opt-level` can be specified multiple times. + // The rightmost flag will be used over any previous flags. + rustc().arg("-O").arg("-O").input("main.rs").run(); + rustc().arg("-O").arg("-C").arg("opt-level=0").input("main.rs").run(); + rustc().arg("-C").arg("opt-level=0").arg("-O").input("main.rs").run(); + rustc().arg("-C").arg("opt-level=0").arg("-C").arg("opt-level=2").input("main.rs").run(); + rustc().arg("-C").arg("opt-level=2").arg("-C").arg("opt-level=0").input("main.rs").run(); + + // Test that `-g` and `-C debuginfo` can be specified multiple times. + // The rightmost flag will be used over any previous flags. + rustc().arg("-g").arg("-g").input("main.rs").run(); + rustc().arg("-g").arg("-C").arg("debuginfo=0").input("main.rs").run(); + rustc().arg("-C").arg("debuginfo=0").arg("-g").input("main.rs").run(); + rustc().arg("-C").arg("debuginfo=0").arg("-C").arg("debuginfo=2").input("main.rs").run(); + rustc().arg("-C").arg("debuginfo=2").arg("-C").arg("debuginfo=0").input("main.rs").run(); +} From 789ee88bd015fde4257464d0120ab57b0d744e0b Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 27 Jun 2024 14:56:57 -0400 Subject: [PATCH 21/22] Tighten spans for async blocks --- compiler/rustc_ast/src/ast.rs | 5 +- compiler/rustc_ast/src/mut_visit.rs | 3 +- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_lowering/src/expr.rs | 7 ++- compiler/rustc_ast_lowering/src/item.rs | 16 +++--- .../rustc_ast_pretty/src/pprust/state/expr.rs | 2 +- .../src/assert/context.rs | 2 +- compiler/rustc_parse/src/parser/expr.rs | 5 +- compiler/rustc_resolve/src/def_collector.rs | 2 +- .../src/suspicious_operation_groupings.rs | 2 +- .../clippy/clippy_utils/src/ast_utils.rs | 2 +- src/tools/rustfmt/src/expr.rs | 2 +- ...block-control-flow-static-semantics.stderr | 26 +++++----- ...async-borrowck-escaping-block-error.stderr | 10 ++-- .../async-closures/wrong-fn-kind.stderr | 24 ++++----- .../ui/async-await/async-is-unwindsafe.stderr | 25 +++++----- tests/ui/async-await/coroutine-desc.stderr | 4 +- .../async-await/coroutine-not-future.stderr | 4 +- .../issue-67252-unnamed-future.stderr | 2 +- tests/ui/async-await/issue-68112.stderr | 15 ++---- .../issue-70935-complex-spans.stderr | 20 +++----- ...sue-74072-lifetime-name-annotations.stderr | 14 +++--- tests/ui/async-await/issue-86507.stderr | 2 +- .../issues/issue-78938-async-block.stderr | 10 ++-- .../async-closure-gate.afn.stderr | 4 +- .../async-closure-gate.nofeat.stderr | 4 +- .../async-await/try-on-option-in-async.stderr | 12 ++--- .../cloning-in-async-block-121547.stderr | 18 +++---- ...break-inside-coroutine-issue-124495.stderr | 50 ++++++++----------- tests/ui/coroutine/clone-impl-async.stderr | 24 ++++----- tests/ui/coroutine/gen_block_is_coro.stderr | 12 ++--- .../coroutine/gen_block_is_no_future.stderr | 6 +-- tests/ui/coroutine/gen_block_move.stderr | 13 ++--- .../issue-90014-tait.stderr | 2 +- tests/ui/impl-trait/issue-55872-3.stderr | 4 +- .../ui/impl-trait/issues/issue-78722-2.stderr | 4 +- tests/ui/impl-trait/issues/issue-78722.stderr | 2 +- .../ui/impl-trait/nested-return-type4.stderr | 2 +- .../mismatch-sugg-for-shorthand-field.stderr | 4 +- .../pattern/non-structural-match-types.stderr | 2 +- .../expected-boxed-future-isnt-pinned.stderr | 2 +- tests/ui/traits/next-solver/async.fail.stderr | 2 +- .../indirect-recursion-issue-112047.stderr | 4 +- 43 files changed, 173 insertions(+), 204 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 4a3ce0e0c3066..f5e79c04d784f 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -1454,7 +1454,10 @@ pub enum ExprKind { Block(P, Option