From ee61f09a364c68a5ffc2a7b14e7a5776d5c2a533 Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Fri, 15 Dec 2023 16:46:34 -0800 Subject: [PATCH 01/14] Add arm64ec-pc-windows-msvc target Introduces the `arm64ec-pc-windows-msvc` target for building Arm64EC ("Emulation Compatible") binaries for Windows. For more information about Arm64EC see . Tier 3 policy: > A tier 3 target must have a designated developer or developers (the "target maintainers") on record to be CCed when issues arise regarding the target. (The mechanism to track and CC such developers may evolve over time.) I will be the maintainer for this target. > Targets must use naming consistent with any existing targets; for instance, a target for the same CPU or OS as an existing Rust target should use the same name for that CPU or OS. Targets should normally use the same names and naming conventions as used elsewhere in the broader ecosystem beyond Rust (such as in other toolchains), unless they have a very good reason to diverge. Changing the name of a target can be highly disruptive, especially once the target reaches a higher tier, so getting the name right is important even for a tier 3 target. Target uses the `arm64ec` architecture to match LLVM and MSVC, and the `-pc-windows-msvc` suffix to indicate that it targets Windows via the MSVC environment. > Target names should not introduce undue confusion or ambiguity unless absolutely necessary to maintain ecosystem compatibility. For example, if the name of the target makes people extremely likely to form incorrect beliefs about what it targets, the name should be changed or augmented to disambiguate it. Target name exactly specifies the type of code that will be produced. > If possible, use only letters, numbers, dashes and underscores for the name. Periods (.) are known to cause issues in Cargo. Done. > Tier 3 targets may have unusual requirements to build or use, but must not create legal issues or impose onerous legal terms for the Rust project or for Rust developers or users. > The target must not introduce license incompatibilities. Uses the same dependencies, requirements and licensing as the other `*-pc-windows-msvc` targets. > Anything added to the Rust repository must be under the standard Rust license (MIT OR Apache-2.0). Understood. > The target must not cause the Rust tools or libraries built for any other host (even when supporting cross-compilation to the target) to depend on any new dependency less permissive than the Rust licensing policy. This applies whether the dependency is a Rust crate that would require adding new license exceptions (as specified by the tidy tool in the rust-lang/rust repository), or whether the dependency is a native library or binary. In other words, the introduction of the target must not cause a user installing or running a version of Rust or the Rust tools to be subject to any new license requirements. > Compiling, linking, and emitting functional binaries, libraries, or other code for the target (whether hosted on the target itself or cross-compiling from another target) must not depend on proprietary (non-FOSS) libraries. Host tools built for the target itself may depend on the ordinary runtime libraries supplied by the platform and commonly used by other applications built for the target, but those libraries must not be required for code generation for the target; cross-compilation to the target must not require such libraries at all. For instance, rustc built for the target may depend on a common proprietary C runtime library or console output library, but must not depend on a proprietary code generation library or code optimization library. Rust's license permits such combinations, but the Rust project has no interest in maintaining such combinations within the scope of Rust itself, even at tier 3. > "onerous" here is an intentionally subjective term. At a minimum, "onerous" legal/licensing terms include but are not limited to: non-disclosure requirements, non-compete requirements, contributor license agreements (CLAs) or equivalent, "non-commercial"/"research-only"/etc terms, requirements conditional on the employer or employment of any particular Rust developers, revocable terms, any requirements that create liability for the Rust project or its developers or users, or any requirements that adversely affect the livelihood or prospects of the Rust project or its developers or users. Uses the same dependencies, requirements and licensing as the other `*-pc-windows-msvc` targets. > Neither this policy nor any decisions made regarding targets shall create any binding agreement or estoppel by any party. If any member of an approving Rust team serves as one of the maintainers of a target, or has any legal or employment requirement (explicit or implicit) that might affect their decisions regarding a target, they must recuse themselves from any approval decisions regarding the target's tier status, though they may otherwise participate in discussions. > This requirement does not prevent part or all of this policy from being cited in an explicit contract or work agreement (e.g. to implement or maintain support for a target). This requirement exists to ensure that a developer or team responsible for reviewing and approving a target does not face any legal threats or obligations that would prevent them from freely exercising their judgment in such approval, even if such judgment involves subjective matters or goes beyond the letter of these requirements. Understood, I am not a member of the Rust team. > Tier 3 targets should attempt to implement as much of the standard libraries as possible and appropriate (core for most targets, alloc for targets that can support dynamic memory allocation, std for targets with an operating system or equivalent layer of system-provided functionality), but may leave some code unimplemented (either unavailable or stubbed out as appropriate), whether because the target makes it impossible to implement or challenging to implement. The authors of pull requests are not obligated to avoid calling any portions of the standard library on the basis of a tier 3 target not implementing those portions. Both `core` and `alloc` are supported. Support for `std` dependends on making changes to the standard library, `stdarch` and `backtrace` which cannot be done yet as the bootstrapping compiler raises a warning ("unexpected `cfg` condition value") for `target_arch = "arm64ec"`. > The target must provide documentation for the Rust community explaining how to build for the target, using cross-compilation if possible. If the target supports running binaries, or running tests (even if they do not pass), the documentation must explain how to run such binaries or tests for the target, using emulation if possible or dedicated hardware if necessary. Documentation is provided in src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md > Tier 3 targets must not impose burden on the authors of pull requests, or other developers in the community, to maintain the target. In particular, do not post comments (automated or manual) on a PR that derail or suggest a block on the PR based on a tier 3 target. Do not send automated messages or notifications (via any medium, including via @) to a PR author or others involved with a PR regarding a tier 3 target, unless they have opted into such messages. > Backlinks such as those generated by the issue/PR tracker when linking to an issue or PR are not considered a violation of this policy, within reason. However, such messages (even on a separate repository) must not generate notifications to anyone involved with a PR who has not requested such notifications. > Patches adding or updating tier 3 targets must not break any existing tier 2 or tier 1 target, and must not knowingly break another tier 3 target without approval of either the compiler team or the maintainers of the other tier 3 target. > In particular, this may come up when working on closely related targets, such as variations of the same architecture with different features. Avoid introducing unconditional uses of features that another variation of the target may not have; use conditional compilation or runtime detection, as appropriate, to let each target run code supported by that target. Understood. --- Cargo.lock | 4 +- .../rustc_codegen_llvm/src/back/archive.rs | 1 + compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_codegen_llvm/src/llvm_util.rs | 8 ++- compiler/rustc_codegen_llvm/src/va_arg.rs | 2 +- compiler/rustc_codegen_ssa/Cargo.toml | 2 +- .../rustc_codegen_ssa/src/back/metadata.rs | 52 +++++++------- .../src/back/symbol_export.rs | 11 +-- compiler/rustc_codegen_ssa/src/base.rs | 6 +- compiler/rustc_llvm/Cargo.toml | 7 +- compiler/rustc_target/src/abi/call/mod.rs | 2 +- compiler/rustc_target/src/spec/mod.rs | 1 + .../spec/targets/arm64ec_pc_windows_msvc.rs | 20 ++++++ compiler/rustc_target/src/target_features.rs | 4 +- src/bootstrap/src/lib.rs | 2 +- src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 1 + .../arm64ec-pc-windows-msvc.md | 69 +++++++++++++++++++ tests/assembly/targets/targets-pe.rs | 3 + tests/ui/check-cfg/well-known-values.stderr | 2 +- 20 files changed, 153 insertions(+), 46 deletions(-) create mode 100644 compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs create mode 100644 src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md diff --git a/Cargo.lock b/Cargo.lock index 4e00c9034bd9b..c74a69a7330b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -471,9 +471,9 @@ version = "0.1.0" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "02f341c093d19155a6e41631ce5971aac4e9a868262212153124c15fa22d1cdc" [[package]] name = "cfg-if" diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index b6bbc81732ee2..6bc3596c3712c 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -55,6 +55,7 @@ fn llvm_machine_type(cpu: &str) -> LLVMMachineType { "x86_64" => LLVMMachineType::AMD64, "x86" => LLVMMachineType::I386, "aarch64" => LLVMMachineType::ARM64, + "arm64ec" => LLVMMachineType::ARM64EC, "arm" => LLVMMachineType::ARM, _ => panic!("unsupported cpu type {cpu}"), } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index dbf35e5f49952..3cd8e139f158c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -56,6 +56,7 @@ pub enum LLVMMachineType { AMD64 = 0x8664, I386 = 0x14c, ARM64 = 0xaa64, + ARM64EC = 0xa641, ARM = 0x01c0, } diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 1b2beac56a20b..11ebab8eae559 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -204,7 +204,13 @@ impl<'a> IntoIterator for LLVMFeature<'a> { // which might lead to failures if the oldest tested / supported LLVM version // doesn't yet support the relevant intrinsics pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> { - let arch = if sess.target.arch == "x86_64" { "x86" } else { &*sess.target.arch }; + let arch = if sess.target.arch == "x86_64" { + "x86" + } else if sess.target.arch == "arm64ec" { + "aarch64" + } else { + &*sess.target.arch + }; match (arch, s) { ("x86", "sse4.2") => { LLVMFeature::with_dependency("sse4.2", TargetFeatureFoldStrength::EnableOnly("crc32")) diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 172c66a7af13c..d51aceddefa08 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -266,7 +266,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>( // Generic x86 "x86" => emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(4).unwrap(), true), // Windows AArch64 - "aarch64" if target.is_like_windows => { + "aarch64" | "arm64ec" if target.is_like_windows => { emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(8).unwrap(), false) } // macOS / iOS AArch64 diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 781c54bdef876..04cf5db50aaca 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" # tidy-alphabetical-start ar_archive_writer = "0.1.5" bitflags = "2.4.1" -cc = "1.0.69" +cc = "1.0.88" itertools = "0.11" jobserver = "0.1.28" pathdiff = "0.2.0" diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index c6b04431fab10..63c1d03feaf6f 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -7,7 +7,7 @@ use std::path::Path; use object::write::{self, StandardSegment, Symbol, SymbolSection}; use object::{ elf, pe, xcoff, Architecture, BinaryFormat, Endianness, FileFlags, Object, ObjectSection, - ObjectSymbol, SectionFlags, SectionKind, SymbolFlags, SymbolKind, SymbolScope, + ObjectSymbol, SectionFlags, SectionKind, SubArchitecture, SymbolFlags, SymbolKind, SymbolScope, }; use rustc_data_structures::memmap::Mmap; @@ -182,37 +182,40 @@ pub(crate) fn create_object_file(sess: &Session) -> Option Endianness::Little, Endian::Big => Endianness::Big, }; - let architecture = match &sess.target.arch[..] { - "arm" => Architecture::Arm, - "aarch64" => { + let (architecture, sub_architecture) = match &sess.target.arch[..] { + "arm" => (Architecture::Arm, None), + "aarch64" => ( if sess.target.pointer_width == 32 { Architecture::Aarch64_Ilp32 } else { Architecture::Aarch64 - } - } - "x86" => Architecture::I386, - "s390x" => Architecture::S390x, - "mips" | "mips32r6" => Architecture::Mips, - "mips64" | "mips64r6" => Architecture::Mips64, - "x86_64" => { + }, + None, + ), + "x86" => (Architecture::I386, None), + "s390x" => (Architecture::S390x, None), + "mips" | "mips32r6" => (Architecture::Mips, None), + "mips64" | "mips64r6" => (Architecture::Mips64, None), + "x86_64" => ( if sess.target.pointer_width == 32 { Architecture::X86_64_X32 } else { Architecture::X86_64 - } - } - "powerpc" => Architecture::PowerPc, - "powerpc64" => Architecture::PowerPc64, - "riscv32" => Architecture::Riscv32, - "riscv64" => Architecture::Riscv64, - "sparc64" => Architecture::Sparc64, - "avr" => Architecture::Avr, - "msp430" => Architecture::Msp430, - "hexagon" => Architecture::Hexagon, - "bpf" => Architecture::Bpf, - "loongarch64" => Architecture::LoongArch64, - "csky" => Architecture::Csky, + }, + None, + ), + "powerpc" => (Architecture::PowerPc, None), + "powerpc64" => (Architecture::PowerPc64, None), + "riscv32" => (Architecture::Riscv32, None), + "riscv64" => (Architecture::Riscv64, None), + "sparc64" => (Architecture::Sparc64, None), + "avr" => (Architecture::Avr, None), + "msp430" => (Architecture::Msp430, None), + "hexagon" => (Architecture::Hexagon, None), + "bpf" => (Architecture::Bpf, None), + "loongarch64" => (Architecture::LoongArch64, None), + "csky" => (Architecture::Csky, None), + "arm64ec" => (Architecture::Aarch64, Some(SubArchitecture::Arm64EC)), // Unsupported architecture. _ => return None, }; @@ -227,6 +230,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option( return undecorated; } - let x86 = match &target.arch[..] { - "x86" => true, - "x86_64" => false, + let prefix = match &target.arch[..] { + "x86" => Some('_'), + "x86_64" => None, + "arm64ec" => Some('#'), // Only x86/64 use symbol decorations. _ => return undecorated, }; @@ -602,8 +603,8 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>( Conv::X86Stdcall => ("_", "@"), Conv::X86VectorCall => ("", "@@"), _ => { - if x86 { - undecorated.insert(0, '_'); + if let Some(prefix) = prefix { + undecorated.insert(0, prefix); } return undecorated; } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index f7afd22a48cab..2161bf61daa41 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -907,7 +907,11 @@ impl CrateInfo { lang_items::required(tcx, l).then_some(name) }) .collect(); - let prefix = if target.is_like_windows && target.arch == "x86" { "_" } else { "" }; + let prefix = match (target.is_like_windows, target.arch.as_ref()) { + (true, "x86") => "_", + (true, "arm64ec") => "#", + _ => "", + }; // This loop only adds new items to values of the hash map, so the order in which we // iterate over the values is not important. diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml index 6598f1db86dac..6e9d885be227c 100644 --- a/compiler/rustc_llvm/Cargo.toml +++ b/compiler/rustc_llvm/Cargo.toml @@ -8,12 +8,7 @@ edition = "2021" libc = "0.2.73" # tidy-alphabetical-end -# FIXME: updating cc past 1.0.79 breaks libstd bootstrapping, pin -# to the last working version here so `cargo update` doesn't cause the -# a higher version to be selected -# https://github.com/rust-lang/cc-rs/issues/913 -# 1.0.{84, 85} fix this but have been yanked [build-dependencies] # tidy-alphabetical-start -cc = "=1.0.79" +cc = "1.0.79" # tidy-alphabetical-end diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index db721212f8e91..0f0448b7b95b5 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -814,7 +814,7 @@ impl<'a, Ty> FnAbi<'a, Ty> { } } }, - "aarch64" => { + "aarch64" | "arm64ec" => { let kind = if cx.target_spec().is_like_osx { aarch64::AbiKind::DarwinPCS } else if cx.target_spec().is_like_windows { diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index d04bcb2d78aac..a008b36efe74e 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1562,6 +1562,7 @@ supported_targets! { ("aarch64-pc-windows-msvc", aarch64_pc_windows_msvc), ("aarch64-uwp-windows-msvc", aarch64_uwp_windows_msvc), + ("arm64ec-pc-windows-msvc", arm64ec_pc_windows_msvc), ("x86_64-pc-windows-msvc", x86_64_pc_windows_msvc), ("x86_64-uwp-windows-msvc", x86_64_uwp_windows_msvc), ("x86_64-win7-windows-msvc", x86_64_win7_windows_msvc), diff --git a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs new file mode 100644 index 0000000000000..de3e30cd238cb --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs @@ -0,0 +1,20 @@ +use crate::spec::{add_link_args, base, LinkerFlavor, Lld, Target}; + +pub fn target() -> Target { + let mut base = base::windows_msvc::opts(); + base.max_atomic_width = Some(128); + base.features = "+v8a,+neon,+fp-armv8".into(); + add_link_args( + &mut base.late_link_args, + LinkerFlavor::Msvc(Lld::No), + &["/machine:arm64ec", "softintrin.lib"], + ); + + Target { + llvm_target: "arm64ec-pc-windows-msvc".into(), + pointer_width: 64, + data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".into(), + arch: "arm64ec".into(), + options: base, + } +} diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs index 2b7ac68c21dfb..af5a565fdc9d3 100644 --- a/compiler/rustc_target/src/target_features.rs +++ b/compiler/rustc_target/src/target_features.rs @@ -409,7 +409,7 @@ impl super::spec::Target { pub fn supported_target_features(&self) -> &'static [(&'static str, Stability)] { match &*self.arch { "arm" => ARM_ALLOWED_FEATURES, - "aarch64" => AARCH64_ALLOWED_FEATURES, + "aarch64" | "arm64ec" => AARCH64_ALLOWED_FEATURES, "x86" | "x86_64" => X86_ALLOWED_FEATURES, "hexagon" => HEXAGON_ALLOWED_FEATURES, "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_ALLOWED_FEATURES, @@ -425,7 +425,7 @@ impl super::spec::Target { pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] { match &*self.arch { - "aarch64" => AARCH64_TIED_FEATURES, + "aarch64" | "arm64ec" => AARCH64_TIED_FEATURES, _ => &[], } } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 965d788bb8371..d777ed23759b2 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -91,7 +91,7 @@ const EXTRA_CHECK_CFGS: &[(Option, &str, Option<&[&'static str]>)] = &[ /* Extra values not defined in the built-in targets yet, but used in std */ (Some(Mode::Std), "target_env", Some(&["libnx"])), // (Some(Mode::Std), "target_os", Some(&[])), - (Some(Mode::Std), "target_arch", Some(&["spirv", "nvptx", "xtensa"])), + (Some(Mode::Std), "target_arch", Some(&["arm64ec", "spirv", "nvptx", "xtensa"])), /* Extra names used by dependencies */ // FIXME: Used by serde_json, but we should not be triggering on external dependencies. (Some(Mode::Rustc), "no_btreemap_remove_entry", None), diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 1f9307203bc3c..da2ca3d0a3710 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -18,6 +18,7 @@ - [arm64e-apple-ios.md](platform-support/arm64e-apple-ios.md) - [arm64e-apple-darwin.md](platform-support/arm64e-apple-darwin.md) - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md) + - [arm64ec-pc-windows-msvc](platform-support/arm64ec-pc-windows-msvc.md) - [\*-apple-tvos](platform-support/apple-tvos.md) - [\*-apple-watchos\*](platform-support/apple-watchos.md) - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 80d9dc85f162a..9edbf4acac9ce 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -236,6 +236,7 @@ target | std | host | notes -------|:---:|:----:|------- [`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS [`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin +[`arm64ec-pc-windows-msvc`](platform-support/arm64ec-pc-windows-msvc.md) | ? | | Arm64EC Windows MSVC `aarch64-apple-ios-macabi` | ? | | Apple Catalyst on ARM64 [`aarch64-apple-tvos`](platform-support/apple-tvos.md) | ? | | ARM64 tvOS [`aarch64-apple-tvos-sim`](platform-support/apple-tvos.md) | ? | | ARM64 tvOS Simulator diff --git a/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md b/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md new file mode 100644 index 0000000000000..1bb2c677b0809 --- /dev/null +++ b/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md @@ -0,0 +1,69 @@ +# `arm64ec-pc-windows-msvc` + +**Tier: 3** + +Arm64EC ("Emulation Compatible") for mixed architecture (AArch64 and x86_64) +applications on AArch64 Windows 11. See . + +## Target maintainers + +- [@dpaoliello](https://github.com/dpaoliello) + +## Requirements + +Target only supports cross-compilation, `core` and `alloc` are supported but +`std` is not. + +Builds Arm64EC static and dynamic libraries and executables which can be run on +AArch64 Windows 11 devices. Arm64EC static libraries can also be linked into +Arm64X dynamic libraries and executables. + +Uses `arm64ec` as its `target_arch` - code built for Arm64EC must be compatible +with x86_64 code (e.g., same structure layouts, function signatures, etc.) but +use AArch64 intrinsics. + +Only supported backend is LLVM 18 (or above). + +## Building the target + +You can build Rust with support for the targets by adding it to the `target` +list in `config.toml` and disabling `std`: + +```toml +[build] +target = [ "arm64ec-pc-windows-msvc" ] + +[target.arm64ec-pc-windows-msvc] +no-std = true +``` + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +## Testing + +Tests can be run on AArch64 Windows 11 devices. + +Since this is a `no_std` target, the Rust test suite is not supported. + +## Cross-compilation toolchains and C code + +C code can be built using the Arm64-targetting MSVC toolchain. + +To compile: + +```bash +cl /arm64EC /c ... +``` + +To link: + +```bash +link /MACHINE:ARM64EC ... +``` + +Further reading: diff --git a/tests/assembly/targets/targets-pe.rs b/tests/assembly/targets/targets-pe.rs index 63b07ee4d1a9d..6415aee6fae90 100644 --- a/tests/assembly/targets/targets-pe.rs +++ b/tests/assembly/targets/targets-pe.rs @@ -12,6 +12,9 @@ //@ revisions: aarch64_uwp_windows_msvc //@ [aarch64_uwp_windows_msvc] compile-flags: --target aarch64-uwp-windows-msvc //@ [aarch64_uwp_windows_msvc] needs-llvm-components: aarch64 +//@ revisions: arm64ec_pc_windows_msvc +//@ [arm64ec_pc_windows_msvc] compile-flags: --target arm64ec-pc-windows-msvc +//@ [arm64ec_pc_windows_msvc] needs-llvm-components: aarch64 //@ revisions: avr_unknown_gnu_atmega328 //@ [avr_unknown_gnu_atmega328] compile-flags: --target avr-unknown-gnu-atmega328 //@ [avr_unknown_gnu_atmega328] needs-llvm-components: avr diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 5f52421fef5b2..587b54475b2d9 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -118,7 +118,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_arch = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_arch` are: `aarch64`, `arm`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64` + = note: expected values for `target_arch` are: `aarch64`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` From a9907b1fdf2887a9839d81e70c7d98d69265fde0 Mon Sep 17 00:00:00 2001 From: "HTGAzureX1212." <39023054+HTGAzureX1212@users.noreply.github.com> Date: Wed, 28 Feb 2024 20:26:19 +0800 Subject: [PATCH 02/14] remove Mutex::unlock --- library/std/src/sync/mutex.rs | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs index fa91f9d907aff..65ff10e02d466 100644 --- a/library/std/src/sync/mutex.rs +++ b/library/std/src/sync/mutex.rs @@ -369,26 +369,6 @@ impl Mutex { } } - /// Immediately drops the guard, and consequently unlocks the mutex. - /// - /// This function is equivalent to calling [`drop`] on the guard but is more self-documenting. - /// Alternately, the guard will be automatically dropped when it goes out of scope. - /// - /// ``` - /// #![feature(mutex_unlock)] - /// - /// use std::sync::Mutex; - /// let mutex = Mutex::new(0); - /// - /// let mut guard = mutex.lock().unwrap(); - /// *guard += 20; - /// Mutex::unlock(guard); - /// ``` - #[unstable(feature = "mutex_unlock", issue = "81872")] - pub fn unlock(guard: MutexGuard<'_, T>) { - drop(guard); - } - /// Determines whether the mutex is poisoned. /// /// If another thread is active, the mutex can still become poisoned at any From 49961947c8a830fc1d5d4ecc5916267a7e4bb6b0 Mon Sep 17 00:00:00 2001 From: Veera Date: Wed, 21 Feb 2024 16:46:57 -0500 Subject: [PATCH 03/14] Improve error messages for generics with default parameters Fixes #120785 --- .../src/infer/error_reporting/mod.rs | 21 ++++++++++++--- compiler/rustc_middle/src/ty/generics.rs | 27 +++++++++++++++++++ ...-for-generics-with-default-issue-120785.rs | 11 ++++++++ ...-generics-with-default-issue-120785.stderr | 27 +++++++++++++++++++ 4 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 tests/ui/type/clarify-error-for-generics-with-default-issue-120785.rs create mode 100644 tests/ui/type/clarify-error-for-generics-with-default-issue-120785.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 911b2f16c8b05..38214ab72e696 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1247,10 +1247,23 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { (&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => { let did1 = def1.did(); let did2 = def2.did(); - let sub_no_defaults_1 = - self.tcx.generics_of(did1).own_args_no_defaults(self.tcx, sub1); - let sub_no_defaults_2 = - self.tcx.generics_of(did2).own_args_no_defaults(self.tcx, sub2); + + let generics1 = self.tcx.generics_of(did1); + let generics2 = self.tcx.generics_of(did2); + + let non_default_after_default = generics1 + .check_concrete_type_after_default(self.tcx, sub1) + || generics2.check_concrete_type_after_default(self.tcx, sub2); + let sub_no_defaults_1 = if non_default_after_default { + generics1.own_args(sub1) + } else { + generics1.own_args_no_defaults(self.tcx, sub1) + }; + let sub_no_defaults_2 = if non_default_after_default { + generics2.own_args(sub2) + } else { + generics2.own_args_no_defaults(self.tcx, sub2) + }; let mut values = (DiagStyledString::new(), DiagStyledString::new()); let path1 = self.tcx.def_path_str(did1); let path2 = self.tcx.def_path_str(did2); diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index c81d9dfbc7d60..4f75b7b42fb23 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -360,6 +360,33 @@ impl<'tcx> Generics { let own = &args[self.parent_count..][..self.params.len()]; if self.has_self && self.parent.is_none() { &own[1..] } else { own } } + + /// Returns true if a concrete type is specified after a default type. + /// For example, consider `struct T>(W, X)` + /// `T` will return true + /// `T` will return false + pub fn check_concrete_type_after_default( + &'tcx self, + tcx: TyCtxt<'tcx>, + args: &'tcx [ty::GenericArg<'tcx>], + ) -> bool { + let mut default_param_seen = false; + for param in self.params.iter() { + if param + .default_value(tcx) + .is_some_and(|default| default.instantiate(tcx, args) == args[param.index as usize]) + { + default_param_seen = true; + } else if default_param_seen + && param.default_value(tcx).is_some_and(|default| { + default.instantiate(tcx, args) != args[param.index as usize] + }) + { + return true; + } + } + false + } } /// Bounds on generics. diff --git a/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.rs b/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.rs new file mode 100644 index 0000000000000..a39c0049d01d0 --- /dev/null +++ b/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.rs @@ -0,0 +1,11 @@ +struct What>(W, X); + +fn main() { + let mut b: What = What(5, vec![1, 2, 3]); + let c: What = What(1, String::from("meow")); + b = c; //~ ERROR mismatched types + + let mut e: What = What(5, vec![1, 2, 3]); + let f: What> = What(1, vec![String::from("meow")]); + e = f; //~ ERROR mismatched types +} diff --git a/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.stderr b/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.stderr new file mode 100644 index 0000000000000..60fd18b968ca5 --- /dev/null +++ b/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.stderr @@ -0,0 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/clarify-error-for-generics-with-default-issue-120785.rs:6:9 + | +LL | let mut b: What = What(5, vec![1, 2, 3]); + | ----------- expected due to this type +LL | let c: What = What(1, String::from("meow")); +LL | b = c; + | ^ expected `What`, found `What` + | + = note: expected struct `What<_, Vec>` + found struct `What<_, String>` + +error[E0308]: mismatched types + --> $DIR/clarify-error-for-generics-with-default-issue-120785.rs:10:9 + | +LL | let mut e: What = What(5, vec![1, 2, 3]); + | ----------- expected due to this type +LL | let f: What> = What(1, vec![String::from("meow")]); +LL | e = f; + | ^ expected `What`, found `What>` + | + = note: expected struct `What<_, Vec>` + found struct `What<_, Vec>` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From 3ba50b36e7a20036c7b2c47ab551508b923b0004 Mon Sep 17 00:00:00 2001 From: Veera Date: Thu, 22 Feb 2024 21:37:11 -0500 Subject: [PATCH 04/14] Avoid code duplication --- compiler/rustc_middle/src/ty/generics.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 4f75b7b42fb23..2630b96869bae 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -372,17 +372,14 @@ impl<'tcx> Generics { ) -> bool { let mut default_param_seen = false; for param in self.params.iter() { - if param - .default_value(tcx) - .is_some_and(|default| default.instantiate(tcx, args) == args[param.index as usize]) + if let Some(inst) = + param.default_value(tcx).map(|default| default.instantiate(tcx, args)) { - default_param_seen = true; - } else if default_param_seen - && param.default_value(tcx).is_some_and(|default| { - default.instantiate(tcx, args) != args[param.index as usize] - }) - { - return true; + if inst == args[param.index as usize] { + default_param_seen = true; + } else if default_param_seen { + return true; + } } } false From cc13f8278f22243a6ecd82d062c4740787a0fc51 Mon Sep 17 00:00:00 2001 From: Veera Date: Fri, 23 Feb 2024 13:22:14 -0500 Subject: [PATCH 05/14] Update item order in test --- ...error-for-generics-with-default-issue-120785.rs | 6 +++--- ...r-for-generics-with-default-issue-120785.stderr | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.rs b/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.rs index a39c0049d01d0..7a923179d3b73 100644 --- a/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.rs +++ b/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.rs @@ -5,7 +5,7 @@ fn main() { let c: What = What(1, String::from("meow")); b = c; //~ ERROR mismatched types - let mut e: What = What(5, vec![1, 2, 3]); - let f: What> = What(1, vec![String::from("meow")]); - e = f; //~ ERROR mismatched types + let mut f: What> = What(1, vec![String::from("meow")]); + let e: What = What(5, vec![1, 2, 3]); + f = e; //~ ERROR mismatched types } diff --git a/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.stderr b/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.stderr index 60fd18b968ca5..d2b3397fbcb03 100644 --- a/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.stderr +++ b/tests/ui/type/clarify-error-for-generics-with-default-issue-120785.stderr @@ -13,14 +13,14 @@ LL | b = c; error[E0308]: mismatched types --> $DIR/clarify-error-for-generics-with-default-issue-120785.rs:10:9 | -LL | let mut e: What = What(5, vec![1, 2, 3]); - | ----------- expected due to this type -LL | let f: What> = What(1, vec![String::from("meow")]); -LL | e = f; - | ^ expected `What`, found `What>` +LL | let mut f: What> = What(1, vec![String::from("meow")]); + | ------------------------ expected due to this type +LL | let e: What = What(5, vec![1, 2, 3]); +LL | f = e; + | ^ expected `What>`, found `What` | - = note: expected struct `What<_, Vec>` - found struct `What<_, Vec>` + = note: expected struct `What<_, Vec>` + found struct `What<_, Vec>` error: aborting due to 2 previous errors From a7832b14b14e1af2e1e8a2cbf56b5b797892bee3 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 28 Feb 2024 18:21:24 +1100 Subject: [PATCH 06/14] Make the success arms of `if lhs || rhs` meet up in a separate block In the previous code, the success block of `lhs` would jump directly to the success block of `rhs`. However, `rhs_success_block` could already contain statements that are specific to the RHS, and the direct goto causes them to be executed in the LHS success path as well. This patch therefore creates a fresh block that the LHS and RHS success blocks can both jump to. --- .../rustc_mir_build/src/build/matches/mod.rs | 10 ++- ...n_conditional.test_complex.built.after.mir | 78 ++++++++++--------- ..._or_in_conditional.test_or.built.after.mir | 26 ++++--- 3 files changed, 64 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 641a278c1d3da..6cdb78d1a9413 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -93,8 +93,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { variable_source_info, true, )); - this.cfg.goto(lhs_success_block, variable_source_info, rhs_success_block); - rhs_success_block.unit() + + // Make the LHS and RHS success arms converge to a common block. + // (We can't just make LHS goto RHS, because `rhs_success_block` + // might contain statements that we don't want on the LHS path.) + let success_block = this.cfg.start_new_block(); + this.cfg.goto(lhs_success_block, variable_source_info, success_block); + this.cfg.goto(rhs_success_block, variable_source_info, success_block); + success_block.unit() } ExprKind::Unary { op: UnOp::Not, arg } => { let local_scope = this.local_scope(); diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir index 89572177b1d28..fd8eb370ca958 100644 --- a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir +++ b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir @@ -19,7 +19,7 @@ fn test_complex() -> () { bb0: { StorageLive(_1); StorageLive(_2); - _2 = E::f() -> [return: bb1, unwind: bb37]; + _2 = E::f() -> [return: bb1, unwind: bb38]; } bb1: { @@ -34,7 +34,7 @@ fn test_complex() -> () { } bb3: { - goto -> bb22; + goto -> bb23; } bb4: { @@ -51,7 +51,7 @@ fn test_complex() -> () { bb7: { StorageLive(_4); - _4 = always_true() -> [return: bb8, unwind: bb37]; + _4 = always_true() -> [return: bb8, unwind: bb38]; } bb8: { @@ -73,7 +73,7 @@ fn test_complex() -> () { } bb11: { - drop(_7) -> [return: bb13, unwind: bb37]; + drop(_7) -> [return: bb13, unwind: bb38]; } bb12: { @@ -83,11 +83,11 @@ fn test_complex() -> () { bb13: { StorageDead(_7); StorageDead(_6); - goto -> bb19; + goto -> bb20; } bb14: { - drop(_7) -> [return: bb15, unwind: bb37]; + drop(_7) -> [return: bb15, unwind: bb38]; } bb15: { @@ -107,106 +107,110 @@ fn test_complex() -> () { } bb17: { - drop(_10) -> [return: bb19, unwind: bb37]; + drop(_10) -> [return: bb19, unwind: bb38]; } bb18: { - goto -> bb20; + goto -> bb21; } bb19: { StorageDead(_10); StorageDead(_9); - _1 = const (); - goto -> bb23; + goto -> bb20; } bb20: { - drop(_10) -> [return: bb21, unwind: bb37]; + _1 = const (); + goto -> bb24; } bb21: { - StorageDead(_10); - StorageDead(_9); - goto -> bb22; + drop(_10) -> [return: bb22, unwind: bb38]; } bb22: { - _1 = const (); + StorageDead(_10); + StorageDead(_9); goto -> bb23; } bb23: { + _1 = const (); + goto -> bb24; + } + + bb24: { StorageDead(_8); StorageDead(_5); StorageDead(_4); StorageDead(_2); StorageDead(_1); StorageLive(_11); - _11 = always_true() -> [return: bb24, unwind: bb37]; - } - - bb24: { - switchInt(move _11) -> [0: bb26, otherwise: bb25]; + _11 = always_true() -> [return: bb25, unwind: bb38]; } bb25: { - goto -> bb35; + switchInt(move _11) -> [0: bb27, otherwise: bb26]; } bb26: { - goto -> bb27; + goto -> bb36; } bb27: { - StorageLive(_12); - _12 = E::f() -> [return: bb28, unwind: bb37]; + goto -> bb28; } bb28: { - PlaceMention(_12); - _13 = discriminant(_12); - switchInt(move _13) -> [1: bb32, otherwise: bb30]; + StorageLive(_12); + _12 = E::f() -> [return: bb29, unwind: bb38]; } bb29: { - FakeRead(ForMatchedPlace(None), _12); - unreachable; + PlaceMention(_12); + _13 = discriminant(_12); + switchInt(move _13) -> [1: bb33, otherwise: bb31]; } bb30: { - goto -> bb35; + FakeRead(ForMatchedPlace(None), _12); + unreachable; } bb31: { - goto -> bb29; + goto -> bb36; } bb32: { - falseEdge -> [real: bb34, imaginary: bb30]; + goto -> bb30; } bb33: { - goto -> bb30; + falseEdge -> [real: bb35, imaginary: bb31]; } bb34: { - _0 = const (); - goto -> bb36; + goto -> bb31; } bb35: { _0 = const (); - goto -> bb36; + goto -> bb37; } bb36: { + _0 = const (); + goto -> bb37; + } + + bb37: { StorageDead(_11); StorageDead(_12); return; } - bb37 (cleanup): { + bb38 (cleanup): { resume; } } diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir index b84c17c21886e..3e7c116016cc1 100644 --- a/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir +++ b/tests/mir-opt/building/logical_or_in_conditional.test_or.built.after.mir @@ -20,7 +20,7 @@ fn test_or() -> () { } bb1: { - drop(_3) -> [return: bb3, unwind: bb12]; + drop(_3) -> [return: bb3, unwind: bb13]; } bb2: { @@ -30,11 +30,11 @@ fn test_or() -> () { bb3: { StorageDead(_3); StorageDead(_2); - goto -> bb8; + goto -> bb9; } bb4: { - drop(_3) -> [return: bb5, unwind: bb12]; + drop(_3) -> [return: bb5, unwind: bb13]; } bb5: { @@ -50,38 +50,42 @@ fn test_or() -> () { } bb6: { - drop(_6) -> [return: bb8, unwind: bb12]; + drop(_6) -> [return: bb8, unwind: bb13]; } bb7: { - goto -> bb9; + goto -> bb10; } bb8: { StorageDead(_6); StorageDead(_5); - _0 = const (); - goto -> bb11; + goto -> bb9; } bb9: { - drop(_6) -> [return: bb10, unwind: bb12]; + _0 = const (); + goto -> bb12; } bb10: { + drop(_6) -> [return: bb11, unwind: bb13]; + } + + bb11: { StorageDead(_6); StorageDead(_5); _0 = const (); - goto -> bb11; + goto -> bb12; } - bb11: { + bb12: { StorageDead(_4); StorageDead(_1); return; } - bb12 (cleanup): { + bb13 (cleanup): { resume; } } From f11713be75dd8c50d9735d9bed7608a149e0f415 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Thu, 22 Feb 2024 18:42:53 +0000 Subject: [PATCH 07/14] Error on stray .stderr/.stdout files for (un-)revisioned tests --- src/tools/tidy/src/iter_header.rs | 32 ++++ src/tools/tidy/src/lib.rs | 2 + src/tools/tidy/src/main.rs | 1 + src/tools/tidy/src/target_specific_tests.rs | 28 +--- .../tests_revision_unpaired_stdout_stderr.rs | 146 ++++++++++++++++++ src/tools/tidy/src/walk.rs | 17 ++ 6 files changed, 202 insertions(+), 24 deletions(-) create mode 100644 src/tools/tidy/src/iter_header.rs create mode 100644 src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs diff --git a/src/tools/tidy/src/iter_header.rs b/src/tools/tidy/src/iter_header.rs new file mode 100644 index 0000000000000..ae635904607e7 --- /dev/null +++ b/src/tools/tidy/src/iter_header.rs @@ -0,0 +1,32 @@ +const COMMENT: &str = "//@"; + +/// A header line, like `//@name: value` consists of the prefix `//@` and the directive +/// `name: value`. It is also possibly revisioned, e.g. `//@[revision] name: value`. +pub(crate) struct HeaderLine<'ln> { + pub(crate) revision: Option<&'ln str>, + pub(crate) directive: &'ln str, +} + +/// Iterate through compiletest headers in a test contents. +/// +/// Adjusted from compiletest/src/header.rs. +pub(crate) fn iter_header<'ln>(contents: &'ln str, it: &mut dyn FnMut(HeaderLine<'ln>)) { + for ln in contents.lines() { + let ln = ln.trim(); + + // We're left with potentially `[rev]name: value`. + let Some(remainder) = ln.strip_prefix(COMMENT) else { + continue; + }; + + if let Some(remainder) = remainder.trim_start().strip_prefix('[') { + let Some((revision, remainder)) = remainder.split_once(']') else { + panic!("malformed revision directive: expected `//@[rev]`, found `{ln}`"); + }; + // We trimmed off the `[rev]` portion, left with `name: value`. + it(HeaderLine { revision: Some(revision), directive: remainder.trim() }); + } else { + it(HeaderLine { revision: None, directive: remainder.trim() }); + } + } +} diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 9514998703346..6f3ade0ab58c7 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -65,6 +65,7 @@ pub mod ext_tool_checks; pub mod extdeps; pub mod features; pub mod fluent_alphabetical; +pub(crate) mod iter_header; pub mod mir_opt_tests; pub mod pal; pub mod rustdoc_css_themes; @@ -73,6 +74,7 @@ pub mod style; pub mod target_policy; pub mod target_specific_tests; pub mod tests_placement; +pub mod tests_revision_unpaired_stdout_stderr; pub mod ui_tests; pub mod unit_tests; pub mod unstable_book; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 870322c44fb85..4b98c91319da0 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -100,6 +100,7 @@ fn main() { // Checks over tests. check!(tests_placement, &root_path); + check!(tests_revision_unpaired_stdout_stderr, &tests_path); check!(debug_artifacts, &tests_path); check!(ui_tests, &tests_path, bless); check!(mir_opt_tests, &tests_path, bless); diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs index c6136a18bd8c6..cb242bff05d1d 100644 --- a/src/tools/tidy/src/target_specific_tests.rs +++ b/src/tools/tidy/src/target_specific_tests.rs @@ -4,32 +4,12 @@ use std::collections::BTreeMap; use std::path::Path; +use crate::iter_header::{iter_header, HeaderLine}; use crate::walk::filter_not_rust; -const COMMENT: &str = "//@"; const LLVM_COMPONENTS_HEADER: &str = "needs-llvm-components:"; const COMPILE_FLAGS_HEADER: &str = "compile-flags:"; -/// Iterate through compiletest headers in a test contents. -/// -/// Adjusted from compiletest/src/header.rs. -fn iter_header<'a>(contents: &'a str, it: &mut dyn FnMut(Option<&'a str>, &'a str)) { - for ln in contents.lines() { - let ln = ln.trim(); - if ln.starts_with(COMMENT) && ln[COMMENT.len()..].trim_start().starts_with('[') { - if let Some(close_brace) = ln.find(']') { - let open_brace = ln.find('[').unwrap(); - let lncfg = &ln[open_brace + 1..close_brace]; - it(Some(lncfg), ln[(close_brace + 1)..].trim_start()); - } else { - panic!("malformed condition directive: expected `//[foo]`, found `{ln}`") - } - } else if ln.starts_with(COMMENT) { - it(None, ln[COMMENT.len()..].trim_start()); - } - } -} - #[derive(Default, Debug)] struct RevisionInfo<'a> { target_arch: Option<&'a str>, @@ -40,9 +20,9 @@ pub fn check(path: &Path, bad: &mut bool) { crate::walk::walk(path, |path, _is_dir| filter_not_rust(path), &mut |entry, content| { let file = entry.path().display(); let mut header_map = BTreeMap::new(); - iter_header(content, &mut |cfg, directive| { + iter_header(content, &mut |HeaderLine { revision, directive }| { if let Some(value) = directive.strip_prefix(LLVM_COMPONENTS_HEADER) { - let info = header_map.entry(cfg).or_insert(RevisionInfo::default()); + let info = header_map.entry(revision).or_insert(RevisionInfo::default()); let comp_vec = info.llvm_components.get_or_insert(Vec::new()); for component in value.split(' ') { let component = component.trim(); @@ -56,7 +36,7 @@ pub fn check(path: &Path, bad: &mut bool) { if let Some((arch, _)) = v.trim_start_matches(|c| c == ' ' || c == '=').split_once("-") { - let info = header_map.entry(cfg).or_insert(RevisionInfo::default()); + let info = header_map.entry(revision).or_insert(RevisionInfo::default()); info.target_arch.replace(arch); } else { eprintln!("{file}: seems to have a malformed --target value"); diff --git a/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs b/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs new file mode 100644 index 0000000000000..394f95e9144d2 --- /dev/null +++ b/src/tools/tidy/src/tests_revision_unpaired_stdout_stderr.rs @@ -0,0 +1,146 @@ +//! Checks that there are no unpaired `.stderr` or `.stdout` for a test with and without revisions. + +use std::collections::{BTreeMap, BTreeSet}; +use std::ffi::OsStr; +use std::path::Path; + +use crate::iter_header::*; +use crate::walk::*; + +// Should be kept in sync with `CompareMode` in `src/tools/compiletest/src/common.rs`, +// as well as `run`. +const IGNORES: &[&str] = &[ + "polonius", + "chalk", + "split-dwarf", + "split-dwarf-single", + "next-solver-coherence", + "next-solver", + "run", +]; +const EXTENSIONS: &[&str] = &["stdout", "stderr"]; +const SPECIAL_TEST: &str = "tests/ui/command/need-crate-arg-ignore-tidy.x.rs"; + +pub fn check(tests_path: impl AsRef, bad: &mut bool) { + // Recurse over subdirectories under `tests/` + walk_dir(tests_path.as_ref(), filter, &mut |entry| { + // We are inspecting a folder. Collect the paths to interesting files `.rs`, `.stderr`, + // `.stdout` under the current folder (shallow). + let mut files_under_inspection = BTreeSet::new(); + for sibling in std::fs::read_dir(entry.path()).unwrap() { + let Ok(sibling) = sibling else { + continue; + }; + + if sibling.path().is_dir() { + continue; + } + + let sibling_path = sibling.path(); + + let Some(ext) = sibling_path.extension().map(OsStr::to_str).flatten() else { + continue; + }; + + if ext == "rs" || EXTENSIONS.contains(&ext) { + files_under_inspection.insert(sibling_path); + } + } + + let mut test_info = BTreeMap::new(); + + for test in + files_under_inspection.iter().filter(|f| f.extension().is_some_and(|ext| ext == "rs")) + { + if test.ends_with(SPECIAL_TEST) { + continue; + } + + let mut expected_revisions = BTreeSet::new(); + + let contents = std::fs::read_to_string(test).unwrap(); + + // Collect directives. + iter_header(&contents, &mut |HeaderLine { revision, directive }| { + // We're trying to *find* `//@ revision: xxx` directives themselves, not revisioned + // directives. + if revision.is_some() { + return; + } + + let directive = directive.trim(); + + if directive.starts_with("revisions") { + let Some((name, value)) = directive.split_once([':', ' ']) else { + return; + }; + + if name == "revisions" { + let revs = value.split(' '); + for rev in revs { + expected_revisions.insert(rev.to_owned()); + } + } + } + }); + + let Some((test_name, _)) = test.to_str().map(|s| s.split_once('.')).flatten() else { + continue; + }; + + test_info.insert(test_name.to_string(), (test, expected_revisions)); + } + + // Our test file `foo.rs` has specified no revisions. There should not be any + // `foo.rev{.stderr,.stdout}` files. rustc-dev-guide says test output files can have names + // of the form: `test-name.revision.compare_mode.extension`, but our only concern is + // `test-name.revision` and `extension`. + for sibling in files_under_inspection.iter().filter(|f| { + f.extension().map(OsStr::to_str).flatten().is_some_and(|ext| EXTENSIONS.contains(&ext)) + }) { + let filename_components = sibling.to_str().unwrap().split('.').collect::>(); + let file_prefix = filename_components[0]; + + let Some((test_path, expected_revisions)) = test_info.get(file_prefix) else { + continue; + }; + + match filename_components[..] { + // Cannot have a revision component, skip. + [] | [_] => return, + [_, _] if !expected_revisions.is_empty() => { + // Found unrevisioned output files for a revisioned test. + tidy_error!( + bad, + "found unrevisioned output file `{}` for a revisioned test `{}`", + sibling.display(), + test_path.display(), + ); + } + [_, _] => return, + [_, found_revision, .., extension] => { + if !IGNORES.contains(&found_revision) + && !expected_revisions.contains(found_revision) + // This is from `//@ stderr-per-bitwidth` + && !(extension == "stderr" && ["32bit", "64bit"].contains(&found_revision)) + { + // Found some unexpected revision-esque component that is not a known + // compare-mode or expected revision. + tidy_error!( + bad, + "found output file `{}` for unexpected revision `{}` of test `{}`", + sibling.display(), + found_revision, + test_path.display() + ); + } + } + } + } + }); +} + +fn filter(path: &Path) -> bool { + filter_dirs(path) // ignore certain dirs + || (path.file_name().is_some_and(|name| name == "auxiliary")) // ignore auxiliary folder +} diff --git a/src/tools/tidy/src/walk.rs b/src/tools/tidy/src/walk.rs index 185e1f3209b10..851c21f1c0f05 100644 --- a/src/tools/tidy/src/walk.rs +++ b/src/tools/tidy/src/walk.rs @@ -86,3 +86,20 @@ pub(crate) fn walk_no_read( } } } + +// Walk through directories and skip symlinks. +pub(crate) fn walk_dir( + path: &Path, + skip: impl Send + Sync + 'static + Fn(&Path) -> bool, + f: &mut dyn FnMut(&DirEntry), +) { + let mut walker = ignore::WalkBuilder::new(path); + let walker = walker.filter_entry(move |e| !skip(e.path())); + for entry in walker.build() { + if let Ok(entry) = entry { + if entry.path().is_dir() { + f(&entry); + } + } + } +} From 19ee457ea34782006f08f336d63fcbb29b4f9cf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Thu, 22 Feb 2024 16:01:01 +0000 Subject: [PATCH 08/14] Remove stray stdout/stderr files --- .../bad-inputs-and-output.current.stderr | 48 ----------- .../bad-inputs-and-output.next.stderr | 48 ----------- .../basic.current_with.stderr | 11 --- .../basic.current_without.stderr | 29 ------- .../basic.next_with.stderr | 11 --- .../basic.next_without.stderr | 29 ------- .../issue-110963-early.current.stderr | 50 ------------ .../issue-110963-early.next.stderr | 50 ------------ .../issue-110963-late.current.stderr | 11 --- .../super-method-bound.current.stderr | 10 --- .../supertrait-bound.current.stderr | 11 --- .../supertrait-bound.next.stderr | 11 --- .../ty-or-ct-params.current.stderr | 28 ------- .../ty-or-ct-params.next.stderr | 28 ------- ...te-return_type_notation.cfg_current.stderr | 27 ------- ...-gate-return_type_notation.cfg_next.stderr | 27 ------- ...ate-return_type_notation.no_current.stderr | 13 --- ...e-gate-return_type_notation.no_next.stderr | 13 --- .../issue-71955.migrate.stderr | 79 ------------------- .../issue-40510-1.migrate.stderr | 13 --- .../issue-40510-3.migrate.stderr | 15 ---- .../old-lub-glb-hr-noteq1.baseleak.stderr | 21 ----- .../old-lub-glb-hr-noteq1.basenoleak.stderr | 12 --- 23 files changed, 595 deletions(-) delete mode 100644 tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.current.stderr delete mode 100644 tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.next.stderr delete mode 100644 tests/ui/associated-type-bounds/return-type-notation/basic.current_with.stderr delete mode 100644 tests/ui/associated-type-bounds/return-type-notation/basic.current_without.stderr delete mode 100644 tests/ui/associated-type-bounds/return-type-notation/basic.next_with.stderr delete mode 100644 tests/ui/associated-type-bounds/return-type-notation/basic.next_without.stderr delete mode 100644 tests/ui/async-await/return-type-notation/issue-110963-early.current.stderr delete mode 100644 tests/ui/async-await/return-type-notation/issue-110963-early.next.stderr delete mode 100644 tests/ui/async-await/return-type-notation/issue-110963-late.current.stderr delete mode 100644 tests/ui/async-await/return-type-notation/super-method-bound.current.stderr delete mode 100644 tests/ui/async-await/return-type-notation/supertrait-bound.current.stderr delete mode 100644 tests/ui/async-await/return-type-notation/supertrait-bound.next.stderr delete mode 100644 tests/ui/async-await/return-type-notation/ty-or-ct-params.current.stderr delete mode 100644 tests/ui/async-await/return-type-notation/ty-or-ct-params.next.stderr delete mode 100644 tests/ui/feature-gates/feature-gate-return_type_notation.cfg_current.stderr delete mode 100644 tests/ui/feature-gates/feature-gate-return_type_notation.cfg_next.stderr delete mode 100644 tests/ui/feature-gates/feature-gate-return_type_notation.no_current.stderr delete mode 100644 tests/ui/feature-gates/feature-gate-return_type_notation.no_next.stderr delete mode 100644 tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.migrate.stderr delete mode 100644 tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.migrate.stderr delete mode 100644 tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.migrate.stderr delete mode 100644 tests/ui/lub-glb/old-lub-glb-hr-noteq1.baseleak.stderr delete mode 100644 tests/ui/lub-glb/old-lub-glb-hr-noteq1.basenoleak.stderr diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.current.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.current.stderr deleted file mode 100644 index 65f7a72fbff5f..0000000000000 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.current.stderr +++ /dev/null @@ -1,48 +0,0 @@ -error: return type notation uses `()` instead of `(..)` for elided arguments - --> $DIR/bad-inputs-and-output.rs:20:24 - | -LL | fn baz>() {} - | ^^ help: remove the `..` - -error[E0658]: associated type bounds are unstable - --> $DIR/bad-inputs-and-output.rs:12:17 - | -LL | fn foo>() {} - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #52662 for more information - = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable - -error[E0658]: associated type bounds are unstable - --> $DIR/bad-inputs-and-output.rs:16:17 - | -LL | fn bar (): Send>>() {} - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #52662 for more information - = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable - -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-inputs-and-output.rs:5:12 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: argument types not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:12:23 - | -LL | fn foo>() {} - | ^^^^^ help: remove the input types: `()` - -error: return type not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:16:25 - | -LL | fn bar (): Send>>() {} - | ^^^^^^ help: remove the return type - -error: aborting due to 5 previous errors; 1 warning emitted - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.next.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.next.stderr deleted file mode 100644 index 65f7a72fbff5f..0000000000000 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.next.stderr +++ /dev/null @@ -1,48 +0,0 @@ -error: return type notation uses `()` instead of `(..)` for elided arguments - --> $DIR/bad-inputs-and-output.rs:20:24 - | -LL | fn baz>() {} - | ^^ help: remove the `..` - -error[E0658]: associated type bounds are unstable - --> $DIR/bad-inputs-and-output.rs:12:17 - | -LL | fn foo>() {} - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #52662 for more information - = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable - -error[E0658]: associated type bounds are unstable - --> $DIR/bad-inputs-and-output.rs:16:17 - | -LL | fn bar (): Send>>() {} - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #52662 for more information - = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable - -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/bad-inputs-and-output.rs:5:12 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: argument types not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:12:23 - | -LL | fn foo>() {} - | ^^^^^ help: remove the input types: `()` - -error: return type not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:16:25 - | -LL | fn bar (): Send>>() {} - | ^^^^^^ help: remove the return type - -error: aborting due to 5 previous errors; 1 warning emitted - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.current_with.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.current_with.stderr deleted file mode 100644 index c4dc5d362964e..0000000000000 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.current_with.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/basic.rs:8:12 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.current_without.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.current_without.stderr deleted file mode 100644 index 3666007e3d388..0000000000000 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.current_without.stderr +++ /dev/null @@ -1,29 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/basic.rs:8:12 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: future cannot be sent between threads safely - --> $DIR/basic.rs:26:13 - | -LL | is_send(foo::()); - | ^^^^^^^^^^ future returned by `foo` is not `Send` - | - = help: within `impl Future>`, the trait `Send` is not implemented for `impl Future>` -note: future is not `Send` as it awaits another future which is not `Send` - --> $DIR/basic.rs:16:5 - | -LL | T::method().await?; - | ^^^^^^^^^^^ await occurs here on type `impl Future>`, which is not `Send` -note: required by a bound in `is_send` - --> $DIR/basic.rs:20:20 - | -LL | fn is_send(_: impl Send) {} - | ^^^^ required by this bound in `is_send` - -error: aborting due to 1 previous error; 1 warning emitted - diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.next_with.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.next_with.stderr deleted file mode 100644 index c4dc5d362964e..0000000000000 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.next_with.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/basic.rs:8:12 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.next_without.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.next_without.stderr deleted file mode 100644 index 3666007e3d388..0000000000000 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.next_without.stderr +++ /dev/null @@ -1,29 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/basic.rs:8:12 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: future cannot be sent between threads safely - --> $DIR/basic.rs:26:13 - | -LL | is_send(foo::()); - | ^^^^^^^^^^ future returned by `foo` is not `Send` - | - = help: within `impl Future>`, the trait `Send` is not implemented for `impl Future>` -note: future is not `Send` as it awaits another future which is not `Send` - --> $DIR/basic.rs:16:5 - | -LL | T::method().await?; - | ^^^^^^^^^^^ await occurs here on type `impl Future>`, which is not `Send` -note: required by a bound in `is_send` - --> $DIR/basic.rs:20:20 - | -LL | fn is_send(_: impl Send) {} - | ^^^^ required by this bound in `is_send` - -error: aborting due to 1 previous error; 1 warning emitted - diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.current.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.current.stderr deleted file mode 100644 index 77385e966ce2f..0000000000000 --- a/tests/ui/async-await/return-type-notation/issue-110963-early.current.stderr +++ /dev/null @@ -1,50 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-110963-early.rs:6:12 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0308]: mismatched types - --> $DIR/issue-110963-early.rs:17:5 - | -LL | / spawn(async move { -LL | | let mut hc = hc; -LL | | if !hc.check().await { -LL | | log_health_check_failure().await; -LL | | } -LL | | }); - | |______^ one type is more general than the other - | - = note: expected trait `Send` - found trait `for<'a> Send` -note: the lifetime requirement is introduced here - --> $DIR/issue-110963-early.rs:37:17 - | -LL | F: Future + Send + 'static, - | ^^^^ - -error[E0308]: mismatched types - --> $DIR/issue-110963-early.rs:17:5 - | -LL | / spawn(async move { -LL | | let mut hc = hc; -LL | | if !hc.check().await { -LL | | log_health_check_failure().await; -LL | | } -LL | | }); - | |______^ one type is more general than the other - | - = note: expected trait `Send` - found trait `for<'a> Send` -note: the lifetime requirement is introduced here - --> $DIR/issue-110963-early.rs:37:17 - | -LL | F: Future + Send + 'static, - | ^^^^ - -error: aborting due to 2 previous errors; 1 warning emitted - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.next.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.next.stderr deleted file mode 100644 index 77385e966ce2f..0000000000000 --- a/tests/ui/async-await/return-type-notation/issue-110963-early.next.stderr +++ /dev/null @@ -1,50 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-110963-early.rs:6:12 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -error[E0308]: mismatched types - --> $DIR/issue-110963-early.rs:17:5 - | -LL | / spawn(async move { -LL | | let mut hc = hc; -LL | | if !hc.check().await { -LL | | log_health_check_failure().await; -LL | | } -LL | | }); - | |______^ one type is more general than the other - | - = note: expected trait `Send` - found trait `for<'a> Send` -note: the lifetime requirement is introduced here - --> $DIR/issue-110963-early.rs:37:17 - | -LL | F: Future + Send + 'static, - | ^^^^ - -error[E0308]: mismatched types - --> $DIR/issue-110963-early.rs:17:5 - | -LL | / spawn(async move { -LL | | let mut hc = hc; -LL | | if !hc.check().await { -LL | | log_health_check_failure().await; -LL | | } -LL | | }); - | |______^ one type is more general than the other - | - = note: expected trait `Send` - found trait `for<'a> Send` -note: the lifetime requirement is introduced here - --> $DIR/issue-110963-early.rs:37:17 - | -LL | F: Future + Send + 'static, - | ^^^^ - -error: aborting due to 2 previous errors; 1 warning emitted - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/async-await/return-type-notation/issue-110963-late.current.stderr b/tests/ui/async-await/return-type-notation/issue-110963-late.current.stderr deleted file mode 100644 index 018f4f2207ae7..0000000000000 --- a/tests/ui/async-await/return-type-notation/issue-110963-late.current.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/issue-110963-late.rs:6:12 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/async-await/return-type-notation/super-method-bound.current.stderr b/tests/ui/async-await/return-type-notation/super-method-bound.current.stderr deleted file mode 100644 index 5f482b6087865..0000000000000 --- a/tests/ui/async-await/return-type-notation/super-method-bound.current.stderr +++ /dev/null @@ -1,10 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/super-method-bound.rs:6:31 - | -LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/async-await/return-type-notation/supertrait-bound.current.stderr b/tests/ui/async-await/return-type-notation/supertrait-bound.current.stderr deleted file mode 100644 index 928b321697cce..0000000000000 --- a/tests/ui/async-await/return-type-notation/supertrait-bound.current.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/supertrait-bound.rs:5:49 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/async-await/return-type-notation/supertrait-bound.next.stderr b/tests/ui/async-await/return-type-notation/supertrait-bound.next.stderr deleted file mode 100644 index 928b321697cce..0000000000000 --- a/tests/ui/async-await/return-type-notation/supertrait-bound.next.stderr +++ /dev/null @@ -1,11 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/supertrait-bound.rs:5:49 - | -LL | #![feature(return_type_notation)] - | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -warning: 1 warning emitted - diff --git a/tests/ui/async-await/return-type-notation/ty-or-ct-params.current.stderr b/tests/ui/async-await/return-type-notation/ty-or-ct-params.current.stderr deleted file mode 100644 index e2bbb6013fc48..0000000000000 --- a/tests/ui/async-await/return-type-notation/ty-or-ct-params.current.stderr +++ /dev/null @@ -1,28 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/ty-or-ct-params.rs:5:31 - | -LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: return type notation is not allowed for functions that have type parameters - --> $DIR/ty-or-ct-params.rs:16:12 - | -LL | async fn bar() {} - | - type parameter declared here -... -LL | T: Foo, - | ^^^^^^^^^^^ - -error: return type notation is not allowed for functions that have const parameters - --> $DIR/ty-or-ct-params.rs:16:25 - | -LL | async fn baz() {} - | -------------- const parameter declared here -... -LL | T: Foo, - | ^^^^^^^^^^^ - -error: aborting due to 2 previous errors; 1 warning emitted - diff --git a/tests/ui/async-await/return-type-notation/ty-or-ct-params.next.stderr b/tests/ui/async-await/return-type-notation/ty-or-ct-params.next.stderr deleted file mode 100644 index e2bbb6013fc48..0000000000000 --- a/tests/ui/async-await/return-type-notation/ty-or-ct-params.next.stderr +++ /dev/null @@ -1,28 +0,0 @@ -warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/ty-or-ct-params.rs:5:31 - | -LL | #![feature(return_type_notation)] | ^^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #109417 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: return type notation is not allowed for functions that have type parameters - --> $DIR/ty-or-ct-params.rs:16:12 - | -LL | async fn bar() {} - | - type parameter declared here -... -LL | T: Foo, - | ^^^^^^^^^^^ - -error: return type notation is not allowed for functions that have const parameters - --> $DIR/ty-or-ct-params.rs:16:25 - | -LL | async fn baz() {} - | -------------- const parameter declared here -... -LL | T: Foo, - | ^^^^^^^^^^^ - -error: aborting due to 2 previous errors; 1 warning emitted - diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg_current.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg_current.stderr deleted file mode 100644 index ce39f6b29713f..0000000000000 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg_current.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0658]: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:17:17 - | -LL | fn foo>() {} - | ^^^^^^^^^ - | - = note: see issue #109417 for more information - = help: add `#![feature(return_type_notation)]` to the crate attributes to enable - -error: parenthesized generic arguments cannot be used in associated type constraints - --> $DIR/feature-gate-return_type_notation.rs:17:17 - | -LL | fn foo>() {} - | ^-- - | | - | help: remove these parentheses - -error[E0220]: associated type `m` not found for `Trait` - --> $DIR/feature-gate-return_type_notation.rs:17:17 - | -LL | fn foo>() {} - | ^ associated type `m` not found - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0220, E0658. -For more information about an error, try `rustc --explain E0220`. diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg_next.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg_next.stderr deleted file mode 100644 index ce39f6b29713f..0000000000000 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg_next.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error[E0658]: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:17:17 - | -LL | fn foo>() {} - | ^^^^^^^^^ - | - = note: see issue #109417 for more information - = help: add `#![feature(return_type_notation)]` to the crate attributes to enable - -error: parenthesized generic arguments cannot be used in associated type constraints - --> $DIR/feature-gate-return_type_notation.rs:17:17 - | -LL | fn foo>() {} - | ^-- - | | - | help: remove these parentheses - -error[E0220]: associated type `m` not found for `Trait` - --> $DIR/feature-gate-return_type_notation.rs:17:17 - | -LL | fn foo>() {} - | ^ associated type `m` not found - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0220, E0658. -For more information about an error, try `rustc --explain E0220`. diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.no_current.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.no_current.stderr deleted file mode 100644 index d11359e7f48cd..0000000000000 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.no_current.stderr +++ /dev/null @@ -1,13 +0,0 @@ -warning: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:17:17 - | -LL | fn foo>() {} - | ^^^^^^^^^ - | - = note: see issue #109417 for more information - = help: add `#![feature(return_type_notation)]` to the crate attributes to enable - = warning: unstable syntax can change at any point in the future, causing a hard error! - = note: for more information, see issue #65860 - -warning: 1 warning emitted - diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.no_next.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.no_next.stderr deleted file mode 100644 index d11359e7f48cd..0000000000000 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.no_next.stderr +++ /dev/null @@ -1,13 +0,0 @@ -warning: return type notation is experimental - --> $DIR/feature-gate-return_type_notation.rs:17:17 - | -LL | fn foo>() {} - | ^^^^^^^^^ - | - = note: see issue #109417 for more information - = help: add `#![feature(return_type_notation)]` to the crate attributes to enable - = warning: unstable syntax can change at any point in the future, causing a hard error! - = note: for more information, see issue #65860 - -warning: 1 warning emitted - diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.migrate.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.migrate.stderr deleted file mode 100644 index 0f38f8e3283a2..0000000000000 --- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-71955.migrate.stderr +++ /dev/null @@ -1,79 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:54:5 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `for<'r, 's> FnOnce<(&'r &'s str,)>` - found type `for<'r> FnOnce<(&'r &str,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:54:24 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:34:9 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:54:5 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `FnOnce<(&&str,)>` - found type `for<'r> FnOnce<(&'r &str,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:54:24 - | -LL | foo(bar, "string", |s| s.len() == 5); - | ^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:34:44 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^ - -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:58:5 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `for<'r, 's> FnOnce<(&'r Wrapper<'s>,)>` - found type `for<'r> FnOnce<(&'r Wrapper<'_>,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:58:24 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:34:9 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error[E0308]: mismatched types - --> $DIR/issue-71955.rs:58:5 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `FnOnce<(&Wrapper<'_>,)>` - found type `for<'r> FnOnce<(&'r Wrapper<'_>,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-71955.rs:58:24 - | -LL | foo(baz, "string", |s| s.0.len() == 5); - | ^^^^^^^^^^^^^^^^^^ -note: the lifetime requirement is introduced here - --> $DIR/issue-71955.rs:34:44 - | -LL | F2: FnOnce(&::Output) -> bool - | ^^^^ - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.migrate.stderr b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.migrate.stderr deleted file mode 100644 index 2090530571b3b..0000000000000 --- a/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-1.migrate.stderr +++ /dev/null @@ -1,13 +0,0 @@ -error: captured variable cannot escape `FnMut` closure body - --> $DIR/issue-40510-1.rs:11:9 - | -LL | || { - | - inferred to be a `FnMut` closure -LL | &mut x - | ^^^^^^ returns a reference to a captured variable which escapes the closure body - | - = note: `FnMut` closures only have access to their captured variables while they are executing... - = note: ...therefore, they cannot allow references to captured variables to escape - -error: aborting due to 1 previous error - diff --git a/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.migrate.stderr b/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.migrate.stderr deleted file mode 100644 index 59aba4a8ef8ba..0000000000000 --- a/tests/ui/issues/issue-40510-captured-variable-return/issue-40510-3.migrate.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: captured variable cannot escape `FnMut` closure body - --> $DIR/issue-40510-3.rs:11:9 - | -LL | || { - | - inferred to be a `FnMut` closure -LL | / || { -LL | | x.push(()) -LL | | } - | |_________^ returns a closure that contains a reference to a captured variable, which then escapes the closure body - | - = note: `FnMut` closures only have access to their captured variables while they are executing... - = note: ...therefore, they cannot allow references to captured variables to escape - -error: aborting due to 1 previous error - diff --git a/tests/ui/lub-glb/old-lub-glb-hr-noteq1.baseleak.stderr b/tests/ui/lub-glb/old-lub-glb-hr-noteq1.baseleak.stderr deleted file mode 100644 index 0d1f9a7690f9d..0000000000000 --- a/tests/ui/lub-glb/old-lub-glb-hr-noteq1.baseleak.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0308]: `match` arms have incompatible types - --> $DIR/old-lub-glb-hr-noteq1.rs:17:14 - | -LL | let z = match 22 { - | _____________- -LL | | 0 => x, - | | - this is found to be of type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` -LL | | _ => y, - | | ^ one type is more general than the other -LL | | -... | -LL | | -LL | | }; - | |_____- `match` arms have incompatible types - | - = note: expected fn pointer `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` - found fn pointer `for<'a> fn(&'a u8, &'a u8) -> &'a u8` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/lub-glb/old-lub-glb-hr-noteq1.basenoleak.stderr b/tests/ui/lub-glb/old-lub-glb-hr-noteq1.basenoleak.stderr deleted file mode 100644 index 8396265356987..0000000000000 --- a/tests/ui/lub-glb/old-lub-glb-hr-noteq1.basenoleak.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/old-lub-glb-hr-noteq1.rs:17:14 - | -LL | _ => y, - | ^ one type is more general than the other - | - = note: expected fn pointer `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` - found fn pointer `for<'a> fn(&'a u8, &'a u8) -> &'a u8` - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. From 721c741756a023f13064a232280a72fceba0b813 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 1 Mar 2024 09:54:00 +1100 Subject: [PATCH 09/14] Remove unnecessary `Level::` qualifiers. We have `use Level::*;` in this file. --- compiler/rustc_errors/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 0a533833e64bd..c03d65f9454ac 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -780,11 +780,11 @@ impl DiagCtxt { let err = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key); err.map(|(err, guar)| { // The use of `::` is safe because level is `Level::Error`. - assert_eq!(err.level, Level::Error); + assert_eq!(err.level, Error); assert!(guar.is_some()); let mut err = Diag::::new_diagnostic(self, err); modify_err(&mut err); - assert_eq!(err.level, Level::Error); + assert_eq!(err.level, Error); err.emit() }) } @@ -803,7 +803,7 @@ impl DiagCtxt { let old_err = self.inner.borrow_mut().stashed_diagnostics.swap_remove(&key); match old_err { Some((old_err, guar)) => { - assert_eq!(old_err.level, Level::Error); + assert_eq!(old_err.level, Error); assert!(guar.is_some()); // Because `old_err` has already been counted, it can only be // safely cancelled because the `new_err` supplants it. @@ -1367,7 +1367,7 @@ impl DiagCtxtInner { } if diagnostic.has_future_breakage() { - // Future breakages aren't emitted if they're Level::Allow, + // Future breakages aren't emitted if they're `Level::Allow`, // but they still need to be constructed and stashed below, // so they'll trigger the must_produce_diag check. self.suppressed_expected_diag = true; @@ -1453,7 +1453,7 @@ impl DiagCtxtInner { diagnostic.children.extract_if(already_emitted_sub).for_each(|_| {}); if already_emitted { let msg = "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`"; - diagnostic.sub(Level::Note, msg, MultiSpan::new()); + diagnostic.sub(Note, msg, MultiSpan::new()); } if is_error { @@ -1623,7 +1623,7 @@ impl DiagCtxtInner { bug.arg("level", bug.level); let msg = crate::fluent_generated::errors_invalid_flushed_delayed_diagnostic_level; let msg = self.eagerly_translate_for_subdiag(&bug, msg); // after the `arg` call - bug.sub(Level::Note, msg, bug.span.primary_span().unwrap().into()); + bug.sub(Note, msg, bug.span.primary_span().unwrap().into()); } bug.level = Bug; @@ -1671,7 +1671,7 @@ impl DelayedDiagInner { diag.arg("emitted_at", diag.emitted_at.clone()); diag.arg("note", self.note); let msg = dcx.eagerly_translate_for_subdiag(&diag, msg); // after the `arg` calls - diag.sub(Level::Note, msg, diag.span.primary_span().unwrap_or(DUMMY_SP).into()); + diag.sub(Note, msg, diag.span.primary_span().unwrap_or(DUMMY_SP).into()); diag } } From 7e6416395140beaafdf50652f92e459d5965bde4 Mon Sep 17 00:00:00 2001 From: Ramon de C Valle Date: Thu, 29 Feb 2024 14:58:21 -0800 Subject: [PATCH 10/14] CFI: Remove unused `typeid_for_fnsig` Removes unused `typeid_for_fnsig` for simplifying the compiler CFI API. --- compiler/rustc_symbol_mangling/src/typeid.rs | 26 ++------------ .../src/typeid/typeid_itanium_cxx_abi.rs | 35 ------------------- 2 files changed, 2 insertions(+), 59 deletions(-) diff --git a/compiler/rustc_symbol_mangling/src/typeid.rs b/compiler/rustc_symbol_mangling/src/typeid.rs index 838d9d774b20c..e8763e49e624b 100644 --- a/compiler/rustc_symbol_mangling/src/typeid.rs +++ b/compiler/rustc_symbol_mangling/src/typeid.rs @@ -4,13 +4,13 @@ /// For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler, /// see design document in the tracking issue #89653. use bitflags::bitflags; -use rustc_middle::ty::{FnSig, Instance, Ty, TyCtxt}; +use rustc_middle::ty::{Instance, Ty, TyCtxt}; use rustc_target::abi::call::FnAbi; use std::hash::Hasher; use twox_hash::XxHash64; bitflags! { - /// Options for typeid_for_fnabi and typeid_for_fnsig. + /// Options for typeid_for_fnabi. #[derive(Clone, Copy, Debug)] pub struct TypeIdOptions: u32 { const GENERALIZE_POINTERS = 1; @@ -30,15 +30,6 @@ pub fn typeid_for_fnabi<'tcx>( typeid_itanium_cxx_abi::typeid_for_fnabi(tcx, fn_abi, options) } -/// Returns a type metadata identifier for the specified FnSig. -pub fn typeid_for_fnsig<'tcx>( - tcx: TyCtxt<'tcx>, - fn_sig: &FnSig<'tcx>, - options: TypeIdOptions, -) -> String { - typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, options) -} - /// Returns a type metadata identifier for the specified Instance. pub fn typeid_for_instance<'tcx>( tcx: TyCtxt<'tcx>, @@ -61,19 +52,6 @@ pub fn kcfi_typeid_for_fnabi<'tcx>( hash.finish() as u32 } -/// Returns a KCFI type metadata identifier for the specified FnSig. -pub fn kcfi_typeid_for_fnsig<'tcx>( - tcx: TyCtxt<'tcx>, - fn_sig: &FnSig<'tcx>, - options: TypeIdOptions, -) -> u32 { - // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the - // xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.) - let mut hash: XxHash64 = Default::default(); - hash.write(typeid_itanium_cxx_abi::typeid_for_fnsig(tcx, fn_sig, options).as_bytes()); - hash.finish() as u32 -} - /// Returns a KCFI type metadata identifier for the specified Instance. pub fn kcfi_typeid_for_instance<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 42d9b519c147f..57163dbb50167 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -1072,41 +1072,6 @@ pub fn typeid_for_fnabi<'tcx>( typeid } -/// Returns a type metadata identifier for the specified FnSig using the Itanium C++ ABI with vendor -/// extended type qualifiers and types for Rust types that are not used at the FFI boundary. -pub fn typeid_for_fnsig<'tcx>( - tcx: TyCtxt<'tcx>, - fn_sig: &FnSig<'tcx>, - options: TypeIdOptions, -) -> String { - // A name is mangled by prefixing "_Z" to an encoding of its name, and in the case of functions - // its type. - let mut typeid = String::from("_Z"); - - // Clang uses the Itanium C++ ABI's virtual tables and RTTI typeinfo structure name as type - // metadata identifiers for function pointers. The typeinfo name encoding is a two-character - // code (i.e., 'TS') prefixed to the type encoding for the function. - typeid.push_str("TS"); - - // A dictionary of substitution candidates used for compression (see - // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression). - let mut dict: FxHashMap, usize> = FxHashMap::default(); - - // Encode the function signature - typeid.push_str(&encode_fnsig(tcx, fn_sig, &mut dict, options)); - - // Add encoding suffixes - if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) { - typeid.push_str(".normalized"); - } - - if options.contains(EncodeTyOptions::GENERALIZE_POINTERS) { - typeid.push_str(".generalized"); - } - - typeid -} - /// Returns a type metadata identifier for the specified Instance using the Itanium C++ ABI with /// vendor extended type qualifiers and types for Rust types that are not used at the FFI boundary. pub fn typeid_for_instance<'tcx>( From 44f0043e82fb2d3156434797f2e638cb61b07ce9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 1 Mar 2024 09:20:08 +1100 Subject: [PATCH 11/14] Handle stashing of delayed bugs. By just emitting them immediately, because it does happen in practice, when errors are downgraded to delayed bugs. We already had one case in `lint.rs` where we handled this at the callsite. This commit changes things so it's handled within `stash_diagnostic` instead, because #121812 identified a second case, and it's possible there are more. Fixes #121812. --- compiler/rustc_errors/src/lib.rs | 36 +++++++++++++------ .../rustc_hir_analysis/src/astconv/lint.rs | 12 ++----- .../invalid-stashed-level-issue-121812.rs | 8 +++++ .../invalid-stashed-level-issue-121812.stderr | 9 +++++ 4 files changed, 44 insertions(+), 21 deletions(-) create mode 100644 tests/ui/typeck/invalid-stashed-level-issue-121812.rs create mode 100644 tests/ui/typeck/invalid-stashed-level-issue-121812.stderr diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index c03d65f9454ac..6b1ccbc5f7c40 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -712,6 +712,7 @@ impl DiagCtxt { /// Stashes a diagnostic for possible later improvement in a different, /// later stage of the compiler. Possible actions depend on the diagnostic /// level: + /// - Level::Bug, Level:Fatal: not allowed, will trigger a panic. /// - Level::Error: immediately counted as an error that has occurred, because it /// is guaranteed to be emitted eventually. Can be later accessed with the /// provided `span` and `key` through @@ -719,26 +720,39 @@ impl DiagCtxt { /// [`DiagCtxt::try_steal_replace_and_emit_err`]. These do not allow /// cancellation or downgrading of the error. Returns /// `Some(ErrorGuaranteed)`. + /// - Level::DelayedBug: this does happen occasionally with errors that are + /// downgraded to delayed bugs. It is not stashed, but immediately + /// emitted as a delayed bug. This is because stashing it would cause it + /// to be counted by `err_count` which we don't want. It doesn't matter + /// that we cannot steal and improve it later, because it's not a + /// user-facing error. Returns `Some(ErrorGuaranteed)` as is normal for + /// delayed bugs. /// - Level::Warning and lower (i.e. !is_error()): can be accessed with the /// provided `span` and `key` through [`DiagCtxt::steal_non_err()`]. This /// allows cancelling and downgrading of the diagnostic. Returns `None`. - /// - Others: not allowed, will trigger a panic. pub fn stash_diagnostic( &self, span: Span, key: StashKey, diag: DiagInner, ) -> Option { - let guar = if diag.level() == Level::Error { - // This `unchecked_error_guaranteed` is valid. It is where the - // `ErrorGuaranteed` for stashed errors originates. See - // `DiagCtxtInner::drop`. - #[allow(deprecated)] - Some(ErrorGuaranteed::unchecked_error_guaranteed()) - } else if !diag.is_error() { - None - } else { - self.span_bug(span, format!("invalid level in `stash_diagnostic`: {}", diag.level)); + let guar = match diag.level { + Bug | Fatal => { + self.span_bug( + span, + format!("invalid level in `stash_diagnostic`: {:?}", diag.level), + ); + } + Error => { + // This `unchecked_error_guaranteed` is valid. It is where the + // `ErrorGuaranteed` for stashed errors originates. See + // `DiagCtxtInner::drop`. + #[allow(deprecated)] + Some(ErrorGuaranteed::unchecked_error_guaranteed()) + } + DelayedBug => return self.inner.borrow_mut().emit_diagnostic(diag), + ForceWarning(_) | Warning | Note | OnceNote | Help | OnceHelp | FailureNote | Allow + | Expect(_) => None, }; // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs index 227254b4cc8b3..fb5f3426cea6a 100644 --- a/compiler/rustc_hir_analysis/src/astconv/lint.rs +++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs @@ -1,5 +1,5 @@ use rustc_ast::TraitObjectSyntax; -use rustc_errors::{codes::*, Diag, EmissionGuarantee, Level, StashKey}; +use rustc_errors::{codes::*, Diag, EmissionGuarantee, StashKey}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability}; @@ -237,15 +237,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } // check if the impl trait that we are considering is a impl of a local trait self.maybe_lint_blanket_trait_impl(self_ty, &mut diag); - match diag.level() { - Level::Error => { - diag.stash(self_ty.span, StashKey::TraitMissingMethod); - } - Level::DelayedBug => { - diag.emit(); - } - _ => unreachable!(), - } + diag.stash(self_ty.span, StashKey::TraitMissingMethod); } else { let msg = "trait objects without an explicit `dyn` are deprecated"; tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| { diff --git a/tests/ui/typeck/invalid-stashed-level-issue-121812.rs b/tests/ui/typeck/invalid-stashed-level-issue-121812.rs new file mode 100644 index 0000000000000..4b61f4f2c63ab --- /dev/null +++ b/tests/ui/typeck/invalid-stashed-level-issue-121812.rs @@ -0,0 +1,8 @@ +union U { + a: u16, + b: [u8; 3], +} + +fn main() { + _ = U { b: [()] }; //~ ERROR mismatched types +} diff --git a/tests/ui/typeck/invalid-stashed-level-issue-121812.stderr b/tests/ui/typeck/invalid-stashed-level-issue-121812.stderr new file mode 100644 index 0000000000000..9465935c8c235 --- /dev/null +++ b/tests/ui/typeck/invalid-stashed-level-issue-121812.stderr @@ -0,0 +1,9 @@ +error[E0308]: mismatched types + --> $DIR/invalid-stashed-level-issue-121812.rs:7:17 + | +LL | _ = U { b: [()] }; + | ^^ expected `u8`, found `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From 2064c19886dbea0eba87d8d05a9cd481bf4b391e Mon Sep 17 00:00:00 2001 From: r0cky Date: Fri, 1 Mar 2024 09:59:44 +0800 Subject: [PATCH 12/14] Remove unused fluent messages --- compiler/rustc_builtin_macros/messages.ftl | 6 ------ compiler/rustc_hir_analysis/messages.ftl | 2 -- compiler/rustc_parse/messages.ftl | 3 --- compiler/rustc_resolve/messages.ftl | 22 ---------------------- 4 files changed, 33 deletions(-) diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index dda466b026d91..bc2a9d5ad1e35 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -221,12 +221,6 @@ builtin_macros_requires_cfg_pattern = macro requires a cfg-pattern as an argument .label = cfg-pattern required -builtin_macros_should_panic = functions using `#[should_panic]` must return `()` - -builtin_macros_test_arg_non_lifetime = functions used as tests can not have any non-lifetime generic parameters - -builtin_macros_test_args = functions used as tests can not have any arguments - builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests .label = `{$kind}` because of this diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 89cd37e757fa2..e376411cd95c1 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -239,8 +239,6 @@ hir_analysis_missing_one_of_trait_item = not all trait items implemented, missin .label = missing one of `{$missing_items_msg}` in implementation .note = required because of this annotation -hir_analysis_missing_tilde_const = missing `~const` qualifier for specialization - hir_analysis_missing_trait_item = not all trait items implemented, missing: `{$missing_items_msg}` .label = missing `{$missing_items_msg}` in implementation diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 55baf6f9f2eb0..60cc138fd7bc2 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -284,9 +284,6 @@ parse_found_expr_would_be_stmt = expected expression, found `{$token}` parse_function_body_equals_expr = function body cannot be `= expression;` .suggestion = surround the expression with `{"{"}` and `{"}"}` instead of `=` and `;` -parse_gen_fn = `gen` functions are not yet implemented - .help = for now you can use `gen {"{}"}` blocks and return `impl Iterator` instead - parse_generic_args_in_pat_require_turbofish_syntax = generic args in patterns require the turbofish syntax parse_generic_parameters_without_angle_brackets = generic parameters without surrounding angle brackets diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 0747685c35c46..fa98338bbb6e8 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -8,10 +8,6 @@ resolve_add_as_non_derive = resolve_added_macro_use = have you added the `#[macro_use]` on the module/import? -resolve_ampersand_used_without_explicit_lifetime_name = - `&` without an explicit lifetime name cannot be used here - .note = explicit lifetime name needed here - resolve_ancestor_only = visibilities can only be restricted to ancestor modules @@ -100,12 +96,6 @@ resolve_const_param_in_non_trivial_anon_const = resolve_const_param_in_ty_of_const_param = const parameters may not be used in the type of const parameters -resolve_crate_may_not_be_imported = - `$crate` may not be imported - -resolve_crate_root_imports_must_be_named_explicitly = - crate root imports need to be explicitly named: `use crate as name;` - resolve_expected_found = expected module, found {$res} `{$path_str}` .label = not a module @@ -220,9 +210,6 @@ resolve_param_in_ty_of_const_param = the type of const parameters must not depend on other generic parameters .label = the type must not depend on the parameter `{$name}` -resolve_parent_module_reset_for_binding = - parent module is reset for binding - resolve_proc_macro_same_crate = can't use a procedural macro from the same crate that defines it .help = you can define integration tests in a directory named `tests` @@ -270,11 +257,6 @@ resolve_trait_impl_duplicate = .old_span_label = previous definition here .trait_item_span = item in trait -resolve_trait_impl_mismatch = - item `{$name}` is an associated {$kind}, which doesn't match its trait `{$trait_path}` - .label = does not match trait - .label_trait_item = item in trait - resolve_try_using_similarly_named_label = try using similarly named label @@ -295,10 +277,6 @@ resolve_undeclared_label = use of undeclared label `{$name}` .label = undeclared label `{$name}` -resolve_underscore_lifetime_name_cannot_be_used_here = - `'_` cannot be used here - .note = `'_` is a reserved lifetime name - resolve_unexpected_res_change_ty_to_const_param_sugg = you might have meant to write a const parameter here From beac5b12aa88da04d2434d5b86bec4345a018925 Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Fri, 1 Mar 2024 08:14:42 +0530 Subject: [PATCH 13/14] Fix typo in comment --- compiler/rustc_mir_transform/src/known_panics_lint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs index 7cab665099482..27477769cef85 100644 --- a/compiler/rustc_mir_transform/src/known_panics_lint.rs +++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs @@ -586,7 +586,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } Aggregate(ref kind, ref fields) => { - // Do not const pop union fields as they can be + // Do not const prop union fields as they can be // made to produce values that don't match their // underlying layout's type (see ICE #121534). // If the last element of the `Adt` tuple From 836ac98482ff93853dbf3aeb2d67ce5253f4b2e0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 28 Feb 2024 12:20:04 +0000 Subject: [PATCH 14/14] Stop using Bubble in coherence and instead emulate it with an intercrate check --- compiler/rustc_infer/src/infer/opaque_types.rs | 16 ++++++++++++++-- .../src/traits/coherence.rs | 2 -- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index ec674407e523d..db384598fc284 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -105,6 +105,16 @@ impl<'tcx> InferCtxt<'tcx> { let process = |a: Ty<'tcx>, b: Ty<'tcx>, a_is_expected| match *a.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => { let def_id = def_id.expect_local(); + if self.intercrate { + // See comment on `insert_hidden_type` for why this is sufficient in coherence + return Some(self.register_hidden_type( + OpaqueTypeKey { def_id, args }, + cause.clone(), + param_env, + b, + a_is_expected, + )); + } match self.defining_use_anchor { DefiningAnchor::Bind(_) => { // Check that this is `impl Trait` type is @@ -146,8 +156,10 @@ impl<'tcx> InferCtxt<'tcx> { } } DefiningAnchor::Bubble => {} - DefiningAnchor::Error => return None, - }; + DefiningAnchor::Error => { + return None; + } + } if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() { // We could accept this, but there are various ways to handle this situation, and we don't // want to make a decision on it right now. Likely this case is so super rare anyway, that diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index e82171de3789e..483d5e61f4653 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -26,7 +26,6 @@ use rustc_infer::traits::{util, TraitEngine, TraitEngineExt}; use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal}; use rustc_middle::traits::specialization_graph::OverlapMode; -use rustc_middle::traits::DefiningAnchor; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; @@ -190,7 +189,6 @@ fn overlap<'tcx>( let infcx = tcx .infer_ctxt() - .with_opaque_type_inference(DefiningAnchor::Bubble) .skip_leak_check(skip_leak_check.is_yes()) .intercrate(true) .with_next_trait_solver(tcx.next_trait_solver_in_coherence())