From d7e6074083231aa8ccf7f299626fc83d59f78ee4 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 30 Oct 2024 13:16:43 -0700 Subject: [PATCH 01/21] 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 74e873e35ff38..d9dba641495ab 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 3bb0ee6d5ff6c..4f63a632030b4 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") From ce3e14a448e090abf494a91b87f124258c542d4c Mon Sep 17 00:00:00 2001 From: Zalathar Date: Thu, 17 Oct 2024 20:11:20 +1100 Subject: [PATCH 02/21] 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 - .../src/debuginfo/metadata.rs | 26 ------------------ .../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 -- .../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 ++---- .../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 2c5ec9dad59f1..64bb22e8cb25e 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 bfa9e8b82a033..cf7b16c9cc4f4 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 9064cfaeb2987..0d1fd0163ebfd 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 72e723aa8491f..b6c20cdcf0cd4 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 8fc586d2c8ffc..5fad7583e1aee 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 8445d16befb3a..d977cca247eea 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 d3762e739db80..35bba149d0a6b 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 3e906f89c15c3..3b7dc6de82553 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 16623915c4019..d2be6ae8d698e 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 d733e32f209db..5ee3b4015ebe9 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 54a4621db2462..2b158627751bc 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 ed091d8fc5710..41da47e9206ca 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 71303bfaff20d..0000000000000 --- 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 58a1b53c0406e..0000000000000 --- 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 f328e4d9d04c3..0000000000000 --- a/tests/run-make/profile/test.rs +++ /dev/null @@ -1 +0,0 @@ -fn main() {} From dd651be7bc74b0d897cd0b4ec76104e51c32cb34 Mon Sep 17 00:00:00 2001 From: binarycat Date: Thu, 31 Oct 2024 11:43:45 -0500 Subject: [PATCH 03/21] 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 74b198c4fdd41..4c4c31eaf0a82 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: /// /// ``` From fc67203d59f5a314d51469ed844189191b5663f6 Mon Sep 17 00:00:00 2001 From: lolbinarycat Date: Thu, 31 Oct 2024 17:27:31 -0500 Subject: [PATCH 04/21] 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 4c4c31eaf0a82..4cf52042a57f6 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: /// From 588c7a934a05fb8d4aaabf7a42c28f75b749db6c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 31 Oct 2024 04:11:38 +0000 Subject: [PATCH 05/21] 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 68776c525551a..963801e57931d 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:?}"); From 41966e71bc386d073124d73cbc34fb279df5f4c8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 31 Oct 2024 04:33:21 +0000 Subject: [PATCH 06/21] 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 + ...-fallback-flowing-into-unsafe.e2015.stderr | 4 + ...-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 cceaabaff65b6..8fd545939341d 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 963801e57931d..02efb12f83561 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 ec49137ba7953..065a6e559c15c 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 a75039b8237a0..b8de1026e377e 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 4138e9f8c8622..de44279ff8ccc 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 From ea4fb7c25cbbd21508dea30aa7f29fbdcc1f149d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 31 Oct 2024 15:59:44 +0000 Subject: [PATCH 07/21] 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 +++ ...ng-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 8fd545939341d..2f09e5e163c15 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 02efb12f83561..d6be237acf4d6 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 134fd098b7e4a..703f3d6266cf6 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 2a3c5edc21847..dee112e245a76 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 From c930bba2836c1daa4ffa72ce3ec4d3e570ce188e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 31 Oct 2024 16:05:42 +0000 Subject: [PATCH 08/21] And locals too --- compiler/rustc_hir_typeck/src/errors.rs | 4 ++++ compiler/rustc_hir_typeck/src/fallback.rs | 13 +++++++++++++ .../never-type-fallback-breaking.e2021.stderr | 4 ++-- .../defaulted-never-note.nofallback.stderr | 4 ++++ ...iverging-fallback-control-flow.nofallback.stderr | 8 ++++---- ...-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 2f09e5e163c15..fdeeed92565c3 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 d6be237acf4d6..cefc28b400f6e 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 703f3d6266cf6..1c6685261fb3e 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 d88615186dd63..6bc4501b6a375 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 dee112e245a76..d40d1da76f9ac 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 b485c94df4d6f..30a5e60a75848 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 From df6f5841e5fcceb2c9ff43035dcede4f35450f5a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 31 Oct 2024 16:58:28 +0000 Subject: [PATCH 09/21] 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 ++ ...verging-fallback-no-leak.nofallback.stderr | 4 ++ .../fallback-closure-ret.nofallback.stderr | 4 ++ ...-fallback-flowing-into-unsafe.e2015.stderr | 28 ++++++++ ...-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 fdeeed92565c3..4f579b05d83b6 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 cefc28b400f6e..ada716addd02d 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 1c6685261fb3e..79eee2a3defd0 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 065a6e559c15c..79f47bb5fbc11 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 11245cc7aabf9..d11c21d9573be 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 3fb5536dee7e3..fb0166dd9e06e 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 b8de1026e377e..6a48a7b9b47af 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 de44279ff8ccc..844cd62c267b5 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 From b4248aeec366d31efe595eb5f671f589c849d6a3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 1 Nov 2024 01:46:17 +0000 Subject: [PATCH 10/21] 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 ada716addd02d..8d8573c65c5b8 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) From 3afbe4f9c72ebd153e767b96a4efe422c91d6903 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Thu, 31 Oct 2024 21:24:31 -0500 Subject: [PATCH 11/21] 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 +- .../invalid-nan-comparison-suggestion.fixed | 14 ++ .../lint/invalid-nan-comparison-suggestion.rs | 14 ++ .../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 88878a018e7a6..48dd8e38a036a 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 46b2d4e9c3f5c..2d88c274080b6 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 558b433d794af..9175344786948 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 c310341de07b7..9d07d3f924023 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 202a5e27e8e4e..1a2c8a7c5a08b 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 054c06d38b30b..486d2a9636c95 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 From b6a49d8969de0f15406815761bcaffda8ce6b797 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 1 Nov 2024 10:15:08 +0800 Subject: [PATCH 12/21] 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 519649779336c..704fa46ab1ee2 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 a20105f0ef378..d1b186fd316d7 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", From 5342eb05975ce7632fca97a83a0775c95c0d76f1 Mon Sep 17 00:00:00 2001 From: chengehe Date: Fri, 1 Nov 2024 16:53:36 +0800 Subject: [PATCH 13/21] 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 80912937f3158..207baccd6abb5 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 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: [PATCH 14/21] 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 e690bf74b6b4b..80ae5a7146dad 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 1f853f6e1c302..46be2aee63742 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 } From 506812d0873c084139b6e9b81040e22f874d4fdc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Nov 2024 11:47:04 +0100 Subject: [PATCH 15/21] 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 b4252ef0103fe..a57e265c7cc00 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 f6e271954fe12..f04c83693ef63 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 e9f5bf4404e25..7c2205fdcd1c3 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 27e51afa800a0..52d2179b04de1 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 9ef99e9dae821..f25d8c642a894 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) { From 901b340c1f5d208561d4261cc3ee634973b35326 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Nov 2024 08:38:03 +0100 Subject: [PATCH 16/21] 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 3a9060df286e8..72adb1bf19019 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 eb4ea4b3c4067..ded8997c634ed 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 75d681d76dfdf..1195f38ab6fa8 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 408e722267a0f..60d47d7eb1a4a 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 86ef1f3f005be..1d7a1e7b2f073 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, From 96e7eaf478f53cdf417ad681d2afa07b00abbdfd Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 1 Nov 2024 22:12:55 +0900 Subject: [PATCH 17/21] Move remaining inline assembly test files into asm directory --- tests/assembly/{asm-comments.rs => asm/comments.rs} | 0 .../codegen/{asm-arm64ec-clobbers.rs => asm/arm64ec-clobbers.rs} | 0 tests/codegen/{ => asm}/foo.s | 0 tests/codegen/{ => asm}/global_asm.rs | 0 tests/codegen/{ => asm}/global_asm_include.rs | 0 tests/codegen/{ => asm}/global_asm_x2.rs | 0 tests/codegen/{asm-goto.rs => asm/goto.rs} | 0 tests/codegen/{asm-may_unwind.rs => asm/may_unwind.rs} | 0 tests/codegen/{asm-maybe-uninit.rs => asm/maybe-uninit.rs} | 0 tests/codegen/{asm-msp430-clobbers.rs => asm/msp430-clobbers.rs} | 0 .../codegen/{asm-multiple-options.rs => asm/multiple-options.rs} | 0 tests/codegen/{asm-options.rs => asm/options.rs} | 0 .../codegen/{asm-powerpc-clobbers.rs => asm/powerpc-clobbers.rs} | 0 tests/codegen/{asm-s390x-clobbers.rs => asm/s390x-clobbers.rs} | 0 tests/codegen/{asm-sanitize-llvm.rs => asm/sanitize-llvm.rs} | 0 tests/codegen/{asm-clobber_abi.rs => asm/x86-clobber_abi.rs} | 0 tests/codegen/{asm-clobbers.rs => asm/x86-clobbers.rs} | 0 .../{asm-target-clobbers.rs => asm/x86-target-clobbers.rs} | 0 18 files changed, 0 insertions(+), 0 deletions(-) rename tests/assembly/{asm-comments.rs => asm/comments.rs} (100%) rename tests/codegen/{asm-arm64ec-clobbers.rs => asm/arm64ec-clobbers.rs} (100%) rename tests/codegen/{ => asm}/foo.s (100%) rename tests/codegen/{ => asm}/global_asm.rs (100%) rename tests/codegen/{ => asm}/global_asm_include.rs (100%) rename tests/codegen/{ => asm}/global_asm_x2.rs (100%) rename tests/codegen/{asm-goto.rs => asm/goto.rs} (100%) rename tests/codegen/{asm-may_unwind.rs => asm/may_unwind.rs} (100%) rename tests/codegen/{asm-maybe-uninit.rs => asm/maybe-uninit.rs} (100%) rename tests/codegen/{asm-msp430-clobbers.rs => asm/msp430-clobbers.rs} (100%) rename tests/codegen/{asm-multiple-options.rs => asm/multiple-options.rs} (100%) rename tests/codegen/{asm-options.rs => asm/options.rs} (100%) rename tests/codegen/{asm-powerpc-clobbers.rs => asm/powerpc-clobbers.rs} (100%) rename tests/codegen/{asm-s390x-clobbers.rs => asm/s390x-clobbers.rs} (100%) rename tests/codegen/{asm-sanitize-llvm.rs => asm/sanitize-llvm.rs} (100%) rename tests/codegen/{asm-clobber_abi.rs => asm/x86-clobber_abi.rs} (100%) rename tests/codegen/{asm-clobbers.rs => asm/x86-clobbers.rs} (100%) rename tests/codegen/{asm-target-clobbers.rs => asm/x86-target-clobbers.rs} (100%) diff --git a/tests/assembly/asm-comments.rs b/tests/assembly/asm/comments.rs similarity index 100% rename from tests/assembly/asm-comments.rs rename to tests/assembly/asm/comments.rs diff --git a/tests/codegen/asm-arm64ec-clobbers.rs b/tests/codegen/asm/arm64ec-clobbers.rs similarity index 100% rename from tests/codegen/asm-arm64ec-clobbers.rs rename to tests/codegen/asm/arm64ec-clobbers.rs diff --git a/tests/codegen/foo.s b/tests/codegen/asm/foo.s similarity index 100% rename from tests/codegen/foo.s rename to tests/codegen/asm/foo.s diff --git a/tests/codegen/global_asm.rs b/tests/codegen/asm/global_asm.rs similarity index 100% rename from tests/codegen/global_asm.rs rename to tests/codegen/asm/global_asm.rs diff --git a/tests/codegen/global_asm_include.rs b/tests/codegen/asm/global_asm_include.rs similarity index 100% rename from tests/codegen/global_asm_include.rs rename to tests/codegen/asm/global_asm_include.rs diff --git a/tests/codegen/global_asm_x2.rs b/tests/codegen/asm/global_asm_x2.rs similarity index 100% rename from tests/codegen/global_asm_x2.rs rename to tests/codegen/asm/global_asm_x2.rs diff --git a/tests/codegen/asm-goto.rs b/tests/codegen/asm/goto.rs similarity index 100% rename from tests/codegen/asm-goto.rs rename to tests/codegen/asm/goto.rs diff --git a/tests/codegen/asm-may_unwind.rs b/tests/codegen/asm/may_unwind.rs similarity index 100% rename from tests/codegen/asm-may_unwind.rs rename to tests/codegen/asm/may_unwind.rs diff --git a/tests/codegen/asm-maybe-uninit.rs b/tests/codegen/asm/maybe-uninit.rs similarity index 100% rename from tests/codegen/asm-maybe-uninit.rs rename to tests/codegen/asm/maybe-uninit.rs diff --git a/tests/codegen/asm-msp430-clobbers.rs b/tests/codegen/asm/msp430-clobbers.rs similarity index 100% rename from tests/codegen/asm-msp430-clobbers.rs rename to tests/codegen/asm/msp430-clobbers.rs diff --git a/tests/codegen/asm-multiple-options.rs b/tests/codegen/asm/multiple-options.rs similarity index 100% rename from tests/codegen/asm-multiple-options.rs rename to tests/codegen/asm/multiple-options.rs diff --git a/tests/codegen/asm-options.rs b/tests/codegen/asm/options.rs similarity index 100% rename from tests/codegen/asm-options.rs rename to tests/codegen/asm/options.rs diff --git a/tests/codegen/asm-powerpc-clobbers.rs b/tests/codegen/asm/powerpc-clobbers.rs similarity index 100% rename from tests/codegen/asm-powerpc-clobbers.rs rename to tests/codegen/asm/powerpc-clobbers.rs diff --git a/tests/codegen/asm-s390x-clobbers.rs b/tests/codegen/asm/s390x-clobbers.rs similarity index 100% rename from tests/codegen/asm-s390x-clobbers.rs rename to tests/codegen/asm/s390x-clobbers.rs diff --git a/tests/codegen/asm-sanitize-llvm.rs b/tests/codegen/asm/sanitize-llvm.rs similarity index 100% rename from tests/codegen/asm-sanitize-llvm.rs rename to tests/codegen/asm/sanitize-llvm.rs diff --git a/tests/codegen/asm-clobber_abi.rs b/tests/codegen/asm/x86-clobber_abi.rs similarity index 100% rename from tests/codegen/asm-clobber_abi.rs rename to tests/codegen/asm/x86-clobber_abi.rs diff --git a/tests/codegen/asm-clobbers.rs b/tests/codegen/asm/x86-clobbers.rs similarity index 100% rename from tests/codegen/asm-clobbers.rs rename to tests/codegen/asm/x86-clobbers.rs diff --git a/tests/codegen/asm-target-clobbers.rs b/tests/codegen/asm/x86-target-clobbers.rs similarity index 100% rename from tests/codegen/asm-target-clobbers.rs rename to tests/codegen/asm/x86-target-clobbers.rs From c9e77e87762ce57ac3d1e8e70bf750fef75a9af5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Nov 2024 14:18:11 +0100 Subject: [PATCH 18/21] 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 95cf9427e02ab..f412ca1716338 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`. From aba20887351e85e53e01c5620e1f74858256f39d Mon Sep 17 00:00:00 2001 From: Aria Beingessner Date: Sat, 2 Mar 2024 19:13:31 -0500 Subject: [PATCH 19/21] 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 75d681d76dfdf..439b9b354a55c 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 408e722267a0f..f25f258aa68ab 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 86ef1f3f005be..8178c440f02c3 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. /// From c38865502eae3cdd930669d68295b30276903d37 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Nov 2024 15:30:08 +0100 Subject: [PATCH 20/21] 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 439b9b354a55c..c436b6870c2c7 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 f25f258aa68ab..9d6fd88f4d441 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 8178c440f02c3..b4c11c7070fb7 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**. /// From a8d4d23107287961e6440cd94df91708f8afe1f7 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Thu, 31 Oct 2024 23:08:31 -0700 Subject: [PATCH 21/21] 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 c62144be3da29..d49b4320db6ff 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 47c21d89177bf..e9d5ba2ea57e1 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 5e9cbef99a950..c6a2d87cbd02b 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 79209cee94f2c..d85ba3a2b14b0 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 7270f170780a2..1c8303d4c2087 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()), } }