From d7e6074083231aa8ccf7f299626fc83d59f78ee4 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 30 Oct 2024 13:16:43 -0700 Subject: style-guide: Only use the new binop heuristic for assignments This avoids pathological cases where chains of binops get progressively deeper. --- src/doc/style-guide/src/editions.md | 5 +++-- src/doc/style-guide/src/expressions.md | 12 +++--------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md index 74e873e35ff..d9dba641495 100644 --- a/src/doc/style-guide/src/editions.md +++ b/src/doc/style-guide/src/editions.md @@ -40,8 +40,9 @@ include: of a delimited expression, delimited expressions are generally combinable, regardless of the number of members. Previously only applied with exactly one member (except for closures with explicit blocks). -- When line-breaking a binary operator, if the first operand spans multiple - lines, use the base indentation of the last line. +- When line-breaking an assignment operator, if the left-hand side spans + multiple lines, use the base indentation of the last line of the left-hand + side to indent the right-hand side. - Miscellaneous `rustfmt` bugfixes. - Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order). - Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase". diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md index 3bb0ee6d5ff..4f63a632030 100644 --- a/src/doc/style-guide/src/expressions.md +++ b/src/doc/style-guide/src/expressions.md @@ -328,9 +328,9 @@ foo_bar Prefer line-breaking at an assignment operator (either `=` or `+=`, etc.) rather than at other binary operators. -If line-breaking at a binary operator (including assignment operators) where the -first operand spans multiple lines, use the base indentation of the *last* -line of the first operand, and indent relative to that: +If line-breaking an assignment operator where the left-hand side spans multiple +lines, use the base indentation of the *last* line of the left-hand side, and +indent the right-hand side relative to that: ```rust impl SomeType { @@ -341,12 +341,6 @@ impl SomeType { .extra_info = long_long_long_long_long_long_long_long_long_long_long_long_long_long_long; - self.array[array_index as usize] - .as_mut() - .expect("thing must exist") - .extra_info - + long_long_long_long_long_long_long_long_long_long_long_long_long_long_long; - self.array[array_index as usize] .as_mut() .expect("thing must exist") -- cgit 1.4.1-3-g733a5 From ce3e14a448e090abf494a91b87f124258c542d4c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 17 Oct 2024 20:11:20 +1100 Subject: Remove support for `-Zprofile` (gcov-style coverage instrumentation) --- compiler/rustc_codegen_llvm/src/attributes.rs | 5 ---- compiler/rustc_codegen_llvm/src/back/write.rs | 1 - .../rustc_codegen_llvm/src/debuginfo/metadata.rs | 26 --------------------- compiler/rustc_codegen_llvm/src/debuginfo/mod.rs | 3 --- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 - compiler/rustc_codegen_ssa/src/back/write.rs | 25 ++++---------------- compiler/rustc_interface/src/tests.rs | 2 -- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 13 ++--------- compiler/rustc_metadata/src/creader.rs | 4 +--- compiler/rustc_session/src/config.rs | 14 +---------- compiler/rustc_session/src/options.rs | 5 ---- src/doc/rustc/src/instrument-coverage.md | 8 ++----- .../unstable-book/src/compiler-flags/profile.md | 27 ---------------------- tests/run-make/profile/rmake.rs | 21 ----------------- tests/run-make/profile/test.rs | 1 - 15 files changed, 10 insertions(+), 146 deletions(-) delete mode 100644 src/doc/unstable-book/src/compiler-flags/profile.md delete mode 100644 tests/run-make/profile/rmake.rs delete mode 100644 tests/run-make/profile/test.rs diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs index 2c5ec9dad59..64bb22e8cb2 100644 --- a/compiler/rustc_codegen_llvm/src/attributes.rs +++ b/compiler/rustc_codegen_llvm/src/attributes.rs @@ -232,11 +232,6 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> { return None; } - // probestack doesn't play nice either with gcov profiling. - if cx.sess().opts.unstable_opts.profile { - return None; - } - let attr_value = match cx.sess().target.stack_probes { StackProbeType::None => return None, // Request LLVM to generate the probes inline. If the given LLVM version does not support diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index bfa9e8b82a0..cf7b16c9cc4 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -591,7 +591,6 @@ pub(crate) unsafe fn llvm_optimize( pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), config.instrument_coverage, instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), - config.instrument_gcov, pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()), config.debug_info_for_profiling, llvm_selfprofiler, diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 9064cfaeb29..0d1fd0163eb 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -7,7 +7,6 @@ use std::{iter, ptr}; use libc::{c_char, c_longlong, c_uint}; use rustc_codegen_ssa::debuginfo::type_names::{VTableNameKind, cpp_like_debuginfo}; use rustc_codegen_ssa::traits::*; -use rustc_fs_util::path_to_c_string; use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::bug; @@ -979,33 +978,8 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>( debug_name_table_kind, ); - if tcx.sess.opts.unstable_opts.profile { - let default_gcda_path = &output_filenames.with_extension("gcda"); - let gcda_path = - tcx.sess.opts.unstable_opts.profile_emit.as_ref().unwrap_or(default_gcda_path); - - let gcov_cu_info = [ - path_to_mdstring(debug_context.llcontext, &output_filenames.with_extension("gcno")), - path_to_mdstring(debug_context.llcontext, gcda_path), - unit_metadata, - ]; - let gcov_metadata = llvm::LLVMMDNodeInContext2( - debug_context.llcontext, - gcov_cu_info.as_ptr(), - gcov_cu_info.len(), - ); - let val = llvm::LLVMMetadataAsValue(debug_context.llcontext, gcov_metadata); - - llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, c"llvm.gcov".as_ptr(), val); - } - return unit_metadata; }; - - fn path_to_mdstring<'ll>(llcx: &'ll llvm::Context, path: &Path) -> &'ll llvm::Metadata { - let path_str = path_to_c_string(path); - unsafe { llvm::LLVMMDStringInContext2(llcx, path_str.as_ptr(), path_str.as_bytes().len()) } - } } /// Creates a `DW_TAG_member` entry inside the DIE represented by the given `type_di_node`. diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 72e723aa849..b6c20cdcf0c 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -55,7 +55,6 @@ const DW_TAG_arg_variable: c_uint = 0x101; /// A context object for maintaining all state needed by the debuginfo module. pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> { - llcontext: &'ll llvm::Context, llmod: &'ll llvm::Module, builder: &'ll mut DIBuilder<'ll>, created_files: RefCell, &'ll DIFile>>, @@ -78,9 +77,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> { debug!("CodegenUnitDebugContext::new"); let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) }; // DIBuilder inherits context from the module, so we'd better use the same one - let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) }; CodegenUnitDebugContext { - llcontext, llmod, builder, created_files: Default::default(), diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 8fc586d2c8f..5fad7583e1a 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2269,7 +2269,6 @@ unsafe extern "C" { PGOUsePath: *const c_char, InstrumentCoverage: bool, InstrProfileOutput: *const c_char, - InstrumentGCOV: bool, PGOSampleUsePath: *const c_char, DebugInfoForProfiling: bool, llvm_selfprofiler: *mut c_void, diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 8445d16befb..d977cca247e 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -90,7 +90,6 @@ pub struct ModuleConfig { pub pgo_sample_use: Option, pub debug_info_for_profiling: bool, pub instrument_coverage: bool, - pub instrument_gcov: bool, pub sanitizer: SanitizerSet, pub sanitizer_recover: SanitizerSet, @@ -123,12 +122,7 @@ pub struct ModuleConfig { } impl ModuleConfig { - fn new( - kind: ModuleKind, - tcx: TyCtxt<'_>, - no_builtins: bool, - is_compiler_builtins: bool, - ) -> ModuleConfig { + fn new(kind: ModuleKind, tcx: TyCtxt<'_>, no_builtins: bool) -> ModuleConfig { // If it's a regular module, use `$regular`, otherwise use `$other`. // `$regular` and `$other` are evaluated lazily. macro_rules! if_regular { @@ -189,13 +183,6 @@ impl ModuleConfig { pgo_sample_use: if_regular!(sess.opts.unstable_opts.profile_sample_use.clone(), None), debug_info_for_profiling: sess.opts.unstable_opts.debug_info_for_profiling, instrument_coverage: if_regular!(sess.instrument_coverage(), false), - instrument_gcov: if_regular!( - // compiler_builtins overrides the codegen-units settings, - // which is incompatible with -Zprofile which requires that - // only a single codegen unit is used per crate. - sess.opts.unstable_opts.profile && !is_compiler_builtins, - false - ), sanitizer: if_regular!(sess.opts.unstable_opts.sanitizer, SanitizerSet::empty()), sanitizer_dataflow_abilist: if_regular!( @@ -473,16 +460,12 @@ pub(crate) fn start_async_codegen( let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID); let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins); - let is_compiler_builtins = attr::contains_name(crate_attrs, sym::compiler_builtins); let crate_info = CrateInfo::new(tcx, target_cpu); - let regular_config = - ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins, is_compiler_builtins); - let metadata_config = - ModuleConfig::new(ModuleKind::Metadata, tcx, no_builtins, is_compiler_builtins); - let allocator_config = - ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins, is_compiler_builtins); + let regular_config = ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins); + let metadata_config = ModuleConfig::new(ModuleKind::Metadata, tcx, no_builtins); + let allocator_config = ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins); let (shared_emitter, shared_emitter_main) = SharedEmitter::new(); let (codegen_worker_send, codegen_worker_receive) = channel(); diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index d3762e739db..35bba149d0a 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -832,8 +832,6 @@ fn test_unstable_options_tracking_hash() { tracked!(polonius, Polonius::Legacy); tracked!(precise_enum_drop_elaboration, false); tracked!(print_fuel, Some("abc".to_string())); - tracked!(profile, true); - tracked!(profile_emit, Some(PathBuf::from("abc"))); tracked!(profile_sample_use, Some(PathBuf::from("abc"))); tracked!(profiler_runtime, "abc".to_string()); tracked!(regparm, Some(3)); diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 3e906f89c15..3b7dc6de825 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -42,7 +42,6 @@ #if LLVM_VERSION_GE(19, 0) #include "llvm/Support/PGOOptions.h" #endif -#include "llvm/Transforms/Instrumentation/GCOVProfiler.h" #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h" #include "llvm/Transforms/Instrumentation/InstrProfiling.h" #include "llvm/Transforms/Instrumentation/MemorySanitizer.h" @@ -714,9 +713,8 @@ extern "C" LLVMRustResult LLVMRustOptimize( bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers, LLVMRustSanitizerOptions *SanitizerOptions, const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage, - const char *InstrProfileOutput, bool InstrumentGCOV, - const char *PGOSampleUsePath, bool DebugInfoForProfiling, - void *LlvmSelfProfiler, + const char *InstrProfileOutput, const char *PGOSampleUsePath, + bool DebugInfoForProfiling, void *LlvmSelfProfiler, LLVMRustSelfProfileBeforePassCallback BeforePassCallback, LLVMRustSelfProfileAfterPassCallback AfterPassCallback, const char *ExtraPasses, size_t ExtraPassesLen, const char *LLVMPlugins, @@ -847,13 +845,6 @@ extern "C" LLVMRustResult LLVMRustOptimize( }); } - if (InstrumentGCOV) { - PipelineStartEPCallbacks.push_back( - [](ModulePassManager &MPM, OptimizationLevel Level) { - MPM.addPass(GCOVProfilerPass(GCOVOptions::getDefault())); - }); - } - if (InstrumentCoverage) { PipelineStartEPCallbacks.push_back( [InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) { diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 16623915c40..d2be6ae8d69 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -778,9 +778,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { fn inject_profiler_runtime(&mut self, krate: &ast::Crate) { if self.sess.opts.unstable_opts.no_profiler_runtime - || !(self.sess.instrument_coverage() - || self.sess.opts.unstable_opts.profile - || self.sess.opts.cg.profile_generate.enabled()) + || !(self.sess.instrument_coverage() || self.sess.opts.cg.profile_generate.enabled()) { return; } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index d733e32f209..5ee3b4015eb 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2453,7 +2453,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let output_types = parse_output_types(early_dcx, &unstable_opts, matches); let mut cg = CodegenOptions::build(early_dcx, matches); - let (disable_local_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto( + let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto( early_dcx, &output_types, matches, @@ -2476,18 +2476,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state); - if unstable_opts.profile && incremental.is_some() { - early_dcx.early_fatal("can't instrument with gcov profiling when compiling incrementally"); - } - if unstable_opts.profile { - match codegen_units { - Some(1) => {} - None => codegen_units = Some(1), - Some(_) => early_dcx - .early_fatal("can't instrument with gcov profiling with multiple codegen units"), - } - } - if cg.profile_generate.enabled() && cg.profile_use.is_some() { early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive"); } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 54a4621db24..2b158627751 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1985,13 +1985,8 @@ options! { proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread, parse_proc_macro_execution_strategy, [UNTRACKED], "how to run proc-macro code (default: same-thread)"), - profile: bool = (false, parse_bool, [TRACKED], - "insert profiling code (default: no)"), profile_closures: bool = (false, parse_no_flag, [UNTRACKED], "profile size of closures"), - profile_emit: Option = (None, parse_opt_pathbuf, [TRACKED], - "file path to emit profiling data at runtime when using 'profile' \ - (default based on relative source path)"), profile_sample_use: Option = (None, parse_opt_pathbuf, [TRACKED], "use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)"), profiler_runtime: String = (String::from("profiler_builtins"), parse_string, [TRACKED], diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md index ed091d8fc57..41da47e9206 100644 --- a/src/doc/rustc/src/instrument-coverage.md +++ b/src/doc/rustc/src/instrument-coverage.md @@ -2,12 +2,8 @@ ## Introduction -The Rust compiler includes two code coverage implementations: - -- A GCC-compatible, gcov-based coverage implementation, enabled with `-Z profile`, which derives coverage data based on DebugInfo. -- A source-based code coverage implementation, enabled with `-C instrument-coverage`, which uses LLVM's native, efficient coverage instrumentation to generate very precise coverage data. - -This document describes how to enable and use the LLVM instrumentation-based coverage, via the `-C instrument-coverage` compiler flag. +This document describes how to enable and use LLVM instrumentation-based coverage, +via the `-C instrument-coverage` compiler flag. ## How it works diff --git a/src/doc/unstable-book/src/compiler-flags/profile.md b/src/doc/unstable-book/src/compiler-flags/profile.md deleted file mode 100644 index 71303bfaff2..00000000000 --- a/src/doc/unstable-book/src/compiler-flags/profile.md +++ /dev/null @@ -1,27 +0,0 @@ -# `profile` - -The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524). - ------------------------- - -This feature allows the generation of code coverage reports. - -Set the `-Zprofile` compiler flag in order to enable gcov profiling. - -For example: -```Bash -cargo new testgcov --bin -cd testgcov -export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort" -export CARGO_INCREMENTAL=0 -cargo build -cargo run -``` - -Once you've built and run your program, files with the `gcno` (after build) and `gcda` (after execution) extensions will be created. -You can parse them with [llvm-cov gcov](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) or [grcov](https://github.com/mozilla/grcov). - -Please note that `RUSTFLAGS` by default applies to everything that cargo builds and runs during a build! -When the `--target` flag is explicitly passed to cargo, the `RUSTFLAGS` no longer apply to build scripts and procedural macros. -For more fine-grained control consider passing a `RUSTC_WRAPPER` program to cargo that only adds the profiling flags to -rustc for the specific crates you want to profile. diff --git a/tests/run-make/profile/rmake.rs b/tests/run-make/profile/rmake.rs deleted file mode 100644 index 58a1b53c040..00000000000 --- a/tests/run-make/profile/rmake.rs +++ /dev/null @@ -1,21 +0,0 @@ -// This test revolves around the rustc flag -Z profile, which should -// generate a .gcno file (initial profiling information) as well -// as a .gcda file (branch counters). The path where these are emitted -// should also be configurable with -Z profile-emit. This test checks -// that the files are produced, and then that the latter flag is respected. -// See https://github.com/rust-lang/rust/pull/42433 - -//@ ignore-cross-compile -//@ needs-profiler-runtime - -use run_make_support::{path, run, rustc}; - -fn main() { - rustc().arg("-g").arg("-Zprofile").input("test.rs").run(); - run("test"); - assert!(path("test.gcno").exists(), "no .gcno file"); - assert!(path("test.gcda").exists(), "no .gcda file"); - rustc().arg("-g").arg("-Zprofile").arg("-Zprofile-emit=abc/abc.gcda").input("test.rs").run(); - run("test"); - assert!(path("abc/abc.gcda").exists(), "gcda file not emitted to defined path"); -} diff --git a/tests/run-make/profile/test.rs b/tests/run-make/profile/test.rs deleted file mode 100644 index f328e4d9d04..00000000000 --- a/tests/run-make/profile/test.rs +++ /dev/null @@ -1 +0,0 @@ -fn main() {} -- cgit 1.4.1-3-g733a5 From dd651be7bc74b0d897cd0b4ec76104e51c32cb34 Mon Sep 17 00:00:00 2001 From: binarycat Date: Thu, 31 Oct 2024 11:43:45 -0500 Subject: update offset_of! docs to reflect the stablization of nesting --- library/core/src/mem/mod.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 74b198c4fdd..4c4c31eaf0a 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1254,12 +1254,10 @@ impl SizedTypeProperties for T {} /// /// Nested field accesses may be used, but not array indexes. /// -/// Enum variants may be traversed as if they were fields. Variants themselves do +/// If the nightly-only feature `offset_of_enum` is enabled, +/// variants may be traversed as if they were fields. Variants themselves do /// not have an offset. /// -/// However, on stable only a single field name is supported, which blocks the use of -/// enum support. -/// /// Visibility is respected - all types and fields must be visible to the call site: /// /// ``` -- cgit 1.4.1-3-g733a5 From fc67203d59f5a314d51469ed844189191b5663f6 Mon Sep 17 00:00:00 2001 From: lolbinarycat Date: Thu, 31 Oct 2024 17:27:31 -0500 Subject: use semantic line break Co-authored-by: Jubilee --- library/core/src/mem/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 4c4c31eaf0a..4cf52042a57 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -1255,8 +1255,8 @@ impl SizedTypeProperties for T {} /// Nested field accesses may be used, but not array indexes. /// /// If the nightly-only feature `offset_of_enum` is enabled, -/// variants may be traversed as if they were fields. Variants themselves do -/// not have an offset. +/// variants may be traversed as if they were fields. +/// Variants themselves do not have an offset. /// /// Visibility is respected - all types and fields must be visible to the call site: /// -- cgit 1.4.1-3-g733a5 From 588c7a934a05fb8d4aaabf7a42c28f75b749db6c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 31 Oct 2024 04:11:38 +0000 Subject: nit: stop using TypeckRootCtxt --- compiler/rustc_hir_typeck/src/fallback.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 68776c52555..963801e5793 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -14,7 +14,7 @@ use rustc_span::{DUMMY_SP, Span}; use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt}; use tracing::debug; -use crate::{FnCtxt, TypeckRootCtxt, errors}; +use crate::{FnCtxt, errors}; #[derive(Copy, Clone)] pub(crate) enum DivergingFallbackBehavior { @@ -419,7 +419,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { root_vid: ty::TyVid, ) { let unsafe_infer_vars = unsafe_infer_vars.get_or_init(|| { - let unsafe_infer_vars = compute_unsafe_infer_vars(self.root_ctxt, self.body_id); + let unsafe_infer_vars = compute_unsafe_infer_vars(self, self.body_id); debug!(?unsafe_infer_vars); unsafe_infer_vars }); @@ -569,27 +569,26 @@ pub(crate) enum UnsafeUseReason { /// /// `compute_unsafe_infer_vars` will return `{ id(?X) -> (hir_id, span, Call) }` fn compute_unsafe_infer_vars<'a, 'tcx>( - root_ctxt: &'a TypeckRootCtxt<'tcx>, + fcx: &'a FnCtxt<'a, 'tcx>, body_id: LocalDefId, ) -> UnordMap { - let body = - root_ctxt.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); + let body = fcx.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner"); let mut res = UnordMap::default(); struct UnsafeInferVarsVisitor<'a, 'tcx> { - root_ctxt: &'a TypeckRootCtxt<'tcx>, + fcx: &'a FnCtxt<'a, 'tcx>, res: &'a mut UnordMap, } impl Visitor<'_> for UnsafeInferVarsVisitor<'_, '_> { fn visit_expr(&mut self, ex: &'_ hir::Expr<'_>) { - let typeck_results = self.root_ctxt.typeck_results.borrow(); + let typeck_results = self.fcx.typeck_results.borrow(); match ex.kind { hir::ExprKind::MethodCall(..) => { if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id) - && let method_ty = self.root_ctxt.tcx.type_of(def_id).instantiate_identity() - && let sig = method_ty.fn_sig(self.root_ctxt.tcx) + && let method_ty = self.fcx.tcx.type_of(def_id).instantiate_identity() + && let sig = method_ty.fn_sig(self.fcx.tcx) && let hir::Safety::Unsafe = sig.safety() { let mut collector = InferVarCollector { @@ -609,7 +608,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( let func_ty = typeck_results.expr_ty(func); if func_ty.is_fn() - && let sig = func_ty.fn_sig(self.root_ctxt.tcx) + && let sig = func_ty.fn_sig(self.fcx.tcx) && let hir::Safety::Unsafe = sig.safety() { let mut collector = InferVarCollector { @@ -640,7 +639,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( // If this path refers to an unsafe function, collect inference variables which may affect it. // `is_fn` excludes closures, but those can't be unsafe. if ty.is_fn() - && let sig = ty.fn_sig(self.root_ctxt.tcx) + && let sig = ty.fn_sig(self.fcx.tcx) && let hir::Safety::Unsafe = sig.safety() { let mut collector = InferVarCollector { @@ -698,7 +697,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>( } } - UnsafeInferVarsVisitor { root_ctxt, res: &mut res }.visit_expr(&body.value); + UnsafeInferVarsVisitor { fcx, res: &mut res }.visit_expr(&body.value); debug!(?res, "collected the following unsafe vars for {body_id:?}"); -- cgit 1.4.1-3-g733a5 From 41966e71bc386d073124d73cbc34fb279df5f4c8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 31 Oct 2024 04:33:21 +0000 Subject: Suggest annotations for never type fallback --- compiler/rustc_hir_typeck/src/errors.rs | 49 ++++++++++++-- compiler/rustc_hir_typeck/src/fallback.rs | 76 ++++++++++++++++++++-- .../dependency-on-fallback-to-unit.stderr | 4 ++ ...-type-fallback-flowing-into-unsafe.e2015.stderr | 4 ++ ...-type-fallback-flowing-into-unsafe.e2024.stderr | 4 ++ 5 files changed, 125 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index cceaabaff65..8fd54593934 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -169,19 +169,34 @@ pub(crate) struct MissingParenthesesInRange { pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe { #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)] - Call, + Call { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)] - Method, + Method { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)] - Path, + Path { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)] - UnionField, + UnionField { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, #[help] #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)] - Deref, + Deref { + #[subdiagnostic] + sugg: SuggestAnnotations, + }, } #[derive(LintDiagnostic)] @@ -191,6 +206,30 @@ pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> { #[note] pub obligation_span: Span, pub obligation: ty::Predicate<'tcx>, + #[subdiagnostic] + pub sugg: SuggestAnnotations, +} + +#[derive(Clone)] +pub(crate) struct SuggestAnnotations { + pub suggestion_spans: Vec, +} +impl Subdiagnostic for SuggestAnnotations { + fn add_to_diag_with>( + self, + diag: &mut Diag<'_, G>, + _: &F, + ) { + if self.suggestion_spans.is_empty() { + return; + } + + diag.multipart_suggestion_verbose( + "use `()` annotations to avoid fallback changes", + self.suggestion_spans.into_iter().map(|span| (span, String::from("()"))).collect(), + Applicability::MachineApplicable, + ); + } } #[derive(Subdiagnostic)] diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 963801e5793..02efb12f835 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -1,5 +1,7 @@ use std::cell::OnceCell; +use std::ops::ControlFlow; +use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::iterate::DepthFirstSearch; use rustc_data_structures::graph::vec_graph::VecGraph; use rustc_data_structures::graph::{self}; @@ -321,7 +323,11 @@ impl<'tcx> FnCtxt<'_, 'tcx> { let mut diverging_fallback = UnordMap::with_capacity(diverging_vids.len()); let unsafe_infer_vars = OnceCell::new(); - self.lint_obligations_broken_by_never_type_fallback_change(behavior, &diverging_vids); + self.lint_obligations_broken_by_never_type_fallback_change( + behavior, + &diverging_vids, + &coercion_graph, + ); for &diverging_vid in &diverging_vids { let diverging_ty = Ty::new_var(self.tcx, diverging_vid); @@ -429,19 +435,31 @@ impl<'tcx> FnCtxt<'_, 'tcx> { .filter_map(|x| unsafe_infer_vars.get(&x).copied()) .collect::>(); + let sugg = self.try_to_suggest_annotations(&[root_vid], coercion_graph); + for (hir_id, span, reason) in affected_unsafe_infer_vars { self.tcx.emit_node_span_lint( lint::builtin::NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE, hir_id, span, match reason { - UnsafeUseReason::Call => errors::NeverTypeFallbackFlowingIntoUnsafe::Call, - UnsafeUseReason::Method => errors::NeverTypeFallbackFlowingIntoUnsafe::Method, - UnsafeUseReason::Path => errors::NeverTypeFallbackFlowingIntoUnsafe::Path, + UnsafeUseReason::Call => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Call { sugg: sugg.clone() } + } + UnsafeUseReason::Method => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Method { sugg: sugg.clone() } + } + UnsafeUseReason::Path => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Path { sugg: sugg.clone() } + } UnsafeUseReason::UnionField => { - errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField + errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField { + sugg: sugg.clone(), + } + } + UnsafeUseReason::Deref => { + errors::NeverTypeFallbackFlowingIntoUnsafe::Deref { sugg: sugg.clone() } } - UnsafeUseReason::Deref => errors::NeverTypeFallbackFlowingIntoUnsafe::Deref, }, ); } @@ -451,6 +469,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { &self, behavior: DivergingFallbackBehavior, diverging_vids: &[ty::TyVid], + coercions: &VecGraph, ) { let DivergingFallbackBehavior::ToUnit = behavior else { return }; @@ -478,13 +497,14 @@ impl<'tcx> FnCtxt<'_, 'tcx> { }; // If we have no errors with `fallback = ()`, but *do* have errors with `fallback = !`, - // then this code will be broken by the never type fallback change.qba + // then this code will be broken by the never type fallback change. let unit_errors = remaining_errors_if_fallback_to(self.tcx.types.unit); if unit_errors.is_empty() && let mut never_errors = remaining_errors_if_fallback_to(self.tcx.types.never) && let [ref mut never_error, ..] = never_errors.as_mut_slice() { self.adjust_fulfillment_error_for_expr_obligation(never_error); + let sugg = self.try_to_suggest_annotations(diverging_vids, coercions); self.tcx.emit_node_span_lint( lint::builtin::DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK, self.tcx.local_def_id_to_hir_id(self.body_id), @@ -492,6 +512,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { errors::DependencyOnUnitNeverTypeFallback { obligation_span: never_error.obligation.cause.span, obligation: never_error.obligation.predicate, + sugg, }, ) } @@ -541,6 +562,47 @@ impl<'tcx> FnCtxt<'_, 'tcx> { fn root_vid(&self, ty: Ty<'tcx>) -> Option { Some(self.root_var(self.shallow_resolve(ty).ty_vid()?)) } + + fn try_to_suggest_annotations( + &self, + diverging_vids: &[ty::TyVid], + coercions: &VecGraph, + ) -> errors::SuggestAnnotations { + let body = + self.tcx.hir().maybe_body_owned_by(self.body_id).expect("body id must have an owner"); + // For each diverging var, look through the HIR for a place to give it + // a type annotation. We do this per var because we only really need one + // per var. + let suggestion_spans = diverging_vids + .iter() + .copied() + .filter_map(|vid| { + let reachable_vids = + graph::depth_first_search_as_undirected(coercions, vid).collect(); + VidVisitor { reachable_vids, fcx: self }.visit_expr(body.value).break_value() + }) + .collect(); + errors::SuggestAnnotations { suggestion_spans } + } +} + +struct VidVisitor<'a, 'tcx> { + reachable_vids: FxHashSet, + fcx: &'a FnCtxt<'a, 'tcx>, +} +impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { + type Result = ControlFlow; + + fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) -> Self::Result { + if let hir::TyKind::Infer = hir_ty.kind + && let ty = self.fcx.typeck_results.borrow().node_type(hir_ty.hir_id) + && let Some(vid) = self.fcx.root_vid(ty) + && self.reachable_vids.contains(&vid) + { + return ControlFlow::Break(hir_ty.span); + } + hir::intravisit::walk_ty(self, hir_ty) + } } #[derive(Debug, Copy, Clone)] diff --git a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr index ec49137ba79..065a6e559c1 100644 --- a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr +++ b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Default` will fail LL | false => <_>::default(), | ^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | false => <()>::default(), + | ~~ warning: this function depends on never type fallback being `()` --> $DIR/dependency-on-fallback-to-unit.rs:19:1 diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr index a75039b8237..b8de1026e37 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr @@ -102,6 +102,10 @@ LL | msg_send!(); = note: for more information, see issue #123748 = help: specify the type explicitly = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use `()` annotations to avoid fallback changes + | +LL | match send_message::<() /* ?0 */>() { + | ~~ warning: 10 warnings emitted diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr index 4138e9f8c86..de44279ff8c 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr @@ -102,6 +102,10 @@ LL | msg_send!(); = note: for more information, see issue #123748 = help: specify the type explicitly = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info) +help: use `()` annotations to avoid fallback changes + | +LL | match send_message::<() /* ?0 */>() { + | ~~ warning: the type `!` does not permit zero-initialization --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18 -- cgit 1.4.1-3-g733a5 From ea4fb7c25cbbd21508dea30aa7f29fbdcc1f149d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 31 Oct 2024 15:59:44 +0000 Subject: Suggest adding self type to method --- compiler/rustc_hir_typeck/src/errors.rs | 25 +++++++++++++++++++--- compiler/rustc_hir_typeck/src/fallback.rs | 25 ++++++++++++++++++---- .../never-type-fallback-breaking.e2021.stderr | 4 ++++ ...verging-fallback-control-flow.nofallback.stderr | 8 +++++++ 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 8fd54593934..2f09e5e163c 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -210,9 +210,15 @@ pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> { pub sugg: SuggestAnnotations, } +#[derive(Clone)] +pub(crate) enum SuggestAnnotation { + Unit(Span), + Path(Span), +} + #[derive(Clone)] pub(crate) struct SuggestAnnotations { - pub suggestion_spans: Vec, + pub suggestions: Vec, } impl Subdiagnostic for SuggestAnnotations { fn add_to_diag_with>( @@ -220,13 +226,26 @@ impl Subdiagnostic for SuggestAnnotations { diag: &mut Diag<'_, G>, _: &F, ) { - if self.suggestion_spans.is_empty() { + if self.suggestions.is_empty() { return; } + let mut suggestions = vec![]; + for suggestion in self.suggestions { + match suggestion { + SuggestAnnotation::Unit(span) => { + suggestions.push((span, "()".to_string())); + } + SuggestAnnotation::Path(span) => { + suggestions.push((span.shrink_to_lo(), "<() as ".to_string())); + suggestions.push((span.shrink_to_hi(), ">".to_string())); + } + } + } + diag.multipart_suggestion_verbose( "use `()` annotations to avoid fallback changes", - self.suggestion_spans.into_iter().map(|span| (span, String::from("()"))).collect(), + suggestions, Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 02efb12f835..d6be237acf4 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -8,6 +8,7 @@ use rustc_data_structures::graph::{self}; use rustc_data_structures::unord::{UnordBag, UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::HirId; +use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::Visitor; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; use rustc_session::lint; @@ -573,7 +574,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // For each diverging var, look through the HIR for a place to give it // a type annotation. We do this per var because we only really need one // per var. - let suggestion_spans = diverging_vids + let suggestions = diverging_vids .iter() .copied() .filter_map(|vid| { @@ -582,16 +583,17 @@ impl<'tcx> FnCtxt<'_, 'tcx> { VidVisitor { reachable_vids, fcx: self }.visit_expr(body.value).break_value() }) .collect(); - errors::SuggestAnnotations { suggestion_spans } + errors::SuggestAnnotations { suggestions } } } +/// Try to collect a useful suggestion to preserve fallback to `()`. struct VidVisitor<'a, 'tcx> { reachable_vids: FxHashSet, fcx: &'a FnCtxt<'a, 'tcx>, } impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { - type Result = ControlFlow; + type Result = ControlFlow; fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) -> Self::Result { if let hir::TyKind::Infer = hir_ty.kind @@ -599,10 +601,25 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { && let Some(vid) = self.fcx.root_vid(ty) && self.reachable_vids.contains(&vid) { - return ControlFlow::Break(hir_ty.span); + return ControlFlow::Break(errors::SuggestAnnotation::Unit(hir_ty.span)); } hir::intravisit::walk_ty(self, hir_ty) } + + fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result { + if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind + && let Res::Def(DefKind::AssocFn, def_id) = path.res + && self.fcx.tcx.trait_of_item(def_id).is_some() + && let self_ty = self.fcx.typeck_results.borrow().node_args(expr.hir_id).type_at(0) + && let Some(vid) = self.fcx.root_vid(self_ty) + && self.reachable_vids.contains(&vid) + && let [.., trait_segment, _method_segment] = path.segments + { + let span = path.span.shrink_to_lo().to(trait_segment.ident.span); + return ControlFlow::Break(errors::SuggestAnnotation::Path(span)); + } + hir::intravisit::walk_expr(self, expr) + } } #[derive(Debug, Copy, Clone)] diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr index 134fd098b7e..703f3d6266c 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Default` will fail LL | true => Default::default(), | ^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | true => <() as Default>::default(), + | ++++++ + warning: this function depends on never type fallback being `()` --> $DIR/never-type-fallback-breaking.rs:27:1 diff --git a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr index 2a3c5edc218..dee112e245a 100644 --- a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: UnitDefault` will fail LL | x = UnitDefault::default(); | ^^^^^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | x = <() as UnitDefault>::default(); + | ++++++ + warning: this function depends on never type fallback being `()` --> $DIR/diverging-fallback-control-flow.rs:42:1 @@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: UnitDefault` will fail | LL | x = UnitDefault::default(); | ^^^^^^^^^^^^^^^^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | x = <() as UnitDefault>::default(); + | ++++++ + warning: 2 warnings emitted -- cgit 1.4.1-3-g733a5 From c930bba2836c1daa4ffa72ce3ec4d3e570ce188e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 31 Oct 2024 16:05:42 +0000 Subject: And locals too --- compiler/rustc_hir_typeck/src/errors.rs | 4 ++++ compiler/rustc_hir_typeck/src/fallback.rs | 13 +++++++++++++ tests/ui/editions/never-type-fallback-breaking.e2021.stderr | 4 ++-- tests/ui/never_type/defaulted-never-note.nofallback.stderr | 4 ++++ .../diverging-fallback-control-flow.nofallback.stderr | 8 ++++---- ...iverging-fallback-unconstrained-return.nofallback.stderr | 4 ++++ 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 2f09e5e163c..fdeeed92565 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -214,6 +214,7 @@ pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> { pub(crate) enum SuggestAnnotation { Unit(Span), Path(Span), + Local(Span), } #[derive(Clone)] @@ -240,6 +241,9 @@ impl Subdiagnostic for SuggestAnnotations { suggestions.push((span.shrink_to_lo(), "<() as ".to_string())); suggestions.push((span.shrink_to_hi(), ">".to_string())); } + SuggestAnnotation::Local(span) => { + suggestions.push((span, ": ()".to_string())); + } } } diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index d6be237acf4..cefc28b400f 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -620,6 +620,19 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { } hir::intravisit::walk_expr(self, expr) } + + fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) -> Self::Result { + if let None = local.ty + && let ty = self.fcx.typeck_results.borrow().node_type(local.hir_id) + && let Some(vid) = self.fcx.root_vid(ty) + && self.reachable_vids.contains(&vid) + { + return ControlFlow::Break(errors::SuggestAnnotation::Local( + local.pat.span.shrink_to_hi(), + )); + } + hir::intravisit::walk_local(self, local) + } } #[derive(Debug, Copy, Clone)] diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr index 703f3d6266c..1c6685261fb 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr @@ -15,8 +15,8 @@ LL | true => Default::default(), = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default help: use `()` annotations to avoid fallback changes | -LL | true => <() as Default>::default(), - | ++++++ + +LL | let x: () = match true { + | ++++ warning: this function depends on never type fallback being `()` --> $DIR/never-type-fallback-breaking.rs:27:1 diff --git a/tests/ui/never_type/defaulted-never-note.nofallback.stderr b/tests/ui/never_type/defaulted-never-note.nofallback.stderr index d88615186dd..6bc4501b6a3 100644 --- a/tests/ui/never_type/defaulted-never-note.nofallback.stderr +++ b/tests/ui/never_type/defaulted-never-note.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will f LL | foo(_x); | ^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | let _x: () = return; + | ++++ warning: 1 warning emitted diff --git a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr index dee112e245a..d40d1da76f9 100644 --- a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr @@ -15,8 +15,8 @@ LL | x = UnitDefault::default(); = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default help: use `()` annotations to avoid fallback changes | -LL | x = <() as UnitDefault>::default(); - | ++++++ + +LL | let x: (); + | ++++ warning: this function depends on never type fallback being `()` --> $DIR/diverging-fallback-control-flow.rs:42:1 @@ -34,8 +34,8 @@ LL | x = UnitDefault::default(); | ^^^^^^^^^^^^^^^^^^^^^^ help: use `()` annotations to avoid fallback changes | -LL | x = <() as UnitDefault>::default(); - | ++++++ + +LL | let x: (); + | ++++ warning: 2 warnings emitted diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr index b485c94df4d..30a5e60a758 100644 --- a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: UnitReturn` will fail LL | let _ = if true { unconstrained_return() } else { panic!() }; | ^^^^^^^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | let _: () = if true { unconstrained_return() } else { panic!() }; + | ++++ warning: 1 warning emitted -- cgit 1.4.1-3-g733a5 From df6f5841e5fcceb2c9ff43035dcede4f35450f5a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 31 Oct 2024 16:58:28 +0000 Subject: And also suggest for qpaths --- compiler/rustc_hir_typeck/src/errors.rs | 11 ++++ compiler/rustc_hir_typeck/src/fallback.rs | 68 ++++++++++++++++++++++ .../never-type-fallback-breaking.e2021.stderr | 4 ++ .../dependency-on-fallback-to-unit.stderr | 4 ++ .../diverging-fallback-no-leak.nofallback.stderr | 4 ++ .../fallback-closure-ret.nofallback.stderr | 4 ++ ...-type-fallback-flowing-into-unsafe.e2015.stderr | 28 +++++++++ ...-type-fallback-flowing-into-unsafe.e2024.stderr | 28 +++++++++ 8 files changed, 151 insertions(+) diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index fdeeed92565..4f579b05d83 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -215,6 +215,7 @@ pub(crate) enum SuggestAnnotation { Unit(Span), Path(Span), Local(Span), + Turbo(Span, usize, usize), } #[derive(Clone)] @@ -244,6 +245,16 @@ impl Subdiagnostic for SuggestAnnotations { SuggestAnnotation::Local(span) => { suggestions.push((span, ": ()".to_string())); } + SuggestAnnotation::Turbo(span, n_args, idx) => suggestions.push(( + span, + format!( + "::<{}>", + (0..n_args) + .map(|i| if i == idx { "()" } else { "_" }) + .collect::>() + .join(", "), + ), + )), } } diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index cefc28b400f..ada716addd0 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -9,6 +9,7 @@ use rustc_data_structures::unord::{UnordBag, UnordMap, UnordSet}; use rustc_hir as hir; use rustc_hir::HirId; use rustc_hir::def::{DefKind, Res}; +use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; use rustc_session::lint; @@ -592,10 +593,45 @@ struct VidVisitor<'a, 'tcx> { reachable_vids: FxHashSet, fcx: &'a FnCtxt<'a, 'tcx>, } +impl<'tcx> VidVisitor<'_, 'tcx> { + fn suggest_for_segment( + &self, + arg_segment: &'tcx hir::PathSegment<'tcx>, + def_id: DefId, + id: HirId, + ) -> ControlFlow { + if arg_segment.args.is_none() + && let Some(all_args) = self.fcx.typeck_results.borrow().node_args_opt(id) + && let generics = self.fcx.tcx.generics_of(def_id) + && let args = &all_args[generics.parent_count..] + // We can't turbofish consts :( + && args.iter().all(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Lifetime(_))) + { + let n_tys = args + .iter() + .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_))) + .count(); + for (idx, arg) in args.iter().enumerate() { + if let Some(ty) = arg.as_type() + && let Some(vid) = self.fcx.root_vid(ty) + && self.reachable_vids.contains(&vid) + { + return ControlFlow::Break(errors::SuggestAnnotation::Turbo( + arg_segment.ident.span.shrink_to_hi(), + n_tys, + idx, + )); + } + } + } + ControlFlow::Continue(()) + } +} impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { type Result = ControlFlow; fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) -> Self::Result { + // Try to replace `_` with `()`. if let hir::TyKind::Infer = hir_ty.kind && let ty = self.fcx.typeck_results.borrow().node_type(hir_ty.hir_id) && let Some(vid) = self.fcx.root_vid(ty) @@ -606,7 +642,32 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { hir::intravisit::walk_ty(self, hir_ty) } + fn visit_qpath( + &mut self, + qpath: &'tcx rustc_hir::QPath<'tcx>, + id: HirId, + _span: Span, + ) -> Self::Result { + let arg_segment = match qpath { + hir::QPath::Resolved(_, path) => { + path.segments.last().expect("paths should have a segment") + } + hir::QPath::TypeRelative(_, segment) => segment, + hir::QPath::LangItem(..) => { + return hir::intravisit::walk_qpath(self, qpath, id); + } + }; + // Alternatively, try to turbofish `::<_, (), _>` (ignoring lifetimes, + // since we don't need to turbofish those; they'll be inferred). + // FIXME: Same logic could work for types... + if let Some(def_id) = self.fcx.typeck_results.borrow().qpath_res(qpath, id).opt_def_id() { + self.suggest_for_segment(arg_segment, def_id, id)?; + } + hir::intravisit::walk_qpath(self, qpath, id) + } + fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result { + // Try to suggest adding an explicit qself `()` to a trait method path. if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let Res::Def(DefKind::AssocFn, def_id) = path.res && self.fcx.tcx.trait_of_item(def_id).is_some() @@ -618,6 +679,13 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { let span = path.span.shrink_to_lo().to(trait_segment.ident.span); return ControlFlow::Break(errors::SuggestAnnotation::Path(span)); } + // Or else turbofishing the method + if let hir::ExprKind::MethodCall(segment, ..) = expr.kind + && let Some(def_id) = + self.fcx.typeck_results.borrow().type_dependent_def_id(expr.hir_id) + { + self.suggest_for_segment(segment, def_id, expr.hir_id)?; + } hir::intravisit::walk_expr(self, expr) } diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr index 1c6685261fb..79eee2a3def 100644 --- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr +++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr @@ -32,6 +32,10 @@ note: in edition 2024, the requirement `!: Default` will fail | LL | deserialize()?; | ^^^^^^^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | deserialize::<()>()?; + | ++++++ warning: 2 warnings emitted diff --git a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr index 065a6e559c1..79f47bb5fbc 100644 --- a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr +++ b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr @@ -32,6 +32,10 @@ note: in edition 2024, the requirement `!: Default` will fail | LL | deserialize()?; | ^^^^^^^^^^^^^ +help: use `()` annotations to avoid fallback changes + | +LL | deserialize::<()>()?; + | ++++++ warning: 2 warnings emitted diff --git a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr index 11245cc7aab..d11c21d9573 100644 --- a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr +++ b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Test` will fail LL | unconstrained_arg(return); | ^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | unconstrained_arg::<()>(return); + | ++++++ warning: 1 warning emitted diff --git a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr index 3fb5536dee7..fb0166dd9e0 100644 --- a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr +++ b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr @@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Bar` will fail LL | foo(|| panic!()); | ^^^^^^^^^^^^^^^^ = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | foo::<(), _>(|| panic!()); + | +++++++++ warning: 1 warning emitted diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr index b8de1026e37..6a48a7b9b47 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr @@ -8,6 +8,10 @@ LL | unsafe { mem::zeroed() } = note: for more information, see issue #123748 = help: specify the type explicitly = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { mem::zeroed::<()>() } + | ++++++ warning: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13 @@ -18,6 +22,10 @@ LL | core::mem::transmute(Zst) = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | core::mem::transmute::<_, ()>(Zst) + | +++++++++ warning: never type fallback affects this union access --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18 @@ -38,6 +46,10 @@ LL | unsafe { *ptr::from_ref(&()).cast() } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { *ptr::from_ref(&()).cast::<()>() } + | ++++++ warning: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18 @@ -48,6 +60,10 @@ LL | unsafe { internally_create(x) } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { internally_create::<()>(x) } + | ++++++ warning: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18 @@ -58,6 +74,10 @@ LL | unsafe { zeroed() } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let zeroed = mem::zeroed::<()>; + | ++++++ warning: never type fallback affects this `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22 @@ -68,6 +88,10 @@ LL | let zeroed = mem::zeroed; = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let zeroed = mem::zeroed::<()>; + | ++++++ warning: never type fallback affects this `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17 @@ -78,6 +102,10 @@ LL | let f = internally_create; = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let f = internally_create::<()>; + | ++++++ warning: never type fallback affects this call to an `unsafe` method --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13 diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr index de44279ff8c..844cd62c267 100644 --- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr +++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr @@ -8,6 +8,10 @@ LL | unsafe { mem::zeroed() } = note: for more information, see issue #123748 = help: specify the type explicitly = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { mem::zeroed::<()>() } + | ++++++ error: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13 @@ -18,6 +22,10 @@ LL | core::mem::transmute(Zst) = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | core::mem::transmute::<_, ()>(Zst) + | +++++++++ error: never type fallback affects this union access --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18 @@ -38,6 +46,10 @@ LL | unsafe { *ptr::from_ref(&()).cast() } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { *ptr::from_ref(&()).cast::<()>() } + | ++++++ error: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18 @@ -48,6 +60,10 @@ LL | unsafe { internally_create(x) } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | unsafe { internally_create::<()>(x) } + | ++++++ error: never type fallback affects this call to an `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18 @@ -58,6 +74,10 @@ LL | unsafe { zeroed() } = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let zeroed = mem::zeroed::<()>; + | ++++++ error: never type fallback affects this `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22 @@ -68,6 +88,10 @@ LL | let zeroed = mem::zeroed; = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let zeroed = mem::zeroed::<()>; + | ++++++ error: never type fallback affects this `unsafe` function --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17 @@ -78,6 +102,10 @@ LL | let f = internally_create; = warning: this will change its meaning in a future release! = note: for more information, see issue #123748 = help: specify the type explicitly +help: use `()` annotations to avoid fallback changes + | +LL | let f = internally_create::<()>; + | ++++++ error: never type fallback affects this call to an `unsafe` method --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13 -- cgit 1.4.1-3-g733a5 From b4248aeec366d31efe595eb5f671f589c849d6a3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 1 Nov 2024 01:46:17 +0000 Subject: nits --- compiler/rustc_hir_typeck/src/fallback.rs | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index ada716addd0..8d8573c65c5 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -565,6 +565,8 @@ impl<'tcx> FnCtxt<'_, 'tcx> { Some(self.root_var(self.shallow_resolve(ty).ty_vid()?)) } + /// Given a set of diverging vids and coercions, walk the HIR to gather a + /// set of suggestions which can be applied to preserve fallback to unit. fn try_to_suggest_annotations( &self, diverging_vids: &[ty::TyVid], @@ -574,26 +576,34 @@ impl<'tcx> FnCtxt<'_, 'tcx> { self.tcx.hir().maybe_body_owned_by(self.body_id).expect("body id must have an owner"); // For each diverging var, look through the HIR for a place to give it // a type annotation. We do this per var because we only really need one - // per var. + // suggestion to influence a var to be `()`. let suggestions = diverging_vids .iter() .copied() .filter_map(|vid| { let reachable_vids = graph::depth_first_search_as_undirected(coercions, vid).collect(); - VidVisitor { reachable_vids, fcx: self }.visit_expr(body.value).break_value() + AnnotateUnitFallbackVisitor { reachable_vids, fcx: self } + .visit_expr(body.value) + .break_value() }) .collect(); errors::SuggestAnnotations { suggestions } } } -/// Try to collect a useful suggestion to preserve fallback to `()`. -struct VidVisitor<'a, 'tcx> { +/// Try to walk the HIR to find a place to insert a useful suggestion +/// to preserve fallback to `()` in 2024. +struct AnnotateUnitFallbackVisitor<'a, 'tcx> { reachable_vids: FxHashSet, fcx: &'a FnCtxt<'a, 'tcx>, } -impl<'tcx> VidVisitor<'_, 'tcx> { +impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> { + // For a given path segment, if it's missing a turbofish, try to suggest adding + // one so we can constrain an argument to `()`. To keep the suggestion simple, + // we want to simply suggest `_` for all the other args. This (for now) only + // works when there are only type variables (and region variables, since we can + // elide them)... fn suggest_for_segment( &self, arg_segment: &'tcx hir::PathSegment<'tcx>, @@ -627,7 +637,7 @@ impl<'tcx> VidVisitor<'_, 'tcx> { ControlFlow::Continue(()) } } -impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { +impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> { type Result = ControlFlow; fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) -> Self::Result { @@ -657,9 +667,7 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { return hir::intravisit::walk_qpath(self, qpath, id); } }; - // Alternatively, try to turbofish `::<_, (), _>` (ignoring lifetimes, - // since we don't need to turbofish those; they'll be inferred). - // FIXME: Same logic could work for types... + // Alternatively, try to turbofish `::<_, (), _>`. if let Some(def_id) = self.fcx.typeck_results.borrow().qpath_res(qpath, id).opt_def_id() { self.suggest_for_segment(arg_segment, def_id, id)?; } @@ -668,6 +676,7 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result { // Try to suggest adding an explicit qself `()` to a trait method path. + // i.e. changing `Default::default()` to `<() as Default>::default()`. if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind && let Res::Def(DefKind::AssocFn, def_id) = path.res && self.fcx.tcx.trait_of_item(def_id).is_some() @@ -679,7 +688,7 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { let span = path.span.shrink_to_lo().to(trait_segment.ident.span); return ControlFlow::Break(errors::SuggestAnnotation::Path(span)); } - // Or else turbofishing the method + // Or else, try suggesting turbofishing the method args. if let hir::ExprKind::MethodCall(segment, ..) = expr.kind && let Some(def_id) = self.fcx.typeck_results.borrow().type_dependent_def_id(expr.hir_id) @@ -690,6 +699,7 @@ impl<'tcx> Visitor<'tcx> for VidVisitor<'_, 'tcx> { } fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) -> Self::Result { + // For a local, try suggest annotating the type if it's missing. if let None = local.ty && let ty = self.fcx.typeck_results.borrow().node_type(local.hir_id) && let Some(vid) = self.fcx.root_vid(ty) -- cgit 1.4.1-3-g733a5 From 3afbe4f9c72ebd153e767b96a4efe422c91d6903 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 31 Oct 2024 21:24:31 -0500 Subject: Add `f16` and `f128` to `invalid_nan_comparison` Currently `f32_nan` and `f64_nan` are used to provide the `invalid_nan_comparison` lint. Since we have `f16_nan` and `f128_nan`, hook these up so the new float types get the same lints. --- compiler/rustc_lint/src/types.rs | 5 +- .../lint/invalid-nan-comparison-suggestion.fixed | 14 ++ tests/ui/lint/invalid-nan-comparison-suggestion.rs | 14 ++ .../lint/invalid-nan-comparison-suggestion.stderr | 70 ++++++-- tests/ui/lint/invalid-nan-comparison.rs | 46 ++++++ tests/ui/lint/invalid-nan-comparison.stderr | 180 ++++++++++++++++++--- 6 files changed, 299 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 88878a018e7..48dd8e38a03 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -204,7 +204,10 @@ fn lint_nan<'tcx>( return false; }; - matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::f32_nan | sym::f64_nan)) + matches!( + cx.tcx.get_diagnostic_name(def_id), + Some(sym::f16_nan | sym::f32_nan | sym::f64_nan | sym::f128_nan) + ) } _ => false, } diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.fixed b/tests/ui/lint/invalid-nan-comparison-suggestion.fixed index 46b2d4e9c3f..2d88c274080 100644 --- a/tests/ui/lint/invalid-nan-comparison-suggestion.fixed +++ b/tests/ui/lint/invalid-nan-comparison-suggestion.fixed @@ -1,7 +1,15 @@ //@ check-pass //@ run-rustfix +#![feature(f16, f128)] + fn main() { + let x = 5f16; + let _ = x.is_nan(); + //~^ WARN incorrect NaN comparison + let _ = !x.is_nan(); + //~^ WARN incorrect NaN comparison + let x = 5f32; let _ = x.is_nan(); //~^ WARN incorrect NaN comparison @@ -14,6 +22,12 @@ fn main() { let _ = !x.is_nan(); //~^ WARN incorrect NaN comparison + let x = 5f128; + let _ = x.is_nan(); + //~^ WARN incorrect NaN comparison + let _ = !x.is_nan(); + //~^ WARN incorrect NaN comparison + let b = &2.3f32; if !b.is_nan() {} //~^ WARN incorrect NaN comparison diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.rs b/tests/ui/lint/invalid-nan-comparison-suggestion.rs index 558b433d794..91753447869 100644 --- a/tests/ui/lint/invalid-nan-comparison-suggestion.rs +++ b/tests/ui/lint/invalid-nan-comparison-suggestion.rs @@ -1,7 +1,15 @@ //@ check-pass //@ run-rustfix +#![feature(f16, f128)] + fn main() { + let x = 5f16; + let _ = x == f16::NAN; + //~^ WARN incorrect NaN comparison + let _ = x != f16::NAN; + //~^ WARN incorrect NaN comparison + let x = 5f32; let _ = x == f32::NAN; //~^ WARN incorrect NaN comparison @@ -14,6 +22,12 @@ fn main() { let _ = x != f64::NAN; //~^ WARN incorrect NaN comparison + let x = 5f128; + let _ = x == f128::NAN; + //~^ WARN incorrect NaN comparison + let _ = x != f128::NAN; + //~^ WARN incorrect NaN comparison + let b = &2.3f32; if b != &f32::NAN {} //~^ WARN incorrect NaN comparison diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.stderr b/tests/ui/lint/invalid-nan-comparison-suggestion.stderr index c310341de07..9d07d3f9240 100644 --- a/tests/ui/lint/invalid-nan-comparison-suggestion.stderr +++ b/tests/ui/lint/invalid-nan-comparison-suggestion.stderr @@ -1,18 +1,42 @@ warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:6:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:8:13 | -LL | let _ = x == f32::NAN; +LL | let _ = x == f16::NAN; | ^^^^^^^^^^^^^ | = note: `#[warn(invalid_nan_comparisons)]` on by default help: use `f32::is_nan()` or `f64::is_nan()` instead | +LL - let _ = x == f16::NAN; +LL + let _ = x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison-suggestion.rs:10:13 + | +LL | let _ = x != f16::NAN; + | ^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - let _ = x != f16::NAN; +LL + let _ = !x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison-suggestion.rs:14:13 + | +LL | let _ = x == f32::NAN; + | ^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | LL - let _ = x == f32::NAN; LL + let _ = x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:8:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:16:13 | LL | let _ = x != f32::NAN; | ^^^^^^^^^^^^^ @@ -24,7 +48,7 @@ LL + let _ = !x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:12:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:20:13 | LL | let _ = x == f64::NAN; | ^^^^^^^^^^^^^ @@ -36,7 +60,7 @@ LL + let _ = x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:14:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:22:13 | LL | let _ = x != f64::NAN; | ^^^^^^^^^^^^^ @@ -48,7 +72,31 @@ LL + let _ = !x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:18:8 + --> $DIR/invalid-nan-comparison-suggestion.rs:26:13 + | +LL | let _ = x == f128::NAN; + | ^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - let _ = x == f128::NAN; +LL + let _ = x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison-suggestion.rs:28:13 + | +LL | let _ = x != f128::NAN; + | ^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - let _ = x != f128::NAN; +LL + let _ = !x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison-suggestion.rs:32:8 | LL | if b != &f32::NAN {} | ^^^^^^^^^^^^^^ @@ -60,7 +108,7 @@ LL + if !b.is_nan() {} | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:22:8 + --> $DIR/invalid-nan-comparison-suggestion.rs:36:8 | LL | if b != { &f32::NAN } {} | ^^^^^^^^^^^^^^^^^^ @@ -72,7 +120,7 @@ LL + if !b.is_nan() {} | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:26:9 + --> $DIR/invalid-nan-comparison-suggestion.rs:40:9 | LL | / b != { LL | | @@ -87,7 +135,7 @@ LL + !b.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:35:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:49:13 | LL | let _ = nan!() == number!(); | ^^^^^^^^^^^^^^^^^^^ @@ -99,7 +147,7 @@ LL + let _ = number!().is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison-suggestion.rs:37:13 + --> $DIR/invalid-nan-comparison-suggestion.rs:51:13 | LL | let _ = number!() != nan!(); | ^^^^^^^^^^^^^^^^^^^ @@ -110,5 +158,5 @@ LL - let _ = number!() != nan!(); LL + let _ = !number!().is_nan(); | -warning: 9 warnings emitted +warning: 13 warnings emitted diff --git a/tests/ui/lint/invalid-nan-comparison.rs b/tests/ui/lint/invalid-nan-comparison.rs index 202a5e27e8e..1a2c8a7c5a0 100644 --- a/tests/ui/lint/invalid-nan-comparison.rs +++ b/tests/ui/lint/invalid-nan-comparison.rs @@ -1,13 +1,38 @@ //@ check-pass +#![feature(f16, f128)] + fn main() { + f16(); f32(); f64(); + f128(); } const TEST: bool = 5f32 == f32::NAN; //~^ WARN incorrect NaN comparison +fn f16() { + macro_rules! number { () => { 5f16 }; } + let x = number!(); + x == f16::NAN; + //~^ WARN incorrect NaN comparison + x != f16::NAN; + //~^ WARN incorrect NaN comparison + x < f16::NAN; + //~^ WARN incorrect NaN comparison + x > f16::NAN; + //~^ WARN incorrect NaN comparison + x <= f16::NAN; + //~^ WARN incorrect NaN comparison + x >= f16::NAN; + //~^ WARN incorrect NaN comparison + number!() == f16::NAN; + //~^ WARN incorrect NaN comparison + f16::NAN != number!(); + //~^ WARN incorrect NaN comparison +} + fn f32() { macro_rules! number { () => { 5f32 }; } let x = number!(); @@ -49,3 +74,24 @@ fn f64() { f64::NAN != number!(); //~^ WARN incorrect NaN comparison } + +fn f128() { + macro_rules! number { () => { 5f128 }; } + let x = number!(); + x == f128::NAN; + //~^ WARN incorrect NaN comparison + x != f128::NAN; + //~^ WARN incorrect NaN comparison + x < f128::NAN; + //~^ WARN incorrect NaN comparison + x > f128::NAN; + //~^ WARN incorrect NaN comparison + x <= f128::NAN; + //~^ WARN incorrect NaN comparison + x >= f128::NAN; + //~^ WARN incorrect NaN comparison + number!() == f128::NAN; + //~^ WARN incorrect NaN comparison + f128::NAN != number!(); + //~^ WARN incorrect NaN comparison +} diff --git a/tests/ui/lint/invalid-nan-comparison.stderr b/tests/ui/lint/invalid-nan-comparison.stderr index 054c06d38b3..486d2a9636c 100644 --- a/tests/ui/lint/invalid-nan-comparison.stderr +++ b/tests/ui/lint/invalid-nan-comparison.stderr @@ -1,5 +1,5 @@ warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:8:20 + --> $DIR/invalid-nan-comparison.rs:12:20 | LL | const TEST: bool = 5f32 == f32::NAN; | ^^^^^^^^^^^^^^^^ @@ -12,7 +12,79 @@ LL + const TEST: bool = 5f32.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:14:5 + --> $DIR/invalid-nan-comparison.rs:18:5 + | +LL | x == f16::NAN; + | ^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - x == f16::NAN; +LL + x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:20:5 + | +LL | x != f16::NAN; + | ^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - x != f16::NAN; +LL + !x.is_nan(); + | + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:22:5 + | +LL | x < f16::NAN; + | ^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:24:5 + | +LL | x > f16::NAN; + | ^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:26:5 + | +LL | x <= f16::NAN; + | ^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:28:5 + | +LL | x >= f16::NAN; + | ^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:30:5 + | +LL | number!() == f16::NAN; + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - number!() == f16::NAN; +LL + number!().is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:32:5 + | +LL | f16::NAN != number!(); + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - f16::NAN != number!(); +LL + !number!().is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:39:5 | LL | x == f32::NAN; | ^^^^^^^^^^^^^ @@ -24,7 +96,7 @@ LL + x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:16:5 + --> $DIR/invalid-nan-comparison.rs:41:5 | LL | x != f32::NAN; | ^^^^^^^^^^^^^ @@ -36,31 +108,31 @@ LL + !x.is_nan(); | warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:18:5 + --> $DIR/invalid-nan-comparison.rs:43:5 | LL | x < f32::NAN; | ^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:20:5 + --> $DIR/invalid-nan-comparison.rs:45:5 | LL | x > f32::NAN; | ^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:22:5 + --> $DIR/invalid-nan-comparison.rs:47:5 | LL | x <= f32::NAN; | ^^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:24:5 + --> $DIR/invalid-nan-comparison.rs:49:5 | LL | x >= f32::NAN; | ^^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:26:5 + --> $DIR/invalid-nan-comparison.rs:51:5 | LL | number!() == f32::NAN; | ^^^^^^^^^^^^^^^^^^^^^ @@ -72,7 +144,7 @@ LL + number!().is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:28:5 + --> $DIR/invalid-nan-comparison.rs:53:5 | LL | f32::NAN != number!(); | ^^^^^^^^^^^^^^^^^^^^^ @@ -84,7 +156,7 @@ LL + !number!().is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:35:5 + --> $DIR/invalid-nan-comparison.rs:60:5 | LL | x == f64::NAN; | ^^^^^^^^^^^^^ @@ -96,7 +168,7 @@ LL + x.is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:37:5 + --> $DIR/invalid-nan-comparison.rs:62:5 | LL | x != f64::NAN; | ^^^^^^^^^^^^^ @@ -108,31 +180,31 @@ LL + !x.is_nan(); | warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:39:5 + --> $DIR/invalid-nan-comparison.rs:64:5 | LL | x < f64::NAN; | ^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:41:5 + --> $DIR/invalid-nan-comparison.rs:66:5 | LL | x > f64::NAN; | ^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:43:5 + --> $DIR/invalid-nan-comparison.rs:68:5 | LL | x <= f64::NAN; | ^^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN is not orderable - --> $DIR/invalid-nan-comparison.rs:45:5 + --> $DIR/invalid-nan-comparison.rs:70:5 | LL | x >= f64::NAN; | ^^^^^^^^^^^^^ warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:47:5 + --> $DIR/invalid-nan-comparison.rs:72:5 | LL | number!() == f64::NAN; | ^^^^^^^^^^^^^^^^^^^^^ @@ -144,7 +216,7 @@ LL + number!().is_nan(); | warning: incorrect NaN comparison, NaN cannot be directly compared to itself - --> $DIR/invalid-nan-comparison.rs:49:5 + --> $DIR/invalid-nan-comparison.rs:74:5 | LL | f64::NAN != number!(); | ^^^^^^^^^^^^^^^^^^^^^ @@ -155,5 +227,77 @@ LL - f64::NAN != number!(); LL + !number!().is_nan(); | -warning: 17 warnings emitted +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:81:5 + | +LL | x == f128::NAN; + | ^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - x == f128::NAN; +LL + x.is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:83:5 + | +LL | x != f128::NAN; + | ^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - x != f128::NAN; +LL + !x.is_nan(); + | + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:85:5 + | +LL | x < f128::NAN; + | ^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:87:5 + | +LL | x > f128::NAN; + | ^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:89:5 + | +LL | x <= f128::NAN; + | ^^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN is not orderable + --> $DIR/invalid-nan-comparison.rs:91:5 + | +LL | x >= f128::NAN; + | ^^^^^^^^^^^^^^ + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:93:5 + | +LL | number!() == f128::NAN; + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - number!() == f128::NAN; +LL + number!().is_nan(); + | + +warning: incorrect NaN comparison, NaN cannot be directly compared to itself + --> $DIR/invalid-nan-comparison.rs:95:5 + | +LL | f128::NAN != number!(); + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: use `f32::is_nan()` or `f64::is_nan()` instead + | +LL - f128::NAN != number!(); +LL + !number!().is_nan(); + | + +warning: 33 warnings emitted -- cgit 1.4.1-3-g733a5 From b6a49d8969de0f15406815761bcaffda8ce6b797 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 1 Nov 2024 10:15:08 +0800 Subject: Remove unncessary option for default rust-analyzer setting --- src/bootstrap/src/core/build_steps/setup.rs | 1 + src/etc/rust_analyzer_settings.json | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs index 51964977933..704fa46ab1e 100644 --- a/src/bootstrap/src/core/build_steps/setup.rs +++ b/src/bootstrap/src/core/build_steps/setup.rs @@ -571,6 +571,7 @@ Select which editor you would like to set up [default: None]: "; "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a", "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000", "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d", + "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4", ], EditorKind::Emacs => vec![ "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0", diff --git a/src/etc/rust_analyzer_settings.json b/src/etc/rust_analyzer_settings.json index a20105f0ef3..d1b186fd316 100644 --- a/src/etc/rust_analyzer_settings.json +++ b/src/etc/rust_analyzer_settings.json @@ -1,6 +1,5 @@ { "git.detectSubmodulesLimit": 20, - "rust-analyzer.check.invocationLocation": "root", "rust-analyzer.check.invocationStrategy": "once", "rust-analyzer.check.overrideCommand": [ "python3", @@ -24,7 +23,6 @@ "rust-analyzer.procMacro.server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv", "rust-analyzer.procMacro.enable": true, "rust-analyzer.cargo.buildScripts.enable": true, - "rust-analyzer.cargo.buildScripts.invocationLocation": "root", "rust-analyzer.cargo.buildScripts.invocationStrategy": "once", "rust-analyzer.cargo.buildScripts.overrideCommand": [ "python3", -- cgit 1.4.1-3-g733a5 From 5342eb05975ce7632fca97a83a0775c95c0d76f1 Mon Sep 17 00:00:00 2001 From: chengehe Date: Fri, 1 Nov 2024 16:53:36 +0800 Subject: Add missing backtick --- tests/ui/consts/promote-not.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ui/consts/promote-not.rs b/tests/ui/consts/promote-not.rs index 80912937f31..207baccd6ab 100644 --- a/tests/ui/consts/promote-not.rs +++ b/tests/ui/consts/promote-not.rs @@ -23,7 +23,7 @@ pub const fn promote_cal(b: bool) -> i32 { 13 } -// We do not promote union field accesses in `fn. +// We do not promote union field accesses in `fn`. union U { x: i32, y: i32 } pub const fn promote_union() { let _x: &'static i32 = &unsafe { U { x: 0 }.x }; //~ ERROR temporary value dropped while borrowed -- cgit 1.4.1-3-g733a5 From 760338526f8a7d7238682fca6b776b28412fd528 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Mon, 7 Oct 2024 10:25:58 +0200 Subject: Show actual MIR when MIR building forgot to terminate block This makes it significantly easier to debug bugs of this kind. --- compiler/rustc_middle/src/mir/pretty.rs | 46 ++++++++++++++++--------------- compiler/rustc_mir_build/src/build/mod.rs | 23 ++++++++++++---- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index e690bf74b6b..80ae5a7146d 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -762,33 +762,35 @@ where // Terminator at the bottom. extra_data(PassWhere::BeforeLocation(current_location), w)?; - let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind); - if options.include_extra_comments { - writeln!( + if data.terminator.is_some() { + let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind); + if options.include_extra_comments { + writeln!( + w, + "{:A$} // {}{}", + indented_terminator, + if tcx.sess.verbose_internals() { + format!("{current_location:?}: ") + } else { + String::new() + }, + comment(tcx, data.terminator().source_info), + A = ALIGN, + )?; + } else { + writeln!(w, "{indented_terminator}")?; + } + + write_extra( + tcx, w, - "{:A$} // {}{}", - indented_terminator, - if tcx.sess.verbose_internals() { - format!("{current_location:?}: ") - } else { - String::new() + |visitor| { + visitor.visit_terminator(data.terminator(), current_location); }, - comment(tcx, data.terminator().source_info), - A = ALIGN, + options, )?; - } else { - writeln!(w, "{indented_terminator}")?; } - write_extra( - tcx, - w, - |visitor| { - visitor.visit_terminator(data.terminator(), current_location); - }, - options, - )?; - extra_data(PassWhere::AfterLocation(current_location), w)?; extra_data(PassWhere::AfterTerminator(block), w)?; diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 1f853f6e1c3..46be2aee637 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -791,12 +791,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } fn finish(self) -> Body<'tcx> { - for (index, block) in self.cfg.basic_blocks.iter().enumerate() { - if block.terminator.is_none() { - span_bug!(self.fn_span, "no terminator on block {:?}", index); - } - } - let mut body = Body::new( MirSource::item(self.def_id.to_def_id()), self.cfg.basic_blocks, @@ -810,6 +804,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None, ); body.coverage_info_hi = self.coverage_info.map(|b| b.into_done()); + + for (index, block) in body.basic_blocks.iter().enumerate() { + if block.terminator.is_none() { + use rustc_middle::mir::pretty; + let options = pretty::PrettyPrintMirOptions::from_cli(self.tcx); + pretty::write_mir_fn( + self.tcx, + &body, + &mut |_, _| Ok(()), + &mut std::io::stdout(), + options, + ) + .unwrap(); + span_bug!(self.fn_span, "no terminator on block {:?}", index); + } + } + body } -- cgit 1.4.1-3-g733a5 From 506812d0873c084139b6e9b81040e22f874d4fdc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Nov 2024 11:47:04 +0100 Subject: remove some unnecessary rustc_allow_const_fn_unstable --- library/core/src/mem/maybe_uninit.rs | 3 --- library/core/src/num/nonzero.rs | 1 - library/core/src/ptr/mod.rs | 1 - library/core/src/slice/mod.rs | 2 -- library/core/src/str/mod.rs | 1 - 5 files changed, 8 deletions(-) diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index b4252ef0103..a57e265c7cc 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -390,9 +390,6 @@ impl MaybeUninit { #[must_use] #[rustc_diagnostic_item = "maybe_uninit_zeroed"] #[stable(feature = "maybe_uninit", since = "1.36.0")] - // These are OK to allow since we do not leak &mut to user-visible API - #[rustc_allow_const_fn_unstable(const_mut_refs)] - #[rustc_allow_const_fn_unstable(const_ptr_write)] #[rustc_const_stable(feature = "const_maybe_uninit_zeroed", since = "1.75.0")] pub const fn zeroed() -> MaybeUninit { let mut u = MaybeUninit::::uninit(); diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index f6e271954fe..f04c83693ef 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1475,7 +1475,6 @@ macro_rules! nonzero_integer_signedness_dependent_methods { /// ``` #[unstable(feature = "num_midpoint", issue = "110840")] #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")] - #[rustc_allow_const_fn_unstable(const_num_midpoint)] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index e9f5bf4404e..7c2205fdcd1 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -844,7 +844,6 @@ pub const fn from_ref(r: &T) -> *const T { #[must_use] #[stable(feature = "ptr_from_ref", since = "1.76.0")] #[rustc_const_stable(feature = "ptr_from_ref", since = "1.76.0")] -#[rustc_allow_const_fn_unstable(const_mut_refs)] #[rustc_never_returns_null_ptr] pub const fn from_mut(r: &mut T) -> *mut T { r diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 27e51afa800..52d2179b04d 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -764,7 +764,6 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - #[rustc_allow_const_fn_unstable(const_mut_refs)] #[rustc_never_returns_null_ptr] #[inline(always)] #[must_use] @@ -1867,7 +1866,6 @@ impl [T] { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_split_at_not_mut", since = "1.71.0")] - #[rustc_allow_const_fn_unstable(split_at_checked)] #[inline] #[track_caller] #[must_use] diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 9ef99e9dae8..f25d8c642a8 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -761,7 +761,6 @@ impl str { #[must_use] #[stable(feature = "split_at_checked", since = "1.80.0")] #[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")] - #[rustc_allow_const_fn_unstable(const_is_char_boundary)] pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { -- cgit 1.4.1-3-g733a5 From 901b340c1f5d208561d4261cc3ee634973b35326 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Nov 2024 08:38:03 +0100 Subject: unchecked_shifts, unchecked_neg are safe-to-const-expose-on-stable, so we can get rid of a bunch of attributes --- library/core/src/num/int_macros.rs | 16 +++++++--------- library/core/src/num/uint_macros.rs | 14 ++++++-------- library/core/src/ptr/const_ptr.rs | 2 +- library/core/src/ptr/mut_ptr.rs | 2 +- library/core/src/ptr/non_null.rs | 2 +- 5 files changed, 16 insertions(+), 20 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 3a9060df286..72adb1bf190 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1161,7 +1161,7 @@ macro_rules! int_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_neg", issue = "85122")] + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_neg", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_neg(self) -> Self { @@ -1227,8 +1227,7 @@ macro_rules! int_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - // We could always go back to wrapping - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1294,7 +1293,7 @@ macro_rules! int_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")] + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { @@ -1353,8 +1352,7 @@ macro_rules! int_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - // We could always go back to wrapping - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1420,7 +1418,7 @@ macro_rules! int_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")] + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { @@ -2151,7 +2149,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shl(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds @@ -2181,7 +2179,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shr(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index eb4ea4b3c40..ded8997c634 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1416,8 +1416,7 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - // We could always go back to wrapping - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1483,7 +1482,7 @@ macro_rules! uint_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")] + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { @@ -1542,8 +1541,7 @@ macro_rules! uint_impl { /// ``` #[stable(feature = "wrapping", since = "1.7.0")] #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")] - // We could always go back to wrapping - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -1609,7 +1607,7 @@ macro_rules! uint_impl { )] #[must_use = "this returns the result of the operation, \ without modifying the original"] - #[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")] + #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { @@ -2132,7 +2130,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shl(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds @@ -2165,7 +2163,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[rustc_allow_const_fn_unstable(unchecked_shifts)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))] pub const fn wrapping_shr(self, rhs: u32) -> Self { // SAFETY: the masking by the bitsize of the type ensures that we do not shift // out of bounds diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 75d681d76df..1195f38ab6f 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -1005,7 +1005,7 @@ impl *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - #[rustc_allow_const_fn_unstable(unchecked_neg)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 408e722267a..60d47d7eb1a 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1085,7 +1085,7 @@ impl *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] - #[rustc_allow_const_fn_unstable(unchecked_neg)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))] #[inline(always)] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub const unsafe fn sub(self, count: usize) -> Self diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 86ef1f3f005..1d7a1e7b2f0 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -635,7 +635,7 @@ impl NonNull { #[must_use = "returns a new pointer rather than modifying its argument"] #[stable(feature = "non_null_convenience", since = "1.80.0")] #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_allow_const_fn_unstable(unchecked_neg)] + #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))] pub const unsafe fn sub(self, count: usize) -> Self where T: Sized, -- cgit 1.4.1-3-g733a5 From 96e7eaf478f53cdf417ad681d2afa07b00abbdfd Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 1 Nov 2024 22:12:55 +0900 Subject: Move remaining inline assembly test files into asm directory --- tests/assembly/asm-comments.rs | 12 ---- tests/assembly/asm/comments.rs | 12 ++++ tests/codegen/asm-arm64ec-clobbers.rs | 36 ----------- tests/codegen/asm-clobber_abi.rs | 36 ----------- tests/codegen/asm-clobbers.rs | 20 ------ tests/codegen/asm-goto.rs | 51 --------------- tests/codegen/asm-may_unwind.rs | 39 ------------ tests/codegen/asm-maybe-uninit.rs | 27 -------- tests/codegen/asm-msp430-clobbers.rs | 36 ----------- tests/codegen/asm-multiple-options.rs | 54 ---------------- tests/codegen/asm-options.rs | 104 ------------------------------- tests/codegen/asm-powerpc-clobbers.rs | 47 -------------- tests/codegen/asm-s390x-clobbers.rs | 50 --------------- tests/codegen/asm-sanitize-llvm.rs | 30 --------- tests/codegen/asm-target-clobbers.rs | 29 --------- tests/codegen/asm/arm64ec-clobbers.rs | 36 +++++++++++ tests/codegen/asm/foo.s | 3 + tests/codegen/asm/global_asm.rs | 28 +++++++++ tests/codegen/asm/global_asm_include.rs | 21 +++++++ tests/codegen/asm/global_asm_x2.rs | 47 ++++++++++++++ tests/codegen/asm/goto.rs | 51 +++++++++++++++ tests/codegen/asm/may_unwind.rs | 39 ++++++++++++ tests/codegen/asm/maybe-uninit.rs | 27 ++++++++ tests/codegen/asm/msp430-clobbers.rs | 36 +++++++++++ tests/codegen/asm/multiple-options.rs | 54 ++++++++++++++++ tests/codegen/asm/options.rs | 104 +++++++++++++++++++++++++++++++ tests/codegen/asm/powerpc-clobbers.rs | 47 ++++++++++++++ tests/codegen/asm/s390x-clobbers.rs | 50 +++++++++++++++ tests/codegen/asm/sanitize-llvm.rs | 30 +++++++++ tests/codegen/asm/x86-clobber_abi.rs | 36 +++++++++++ tests/codegen/asm/x86-clobbers.rs | 20 ++++++ tests/codegen/asm/x86-target-clobbers.rs | 29 +++++++++ tests/codegen/foo.s | 3 - tests/codegen/global_asm.rs | 28 --------- tests/codegen/global_asm_include.rs | 21 ------- tests/codegen/global_asm_x2.rs | 47 -------------- 36 files changed, 670 insertions(+), 670 deletions(-) delete mode 100644 tests/assembly/asm-comments.rs create mode 100644 tests/assembly/asm/comments.rs delete mode 100644 tests/codegen/asm-arm64ec-clobbers.rs delete mode 100644 tests/codegen/asm-clobber_abi.rs delete mode 100644 tests/codegen/asm-clobbers.rs delete mode 100644 tests/codegen/asm-goto.rs delete mode 100644 tests/codegen/asm-may_unwind.rs delete mode 100644 tests/codegen/asm-maybe-uninit.rs delete mode 100644 tests/codegen/asm-msp430-clobbers.rs delete mode 100644 tests/codegen/asm-multiple-options.rs delete mode 100644 tests/codegen/asm-options.rs delete mode 100644 tests/codegen/asm-powerpc-clobbers.rs delete mode 100644 tests/codegen/asm-s390x-clobbers.rs delete mode 100644 tests/codegen/asm-sanitize-llvm.rs delete mode 100644 tests/codegen/asm-target-clobbers.rs create mode 100644 tests/codegen/asm/arm64ec-clobbers.rs create mode 100644 tests/codegen/asm/foo.s create mode 100644 tests/codegen/asm/global_asm.rs create mode 100644 tests/codegen/asm/global_asm_include.rs create mode 100644 tests/codegen/asm/global_asm_x2.rs create mode 100644 tests/codegen/asm/goto.rs create mode 100644 tests/codegen/asm/may_unwind.rs create mode 100644 tests/codegen/asm/maybe-uninit.rs create mode 100644 tests/codegen/asm/msp430-clobbers.rs create mode 100644 tests/codegen/asm/multiple-options.rs create mode 100644 tests/codegen/asm/options.rs create mode 100644 tests/codegen/asm/powerpc-clobbers.rs create mode 100644 tests/codegen/asm/s390x-clobbers.rs create mode 100644 tests/codegen/asm/sanitize-llvm.rs create mode 100644 tests/codegen/asm/x86-clobber_abi.rs create mode 100644 tests/codegen/asm/x86-clobbers.rs create mode 100644 tests/codegen/asm/x86-target-clobbers.rs delete mode 100644 tests/codegen/foo.s delete mode 100644 tests/codegen/global_asm.rs delete mode 100644 tests/codegen/global_asm_include.rs delete mode 100644 tests/codegen/global_asm_x2.rs diff --git a/tests/assembly/asm-comments.rs b/tests/assembly/asm-comments.rs deleted file mode 100644 index 557009975dd..00000000000 --- a/tests/assembly/asm-comments.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ assembly-output: emit-asm -//@ only-x86_64 -// Check that comments in assembly get passed - -#![crate_type = "lib"] - -// CHECK-LABEL: test_comments: -#[no_mangle] -pub fn test_comments() { - // CHECK: example comment - unsafe { core::arch::asm!("nop // example comment") }; -} diff --git a/tests/assembly/asm/comments.rs b/tests/assembly/asm/comments.rs new file mode 100644 index 00000000000..557009975dd --- /dev/null +++ b/tests/assembly/asm/comments.rs @@ -0,0 +1,12 @@ +//@ assembly-output: emit-asm +//@ only-x86_64 +// Check that comments in assembly get passed + +#![crate_type = "lib"] + +// CHECK-LABEL: test_comments: +#[no_mangle] +pub fn test_comments() { + // CHECK: example comment + unsafe { core::arch::asm!("nop // example comment") }; +} diff --git a/tests/codegen/asm-arm64ec-clobbers.rs b/tests/codegen/asm-arm64ec-clobbers.rs deleted file mode 100644 index 2ec61907947..00000000000 --- a/tests/codegen/asm-arm64ec-clobbers.rs +++ /dev/null @@ -1,36 +0,0 @@ -//@ assembly-output: emit-asm -//@ compile-flags: --target arm64ec-pc-windows-msvc -//@ needs-llvm-components: aarch64 - -#![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] -#![no_core] - -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} - -// CHECK-LABEL: @cc_clobber -// CHECK: call void asm sideeffect "", "~{cc}"() -#[no_mangle] -pub unsafe fn cc_clobber() { - asm!("", options(nostack, nomem)); -} - -// CHECK-LABEL: @no_clobber -// CHECK: call void asm sideeffect "", ""() -#[no_mangle] -pub unsafe fn no_clobber() { - asm!("", options(nostack, nomem, preserves_flags)); -} - -// CHECK-LABEL: @clobber_abi -// CHECK: asm sideeffect "", "={w0},={w1},={w2},={w3},={w4},={w5},={w6},={w7},={w8},={w9},={w10},={w11},={w12},={w15},={w16},={w17},={w30},={q0},={q1},={q2},={q3},={q4},={q5},={q6},={q7},={q8},={q9},={q10},={q11},={q12},={q13},={q14},={q15}"() -#[no_mangle] -pub unsafe fn clobber_abi() { - asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); -} diff --git a/tests/codegen/asm-clobber_abi.rs b/tests/codegen/asm-clobber_abi.rs deleted file mode 100644 index cc563474bf8..00000000000 --- a/tests/codegen/asm-clobber_abi.rs +++ /dev/null @@ -1,36 +0,0 @@ -//@ compile-flags: -O -//@ only-x86_64 - -#![crate_type = "rlib"] - -use std::arch::asm; - -// CHECK-LABEL: @clobber_sysv64 -// CHECK: ={ax},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{tmm0},~{tmm1},~{tmm2},~{tmm3},~{tmm4},~{tmm5},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags},~{memory} -#[no_mangle] -pub unsafe fn clobber_sysv64() { - asm!("", clobber_abi("sysv64")); -} - -// CHECK-LABEL: @clobber_win64 -// CHECK: ={ax},={cx},={dx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{tmm0},~{tmm1},~{tmm2},~{tmm3},~{tmm4},~{tmm5},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags},~{memory} -#[no_mangle] -pub unsafe fn clobber_win64() { - asm!("", clobber_abi("win64")); -} - -// CHECK-LABEL: @clobber_sysv64 -// CHECK: =&{dx},={ax},={cx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{tmm0},~{tmm1},~{tmm2},~{tmm3},~{tmm4},~{tmm5},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags},~{memory} -#[no_mangle] -pub unsafe fn clobber_sysv64_edx() { - let foo: i32; - asm!("", out("edx") foo, clobber_abi("sysv64")); -} - -// CHECK-LABEL: @clobber_win64 -// CHECK: =&{dx},={ax},={cx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{tmm0},~{tmm1},~{tmm2},~{tmm3},~{tmm4},~{tmm5},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags},~{memory} -#[no_mangle] -pub unsafe fn clobber_win64_edx() { - let foo: i32; - asm!("", out("edx") foo, clobber_abi("win64")); -} diff --git a/tests/codegen/asm-clobbers.rs b/tests/codegen/asm-clobbers.rs deleted file mode 100644 index 4094db74134..00000000000 --- a/tests/codegen/asm-clobbers.rs +++ /dev/null @@ -1,20 +0,0 @@ -//@ compile-flags: -O -//@ only-x86_64 - -#![crate_type = "rlib"] - -use std::arch::asm; - -// CHECK-LABEL: @x87_clobber -// CHECK: ~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)} -#[no_mangle] -pub unsafe fn x87_clobber() { - asm!("foo", out("st") _); -} - -// CHECK-LABEL: @mmx_clobber -// CHECK: ~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)} -#[no_mangle] -pub unsafe fn mmx_clobber() { - asm!("bar", out("mm0") _, out("mm1") _); -} diff --git a/tests/codegen/asm-goto.rs b/tests/codegen/asm-goto.rs deleted file mode 100644 index e522d0da5b4..00000000000 --- a/tests/codegen/asm-goto.rs +++ /dev/null @@ -1,51 +0,0 @@ -//@ compile-flags: -O -//@ only-x86_64 - -#![crate_type = "rlib"] -#![feature(asm_goto)] - -use std::arch::asm; - -#[no_mangle] -pub extern "C" fn panicky() {} - -struct Foo; - -impl Drop for Foo { - fn drop(&mut self) { - println!(); - } -} - -// CHECK-LABEL: @asm_goto -#[no_mangle] -pub unsafe fn asm_goto() { - // CHECK: callbr void asm sideeffect alignstack inteldialect " - // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]] - asm!("jmp {}", label {}); -} - -// CHECK-LABEL: @asm_goto_with_outputs -#[no_mangle] -pub unsafe fn asm_goto_with_outputs() -> u64 { - let out: u64; - // CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect " - // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]] - asm!("{} /* {} */", out(reg) out, label { return 1; }); - // CHECK: [[JUMPBB]]: - // CHECK-NEXT: [[RET:%.+]] = phi i64 [ [[RES]], %[[FALLTHROUGHBB]] ], [ 1, %start ] - // CHECK-NEXT: ret i64 [[RET]] - out -} - -// CHECK-LABEL: @asm_goto_noreturn -#[no_mangle] -pub unsafe fn asm_goto_noreturn() -> u64 { - let out: u64; - // CHECK: callbr void asm sideeffect alignstack inteldialect " - // CHECK-NEXT: to label %unreachable [label %[[JUMPBB:[a-b0-9]+]]] - asm!("jmp {}", label { return 1; }, options(noreturn)); - // CHECK: [[JUMPBB]]: - // CHECK-NEXT: ret i64 1 - out -} diff --git a/tests/codegen/asm-may_unwind.rs b/tests/codegen/asm-may_unwind.rs deleted file mode 100644 index be66b3975ff..00000000000 --- a/tests/codegen/asm-may_unwind.rs +++ /dev/null @@ -1,39 +0,0 @@ -//@ compile-flags: -O -//@ only-x86_64 - -#![crate_type = "rlib"] -#![feature(asm_unwind)] - -use std::arch::asm; - -#[no_mangle] -pub extern "C" fn panicky() {} - -struct Foo; - -impl Drop for Foo { - fn drop(&mut self) { - println!(); - } -} - -// CHECK-LABEL: @asm_may_unwind -#[no_mangle] -pub unsafe fn asm_may_unwind() { - let _m = Foo; - // CHECK: invoke void asm sideeffect alignstack inteldialect unwind "" - asm!("", options(may_unwind)); -} - -// CHECK-LABEL: @asm_with_result_may_unwind -#[no_mangle] -pub unsafe fn asm_with_result_may_unwind() -> u64 { - let _m = Foo; - let res: u64; - // CHECK: [[RES:%[0-9]+]] = invoke i64 asm sideeffect alignstack inteldialect unwind - // CHECK-NEXT: to label %[[NORMALBB:[a-b0-9]+]] - asm!("mov {}, 1", out(reg) res, options(may_unwind)); - // CHECK: [[NORMALBB]]: - // CHECK: ret i64 [[RES:%[0-9]+]] - res -} diff --git a/tests/codegen/asm-maybe-uninit.rs b/tests/codegen/asm-maybe-uninit.rs deleted file mode 100644 index 55813c35a46..00000000000 --- a/tests/codegen/asm-maybe-uninit.rs +++ /dev/null @@ -1,27 +0,0 @@ -//@ compile-flags: -O -//@ only-x86_64 - -#![crate_type = "rlib"] -#![allow(asm_sub_register)] - -use std::arch::asm; -use std::mem::MaybeUninit; - -// CHECK-LABEL: @int -#[no_mangle] -pub unsafe fn int(x: MaybeUninit) -> MaybeUninit { - let y: MaybeUninit; - asm!("/*{}{}*/", in(reg) x, out(reg) y); - y -} - -// CHECK-LABEL: @inout -#[no_mangle] -pub unsafe fn inout(mut x: i32) -> MaybeUninit { - let mut y: MaybeUninit; - asm!("/*{}*/", inout(reg) x => y); - asm!("/*{}*/", inout(reg) y => x); - asm!("/*{}*/", inlateout(reg) x => y); - asm!("/*{}*/", inlateout(reg) y => x); - y -} diff --git a/tests/codegen/asm-msp430-clobbers.rs b/tests/codegen/asm-msp430-clobbers.rs deleted file mode 100644 index c00c04f3088..00000000000 --- a/tests/codegen/asm-msp430-clobbers.rs +++ /dev/null @@ -1,36 +0,0 @@ -//@ assembly-output: emit-asm -//@ compile-flags: --target msp430-none-elf -//@ needs-llvm-components: msp430 - -#![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] -#![no_core] - -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} - -// CHECK-LABEL: @sr_clobber -// CHECK: call void asm sideeffect "", "~{sr}"() -#[no_mangle] -pub unsafe fn sr_clobber() { - asm!("", options(nostack, nomem)); -} - -// CHECK-LABEL: @no_clobber -// CHECK: call void asm sideeffect "", ""() -#[no_mangle] -pub unsafe fn no_clobber() { - asm!("", options(nostack, nomem, preserves_flags)); -} - -// CHECK-LABEL: @clobber_abi -// CHECK: asm sideeffect "", "={r11},={r12},={r13},={r14},={r15}"() -#[no_mangle] -pub unsafe fn clobber_abi() { - asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); -} diff --git a/tests/codegen/asm-multiple-options.rs b/tests/codegen/asm-multiple-options.rs deleted file mode 100644 index 1ee295e32c9..00000000000 --- a/tests/codegen/asm-multiple-options.rs +++ /dev/null @@ -1,54 +0,0 @@ -//@ compile-flags: -O -//@ only-x86_64 - -#![crate_type = "rlib"] - -use std::arch::asm; - -// CHECK-LABEL: @pure -// CHECK-NOT: asm -// CHECK: ret void -#[no_mangle] -pub unsafe fn pure(x: i32) { - let y: i32; - asm!("", out("ax") y, in("cx") x, options(pure), options(nomem)); -} - -pub static mut VAR: i32 = 0; -pub static mut DUMMY_OUTPUT: i32 = 0; - -// CHECK-LABEL: @readonly -// CHECK: call i32 asm -// CHECK: ret i32 1 -#[no_mangle] -pub unsafe fn readonly() -> i32 { - VAR = 1; - asm!("", out("ax") DUMMY_OUTPUT, options(pure), options(readonly)); - VAR -} - -// CHECK-LABEL: @nomem -// CHECK-NOT: store -// CHECK: call i32 asm -// CHECK: store -// CHECK: ret i32 2 -#[no_mangle] -pub unsafe fn nomem() -> i32 { - VAR = 1; - asm!("", out("ax") DUMMY_OUTPUT, options(pure), options(nomem)); - VAR = 2; - VAR -} - -// CHECK-LABEL: @not_nomem -// CHECK: store -// CHECK: call i32 asm -// CHECK: store -// CHECK: ret i32 2 -#[no_mangle] -pub unsafe fn not_nomem() -> i32 { - VAR = 1; - asm!("", out("ax") DUMMY_OUTPUT, options(pure), options(readonly)); - VAR = 2; - VAR -} diff --git a/tests/codegen/asm-options.rs b/tests/codegen/asm-options.rs deleted file mode 100644 index 96a72c2f5ae..00000000000 --- a/tests/codegen/asm-options.rs +++ /dev/null @@ -1,104 +0,0 @@ -//@ compile-flags: -O -//@ only-x86_64 - -#![crate_type = "rlib"] - -use std::arch::asm; - -// CHECK-LABEL: @pure -// CHECK-NOT: asm -// CHECK: ret void -#[no_mangle] -pub unsafe fn pure(x: i32) { - let y: i32; - asm!("", out("ax") y, in("cx") x, options(pure, nomem)); -} - -// CHECK-LABEL: @noreturn -// CHECK: call void asm -// CHECK-NEXT: unreachable -#[no_mangle] -pub unsafe fn noreturn() { - asm!("", options(noreturn)); -} - -pub static mut VAR: i32 = 0; -pub static mut DUMMY_OUTPUT: i32 = 0; - -// CHECK-LABEL: @readonly -// CHECK: call i32 asm -// CHECK: ret i32 1 -#[no_mangle] -pub unsafe fn readonly() -> i32 { - VAR = 1; - asm!("", out("ax") DUMMY_OUTPUT, options(pure, readonly)); - VAR -} - -// CHECK-LABEL: @not_readonly -// CHECK: call i32 asm -// CHECK: ret i32 % -#[no_mangle] -pub unsafe fn not_readonly() -> i32 { - VAR = 1; - asm!("", out("ax") DUMMY_OUTPUT, options()); - VAR -} - -// CHECK-LABEL: @nomem -// CHECK-NOT: store -// CHECK: call i32 asm -// CHECK: store -// CHECK: ret i32 2 -#[no_mangle] -pub unsafe fn nomem() -> i32 { - VAR = 1; - asm!("", out("ax") DUMMY_OUTPUT, options(pure, nomem)); - VAR = 2; - VAR -} - -// CHECK-LABEL: @nomem_nopure -// CHECK-NOT: store -// CHECK: call i32 asm -// CHECK: store -// CHECK: ret i32 2 -#[no_mangle] -pub unsafe fn nomem_nopure() -> i32 { - VAR = 1; - asm!("", out("ax") DUMMY_OUTPUT, options(nomem)); - VAR = 2; - VAR -} - -// CHECK-LABEL: @not_nomem -// CHECK: store -// CHECK: call i32 asm -// CHECK: store -// CHECK: ret i32 2 -#[no_mangle] -pub unsafe fn not_nomem() -> i32 { - VAR = 1; - asm!("", out("ax") DUMMY_OUTPUT, options(pure, readonly)); - VAR = 2; - VAR -} - -// CHECK-LABEL: @dont_remove_nonpure -// CHECK: call void asm -// CHECK: call void asm -// CHECK: call void asm -// CHECK: ret void -#[no_mangle] -pub unsafe fn dont_remove_nonpure() { - asm!("", options()); - asm!("", options(nomem)); - asm!("", options(readonly)); -} - -// CHECK-LABEL: @raw -// CHECK: call void asm sideeffect inteldialect "{} {}", ""() -#[no_mangle] -pub unsafe fn raw() { - asm!("{} {}", options(nostack, nomem, preserves_flags, raw)); -} diff --git a/tests/codegen/asm-powerpc-clobbers.rs b/tests/codegen/asm-powerpc-clobbers.rs deleted file mode 100644 index 0be1b66bd99..00000000000 --- a/tests/codegen/asm-powerpc-clobbers.rs +++ /dev/null @@ -1,47 +0,0 @@ -//@ revisions: powerpc powerpc64 powerpc64le -//@[powerpc] compile-flags: --target powerpc-unknown-linux-gnu -//@[powerpc] needs-llvm-components: powerpc -//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu -//@[powerpc64] needs-llvm-components: powerpc -//@[powerpc64le] compile-flags: --target powerpc64le-unknown-linux-gnu -//@[powerpc64le] needs-llvm-components: powerpc - -#![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] -#![no_core] - -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} - -// CHECK-LABEL: @cr_clobber -// CHECK: call void asm sideeffect "", "~{cr}"() -#[no_mangle] -pub unsafe fn cr_clobber() { - asm!("", out("cr") _, options(nostack, nomem)); -} - -// CHECK-LABEL: @cr0_clobber -// CHECK: call void asm sideeffect "", "~{cr0}"() -#[no_mangle] -pub unsafe fn cr0_clobber() { - asm!("", out("cr0") _, options(nostack, nomem)); -} - -// CHECK-LABEL: @cr5_clobber -// CHECK: call void asm sideeffect "", "~{cr5}"() -#[no_mangle] -pub unsafe fn cr5_clobber() { - asm!("", out("cr5") _, options(nostack, nomem)); -} - -// CHECK-LABEL: @xer_clobber -// CHECK: call void asm sideeffect "", "~{xer}"() -#[no_mangle] -pub unsafe fn xer_clobber() { - asm!("", out("xer") _, options(nostack, nomem)); -} diff --git a/tests/codegen/asm-s390x-clobbers.rs b/tests/codegen/asm-s390x-clobbers.rs deleted file mode 100644 index 45f72206bdf..00000000000 --- a/tests/codegen/asm-s390x-clobbers.rs +++ /dev/null @@ -1,50 +0,0 @@ -//@ revisions: s390x -//@[s390x] compile-flags: --target s390x-unknown-linux-gnu -//@[s390x] needs-llvm-components: systemz - -#![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] -#![no_core] - -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} - -// CHECK-LABEL: @cc_clobber -// CHECK: call void asm sideeffect "", "~{cc}"() -#[no_mangle] -pub unsafe fn cc_clobber() { - asm!("", options(nostack, nomem)); -} - -// CHECK-LABEL: @no_clobber -// CHECK: call void asm sideeffect "", ""() -#[no_mangle] -pub unsafe fn no_clobber() { - asm!("", options(nostack, nomem, preserves_flags)); -} - -// CHECK-LABEL: @a2_clobber -// CHECK: call void asm sideeffect "", "~{a2}"() -#[no_mangle] -pub unsafe fn a2_clobber() { - asm!("", out("a2") _, options(nostack, nomem, preserves_flags)); -} - -// CHECK-LABEL: @v0_clobber -// CHECK: call void asm sideeffect "", "~{v0}"() -#[no_mangle] -pub unsafe fn v0_clobber() { - asm!("", out("v0") _, options(nostack, nomem, preserves_flags)); -} - -// CHECK-LABEL: @clobber_abi -// CHECK: asm sideeffect "", "={r0},={r1},={r2},={r3},={r4},={r5},={r14},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{a2},~{a3},~{a4},~{a5},~{a6},~{a7},~{a8},~{a9},~{a10},~{a11},~{a12},~{a13},~{a14},~{a15}"() -#[no_mangle] -pub unsafe fn clobber_abi() { - asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); -} diff --git a/tests/codegen/asm-sanitize-llvm.rs b/tests/codegen/asm-sanitize-llvm.rs deleted file mode 100644 index fb332f9a0f3..00000000000 --- a/tests/codegen/asm-sanitize-llvm.rs +++ /dev/null @@ -1,30 +0,0 @@ -// FIXME(nagisa): remove the flags below once all targets support `asm!`. -//@ compile-flags: --target x86_64-unknown-linux-gnu -Copt-level=0 -//@ needs-llvm-components: x86 - -// Verify we sanitize the special tokens for the LLVM inline-assembly, ensuring people won't -// inadvertently rely on the LLVM-specific syntax and features. -#![no_core] -#![feature(no_core, lang_items, rustc_attrs)] -#![crate_type = "rlib"] -#![allow(named_asm_labels)] - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} - -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} - -pub unsafe fn we_escape_dollar_signs() { - // CHECK: call void asm sideeffect alignstack inteldialect "banana$$:" - asm!(r"banana$:",) -} - -pub unsafe fn we_escape_escapes_too() { - // CHECK: call void asm sideeffect alignstack inteldialect "banana\{{(\\|5C)}}36:" - asm!(r"banana\36:",) -} diff --git a/tests/codegen/asm-target-clobbers.rs b/tests/codegen/asm-target-clobbers.rs deleted file mode 100644 index 119372491ff..00000000000 --- a/tests/codegen/asm-target-clobbers.rs +++ /dev/null @@ -1,29 +0,0 @@ -//@ only-x86_64 -//@ revisions: base avx512 -//@ [avx512]compile-flags: -C target-feature=+avx512f - -#![crate_type = "rlib"] - -use std::arch::asm; - -// CHECK-LABEL: @amx_clobber -// base: call void asm sideeffect inteldialect "", "~{tmm0}"() -#[no_mangle] -pub unsafe fn amx_clobber() { - asm!("", out("tmm0") _, options(nostack, nomem, preserves_flags)); -} - -// CHECK-LABEL: @avx512_clobber -// base: call void asm sideeffect inteldialect "", "~{xmm31}"() -// avx512: call float asm sideeffect inteldialect "", "=&{xmm31}"() -#[no_mangle] -pub unsafe fn avx512_clobber() { - asm!("", out("zmm31") _, options(nostack, nomem, preserves_flags)); -} - -// CHECK-LABEL: @eax_clobber -// CHECK: call i32 asm sideeffect inteldialect "", "=&{ax}"() -#[no_mangle] -pub unsafe fn eax_clobber() { - asm!("", out("eax") _, options(nostack, nomem, preserves_flags)); -} diff --git a/tests/codegen/asm/arm64ec-clobbers.rs b/tests/codegen/asm/arm64ec-clobbers.rs new file mode 100644 index 00000000000..2ec61907947 --- /dev/null +++ b/tests/codegen/asm/arm64ec-clobbers.rs @@ -0,0 +1,36 @@ +//@ assembly-output: emit-asm +//@ compile-flags: --target arm64ec-pc-windows-msvc +//@ needs-llvm-components: aarch64 + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @cc_clobber +// CHECK: call void asm sideeffect "", "~{cc}"() +#[no_mangle] +pub unsafe fn cc_clobber() { + asm!("", options(nostack, nomem)); +} + +// CHECK-LABEL: @no_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn no_clobber() { + asm!("", options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @clobber_abi +// CHECK: asm sideeffect "", "={w0},={w1},={w2},={w3},={w4},={w5},={w6},={w7},={w8},={w9},={w10},={w11},={w12},={w15},={w16},={w17},={w30},={q0},={q1},={q2},={q3},={q4},={q5},={q6},={q7},={q8},={q9},={q10},={q11},={q12},={q13},={q14},={q15}"() +#[no_mangle] +pub unsafe fn clobber_abi() { + asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); +} diff --git a/tests/codegen/asm/foo.s b/tests/codegen/asm/foo.s new file mode 100644 index 00000000000..304d82aa0c6 --- /dev/null +++ b/tests/codegen/asm/foo.s @@ -0,0 +1,3 @@ +.global foo +foo: + jmp baz diff --git a/tests/codegen/asm/global_asm.rs b/tests/codegen/asm/global_asm.rs new file mode 100644 index 00000000000..32075daa3cf --- /dev/null +++ b/tests/codegen/asm/global_asm.rs @@ -0,0 +1,28 @@ +//@ revisions: x32 x64 +//@[x32] only-x86 +//@[x64] only-x86_64 +//@ compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +use std::arch::global_asm; + +// CHECK-LABEL: foo +// CHECK: module asm +// this regex will capture the correct unconditional branch inst. +// CHECK: module asm "{{[[:space:]]+}}jmp baz" +global_asm!( + r#" + .global foo +foo: + jmp baz +"# +); + +extern "C" { + fn foo(); +} + +// CHECK-LABEL: @baz +#[no_mangle] +pub unsafe extern "C" fn baz() {} diff --git a/tests/codegen/asm/global_asm_include.rs b/tests/codegen/asm/global_asm_include.rs new file mode 100644 index 00000000000..98be9c3e333 --- /dev/null +++ b/tests/codegen/asm/global_asm_include.rs @@ -0,0 +1,21 @@ +//@ revisions: x32 x64 +//@[x32] only-x86 +//@[x64] only-x86_64 +//@ compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] + +use std::arch::global_asm; + +// CHECK-LABEL: foo +// CHECK: module asm +// CHECK: module asm "{{[[:space:]]+}}jmp baz" +global_asm!(include_str!("foo.s")); + +extern "C" { + fn foo(); +} + +// CHECK-LABEL: @baz +#[no_mangle] +pub unsafe extern "C" fn baz() {} diff --git a/tests/codegen/asm/global_asm_x2.rs b/tests/codegen/asm/global_asm_x2.rs new file mode 100644 index 00000000000..9e3a00f0680 --- /dev/null +++ b/tests/codegen/asm/global_asm_x2.rs @@ -0,0 +1,47 @@ +//@ revisions: x32 x64 +//@[x32] only-x86 +//@[x64] only-x86_64 +//@ compile-flags: -C no-prepopulate-passes + +#![crate_type = "lib"] +#![no_std] + +use core::arch::global_asm; + +// CHECK-LABEL: foo +// CHECK: module asm +// CHECK: module asm "{{[[:space:]]+}}jmp baz" +// any other global_asm will be appended to this first block, so: +// CHECK-LABEL: bar +// CHECK: module asm "{{[[:space:]]+}}jmp quux" +global_asm!( + r#" + .global foo +foo: + jmp baz +"# +); + +extern "C" { + fn foo(); +} + +// CHECK-LABEL: @baz +#[no_mangle] +pub unsafe extern "C" fn baz() {} + +// no checks here; this has been appended to the first occurrence +global_asm!( + r#" + .global bar +bar: + jmp quux +"# +); + +extern "C" { + fn bar(); +} + +#[no_mangle] +pub unsafe extern "C" fn quux() {} diff --git a/tests/codegen/asm/goto.rs b/tests/codegen/asm/goto.rs new file mode 100644 index 00000000000..e522d0da5b4 --- /dev/null +++ b/tests/codegen/asm/goto.rs @@ -0,0 +1,51 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] +#![feature(asm_goto)] + +use std::arch::asm; + +#[no_mangle] +pub extern "C" fn panicky() {} + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) { + println!(); + } +} + +// CHECK-LABEL: @asm_goto +#[no_mangle] +pub unsafe fn asm_goto() { + // CHECK: callbr void asm sideeffect alignstack inteldialect " + // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]] + asm!("jmp {}", label {}); +} + +// CHECK-LABEL: @asm_goto_with_outputs +#[no_mangle] +pub unsafe fn asm_goto_with_outputs() -> u64 { + let out: u64; + // CHECK: [[RES:%[0-9]+]] = callbr i64 asm sideeffect alignstack inteldialect " + // CHECK-NEXT: to label %[[FALLTHROUGHBB:[a-b0-9]+]] [label %[[JUMPBB:[a-b0-9]+]]] + asm!("{} /* {} */", out(reg) out, label { return 1; }); + // CHECK: [[JUMPBB]]: + // CHECK-NEXT: [[RET:%.+]] = phi i64 [ [[RES]], %[[FALLTHROUGHBB]] ], [ 1, %start ] + // CHECK-NEXT: ret i64 [[RET]] + out +} + +// CHECK-LABEL: @asm_goto_noreturn +#[no_mangle] +pub unsafe fn asm_goto_noreturn() -> u64 { + let out: u64; + // CHECK: callbr void asm sideeffect alignstack inteldialect " + // CHECK-NEXT: to label %unreachable [label %[[JUMPBB:[a-b0-9]+]]] + asm!("jmp {}", label { return 1; }, options(noreturn)); + // CHECK: [[JUMPBB]]: + // CHECK-NEXT: ret i64 1 + out +} diff --git a/tests/codegen/asm/may_unwind.rs b/tests/codegen/asm/may_unwind.rs new file mode 100644 index 00000000000..be66b3975ff --- /dev/null +++ b/tests/codegen/asm/may_unwind.rs @@ -0,0 +1,39 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] +#![feature(asm_unwind)] + +use std::arch::asm; + +#[no_mangle] +pub extern "C" fn panicky() {} + +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) { + println!(); + } +} + +// CHECK-LABEL: @asm_may_unwind +#[no_mangle] +pub unsafe fn asm_may_unwind() { + let _m = Foo; + // CHECK: invoke void asm sideeffect alignstack inteldialect unwind "" + asm!("", options(may_unwind)); +} + +// CHECK-LABEL: @asm_with_result_may_unwind +#[no_mangle] +pub unsafe fn asm_with_result_may_unwind() -> u64 { + let _m = Foo; + let res: u64; + // CHECK: [[RES:%[0-9]+]] = invoke i64 asm sideeffect alignstack inteldialect unwind + // CHECK-NEXT: to label %[[NORMALBB:[a-b0-9]+]] + asm!("mov {}, 1", out(reg) res, options(may_unwind)); + // CHECK: [[NORMALBB]]: + // CHECK: ret i64 [[RES:%[0-9]+]] + res +} diff --git a/tests/codegen/asm/maybe-uninit.rs b/tests/codegen/asm/maybe-uninit.rs new file mode 100644 index 00000000000..55813c35a46 --- /dev/null +++ b/tests/codegen/asm/maybe-uninit.rs @@ -0,0 +1,27 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] +#![allow(asm_sub_register)] + +use std::arch::asm; +use std::mem::MaybeUninit; + +// CHECK-LABEL: @int +#[no_mangle] +pub unsafe fn int(x: MaybeUninit) -> MaybeUninit { + let y: MaybeUninit; + asm!("/*{}{}*/", in(reg) x, out(reg) y); + y +} + +// CHECK-LABEL: @inout +#[no_mangle] +pub unsafe fn inout(mut x: i32) -> MaybeUninit { + let mut y: MaybeUninit; + asm!("/*{}*/", inout(reg) x => y); + asm!("/*{}*/", inout(reg) y => x); + asm!("/*{}*/", inlateout(reg) x => y); + asm!("/*{}*/", inlateout(reg) y => x); + y +} diff --git a/tests/codegen/asm/msp430-clobbers.rs b/tests/codegen/asm/msp430-clobbers.rs new file mode 100644 index 00000000000..c00c04f3088 --- /dev/null +++ b/tests/codegen/asm/msp430-clobbers.rs @@ -0,0 +1,36 @@ +//@ assembly-output: emit-asm +//@ compile-flags: --target msp430-none-elf +//@ needs-llvm-components: msp430 + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @sr_clobber +// CHECK: call void asm sideeffect "", "~{sr}"() +#[no_mangle] +pub unsafe fn sr_clobber() { + asm!("", options(nostack, nomem)); +} + +// CHECK-LABEL: @no_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn no_clobber() { + asm!("", options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @clobber_abi +// CHECK: asm sideeffect "", "={r11},={r12},={r13},={r14},={r15}"() +#[no_mangle] +pub unsafe fn clobber_abi() { + asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); +} diff --git a/tests/codegen/asm/multiple-options.rs b/tests/codegen/asm/multiple-options.rs new file mode 100644 index 00000000000..1ee295e32c9 --- /dev/null +++ b/tests/codegen/asm/multiple-options.rs @@ -0,0 +1,54 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] + +use std::arch::asm; + +// CHECK-LABEL: @pure +// CHECK-NOT: asm +// CHECK: ret void +#[no_mangle] +pub unsafe fn pure(x: i32) { + let y: i32; + asm!("", out("ax") y, in("cx") x, options(pure), options(nomem)); +} + +pub static mut VAR: i32 = 0; +pub static mut DUMMY_OUTPUT: i32 = 0; + +// CHECK-LABEL: @readonly +// CHECK: call i32 asm +// CHECK: ret i32 1 +#[no_mangle] +pub unsafe fn readonly() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(pure), options(readonly)); + VAR +} + +// CHECK-LABEL: @nomem +// CHECK-NOT: store +// CHECK: call i32 asm +// CHECK: store +// CHECK: ret i32 2 +#[no_mangle] +pub unsafe fn nomem() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(pure), options(nomem)); + VAR = 2; + VAR +} + +// CHECK-LABEL: @not_nomem +// CHECK: store +// CHECK: call i32 asm +// CHECK: store +// CHECK: ret i32 2 +#[no_mangle] +pub unsafe fn not_nomem() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(pure), options(readonly)); + VAR = 2; + VAR +} diff --git a/tests/codegen/asm/options.rs b/tests/codegen/asm/options.rs new file mode 100644 index 00000000000..96a72c2f5ae --- /dev/null +++ b/tests/codegen/asm/options.rs @@ -0,0 +1,104 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] + +use std::arch::asm; + +// CHECK-LABEL: @pure +// CHECK-NOT: asm +// CHECK: ret void +#[no_mangle] +pub unsafe fn pure(x: i32) { + let y: i32; + asm!("", out("ax") y, in("cx") x, options(pure, nomem)); +} + +// CHECK-LABEL: @noreturn +// CHECK: call void asm +// CHECK-NEXT: unreachable +#[no_mangle] +pub unsafe fn noreturn() { + asm!("", options(noreturn)); +} + +pub static mut VAR: i32 = 0; +pub static mut DUMMY_OUTPUT: i32 = 0; + +// CHECK-LABEL: @readonly +// CHECK: call i32 asm +// CHECK: ret i32 1 +#[no_mangle] +pub unsafe fn readonly() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(pure, readonly)); + VAR +} + +// CHECK-LABEL: @not_readonly +// CHECK: call i32 asm +// CHECK: ret i32 % +#[no_mangle] +pub unsafe fn not_readonly() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options()); + VAR +} + +// CHECK-LABEL: @nomem +// CHECK-NOT: store +// CHECK: call i32 asm +// CHECK: store +// CHECK: ret i32 2 +#[no_mangle] +pub unsafe fn nomem() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(pure, nomem)); + VAR = 2; + VAR +} + +// CHECK-LABEL: @nomem_nopure +// CHECK-NOT: store +// CHECK: call i32 asm +// CHECK: store +// CHECK: ret i32 2 +#[no_mangle] +pub unsafe fn nomem_nopure() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(nomem)); + VAR = 2; + VAR +} + +// CHECK-LABEL: @not_nomem +// CHECK: store +// CHECK: call i32 asm +// CHECK: store +// CHECK: ret i32 2 +#[no_mangle] +pub unsafe fn not_nomem() -> i32 { + VAR = 1; + asm!("", out("ax") DUMMY_OUTPUT, options(pure, readonly)); + VAR = 2; + VAR +} + +// CHECK-LABEL: @dont_remove_nonpure +// CHECK: call void asm +// CHECK: call void asm +// CHECK: call void asm +// CHECK: ret void +#[no_mangle] +pub unsafe fn dont_remove_nonpure() { + asm!("", options()); + asm!("", options(nomem)); + asm!("", options(readonly)); +} + +// CHECK-LABEL: @raw +// CHECK: call void asm sideeffect inteldialect "{} {}", ""() +#[no_mangle] +pub unsafe fn raw() { + asm!("{} {}", options(nostack, nomem, preserves_flags, raw)); +} diff --git a/tests/codegen/asm/powerpc-clobbers.rs b/tests/codegen/asm/powerpc-clobbers.rs new file mode 100644 index 00000000000..0be1b66bd99 --- /dev/null +++ b/tests/codegen/asm/powerpc-clobbers.rs @@ -0,0 +1,47 @@ +//@ revisions: powerpc powerpc64 powerpc64le +//@[powerpc] compile-flags: --target powerpc-unknown-linux-gnu +//@[powerpc] needs-llvm-components: powerpc +//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu +//@[powerpc64] needs-llvm-components: powerpc +//@[powerpc64le] compile-flags: --target powerpc64le-unknown-linux-gnu +//@[powerpc64le] needs-llvm-components: powerpc + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @cr_clobber +// CHECK: call void asm sideeffect "", "~{cr}"() +#[no_mangle] +pub unsafe fn cr_clobber() { + asm!("", out("cr") _, options(nostack, nomem)); +} + +// CHECK-LABEL: @cr0_clobber +// CHECK: call void asm sideeffect "", "~{cr0}"() +#[no_mangle] +pub unsafe fn cr0_clobber() { + asm!("", out("cr0") _, options(nostack, nomem)); +} + +// CHECK-LABEL: @cr5_clobber +// CHECK: call void asm sideeffect "", "~{cr5}"() +#[no_mangle] +pub unsafe fn cr5_clobber() { + asm!("", out("cr5") _, options(nostack, nomem)); +} + +// CHECK-LABEL: @xer_clobber +// CHECK: call void asm sideeffect "", "~{xer}"() +#[no_mangle] +pub unsafe fn xer_clobber() { + asm!("", out("xer") _, options(nostack, nomem)); +} diff --git a/tests/codegen/asm/s390x-clobbers.rs b/tests/codegen/asm/s390x-clobbers.rs new file mode 100644 index 00000000000..45f72206bdf --- /dev/null +++ b/tests/codegen/asm/s390x-clobbers.rs @@ -0,0 +1,50 @@ +//@ revisions: s390x +//@[s390x] compile-flags: --target s390x-unknown-linux-gnu +//@[s390x] needs-llvm-components: systemz + +#![crate_type = "rlib"] +#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +// CHECK-LABEL: @cc_clobber +// CHECK: call void asm sideeffect "", "~{cc}"() +#[no_mangle] +pub unsafe fn cc_clobber() { + asm!("", options(nostack, nomem)); +} + +// CHECK-LABEL: @no_clobber +// CHECK: call void asm sideeffect "", ""() +#[no_mangle] +pub unsafe fn no_clobber() { + asm!("", options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @a2_clobber +// CHECK: call void asm sideeffect "", "~{a2}"() +#[no_mangle] +pub unsafe fn a2_clobber() { + asm!("", out("a2") _, options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @v0_clobber +// CHECK: call void asm sideeffect "", "~{v0}"() +#[no_mangle] +pub unsafe fn v0_clobber() { + asm!("", out("v0") _, options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @clobber_abi +// CHECK: asm sideeffect "", "={r0},={r1},={r2},={r3},={r4},={r5},={r14},={f0},={f1},={f2},={f3},={f4},={f5},={f6},={f7},~{v0},~{v1},~{v2},~{v3},~{v4},~{v5},~{v6},~{v7},~{v8},~{v9},~{v10},~{v11},~{v12},~{v13},~{v14},~{v15},~{v16},~{v17},~{v18},~{v19},~{v20},~{v21},~{v22},~{v23},~{v24},~{v25},~{v26},~{v27},~{v28},~{v29},~{v30},~{v31},~{a2},~{a3},~{a4},~{a5},~{a6},~{a7},~{a8},~{a9},~{a10},~{a11},~{a12},~{a13},~{a14},~{a15}"() +#[no_mangle] +pub unsafe fn clobber_abi() { + asm!("", clobber_abi("C"), options(nostack, nomem, preserves_flags)); +} diff --git a/tests/codegen/asm/sanitize-llvm.rs b/tests/codegen/asm/sanitize-llvm.rs new file mode 100644 index 00000000000..fb332f9a0f3 --- /dev/null +++ b/tests/codegen/asm/sanitize-llvm.rs @@ -0,0 +1,30 @@ +// FIXME(nagisa): remove the flags below once all targets support `asm!`. +//@ compile-flags: --target x86_64-unknown-linux-gnu -Copt-level=0 +//@ needs-llvm-components: x86 + +// Verify we sanitize the special tokens for the LLVM inline-assembly, ensuring people won't +// inadvertently rely on the LLVM-specific syntax and features. +#![no_core] +#![feature(no_core, lang_items, rustc_attrs)] +#![crate_type = "rlib"] +#![allow(named_asm_labels)] + +#[rustc_builtin_macro] +macro_rules! asm { + () => {}; +} + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +pub unsafe fn we_escape_dollar_signs() { + // CHECK: call void asm sideeffect alignstack inteldialect "banana$$:" + asm!(r"banana$:",) +} + +pub unsafe fn we_escape_escapes_too() { + // CHECK: call void asm sideeffect alignstack inteldialect "banana\{{(\\|5C)}}36:" + asm!(r"banana\36:",) +} diff --git a/tests/codegen/asm/x86-clobber_abi.rs b/tests/codegen/asm/x86-clobber_abi.rs new file mode 100644 index 00000000000..cc563474bf8 --- /dev/null +++ b/tests/codegen/asm/x86-clobber_abi.rs @@ -0,0 +1,36 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] + +use std::arch::asm; + +// CHECK-LABEL: @clobber_sysv64 +// CHECK: ={ax},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{tmm0},~{tmm1},~{tmm2},~{tmm3},~{tmm4},~{tmm5},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags},~{memory} +#[no_mangle] +pub unsafe fn clobber_sysv64() { + asm!("", clobber_abi("sysv64")); +} + +// CHECK-LABEL: @clobber_win64 +// CHECK: ={ax},={cx},={dx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{tmm0},~{tmm1},~{tmm2},~{tmm3},~{tmm4},~{tmm5},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags},~{memory} +#[no_mangle] +pub unsafe fn clobber_win64() { + asm!("", clobber_abi("win64")); +} + +// CHECK-LABEL: @clobber_sysv64 +// CHECK: =&{dx},={ax},={cx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{tmm0},~{tmm1},~{tmm2},~{tmm3},~{tmm4},~{tmm5},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags},~{memory} +#[no_mangle] +pub unsafe fn clobber_sysv64_edx() { + let foo: i32; + asm!("", out("edx") foo, clobber_abi("sysv64")); +} + +// CHECK-LABEL: @clobber_win64 +// CHECK: =&{dx},={ax},={cx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{tmm0},~{tmm1},~{tmm2},~{tmm3},~{tmm4},~{tmm5},~{tmm6},~{tmm7},~{dirflag},~{fpsr},~{flags},~{memory} +#[no_mangle] +pub unsafe fn clobber_win64_edx() { + let foo: i32; + asm!("", out("edx") foo, clobber_abi("win64")); +} diff --git a/tests/codegen/asm/x86-clobbers.rs b/tests/codegen/asm/x86-clobbers.rs new file mode 100644 index 00000000000..4094db74134 --- /dev/null +++ b/tests/codegen/asm/x86-clobbers.rs @@ -0,0 +1,20 @@ +//@ compile-flags: -O +//@ only-x86_64 + +#![crate_type = "rlib"] + +use std::arch::asm; + +// CHECK-LABEL: @x87_clobber +// CHECK: ~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)} +#[no_mangle] +pub unsafe fn x87_clobber() { + asm!("foo", out("st") _); +} + +// CHECK-LABEL: @mmx_clobber +// CHECK: ~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)} +#[no_mangle] +pub unsafe fn mmx_clobber() { + asm!("bar", out("mm0") _, out("mm1") _); +} diff --git a/tests/codegen/asm/x86-target-clobbers.rs b/tests/codegen/asm/x86-target-clobbers.rs new file mode 100644 index 00000000000..119372491ff --- /dev/null +++ b/tests/codegen/asm/x86-target-clobbers.rs @@ -0,0 +1,29 @@ +//@ only-x86_64 +//@ revisions: base avx512 +//@ [avx512]compile-flags: -C target-feature=+avx512f + +#![crate_type = "rlib"] + +use std::arch::asm; + +// CHECK-LABEL: @amx_clobber +// base: call void asm sideeffect inteldialect "", "~{tmm0}"() +#[no_mangle] +pub unsafe fn amx_clobber() { + asm!("", out("tmm0") _, options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @avx512_clobber +// base: call void asm sideeffect inteldialect "", "~{xmm31}"() +// avx512: call float asm sideeffect inteldialect "", "=&{xmm31}"() +#[no_mangle] +pub unsafe fn avx512_clobber() { + asm!("", out("zmm31") _, options(nostack, nomem, preserves_flags)); +} + +// CHECK-LABEL: @eax_clobber +// CHECK: call i32 asm sideeffect inteldialect "", "=&{ax}"() +#[no_mangle] +pub unsafe fn eax_clobber() { + asm!("", out("eax") _, options(nostack, nomem, preserves_flags)); +} diff --git a/tests/codegen/foo.s b/tests/codegen/foo.s deleted file mode 100644 index 304d82aa0c6..00000000000 --- a/tests/codegen/foo.s +++ /dev/null @@ -1,3 +0,0 @@ -.global foo -foo: - jmp baz diff --git a/tests/codegen/global_asm.rs b/tests/codegen/global_asm.rs deleted file mode 100644 index 32075daa3cf..00000000000 --- a/tests/codegen/global_asm.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ revisions: x32 x64 -//@[x32] only-x86 -//@[x64] only-x86_64 -//@ compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] - -use std::arch::global_asm; - -// CHECK-LABEL: foo -// CHECK: module asm -// this regex will capture the correct unconditional branch inst. -// CHECK: module asm "{{[[:space:]]+}}jmp baz" -global_asm!( - r#" - .global foo -foo: - jmp baz -"# -); - -extern "C" { - fn foo(); -} - -// CHECK-LABEL: @baz -#[no_mangle] -pub unsafe extern "C" fn baz() {} diff --git a/tests/codegen/global_asm_include.rs b/tests/codegen/global_asm_include.rs deleted file mode 100644 index 98be9c3e333..00000000000 --- a/tests/codegen/global_asm_include.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@ revisions: x32 x64 -//@[x32] only-x86 -//@[x64] only-x86_64 -//@ compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] - -use std::arch::global_asm; - -// CHECK-LABEL: foo -// CHECK: module asm -// CHECK: module asm "{{[[:space:]]+}}jmp baz" -global_asm!(include_str!("foo.s")); - -extern "C" { - fn foo(); -} - -// CHECK-LABEL: @baz -#[no_mangle] -pub unsafe extern "C" fn baz() {} diff --git a/tests/codegen/global_asm_x2.rs b/tests/codegen/global_asm_x2.rs deleted file mode 100644 index 9e3a00f0680..00000000000 --- a/tests/codegen/global_asm_x2.rs +++ /dev/null @@ -1,47 +0,0 @@ -//@ revisions: x32 x64 -//@[x32] only-x86 -//@[x64] only-x86_64 -//@ compile-flags: -C no-prepopulate-passes - -#![crate_type = "lib"] -#![no_std] - -use core::arch::global_asm; - -// CHECK-LABEL: foo -// CHECK: module asm -// CHECK: module asm "{{[[:space:]]+}}jmp baz" -// any other global_asm will be appended to this first block, so: -// CHECK-LABEL: bar -// CHECK: module asm "{{[[:space:]]+}}jmp quux" -global_asm!( - r#" - .global foo -foo: - jmp baz -"# -); - -extern "C" { - fn foo(); -} - -// CHECK-LABEL: @baz -#[no_mangle] -pub unsafe extern "C" fn baz() {} - -// no checks here; this has been appended to the first occurrence -global_asm!( - r#" - .global bar -bar: - jmp quux -"# -); - -extern "C" { - fn bar(); -} - -#[no_mangle] -pub unsafe extern "C" fn quux() {} -- cgit 1.4.1-3-g733a5 From c9e77e87762ce57ac3d1e8e70bf750fef75a9af5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Nov 2024 14:18:11 +0100 Subject: make const_alloc_layout feature gate only about functions that are already stable the rest has their constness guarded by their usual feature gate --- library/core/src/alloc/layout.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index 95cf9427e02..f412ca17163 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -216,7 +216,7 @@ impl Layout { /// [trait object]: ../../book/ch17-02-trait-objects.html /// [extern type]: ../../unstable-book/language-features/extern-types.html #[unstable(feature = "layout_for_ptr", issue = "69835")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] + #[rustc_const_unstable(feature = "layout_for_ptr", issue = "69835")] #[must_use] pub const unsafe fn for_value_raw(t: *const T) -> Self { // SAFETY: we pass along the prerequisites of these functions to the caller @@ -232,7 +232,6 @@ impl Layout { /// sentinel value. Types that lazily allocate must track initialization by /// some other means. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "alloc_layout_extra", issue = "55724")] #[must_use] #[inline] pub const fn dangling(&self) -> NonNull { @@ -256,6 +255,7 @@ impl Layout { /// `align` violates the conditions listed in [`Layout::from_size_align`]. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[inline] pub const fn align_to(&self, align: usize) -> Result { if let Some(align) = Alignment::new(align) { @@ -282,7 +282,6 @@ impl Layout { /// address for the whole allocated block of memory. One way to /// satisfy this constraint is to ensure `align <= self.align()`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[must_use = "this returns the padding needed, \ without modifying the `Layout`"] #[inline] @@ -332,6 +331,7 @@ impl Layout { /// to the layout's current size. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[must_use = "this returns a new `Layout`, \ without modifying the original"] #[inline] @@ -374,7 +374,6 @@ impl Layout { /// assert_eq!(repeated, (Layout::from_size_align(24, 4).unwrap(), 8)); /// ``` #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] pub const fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> { let padded = self.pad_to_align(); @@ -432,6 +431,7 @@ impl Layout { /// ``` #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[inline] pub const fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> { let new_align = Alignment::max(self.align, next.align); @@ -463,7 +463,6 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] pub const fn repeat_packed(&self, n: usize) -> Result { if let Some(size) = self.size.checked_mul(n) { @@ -481,7 +480,6 @@ impl Layout { /// /// On arithmetic overflow, returns `LayoutError`. #[unstable(feature = "alloc_layout_extra", issue = "55724")] - #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] #[inline] pub const fn extend_packed(&self, next: Self) -> Result { // SAFETY: each `size` is at most `isize::MAX == usize::MAX/2`, so the @@ -497,6 +495,7 @@ impl Layout { /// `isize::MAX`, returns `LayoutError`. #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")] #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")] + #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] #[inline] pub const fn array(n: usize) -> Result { // Reduce the amount of code we need to monomorphize per `T`. -- cgit 1.4.1-3-g733a5 From aba20887351e85e53e01c5620e1f74858256f39d Mon Sep 17 00:00:00 2001 From: Aria Beingessner Date: Sat, 2 Mar 2024 19:13:31 -0500 Subject: feat(byte_sub_ptr): add ptr::byte_sub_ptr This is an API that naturally should exist as a combination of byte_offset_from and sub_ptr both existing (they showed up at similar times so this union was never made). Adding these is a logical (and perhaps final) precondition of stabilizing ptr_sub_ptr (#95892). --- library/core/src/ptr/const_ptr.rs | 19 +++++++++++++++++++ library/core/src/ptr/mut_ptr.rs | 19 +++++++++++++++++++ library/core/src/ptr/non_null.rs | 19 +++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 75d681d76df..439b9b354a5 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -790,6 +790,25 @@ impl *const T { unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } } + /// Calculates the distance between two pointers, *where it's known that + /// `self` is equal to or greater than `origin`*. The returned value is in + /// units of **bytes**. + /// + /// This is purely a convenience for casting to a `u8` pointer and + /// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for + /// documentation and safety requirements. + /// + /// For non-`Sized` pointees this operation considers only the data pointers, + /// ignoring the metadata. + #[unstable(feature = "ptr_sub_ptr", issue = "95892")] + #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub const unsafe fn byte_sub_ptr(self, origin: *const U) -> usize { + // SAFETY: the caller must uphold the safety contract for `sub_ptr`. + unsafe { self.cast::().sub_ptr(origin.cast::()) } + } + /// Returns whether two pointers are guaranteed to be equal. /// /// At runtime this function behaves like `Some(self == other)`. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 408e722267a..f25f258aa68 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -930,6 +930,25 @@ impl *mut T { unsafe { (self as *const T).sub_ptr(origin) } } + /// Calculates the distance between two pointers, *where it's known that + /// `self` is equal to or greater than `origin`*. The returned value is in + /// units of **bytes**. + /// + /// This is purely a convenience for casting to a `u8` pointer and + /// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for + /// documentation and safety requirements. + /// + /// For non-`Sized` pointees this operation considers only the data pointers, + /// ignoring the metadata. + #[unstable(feature = "ptr_sub_ptr", issue = "95892")] + #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] + #[inline] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + pub const unsafe fn byte_sub_ptr(self, origin: *mut U) -> usize { + // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. + unsafe { (self as *const T).byte_sub_ptr(origin) } + } + /// Adds an unsigned offset to a pointer. /// /// This can only move the pointer forward (or not move it). If you need to move forward or diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 86ef1f3f005..8178c440f02 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -866,6 +866,25 @@ impl NonNull { unsafe { self.pointer.sub_ptr(subtracted.pointer) } } + /// Calculates the distance between two pointers, *where it's known that + /// `self` is equal to or greater than `origin`*. The returned value is in + /// units of **bytes**. + /// + /// This is purely a convenience for casting to a `u8` pointer and + /// using [`sub_ptr`][NonNull::sub_ptr] on it. See that method for + /// documentation and safety requirements. + /// + /// For non-`Sized` pointees this operation considers only the data pointers, + /// ignoring the metadata. + #[inline(always)] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[unstable(feature = "ptr_sub_ptr", issue = "95892")] + #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")] + pub const unsafe fn byte_sub_ptr(self, origin: NonNull) -> usize { + // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`. + unsafe { self.pointer.byte_sub_ptr(origin.pointer) } + } + /// Reads the value from `self` without moving it. This leaves the /// memory in `self` unchanged. /// -- cgit 1.4.1-3-g733a5 From c38865502eae3cdd930669d68295b30276903d37 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Nov 2024 15:30:08 +0100 Subject: offset_from / sub_ptr docs: emphasize that pointers must be in the same allocation --- library/core/src/ptr/const_ptr.rs | 8 ++++---- library/core/src/ptr/mut_ptr.rs | 8 ++++---- library/core/src/ptr/non_null.rs | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 439b9b354a5..c436b6870c2 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -582,7 +582,7 @@ impl *const T { intrinsics::ptr_mask(self.cast::<()>(), mask).with_metadata_of(self) } - /// Calculates the distance between two pointers. The returned value is in + /// Calculates the distance between two pointers within the same allocation. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::()`. /// /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::() as isize)`, @@ -677,7 +677,7 @@ impl *const T { unsafe { intrinsics::ptr_offset_from(self, origin) } } - /// Calculates the distance between two pointers. The returned value is in + /// Calculates the distance between two pointers within the same allocation. The returned value is in /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and @@ -695,7 +695,7 @@ impl *const T { unsafe { self.cast::().offset_from(origin.cast::()) } } - /// Calculates the distance between two pointers, *where it's known that + /// Calculates the distance between two pointers within the same allocation, *where it's known that /// `self` is equal to or greater than `origin`*. The returned value is in /// units of T: the distance in bytes is divided by `mem::size_of::()`. /// @@ -790,7 +790,7 @@ impl *const T { unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) } } - /// Calculates the distance between two pointers, *where it's known that + /// Calculates the distance between two pointers within the same allocation, *where it's known that /// `self` is equal to or greater than `origin`*. The returned value is in /// units of **bytes**. /// diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index f25f258aa68..9d6fd88f4d4 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -746,7 +746,7 @@ impl *mut T { (self as *const T).guaranteed_ne(other as _) } - /// Calculates the distance between two pointers. The returned value is in + /// Calculates the distance between two pointers within the same allocation. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::()`. /// /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::() as isize)`, @@ -839,7 +839,7 @@ impl *mut T { unsafe { (self as *const T).offset_from(origin) } } - /// Calculates the distance between two pointers. The returned value is in + /// Calculates the distance between two pointers within the same allocation. The returned value is in /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and @@ -857,7 +857,7 @@ impl *mut T { unsafe { self.cast::().offset_from(origin.cast::()) } } - /// Calculates the distance between two pointers, *where it's known that + /// Calculates the distance between two pointers within the same allocation, *where it's known that /// `self` is equal to or greater than `origin`*. The returned value is in /// units of T: the distance in bytes is divided by `mem::size_of::()`. /// @@ -930,7 +930,7 @@ impl *mut T { unsafe { (self as *const T).sub_ptr(origin) } } - /// Calculates the distance between two pointers, *where it's known that + /// Calculates the distance between two pointers within the same allocation, *where it's known that /// `self` is equal to or greater than `origin`*. The returned value is in /// units of **bytes**. /// diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 8178c440f02..b4c11c7070f 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -676,7 +676,7 @@ impl NonNull { unsafe { NonNull { pointer: self.pointer.byte_sub(count) } } } - /// Calculates the distance between two pointers. The returned value is in + /// Calculates the distance between two pointers within the same allocation. The returned value is in /// units of T: the distance in bytes divided by `mem::size_of::()`. /// /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::() as isize)`, @@ -773,7 +773,7 @@ impl NonNull { unsafe { self.pointer.offset_from(origin.pointer) } } - /// Calculates the distance between two pointers. The returned value is in + /// Calculates the distance between two pointers within the same allocation. The returned value is in /// units of **bytes**. /// /// This is purely a convenience for casting to a `u8` pointer and @@ -793,7 +793,7 @@ impl NonNull { // N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null - /// Calculates the distance between two pointers, *where it's known that + /// Calculates the distance between two pointers within the same allocation, *where it's known that /// `self` is equal to or greater than `origin`*. The returned value is in /// units of T: the distance in bytes is divided by `mem::size_of::()`. /// @@ -866,7 +866,7 @@ impl NonNull { unsafe { self.pointer.sub_ptr(subtracted.pointer) } } - /// Calculates the distance between two pointers, *where it's known that + /// Calculates the distance between two pointers within the same allocation, *where it's known that /// `self` is equal to or greater than `origin`*. The returned value is in /// units of **bytes**. /// -- cgit 1.4.1-3-g733a5 From a8d4d23107287961e6440cd94df91708f8afe1f7 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Thu, 31 Oct 2024 23:08:31 -0700 Subject: rustdoc: Directly use rustc_abi instead of reexports rustc_target reexports a lot of things that are in rustc_abi, but that will be over soon and now is probably a good time to switch. Uses of rustc_target remain where they inquire about the target tuple. --- src/librustdoc/clean/types.rs | 7 +++---- src/librustdoc/html/format.rs | 6 +++--- src/librustdoc/html/render/print_item.rs | 2 +- src/librustdoc/html/render/type_layout.rs | 2 +- src/librustdoc/json/conversions.rs | 22 +++++++++++----------- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index c62144be3da..d49b4320db6 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -5,6 +5,7 @@ use std::sync::{Arc, OnceLock as OnceCell}; use std::{fmt, iter}; use arrayvec::ArrayVec; +use rustc_abi::{ExternAbi, VariantIdx}; use rustc_ast::MetaItemInner; use rustc_ast_pretty::pprust; use rustc_attr::{ConstStability, Deprecation, Stability, StableSince}; @@ -26,8 +27,6 @@ use rustc_session::Session; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, FileName, Loc}; -use rustc_target::abi::VariantIdx; -use rustc_target::spec::abi::Abi; use thin_vec::ThinVec; use tracing::{debug, trace}; use {rustc_ast as ast, rustc_hir as hir}; @@ -656,7 +655,7 @@ impl Item { let def_id = self.def_id().unwrap(); let abi = tcx.fn_sig(def_id).skip_binder().abi(); hir::FnHeader { - safety: if abi == Abi::RustIntrinsic { + safety: if abi == ExternAbi::RustIntrinsic { intrinsic_operation_unsafety(tcx, def_id.expect_local()) } else { safety @@ -2342,7 +2341,7 @@ pub(crate) struct BareFunctionDecl { pub(crate) safety: hir::Safety, pub(crate) generic_params: Vec, pub(crate) decl: FnDecl, - pub(crate) abi: Abi, + pub(crate) abi: ExternAbi, } #[derive(Clone, Debug)] diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 47c21d89177..e9d5ba2ea57 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -13,6 +13,7 @@ use std::fmt::{self, Display, Write}; use std::iter::{self, once}; use itertools::Itertools; +use rustc_abi::ExternAbi; use rustc_attr::{ConstStability, StabilityLevel, StableSince}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; @@ -23,7 +24,6 @@ use rustc_metadata::creader::{CStore, LoadedMacro}; use rustc_middle::ty::{self, TyCtxt, TypingMode}; use rustc_span::symbol::kw; use rustc_span::{Symbol, sym}; -use rustc_target::spec::abi::Abi; use tracing::{debug, trace}; use super::url_parts_builder::{UrlPartsBuilder, estimate_item_path_byte_length}; @@ -1787,11 +1787,11 @@ impl clean::AssocItemConstraint { } } -pub(crate) fn print_abi_with_space(abi: Abi) -> impl Display { +pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display { display_fn(move |f| { let quot = if f.alternate() { "\"" } else { """ }; match abi { - Abi::Rust => Ok(()), + ExternAbi::Rust => Ok(()), abi => write!(f, "extern {0}{1}{0} ", quot, abi.name()), } }) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 5e9cbef99a9..c6a2d87cbd0 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -5,6 +5,7 @@ use std::rc::Rc; use itertools::Itertools; use rinja::Template; +use rustc_abi::VariantIdx; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_hir as hir; @@ -14,7 +15,6 @@ use rustc_index::IndexVec; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{Symbol, kw, sym}; -use rustc_target::abi::VariantIdx; use tracing::{debug, info}; use super::type_layout::document_type_layout; diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index 79209cee94f..d85ba3a2b14 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -1,13 +1,13 @@ use std::fmt; use rinja::Template; +use rustc_abi::{Primitive, TagEncoding, Variants}; use rustc_data_structures::captures::Captures; use rustc_hir::def_id::DefId; use rustc_middle::span_bug; use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::{self}; use rustc_span::symbol::Symbol; -use rustc_target::abi::{Primitive, TagEncoding, Variants}; use crate::html::format::display_fn; use crate::html::render::Context; diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 7270f170780..1c8303d4c20 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -4,6 +4,7 @@ #![allow(rustc::default_hash_types)] +use rustc_abi::ExternAbi; use rustc_ast::ast; use rustc_attr::DeprecatedSince; use rustc_hir::def::{CtorKind, DefKind}; @@ -11,7 +12,6 @@ use rustc_hir::def_id::DefId; use rustc_metadata::rendered_const; use rustc_middle::{bug, ty}; use rustc_span::{Pos, Symbol, sym}; -use rustc_target::spec::abi::Abi as RustcAbi; use rustdoc_json_types::*; use super::FullItemId; @@ -421,17 +421,17 @@ pub(crate) fn from_fn_header(header: &rustc_hir::FnHeader) -> FunctionHeader { } } -fn convert_abi(a: RustcAbi) -> Abi { +fn convert_abi(a: ExternAbi) -> Abi { match a { - RustcAbi::Rust => Abi::Rust, - RustcAbi::C { unwind } => Abi::C { unwind }, - RustcAbi::Cdecl { unwind } => Abi::Cdecl { unwind }, - RustcAbi::Stdcall { unwind } => Abi::Stdcall { unwind }, - RustcAbi::Fastcall { unwind } => Abi::Fastcall { unwind }, - RustcAbi::Aapcs { unwind } => Abi::Aapcs { unwind }, - RustcAbi::Win64 { unwind } => Abi::Win64 { unwind }, - RustcAbi::SysV64 { unwind } => Abi::SysV64 { unwind }, - RustcAbi::System { unwind } => Abi::System { unwind }, + ExternAbi::Rust => Abi::Rust, + ExternAbi::C { unwind } => Abi::C { unwind }, + ExternAbi::Cdecl { unwind } => Abi::Cdecl { unwind }, + ExternAbi::Stdcall { unwind } => Abi::Stdcall { unwind }, + ExternAbi::Fastcall { unwind } => Abi::Fastcall { unwind }, + ExternAbi::Aapcs { unwind } => Abi::Aapcs { unwind }, + ExternAbi::Win64 { unwind } => Abi::Win64 { unwind }, + ExternAbi::SysV64 { unwind } => Abi::SysV64 { unwind }, + ExternAbi::System { unwind } => Abi::System { unwind }, _ => Abi::Other(a.to_string()), } } -- cgit 1.4.1-3-g733a5