diff --git a/Cargo.lock b/Cargo.lock index 94798596fc8c0..ad6dac97a0af3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2591,9 +2591,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.32.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "compiler_builtins", "crc32fast", diff --git a/compiler/rustc_codegen_gcc/.github/workflows/ci.yml b/compiler/rustc_codegen_gcc/.github/workflows/ci.yml index 65e7a697ab0df..308bc55ead71e 100644 --- a/compiler/rustc_codegen_gcc/.github/workflows/ci.yml +++ b/compiler/rustc_codegen_gcc/.github/workflows/ci.yml @@ -99,8 +99,10 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore - ./y.sh build - cargo test + # TODO: remove --features master when it is back to the default. + ./y.sh build --features master + # TODO: remove --features master when it is back to the default. + cargo test --features master ./clean_all.sh - name: Prepare dependencies @@ -121,7 +123,8 @@ jobs: - name: Run tests run: | - ./test.sh --release --clean --build-sysroot ${{ matrix.commands }} + # TODO: remove --features master when it is back to the default. + ./test.sh --features master --release --clean --build-sysroot ${{ matrix.commands }} duplicates: runs-on: ubuntu-latest diff --git a/compiler/rustc_codegen_gcc/.github/workflows/failures.yml b/compiler/rustc_codegen_gcc/.github/workflows/failures.yml index 27864dcadd0fe..ae8de79b773db 100644 --- a/compiler/rustc_codegen_gcc/.github/workflows/failures.yml +++ b/compiler/rustc_codegen_gcc/.github/workflows/failures.yml @@ -21,11 +21,14 @@ jobs: libgccjit_version: - gcc: "libgccjit.so" artifacts_branch: "master" + # TODO: switch back to --no-default-features in the case of libgccjit 12 when the default is to enable + # master again. + extra: "--features master" - gcc: "libgccjit_without_int128.so" artifacts_branch: "master-without-128bit-integers" + extra: "--features master" - gcc: "libgccjit12.so" artifacts_branch: "gcc12" - extra: "--no-default-features" # FIXME(antoyo): we need to set GCC_EXEC_PREFIX so that the linker can find the linker plugin. # Not sure why it's not found otherwise. env_extra: "TEST_FLAGS='-Cpanic=abort -Zpanic-abort-tests' GCC_EXEC_PREFIX=/usr/lib/gcc/" diff --git a/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml b/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml index 55ee0a212142e..4d9d7e23dc2b5 100644 --- a/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml +++ b/compiler/rustc_codegen_gcc/.github/workflows/m68k.yml @@ -114,8 +114,10 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore --cross - ./y.sh build --target-triple m68k-unknown-linux-gnu - CG_GCC_TEST_TARGET=m68k-unknown-linux-gnu cargo test + # TODO: remove --features master when it is back to the default. + ./y.sh build --target-triple m68k-unknown-linux-gnu --features master + # TODO: remove --features master when it is back to the default. + CG_GCC_TEST_TARGET=m68k-unknown-linux-gnu cargo test --features master ./clean_all.sh - name: Prepare dependencies @@ -136,4 +138,5 @@ jobs: - name: Run tests run: | - ./test.sh --release --clean --build-sysroot ${{ matrix.commands }} + # TODO: remove --features master when it is back to the default. + ./test.sh --release --features master --clean --build-sysroot ${{ matrix.commands }} diff --git a/compiler/rustc_codegen_gcc/.github/workflows/release.yml b/compiler/rustc_codegen_gcc/.github/workflows/release.yml index ae1134177a77e..43b90fcec9337 100644 --- a/compiler/rustc_codegen_gcc/.github/workflows/release.yml +++ b/compiler/rustc_codegen_gcc/.github/workflows/release.yml @@ -78,8 +78,10 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore - EMBED_LTO_BITCODE=1 ./y.sh build --release --release-sysroot - cargo test + # TODO: remove --features master when it is back to the default. + EMBED_LTO_BITCODE=1 ./y.sh build --release --release-sysroot --features master + # TODO: remove --features master when it is back to the default. + cargo test --features master ./clean_all.sh - name: Prepare dependencies @@ -102,4 +104,5 @@ jobs: - name: Run tests run: | - EMBED_LTO_BITCODE=1 ./test.sh --release --clean --release-sysroot --build-sysroot ${{ matrix.commands }} + # TODO: remove --features master when it is back to the default. + EMBED_LTO_BITCODE=1 ./test.sh --release --clean --release-sysroot --build-sysroot ${{ matrix.commands }} --features master diff --git a/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml b/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml index 28ac3cb65422f..42109ba3e0245 100644 --- a/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml +++ b/compiler/rustc_codegen_gcc/.github/workflows/stdarch.yml @@ -92,8 +92,10 @@ jobs: - name: Build run: | ./y.sh prepare --only-libcore - ./y.sh build --release --release-sysroot - cargo test + # TODO: remove `--features master` when it is back to the default. + ./y.sh build --release --release-sysroot --features master + # TODO: remove --features master when it is back to the default. + cargo test --features master - name: Clean if: ${{ !matrix.cargo_runner }} @@ -111,12 +113,14 @@ jobs: uses: actions-rs/cargo@v1.0.3 with: command: build - args: --release + # TODO: remove `--features master` when it is back to the default. + args: --release --features master - name: Run tests if: ${{ !matrix.cargo_runner }} run: | - ./test.sh --release --clean --release-sysroot --build-sysroot --mini-tests --std-tests --test-libcore + # TODO: remove `--features master` when it is back to the default. + ./test.sh --release --clean --release-sysroot --build-sysroot --mini-tests --std-tests --test-libcore --features master - name: Run stdarch tests if: ${{ !matrix.cargo_runner }} diff --git a/compiler/rustc_codegen_gcc/Cargo.lock b/compiler/rustc_codegen_gcc/Cargo.lock index b8e2e5d808044..7c18633692783 100644 --- a/compiler/rustc_codegen_gcc/Cargo.lock +++ b/compiler/rustc_codegen_gcc/Cargo.lock @@ -74,7 +74,7 @@ dependencies = [ [[package]] name = "gccjit" version = "1.0.0" -source = "git+https://github.com/antoyo/gccjit.rs#c52a218f5529321285b4489e5562a00e5428e033" +source = "git+https://github.com/antoyo/gccjit.rs#6e290f25b1d1edab5ae9ace486fd2dc8c08d6421" dependencies = [ "gccjit_sys", ] @@ -82,7 +82,7 @@ dependencies = [ [[package]] name = "gccjit_sys" version = "0.0.1" -source = "git+https://github.com/antoyo/gccjit.rs#c52a218f5529321285b4489e5562a00e5428e033" +source = "git+https://github.com/antoyo/gccjit.rs#6e290f25b1d1edab5ae9ace486fd2dc8c08d6421" dependencies = [ "libc", ] diff --git a/compiler/rustc_codegen_gcc/build_sysroot/build_sysroot.sh b/compiler/rustc_codegen_gcc/build_sysroot/build_sysroot.sh index 116fd36e7a7b3..ebc7dc375b125 100755 --- a/compiler/rustc_codegen_gcc/build_sysroot/build_sysroot.sh +++ b/compiler/rustc_codegen_gcc/build_sysroot/build_sysroot.sh @@ -28,3 +28,7 @@ fi # Copy files to sysroot mkdir -p sysroot/lib/rustlib/$TARGET_TRIPLE/lib/ cp -r target/$TARGET_TRIPLE/$sysroot_channel/deps/* sysroot/lib/rustlib/$TARGET_TRIPLE/lib/ +# Copy the source files to the sysroot (Rust for Linux needs this). +source_dir=sysroot/lib/rustlib/src/rust +mkdir -p $source_dir +cp -r sysroot_src/library/ $source_dir diff --git a/compiler/rustc_codegen_gcc/build_system/src/build.rs b/compiler/rustc_codegen_gcc/build_system/src/build.rs index eaca7a987d6b8..f1c3701a946ec 100644 --- a/compiler/rustc_codegen_gcc/build_system/src/build.rs +++ b/compiler/rustc_codegen_gcc/build_system/src/build.rs @@ -194,6 +194,12 @@ fn build_sysroot( copier, )?; + // Copy the source files to the sysroot (Rust for Linux needs this). + let sysroot_src_path = "sysroot/lib/rustlib/src/rust"; + fs::create_dir_all(&sysroot_src_path) + .map_err(|error| format!("Failed to create directory `{}`: {:?}", sysroot_src_path, error))?; + run_command(&[&"cp", &"-r", &"sysroot_src/library/", &sysroot_src_path], None)?; + Ok(()) } diff --git a/compiler/rustc_codegen_gcc/failing-ui-tests12.txt b/compiler/rustc_codegen_gcc/failing-ui-tests12.txt index f91aa92531848..4af93939b0642 100644 --- a/compiler/rustc_codegen_gcc/failing-ui-tests12.txt +++ b/compiler/rustc_codegen_gcc/failing-ui-tests12.txt @@ -38,3 +38,5 @@ tests/ui/target-feature/missing-plusminus.rs tests/ui/sse2.rs tests/ui/codegen/issue-79865-llvm-miscompile.rs tests/ui/intrinsics/intrinsics-integer.rs +tests/ui/std-backtrace.rs +tests/ui/mir/alignment/packed.rs diff --git a/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch b/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch index 9520a5a39edcd..914ae986b50e7 100644 --- a/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch +++ b/compiler/rustc_codegen_gcc/patches/libgccjit12/0001-core-Disable-portable-simd-test.patch @@ -1,6 +1,6 @@ -From 7bcd24ec6d4a96121874cb1ae5a23ea274aeff34 Mon Sep 17 00:00:00 2001 +From a5663265f797a43c502915c356fe7899c16cee92 Mon Sep 17 00:00:00 2001 From: None -Date: Thu, 19 Oct 2023 13:12:51 -0400 +Date: Sat, 18 Nov 2023 10:50:36 -0500 Subject: [PATCH] [core] Disable portable-simd test --- @@ -8,18 +8,18 @@ Subject: [PATCH] [core] Disable portable-simd test 1 file changed, 2 deletions(-) diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs -index 5814ed4..194ad4c 100644 +index d0a119c..76fdece 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs -@@ -90,7 +90,6 @@ +@@ -89,7 +89,6 @@ + #![feature(never_type)] #![feature(unwrap_infallible)] - #![feature(pointer_byte_offsets)] #![feature(pointer_is_aligned)] -#![feature(portable_simd)] #![feature(ptr_metadata)] #![feature(lazy_cell)] #![feature(unsized_tuple_coercion)] -@@ -157,7 +156,6 @@ mod pin; +@@ -155,7 +154,6 @@ mod pin; mod pin_macro; mod ptr; mod result; @@ -28,5 +28,5 @@ index 5814ed4..194ad4c 100644 mod str; mod str_lossy; -- -2.42.0 +2.42.1 diff --git a/compiler/rustc_codegen_gcc/rust-toolchain b/compiler/rustc_codegen_gcc/rust-toolchain index 205ec53b425bf..1962c217258a4 100644 --- a/compiler/rustc_codegen_gcc/rust-toolchain +++ b/compiler/rustc_codegen_gcc/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-10-21" +channel = "nightly-2023-11-17" components = ["rust-src", "rustc-dev", "llvm-tools-preview"] diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs index 5073066c1383c..b0788718da4d1 100644 --- a/compiler/rustc_codegen_gcc/src/base.rs +++ b/compiler/rustc_codegen_gcc/src/base.rs @@ -3,7 +3,6 @@ use std::env; use std::time::Instant; use gccjit::{ - Context, FunctionType, GlobalKind, }; @@ -18,8 +17,9 @@ use rustc_codegen_ssa::mono_item::MonoItemExt; use rustc_codegen_ssa::traits::DebugInfoMethods; use rustc_session::config::DebugInfo; use rustc_span::Symbol; +use rustc_target::spec::PanicStrategy; -use crate::{LockedTargetInfo, gcc_util}; +use crate::{LockedTargetInfo, gcc_util, new_context}; use crate::GccContext; use crate::builder::Builder; use crate::context::CodegenCx; @@ -88,20 +88,18 @@ pub fn compile_codegen_unit(tcx: TyCtxt<'_>, cgu_name: Symbol, target_info: Lock fn module_codegen(tcx: TyCtxt<'_>, (cgu_name, target_info): (Symbol, LockedTargetInfo)) -> ModuleCodegen { let cgu = tcx.codegen_unit(cgu_name); // Instantiate monomorphizations without filling out definitions yet... - let context = Context::default(); + let context = new_context(tcx); - context.add_command_line_option("-fexceptions"); - context.add_driver_option("-fexceptions"); + if tcx.sess.panic_strategy() == PanicStrategy::Unwind { + context.add_command_line_option("-fexceptions"); + context.add_driver_option("-fexceptions"); + } let disabled_features: HashSet<_> = tcx.sess.opts.cg.target_feature.split(',') .filter(|feature| feature.starts_with('-')) .map(|string| &string[1..]) .collect(); - if tcx.sess.target.arch == "x86" || tcx.sess.target.arch == "x86_64" { - context.add_command_line_option("-masm=intel"); - } - if !disabled_features.contains("avx") && tcx.sess.target.arch == "x86_64" { // NOTE: we always enable AVX because the equivalent of llvm.x86.sse2.cmp.pd in GCC for // SSE2 is multiple builtins, so we use the AVX __builtin_ia32_cmppd instead. diff --git a/compiler/rustc_codegen_gcc/src/int.rs b/compiler/rustc_codegen_gcc/src/int.rs index ea8550d20f362..9b9b3ea4f8704 100644 --- a/compiler/rustc_codegen_gcc/src/int.rs +++ b/compiler/rustc_codegen_gcc/src/int.rs @@ -76,6 +76,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { a >> b } } + else if a_type.is_vector() && a_type.is_vector() { + a >> b + } else if a_native && !b_native { self.gcc_lshr(a, self.gcc_int_cast(b, a_type)) } @@ -144,7 +147,7 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { fn additive_operation(&self, operation: BinaryOp, a: RValue<'gcc>, mut b: RValue<'gcc>) -> RValue<'gcc> { let a_type = a.get_type(); let b_type = b.get_type(); - if self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type) { + if (self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type)) || (a_type.is_vector() && b_type.is_vector()) { if a_type != b_type { if a_type.is_vector() { // Vector types need to be bitcast. @@ -158,6 +161,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { self.context.new_binary_op(None, operation, a_type, a, b) } else { + debug_assert!(a_type.dyncast_array().is_some()); + debug_assert!(b_type.dyncast_array().is_some()); let signed = a_type.is_compatible_with(self.i128_type); let func_name = match (operation, signed) { @@ -189,10 +194,12 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { fn multiplicative_operation(&self, operation: BinaryOp, operation_name: &str, signed: bool, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { let a_type = a.get_type(); let b_type = b.get_type(); - if self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type) { + if (self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type)) || (a_type.is_vector() && b_type.is_vector()) { self.context.new_binary_op(None, operation, a_type, a, b) } else { + debug_assert!(a_type.dyncast_array().is_some()); + debug_assert!(b_type.dyncast_array().is_some()); let sign = if signed { "" @@ -337,6 +344,8 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { pub fn operation_with_overflow(&self, func_name: &str, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> (RValue<'gcc>, RValue<'gcc>) { let a_type = lhs.get_type(); let b_type = rhs.get_type(); + debug_assert!(a_type.dyncast_array().is_some()); + debug_assert!(b_type.dyncast_array().is_some()); let param_a = self.context.new_parameter(None, a_type, "a"); let param_b = self.context.new_parameter(None, b_type, "b"); let result_field = self.context.new_field(None, a_type, "result"); @@ -496,7 +505,11 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { pub fn gcc_xor(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> { let a_type = a.get_type(); let b_type = b.get_type(); - if self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type) { + if a_type.is_vector() && b_type.is_vector() { + let b = self.bitcast_if_needed(b, a_type); + a ^ b + } + else if self.is_native_int_type_or_bool(a_type) && self.is_native_int_type_or_bool(b_type) { a ^ b } else { @@ -527,6 +540,9 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> { a << b } } + else if a_type.is_vector() && a_type.is_vector() { + a << b + } else if a_native && !b_native { self.gcc_shl(a, self.gcc_int_cast(b, a_type)) } @@ -690,6 +706,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { let a_native = self.is_native_int_type_or_bool(a_type); let b_native = self.is_native_int_type_or_bool(b_type); if a_type.is_vector() && b_type.is_vector() { + let b = self.bitcast_if_needed(b, a_type); self.context.new_binary_op(None, operation, a_type, a, b) } else if a_native && b_native { @@ -748,6 +765,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { return self.context.new_cast(None, value, dest_typ); } + debug_assert!(value_type.dyncast_array().is_some()); let name_suffix = match self.type_kind(dest_typ) { TypeKind::Float => "tisf", @@ -781,6 +799,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { return self.context.new_cast(None, value, dest_typ); } + debug_assert!(value_type.dyncast_array().is_some()); let name_suffix = match self.type_kind(value_type) { TypeKind::Float => "sfti", diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index fd4af984bc039..8c7bae0c8866d 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -39,6 +39,8 @@ extern crate rustc_errors; extern crate rustc_fluent_macro; extern crate rustc_fs_util; extern crate rustc_hir; +#[cfg(feature="master")] +extern crate rustc_interface; extern crate rustc_macros; extern crate rustc_metadata; extern crate rustc_middle; @@ -86,7 +88,7 @@ use std::sync::atomic::Ordering; use gccjit::{Context, OptimizationLevel}; #[cfg(feature="master")] -use gccjit::TargetInfo; +use gccjit::{TargetInfo, Version}; #[cfg(not(feature="master"))] use gccjit::CType; use errors::LTONotSupported; @@ -244,17 +246,33 @@ impl CodegenBackend for GccCodegenBackend { } } +fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> { + let context = Context::default(); + if tcx.sess.target.arch == "x86" || tcx.sess.target.arch == "x86_64" { + context.add_command_line_option("-masm=intel"); + } + #[cfg(feature="master")] + { + let version = Version::get(); + let version = format!("{}.{}.{}", version.major, version.minor, version.patch); + context.set_output_ident(&format!("rustc version {} with libgccjit {}", + rustc_interface::util::rustc_version_str().unwrap_or("unknown version"), + version, + )); + } + // TODO(antoyo): check if this should only be added when using -Cforce-unwind-tables=n. + context.add_command_line_option("-fno-asynchronous-unwind-tables"); + context +} + impl ExtraBackendMethods for GccCodegenBackend { fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) -> Self::Module { let mut mods = GccContext { - context: Context::default(), + context: new_context(tcx), should_combine_object_files: false, temp_dir: None, }; - if tcx.sess.target.arch == "x86" || tcx.sess.target.arch == "x86_64" { - mods.context.add_command_line_option("-masm=intel"); - } unsafe { allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); } mods } diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index 4dae49f81a386..d385d367f396e 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -46,7 +46,7 @@ libc = "0.2.50" # tidy-alphabetical-end [dependencies.object] -version = "0.32.0" +version = "0.32.1" default-features = false features = ["read_core", "elf", "macho", "pe", "xcoff", "unaligned", "archive", "write"] diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index cb60ed729c1bf..d716774690aa5 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -226,6 +226,10 @@ pub(crate) fn create_object_file(sess: &Session) -> Option object::write::Mach build_version } +/// Is Apple's CPU subtype `arm64e`s +fn macho_is_arm64e(target: &Target) -> bool { + return target.llvm_target.starts_with("arm64e"); +} + pub enum MetadataPosition { First, Last, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 198e5696357af..23054975548c5 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -322,8 +322,13 @@ pub fn cast_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( if lhs_sz < rhs_sz { bx.trunc(rhs, lhs_llty) } else if lhs_sz > rhs_sz { - // FIXME (#1877: If in the future shifting by negative - // values is no longer undefined then this is wrong. + // We zero-extend even if the RHS is signed. So e.g. `(x: i32) << -1i8` will zero-extend the + // RHS to `255i32`. But then we mask the shift amount to be within the size of the LHS + // anyway so the result is `31` as it should be. All the extra bits introduced by zext + // are masked off so their value does not matter. + // FIXME: if we ever support 512bit integers, this will be wrong! For such large integers, + // the extra bits introduced by zext are *not* all masked away any more. + assert!(lhs_sz <= 256); bx.zext(rhs, lhs_llty) } else { rhs diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 128b548f43d49..538077a0b777a 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -156,41 +156,35 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Shift ops can have an RHS with a different numeric type. if matches!(bin_op, Shl | ShlUnchecked | Shr | ShrUnchecked) { - let size = u128::from(left_layout.size.bits()); - // Even if `r` is signed, we treat it as if it was unsigned (i.e., we use its - // zero-extended form). This matches the codegen backend: - // . - // The overflow check is also ignorant to the sign: - // . - // This would behave rather strangely if we had integer types of size 256: a shift by - // -1i8 would actually shift by 255, but that would *not* be considered overflowing. A - // shift by -1i16 though would be considered overflowing. If we had integers of size - // 512, then a shift by -1i8 would even produce a different result than one by -1i16: - // the first shifts by 255, the latter by u16::MAX % 512 = 511. Lucky enough, our - // integers are maximally 128bits wide, so negative shifts *always* overflow and we have - // consistent results for the same value represented at different bit widths. - assert!(size <= 128); - let original_r = r; - let overflow = r >= size; - // The shift offset is implicitly masked to the type size, to make sure this operation - // is always defined. This is the one MIR operator that does *not* directly map to a - // single LLVM operation. See - // - // for the corresponding truncation in our codegen backends. - let r = r % size; - let r = u32::try_from(r).unwrap(); // we masked so this will always fit + let size = left_layout.size.bits(); + // The shift offset is implicitly masked to the type size. (This is the one MIR operator + // that does *not* directly map to a single LLVM operation.) Compute how much we + // actually shift and whether there was an overflow due to shifting too much. + let (shift_amount, overflow) = if right_layout.abi.is_signed() { + let shift_amount = self.sign_extend(r, right_layout) as i128; + let overflow = shift_amount < 0 || shift_amount >= i128::from(size); + let masked_amount = (shift_amount as u128) % u128::from(size); + debug_assert_eq!(overflow, shift_amount != (masked_amount as i128)); + (masked_amount, overflow) + } else { + let shift_amount = r; + let masked_amount = shift_amount % u128::from(size); + (masked_amount, shift_amount != masked_amount) + }; + let shift_amount = u32::try_from(shift_amount).unwrap(); // we masked so this will always fit + // Compute the shifted result. let result = if left_layout.abi.is_signed() { let l = self.sign_extend(l, left_layout) as i128; let result = match bin_op { - Shl | ShlUnchecked => l.checked_shl(r).unwrap(), - Shr | ShrUnchecked => l.checked_shr(r).unwrap(), + Shl | ShlUnchecked => l.checked_shl(shift_amount).unwrap(), + Shr | ShrUnchecked => l.checked_shr(shift_amount).unwrap(), _ => bug!(), }; result as u128 } else { match bin_op { - Shl | ShlUnchecked => l.checked_shl(r).unwrap(), - Shr | ShrUnchecked => l.checked_shr(r).unwrap(), + Shl | ShlUnchecked => l.checked_shl(shift_amount).unwrap(), + Shr | ShrUnchecked => l.checked_shr(shift_amount).unwrap(), _ => bug!(), } }; @@ -199,7 +193,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { if overflow && let Some(intrinsic_name) = throw_ub_on_overflow { throw_ub_custom!( fluent::const_eval_overflow_shift, - val = original_r, + val = if right_layout.abi.is_signed() { + (self.sign_extend(r, right_layout) as i128).to_string() + } else { + r.to_string() + }, name = intrinsic_name ); } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 0cb75c71b7346..38699c26680b0 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -145,6 +145,25 @@ impl JsonEmitter { pub fn ignored_directories_in_source_blocks(self, value: Vec) -> Self { Self { ignored_directories_in_source_blocks: value, ..self } } + + fn emit(&mut self, val: EmitTyped<'_>) -> io::Result<()> { + if self.pretty { + serde_json::to_writer_pretty(&mut *self.dst, &val)? + } else { + serde_json::to_writer(&mut *self.dst, &val)? + }; + self.dst.write_all(b"\n")?; + self.dst.flush() + } +} + +#[derive(Serialize)] +#[serde(tag = "$message_type", rename_all = "snake_case")] +enum EmitTyped<'a> { + Diagnostic(Diagnostic), + Artifact(ArtifactNotification<'a>), + FutureIncompat(FutureIncompatReport<'a>), + UnusedExtern(UnusedExterns<'a, 'a, 'a>), } impl Translate for JsonEmitter { @@ -160,12 +179,7 @@ impl Translate for JsonEmitter { impl Emitter for JsonEmitter { fn emit_diagnostic(&mut self, diag: &crate::Diagnostic) { let data = Diagnostic::from_errors_diagnostic(diag, self); - let result = if self.pretty { - writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap()) - } else { - writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap()) - } - .and_then(|_| self.dst.flush()); + let result = self.emit(EmitTyped::Diagnostic(data)); if let Err(e) = result { panic!("failed to print diagnostics: {e:?}"); } @@ -173,34 +187,28 @@ impl Emitter for JsonEmitter { fn emit_artifact_notification(&mut self, path: &Path, artifact_type: &str) { let data = ArtifactNotification { artifact: path, emit: artifact_type }; - let result = if self.pretty { - writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap()) - } else { - writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap()) - } - .and_then(|_| self.dst.flush()); + let result = self.emit(EmitTyped::Artifact(data)); if let Err(e) = result { panic!("failed to print notification: {e:?}"); } } fn emit_future_breakage_report(&mut self, diags: Vec) { - let data: Vec = diags + let data: Vec> = diags .into_iter() .map(|mut diag| { if diag.level == crate::Level::Allow { diag.level = crate::Level::Warning(None); } - FutureBreakageItem { diagnostic: Diagnostic::from_errors_diagnostic(&diag, self) } + FutureBreakageItem { + diagnostic: EmitTyped::Diagnostic(Diagnostic::from_errors_diagnostic( + &diag, self, + )), + } }) .collect(); let report = FutureIncompatReport { future_incompat_report: data }; - let result = if self.pretty { - writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&report).unwrap()) - } else { - writeln!(&mut self.dst, "{}", serde_json::to_string(&report).unwrap()) - } - .and_then(|_| self.dst.flush()); + let result = self.emit(EmitTyped::FutureIncompat(report)); if let Err(e) = result { panic!("failed to print future breakage report: {e:?}"); } @@ -209,12 +217,7 @@ impl Emitter for JsonEmitter { fn emit_unused_externs(&mut self, lint_level: rustc_lint_defs::Level, unused_externs: &[&str]) { let lint_level = lint_level.as_str(); let data = UnusedExterns { lint_level, unused_extern_names: unused_externs }; - let result = if self.pretty { - writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap()) - } else { - writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap()) - } - .and_then(|_| self.dst.flush()); + let result = self.emit(EmitTyped::UnusedExtern(data)); if let Err(e) = result { panic!("failed to print unused externs: {e:?}"); } @@ -313,13 +316,14 @@ struct ArtifactNotification<'a> { } #[derive(Serialize)] -struct FutureBreakageItem { - diagnostic: Diagnostic, +struct FutureBreakageItem<'a> { + // Actually Diagnostic, but we want to make sure it gets serialized with `type`. + diagnostic: EmitTyped<'a>, } #[derive(Serialize)] -struct FutureIncompatReport { - future_incompat_report: Vec, +struct FutureIncompatReport<'a> { + future_incompat_report: Vec>, } // NOTE: Keep this in sync with the equivalent structs in rustdoc's diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs index 7ced37e5694e5..8f4b83966dff8 100644 --- a/compiler/rustc_hir_analysis/src/astconv/errors.rs +++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs @@ -4,7 +4,7 @@ use crate::errors::{ ParenthesizedFnTraitExpansion, }; use crate::traits::error_reporting::report_object_safety_error; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -16,8 +16,6 @@ use rustc_span::symbol::{sym, Ident}; use rustc_span::{Span, Symbol, DUMMY_SP}; use rustc_trait_selection::traits::object_safety_violations_for_assoc_item; -use std::collections::BTreeSet; - impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// On missing type parameters, emit an E0393 error and provide a structured suggestion using /// the type parameter's name as a placeholder. @@ -504,7 +502,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { /// emit a generic note suggesting using a `where` clause to constraint instead. pub(crate) fn complain_about_missing_associated_types( &self, - associated_types: FxHashMap>, + associated_types: FxIndexMap>, potential_assoc_types: Vec, trait_bounds: &[hir::PolyTraitRef<'_>], ) { @@ -514,13 +512,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let tcx = self.tcx(); // FIXME: Marked `mut` so that we can replace the spans further below with a more // appropriate one, but this should be handled earlier in the span assignment. - let mut associated_types: FxHashMap> = associated_types + let mut associated_types: FxIndexMap> = associated_types .into_iter() .map(|(span, def_ids)| { (span, def_ids.into_iter().map(|did| tcx.associated_item(did)).collect()) }) .collect(); - let mut names: FxHashMap> = Default::default(); + let mut names: FxIndexMap> = Default::default(); let mut names_len = 0; // Account for things like `dyn Foo + 'a`, like in tests `issue-22434.rs` and diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs index 00ff3f836adf3..78c5809f8b4f9 100644 --- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs +++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs @@ -1,7 +1,7 @@ use crate::astconv::{GenericArgCountMismatch, GenericArgCountResult, OnlySelfBounds}; use crate::bounds::Bounds; use crate::errors::TraitObjectDeclaredWithNoTraits; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -14,7 +14,6 @@ use rustc_trait_selection::traits::error_reporting::report_object_safety_error; use rustc_trait_selection::traits::{self, astconv_object_safety_violations}; use smallvec::{smallvec, SmallVec}; -use std::collections::BTreeSet; use super::AstConv; @@ -148,8 +147,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } - // Use a `BTreeSet` to keep output in a more consistent order. - let mut associated_types: FxHashMap> = FxHashMap::default(); + let mut associated_types: FxIndexMap> = FxIndexMap::default(); let regular_traits_refs_spans = trait_bounds .into_iter() diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 7b0f27f9b348c..8cf9e55f0b603 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -1404,18 +1404,18 @@ pub enum BinOp { BitOr, /// The `<<` operator (shift left) /// - /// The offset is truncated to the size of the first operand before shifting. + /// The offset is truncated to the size of the first operand and made unsigned before shifting. Shl, - /// Like `Shl`, but is UB if the RHS >= LHS::BITS + /// Like `Shl`, but is UB if the RHS >= LHS::BITS or RHS < 0 ShlUnchecked, /// The `>>` operator (shift right) /// - /// The offset is truncated to the size of the first operand before shifting. + /// The offset is truncated to the size of the first operand and made unsigned before shifting. /// /// This is an arithmetic shift if the LHS is signed /// and a logical shift if the LHS is unsigned. Shr, - /// Like `Shl`, but is UB if the RHS >= LHS::BITS + /// Like `Shl`, but is UB if the RHS >= LHS::BITS or RHS < 0 ShrUnchecked, /// The `==` operator (equality) Eq, diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index eece8684e3601..2130dbdc033ed 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -600,10 +600,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { BinOp::Shl | BinOp::Shr if self.check_overflow && ty.is_integral() => { // For an unsigned RHS, the shift is in-range for `rhs < bits`. // For a signed RHS, `IntToInt` cast to the equivalent unsigned - // type and do that same comparison. Because the type is the - // same size, there's no negative shift amount that ends up - // overlapping with valid ones, thus it catches negatives too. + // type and do that same comparison. + // A negative value will be *at least* 128 after the cast (that's i8::MIN), + // and 128 is an overflowing shift amount for all our currently existing types, + // so this cast can never make us miss an overflow. let (lhs_size, _) = ty.int_size_and_signed(self.tcx); + assert!(lhs_size.bits() <= 128); let rhs_ty = rhs.ty(&self.local_decls, self.tcx); let (rhs_size, _) = rhs_ty.int_size_and_signed(self.tcx); @@ -625,7 +627,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // This can't overflow because the largest shiftable types are 128-bit, // which fits in `u8`, the smallest possible `unsigned_ty`. - // (And `from_uint` will `bug!` if that's ever no longer true.) let lhs_bits = Operand::const_from_scalar( self.tcx, unsigned_ty, diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 266190da035e0..49a2c4144674d 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -739,6 +739,9 @@ parse_trailing_vert_not_allowed = a trailing `|` is not allowed in an or-pattern parse_trait_alias_cannot_be_auto = trait aliases cannot be `auto` parse_trait_alias_cannot_be_unsafe = trait aliases cannot be `unsafe` +parse_transpose_dyn_or_impl = `for<...>` expected after `{$kw}`, not before + .suggestion = move `{$kw}` before the `for<...>` + parse_type_ascription_removed = if you meant to annotate an expression with a type, the type ascription syntax has been removed, see issue #101728 diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 99e66fddc705b..7ce348619c6bb 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2827,3 +2827,23 @@ pub(crate) struct GenericArgsInPatRequireTurbofishSyntax { )] pub suggest_turbofish: Span, } + +#[derive(Diagnostic)] +#[diag(parse_transpose_dyn_or_impl)] +pub(crate) struct TransposeDynOrImpl<'a> { + #[primary_span] + pub span: Span, + pub kw: &'a str, + #[subdiagnostic] + pub sugg: TransposeDynOrImplSugg<'a>, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] +pub(crate) struct TransposeDynOrImplSugg<'a> { + #[suggestion_part(code = "")] + pub removal_span: Span, + #[suggestion_part(code = "{kw} ")] + pub insertion_span: Span, + pub kw: &'a str, +} diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index dc0f139652307..75617b1b3ea5b 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -287,6 +287,7 @@ impl<'a> Parser<'a> { // Function pointer type self.parse_ty_bare_fn(lo, ThinVec::new(), None, recover_return_sign)? } else if self.check_keyword(kw::For) { + let for_span = self.token.span; // Function pointer type or bound list (trait object type) starting with a poly-trait. // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T` // `for<'lt> Trait1<'lt> + Trait2 + 'a` @@ -299,9 +300,42 @@ impl<'a> Parser<'a> { recover_return_sign, )? } else { - let path = self.parse_path(PathStyle::Type)?; - let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); - self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)? + // Try to recover `for<'a> dyn Trait` or `for<'a> impl Trait`. + if self.may_recover() + && (self.eat_keyword_noexpect(kw::Impl) || self.eat_keyword_noexpect(kw::Dyn)) + { + let kw = self.prev_token.ident().unwrap().0.name; + let mut err = self.sess.create_err(errors::TransposeDynOrImpl { + span: self.prev_token.span, + kw: kw.as_str(), + sugg: errors::TransposeDynOrImplSugg { + removal_span: self.prev_token.span.with_hi(self.token.span.lo()), + insertion_span: for_span.shrink_to_lo(), + kw: kw.as_str(), + }, + }); + let path = self.parse_path(PathStyle::Type)?; + let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); + let kind = + self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?; + // Take the parsed bare trait object and turn it either + // into a `dyn` object or an `impl Trait`. + let kind = match (kind, kw) { + (TyKind::TraitObject(bounds, _), kw::Dyn) => { + TyKind::TraitObject(bounds, TraitObjectSyntax::Dyn) + } + (TyKind::TraitObject(bounds, _), kw::Impl) => { + TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds) + } + _ => return Err(err), + }; + err.emit(); + kind + } else { + let path = self.parse_path(PathStyle::Type)?; + let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); + self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)? + } } } else if self.eat_keyword(kw::Impl) { self.parse_impl_ty(&mut impl_dyn_multi)? diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 99e64503e2574..f32cb06d68f69 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -9,11 +9,12 @@ mod tests; use Arch::*; #[allow(non_camel_case_types)] -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq)] pub enum Arch { Armv7k, Armv7s, Arm64, + Arm64e, Arm64_32, I386, I686, @@ -31,6 +32,7 @@ impl Arch { Armv7k => "armv7k", Armv7s => "armv7s", Arm64 | Arm64_macabi | Arm64_sim => "arm64", + Arm64e => "arm64e", Arm64_32 => "arm64_32", I386 => "i386", I686 => "i686", @@ -42,7 +44,7 @@ impl Arch { pub fn target_arch(self) -> Cow<'static, str> { Cow::Borrowed(match self { Armv7k | Armv7s => "arm", - Arm64 | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64", + Arm64 | Arm64e | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64", I386 | I686 => "x86", X86_64 | X86_64_sim | X86_64_macabi | X86_64h => "x86_64", }) @@ -50,7 +52,7 @@ impl Arch { fn target_abi(self) -> &'static str { match self { - Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "", + Armv7k | Armv7s | Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "", X86_64_macabi | Arm64_macabi => "macabi", // x86_64-apple-ios is a simulator target, even though it isn't // declared that way in the target like the other ones... @@ -63,6 +65,7 @@ impl Arch { Armv7k => "cortex-a8", Armv7s => "swift", // iOS 10 is only supported on iPhone 5 or higher. Arm64 => "apple-a7", + Arm64e => "apple-a12", Arm64_32 => "apple-s4", // Only macOS 10.12+ is supported, which means // all x86_64/x86 CPUs must be running at least penryn @@ -88,7 +91,7 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs { }; let platform_version: StaticCow = match os { - "ios" => ios_lld_platform_version(), + "ios" => ios_lld_platform_version(arch), "tvos" => tvos_lld_platform_version(), "watchos" => watchos_lld_platform_version(), "macos" => macos_lld_platform_version(arch), @@ -202,12 +205,22 @@ pub fn deployment_target(target: &Target) -> Option<(u32, u32)> { let (major, minor) = match &*target.os { "macos" => { // This does not need to be specific. It just needs to handle x86 vs M1. - let arch = if target.arch == "x86" || target.arch == "x86_64" { X86_64 } else { Arm64 }; + let arch = match target.arch.as_ref() { + "x86" | "x86_64" => X86_64, + "arm64e" => Arm64e, + _ => Arm64, + }; macos_deployment_target(arch) } "ios" => match &*target.abi { "macabi" => mac_catalyst_deployment_target(), - _ => ios_deployment_target(), + _ => { + let arch = match target.arch.as_ref() { + "arm64e" => Arm64e, + _ => Arm64, + }; + ios_deployment_target(arch) + } }, "watchos" => watchos_deployment_target(), "tvos" => tvos_deployment_target(), @@ -228,7 +241,7 @@ fn from_set_deployment_target(var_name: &str) -> Option<(u32, u32)> { fn macos_default_deployment_target(arch: Arch) -> (u32, u32) { match arch { // Note: Arm64_sim is not included since macOS has no simulator. - Arm64 | Arm64_macabi => (11, 0), + Arm64 | Arm64e | Arm64_macabi => (11, 0), _ => (10, 12), } } @@ -280,8 +293,8 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow]> // Otherwise if cross-compiling for a different OS/SDK, remove any part // of the linking environment that's wrong and reversed. match arch { - Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim | X86_64h - | Arm64_sim => { + Armv7k | Armv7s | Arm64 | Arm64e | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim + | X86_64h | Arm64_sim => { cvs!["MACOSX_DEPLOYMENT_TARGET"] } X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"], @@ -289,9 +302,10 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow]> } } -fn ios_deployment_target() -> (u32, u32) { +fn ios_deployment_target(arch: Arch) -> (u32, u32) { // If you are looking for the default deployment target, prefer `rustc --print deployment-target`. - from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((10, 0)) + let (major, minor) = if arch == Arm64e { (14, 0) } else { (10, 0) }; + from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((major, minor)) } fn mac_catalyst_deployment_target() -> (u32, u32) { @@ -306,17 +320,17 @@ pub fn ios_llvm_target(arch: Arch) -> String { // set high enough. Luckily one LC_BUILD_VERSION is enough, for Xcode // to pick it up (since std and core are still built with the fallback // of version 7.0 and hence emit the old LC_IPHONE_MIN_VERSION). - let (major, minor) = ios_deployment_target(); + let (major, minor) = ios_deployment_target(arch); format!("{}-apple-ios{}.{}.0", arch.target_name(), major, minor) } -fn ios_lld_platform_version() -> String { - let (major, minor) = ios_deployment_target(); +fn ios_lld_platform_version(arch: Arch) -> String { + let (major, minor) = ios_deployment_target(arch); format!("{major}.{minor}") } pub fn ios_sim_llvm_target(arch: Arch) -> String { - let (major, minor) = ios_deployment_target(); + let (major, minor) = ios_deployment_target(arch); format!("{}-apple-ios{}.{}.0-simulator", arch.target_name(), major, minor) } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 9de8aa7c71269..771aec4de7b17 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1544,6 +1544,7 @@ supported_targets! { ("i686-unknown-hurd-gnu", i686_unknown_hurd_gnu), ("aarch64-apple-darwin", aarch64_apple_darwin), + ("arm64e-apple-darwin", arm64e_apple_darwin), ("x86_64-apple-darwin", x86_64_apple_darwin), ("x86_64h-apple-darwin", x86_64h_apple_darwin), ("i686-apple-darwin", i686_apple_darwin), @@ -1566,6 +1567,7 @@ supported_targets! { ("i386-apple-ios", i386_apple_ios), ("x86_64-apple-ios", x86_64_apple_ios), ("aarch64-apple-ios", aarch64_apple_ios), + ("arm64e-apple-ios", arm64e_apple_ios), ("armv7s-apple-ios", armv7s_apple_ios), ("x86_64-apple-ios-macabi", x86_64_apple_ios_macabi), ("aarch64-apple-ios-macabi", aarch64_apple_ios_macabi), diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs new file mode 100644 index 0000000000000..5d1f81158b696 --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs @@ -0,0 +1,27 @@ +use crate::spec::base::apple::{macos_llvm_target, opts, Arch}; +use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; + +pub fn target() -> Target { + let arch = Arch::Arm64e; + let mut base = opts("macos", arch); + base.cpu = "apple-m1".into(); + base.max_atomic_width = Some(128); + + // FIXME: The leak sanitizer currently fails the tests, see #88132. + base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD; + + Target { + // Clang automatically chooses a more specific target based on + // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work + // correctly, we do too. + llvm_target: macos_llvm_target(arch).into(), + pointer_width: 64, + data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), + arch: arch.target_arch(), + options: TargetOptions { + mcount: "\u{1}mcount".into(), + frame_pointer: FramePointer::NonLeaf, + ..base + }, + } +} diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs new file mode 100644 index 0000000000000..8daa78a02ed2e --- /dev/null +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs @@ -0,0 +1,30 @@ +use crate::spec::base::apple::{ios_llvm_target, opts, Arch}; +use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; + +pub fn target() -> Target { + let arch = Arch::Arm64e; + let mut base = opts("ios", arch); + base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; + + Target { + llvm_target: ios_llvm_target(arch).into(), + pointer_width: 64, + data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), + arch: arch.target_arch(), + options: TargetOptions { + features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+paca,+pacg".into(), + max_atomic_width: Some(128), + forces_embed_bitcode: true, + frame_pointer: FramePointer::NonLeaf, + bitcode_llvm_cmdline: "-triple\0\ + arm64e-apple-ios14.1.0\0\ + -emit-obj\0\ + -disable-llvm-passes\0\ + -target-abi\0\ + darwinpcs\0\ + -Os\0" + .into(), + ..base + }, + } +} diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 7ca33ae41c0ce..16e44c0006a96 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -408,7 +408,7 @@ fn impl_intersection_has_negative_obligation( // Equate the headers to find their intersection (the general type, with infer vars, // that may apply both impls). - let Some(_equate_obligations) = + let Some(equate_obligations) = equate_impl_headers(infcx, param_env, &impl1_header, &impl2_header) else { return false; @@ -416,6 +416,13 @@ fn impl_intersection_has_negative_obligation( plug_infer_with_placeholders(infcx, universe, (impl1_header.impl_args, impl2_header.impl_args)); + // FIXME(with_negative_coherence): the infcx has constraints from equating + // the impl headers. We should use these constraints as assumptions, not as + // requirements, when proving the negated where clauses below. + drop(equate_obligations); + drop(infcx.take_registered_region_obligations()); + drop(infcx.take_and_reset_region_constraints()); + util::elaborate(tcx, tcx.predicates_of(impl2_def_id).instantiate(tcx, impl2_header.impl_args)) .any(|(clause, _)| try_prove_negated_where_clause(infcx, clause, param_env)) } @@ -541,14 +548,6 @@ fn try_prove_negated_where_clause<'tcx>( return false; }; - // FIXME(with_negative_coherence): the infcx has region contraints from equating - // the impl headers as requirements. Given that the only region constraints we - // get are involving inference regions in the root, it shouldn't matter, but - // still sus. - // - // We probably should just throw away the region obligations registered up until - // now, or ideally use them as assumptions when proving the region obligations - // that we get from proving the negative predicate below. let ref infcx = root_infcx.fork(); let ocx = ObligationCtxt::new(infcx); diff --git a/library/std/src/os/linux/process.rs b/library/std/src/os/linux/process.rs index 2b3ff76d7a4a7..51af432d0568d 100644 --- a/library/std/src/os/linux/process.rs +++ b/library/std/src/os/linux/process.rs @@ -152,6 +152,12 @@ pub trait CommandExt: Sealed { /// in a guaranteed race-free manner (e.g. if the `clone3` system call /// is supported). Otherwise, [`pidfd`] will return an error. /// + /// If a pidfd has been successfully created and not been taken from the `Child` + /// then calls to `kill()`, `wait()` and `try_wait()` will use the pidfd + /// instead of the pid. This can prevent pid recycling races, e.g. + /// those caused by rogue libraries in the same process prematurely reaping + /// zombie children via `waitpid(-1, ...)` calls. + /// /// [`Command`]: process::Command /// [`Child`]: process::Child /// [`pidfd`]: fn@ChildExt::pidfd diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 72aca4e665939..ee86a5f88dd78 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -9,6 +9,8 @@ use core::ffi::NonZero_c_int; #[cfg(target_os = "linux")] use crate::os::linux::process::PidFd; +#[cfg(target_os = "linux")] +use crate::os::unix::io::AsRawFd; #[cfg(any( target_os = "macos", @@ -696,11 +698,12 @@ impl Command { msg.msg_iov = &mut iov as *mut _ as *mut _; msg.msg_iovlen = 1; - msg.msg_controllen = mem::size_of_val(&cmsg.buf) as _; - msg.msg_control = &mut cmsg.buf as *mut _ as *mut _; // only attach cmsg if we successfully acquired the pidfd if pidfd >= 0 { + msg.msg_controllen = mem::size_of_val(&cmsg.buf) as _; + msg.msg_control = &mut cmsg.buf as *mut _ as *mut _; + let hdr = CMSG_FIRSTHDR(&mut msg as *mut _ as *mut _); (*hdr).cmsg_level = SOL_SOCKET; (*hdr).cmsg_type = SCM_RIGHTS; @@ -717,7 +720,7 @@ impl Command { // so we get a consistent SEQPACKET order match cvt_r(|| libc::sendmsg(sock.as_raw(), &msg, 0)) { Ok(0) => {} - _ => rtabort!("failed to communicate with parent process"), + other => rtabort!("failed to communicate with parent process. {:?}", other), } } } @@ -748,7 +751,7 @@ impl Command { msg.msg_controllen = mem::size_of::() as _; msg.msg_control = &mut cmsg as *mut _ as *mut _; - match cvt_r(|| libc::recvmsg(sock.as_raw(), &mut msg, 0)) { + match cvt_r(|| libc::recvmsg(sock.as_raw(), &mut msg, libc::MSG_CMSG_CLOEXEC)) { Err(_) => return -1, Ok(_) => {} } @@ -787,7 +790,7 @@ pub struct Process { // On Linux, stores the pidfd created for this child. // This is None if the user did not request pidfd creation, // or if the pidfd could not be created for some reason - // (e.g. the `clone3` syscall was not available). + // (e.g. the `pidfd_open` syscall was not available). #[cfg(target_os = "linux")] pidfd: Option, } @@ -816,10 +819,23 @@ impl Process { // and used for another process, and we probably shouldn't be killing // random processes, so return Ok because the process has exited already. if self.status.is_some() { - Ok(()) - } else { - cvt(unsafe { libc::kill(self.pid, libc::SIGKILL) }).map(drop) + return Ok(()); + } + #[cfg(target_os = "linux")] + if let Some(pid_fd) = self.pidfd.as_ref() { + // pidfd_send_signal predates pidfd_open. so if we were able to get an fd then sending signals will work too + return cvt(unsafe { + libc::syscall( + libc::SYS_pidfd_send_signal, + pid_fd.as_raw_fd(), + libc::SIGKILL, + crate::ptr::null::<()>(), + 0, + ) + }) + .map(drop); } + cvt(unsafe { libc::kill(self.pid, libc::SIGKILL) }).map(drop) } pub fn wait(&mut self) -> io::Result { @@ -827,6 +843,17 @@ impl Process { if let Some(status) = self.status { return Ok(status); } + #[cfg(target_os = "linux")] + if let Some(pid_fd) = self.pidfd.as_ref() { + let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() }; + + cvt_r(|| unsafe { + libc::waitid(libc::P_PIDFD, pid_fd.as_raw_fd() as u32, &mut siginfo, libc::WEXITED) + })?; + let status = ExitStatus::from_waitid_siginfo(siginfo); + self.status = Some(status); + return Ok(status); + } let mut status = 0 as c_int; cvt_r(|| unsafe { libc::waitpid(self.pid, &mut status, 0) })?; self.status = Some(ExitStatus::new(status)); @@ -837,6 +864,25 @@ impl Process { if let Some(status) = self.status { return Ok(Some(status)); } + #[cfg(target_os = "linux")] + if let Some(pid_fd) = self.pidfd.as_ref() { + let mut siginfo: libc::siginfo_t = unsafe { crate::mem::zeroed() }; + + cvt(unsafe { + libc::waitid( + libc::P_PIDFD, + pid_fd.as_raw_fd() as u32, + &mut siginfo, + libc::WEXITED | libc::WNOHANG, + ) + })?; + if unsafe { siginfo.si_pid() } == 0 { + return Ok(None); + } + let status = ExitStatus::from_waitid_siginfo(siginfo); + self.status = Some(status); + return Ok(Some(status)); + } let mut status = 0 as c_int; let pid = cvt(unsafe { libc::waitpid(self.pid, &mut status, libc::WNOHANG) })?; if pid == 0 { @@ -866,6 +912,20 @@ impl ExitStatus { ExitStatus(status) } + #[cfg(target_os = "linux")] + pub fn from_waitid_siginfo(siginfo: libc::siginfo_t) -> ExitStatus { + let status = unsafe { siginfo.si_status() }; + + match siginfo.si_code { + libc::CLD_EXITED => ExitStatus((status & 0xff) << 8), + libc::CLD_KILLED => ExitStatus(status), + libc::CLD_DUMPED => ExitStatus(status | 0x80), + libc::CLD_CONTINUED => ExitStatus(0xffff), + libc::CLD_STOPPED | libc::CLD_TRAPPED => ExitStatus(((status & 0xff) << 8) | 0x7f), + _ => unreachable!("waitid() should only return the above codes"), + } + } + fn exited(&self) -> bool { libc::WIFEXITED(self.0) } diff --git a/library/std/src/sys/unix/process/process_unix/tests.rs b/library/std/src/sys/unix/process/process_unix/tests.rs index 6aa79e7f9e710..6e952ed7c42af 100644 --- a/library/std/src/sys/unix/process/process_unix/tests.rs +++ b/library/std/src/sys/unix/process/process_unix/tests.rs @@ -64,7 +64,8 @@ fn test_command_fork_no_unwind() { #[test] #[cfg(target_os = "linux")] fn test_command_pidfd() { - use crate::os::fd::RawFd; + use crate::assert_matches::assert_matches; + use crate::os::fd::{AsRawFd, RawFd}; use crate::os::linux::process::{ChildExt, CommandExt}; use crate::process::Command; @@ -78,10 +79,22 @@ fn test_command_pidfd() { }; // always exercise creation attempts - let child = Command::new("echo").create_pidfd(true).spawn().unwrap(); + let mut child = Command::new("false").create_pidfd(true).spawn().unwrap(); // but only check if we know that the kernel supports pidfds if pidfd_open_available { - assert!(child.pidfd().is_ok()) + assert!(child.pidfd().is_ok()); } + if let Ok(pidfd) = child.pidfd() { + let flags = super::cvt(unsafe { libc::fcntl(pidfd.as_raw_fd(), libc::F_GETFD) }).unwrap(); + assert!(flags & libc::FD_CLOEXEC != 0); + } + let status = child.wait().expect("error waiting on pidfd"); + assert_eq!(status.code(), Some(1)); + + let mut child = Command::new("sleep").arg("1000").create_pidfd(true).spawn().unwrap(); + assert_matches!(child.try_wait(), Ok(None)); + child.kill().expect("failed to kill child"); + let status = child.wait().expect("error waiting on pidfd"); + assert_eq!(status.signal(), Some(libc::SIGKILL)); } diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 1b27b77b3e6b2..3bd90f7062dc2 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -15,6 +15,8 @@ - [Platform Support](platform-support.md) - [Target Tier Policy](target-tier-policy.md) - [Template for Target-specific Documentation](platform-support/TEMPLATE.md) + - [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) - [\*-apple-tvos](platform-support/apple-tvos.md) - [\*-apple-watchos\*](platform-support/apple-watchos.md) diff --git a/src/doc/rustc/src/json.md b/src/doc/rustc/src/json.md index 11d7b5b59381b..eaace8883f2d6 100644 --- a/src/doc/rustc/src/json.md +++ b/src/doc/rustc/src/json.md @@ -11,9 +11,11 @@ If parsing the output with Rust, the [`cargo_metadata`](https://crates.io/crates/cargo_metadata) crate provides some support for parsing the messages. -When parsing, care should be taken to be forwards-compatible with future changes -to the format. Optional values may be `null`. New fields may be added. Enumerated -fields like "level" or "suggestion_applicability" may add new values. +Each type of message has a `$message_type` field which can be used to +distinguish the different formats. When parsing, care should be taken +to be forwards-compatible with future changes to the format. Optional +values may be `null`. New fields may be added. Enumerated fields like +"level" or "suggestion_applicability" may add new values. ## Diagnostics @@ -29,6 +31,8 @@ Diagnostics have the following format: ```javascript { + /* Type of this message */ + "$message_type": "diagnostic", /* The primary message. */ "message": "unused variable: `x`", /* The diagnostic code. @@ -217,6 +221,8 @@ flag][option-emit] documentation. ```javascript { + /* Type of this message */ + "type": "artifact", /* The filename that was generated. */ "artifact": "libfoo.rlib", /* The kind of artifact that was generated. Possible values: @@ -239,6 +245,8 @@ information, even if the diagnostics have been suppressed (such as with an ```javascript { + /* Type of this message */ + "type": "future_incompat", /* An array of objects describing a warning that will become a hard error in the future. */ diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index c1e7924800359..d7266c0f56e0e 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -215,6 +215,8 @@ host tools. 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 `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/arm64e-apple-darwin.md b/src/doc/rustc/src/platform-support/arm64e-apple-darwin.md new file mode 100644 index 0000000000000..f93555129a20f --- /dev/null +++ b/src/doc/rustc/src/platform-support/arm64e-apple-darwin.md @@ -0,0 +1,36 @@ +# `arm64e-apple-darwin` + +**Tier: 3 (with Host Tools)** + +ARM64e macOS (11.0+, Big Sur+) + +## Target maintainers + +- Artyom Tetyukhin ([@arttet](https://github.com/https://github.com/arttet)) + +## Requirements + +Target for `macOS` on late-generation `M` series Apple chips. + +## Building the target + +You can build Rust with support for the targets by adding it to the `target` list in `config.toml`: + +```toml +[build] +target = [ "arm64e-apple-darwin" ] +``` + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. +To compile for this target, you will need to build Rust with the target enabled (see [Building the target](#building-the-target) above). + +## Testing + +The target does support running binaries on macOS platforms with `arm64e` architecture. + +## Cross-compilation toolchains and C code + +The targets do support `C` code. +To build compatible `C` code, you have to use XCode with the same compiler and flags. diff --git a/src/doc/rustc/src/platform-support/arm64e-apple-ios.md b/src/doc/rustc/src/platform-support/arm64e-apple-ios.md new file mode 100644 index 0000000000000..2b2e0289975f2 --- /dev/null +++ b/src/doc/rustc/src/platform-support/arm64e-apple-ios.md @@ -0,0 +1,37 @@ +# `arm64e-apple-ios` + +**Tier: 3** + +ARM64e iOS (12.0+) + +## Target maintainers + +- Artyom Tetyukhin ([@arttet](https://github.com/https://github.com/arttet)) + +## Requirements + +These targets only support cross-compilation. +The targets do support `std`. + +## Building the target + +You can build Rust with support for the targets by adding it to the `target` list in `config.toml`: + +```toml +[build] +target = [ "arm64e-apple-ios" ] +``` + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. +To compile for this target, you will need to build Rust with the target enabled (see [Building the target](#building-the-target) above). + +## Testing + +The target does support running binaries on iOS platforms with `arm64e` architecture. + +## Cross-compilation toolchains and C code + +The targets do support `C` code. +To build compatible `C` code, you have to use XCode with the same compiler and flags. diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 30c7c7d2b25ed..215ffc771f3da 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -50,7 +50,9 @@ static HOSTS: &[&str] = &[ static TARGETS: &[&str] = &[ "aarch64-apple-darwin", + "arm64e-apple-darwin", "aarch64-apple-ios", + "arm64e-apple-ios", "aarch64-apple-ios-sim", "aarch64-unknown-fuchsia", "aarch64-linux-android", diff --git a/src/tools/miri/tests/fail/intrinsics/unchecked_shl2.rs b/src/tools/miri/tests/fail/intrinsics/unchecked_shl2.rs new file mode 100644 index 0000000000000..a5777ebbb7f33 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/unchecked_shl2.rs @@ -0,0 +1,9 @@ +#![feature(core_intrinsics)] +use std::intrinsics; + +fn main() { + unsafe { + let _n = intrinsics::unchecked_shl(1i8, -1); + //~^ ERROR: overflowing shift by -1 in `unchecked_shl` + } +} diff --git a/src/tools/miri/tests/fail/intrinsics/unchecked_shl2.stderr b/src/tools/miri/tests/fail/intrinsics/unchecked_shl2.stderr new file mode 100644 index 0000000000000..ab27c9fe91166 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/unchecked_shl2.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: overflowing shift by -1 in `unchecked_shl` + --> $DIR/unchecked_shl2.rs:LL:CC + | +LL | let _n = intrinsics::unchecked_shl(1i8, -1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -1 in `unchecked_shl` + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/unchecked_shl2.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/tests/ui/associated-types/missing-associated-types.stderr b/tests/ui/associated-types/missing-associated-types.stderr index e9669afe8c704..0636667ea1fd5 100644 --- a/tests/ui/associated-types/missing-associated-types.stderr +++ b/tests/ui/associated-types/missing-associated-types.stderr @@ -49,7 +49,7 @@ LL | type B; LL | type Bar = dyn Add + Sub + X + Z; | ^^^^^^^^ ^^^^^^^^ ^^^^^^ ^^^^^^ associated types `A`, `B`, `Output` must be specified | | | | - | | | associated types `Output` (from trait `Mul`), `Output` (from trait `Div`) must be specified + | | | associated types `Output` (from trait `Div`), `Output` (from trait `Mul`) must be specified | | associated type `Output` must be specified | associated type `Output` must be specified | @@ -119,7 +119,7 @@ error[E0191]: the value of the associated types `Output` in `Div`, `Output` in ` --> $DIR/missing-associated-types.rs:24:21 | LL | type Bal = dyn X; - | ^^^^^^ associated types `Output` (from trait `Mul`), `Output` (from trait `Div`) must be specified + | ^^^^^^ associated types `Output` (from trait `Div`), `Output` (from trait `Mul`) must be specified | = help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types diff --git a/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr b/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr new file mode 100644 index 0000000000000..34f3904443c31 --- /dev/null +++ b/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr @@ -0,0 +1,19 @@ +error: conflicting implementations of trait `FnMarker` for type `fn(&_)` + --> $DIR/negative-coherence-placeholder-region-constraints-on-unification.rs:21:1 + | +LL | impl FnMarker for fn(T) {} + | ------------------------------------------- first implementation here +LL | impl FnMarker for fn(&T) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(&_)` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #56105 + = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details +note: the lint level is defined here + --> $DIR/negative-coherence-placeholder-region-constraints-on-unification.rs:4:11 + | +LL | #![forbid(coherence_leak_check)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.rs b/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.rs new file mode 100644 index 0000000000000..26d9d84d8f0c9 --- /dev/null +++ b/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.rs @@ -0,0 +1,25 @@ +// revisions: explicit implicit +//[implicit] check-pass + +#![forbid(coherence_leak_check)] +#![feature(negative_impls, with_negative_coherence)] + +pub trait Marker {} + +#[cfg(implicit)] +impl !Marker for &T {} + +#[cfg(explicit)] +impl<'a, T: ?Sized + 'a> !Marker for &'a T {} + +trait FnMarker {} + +// Unifying these two impls below results in a `T: '!0` obligation +// that we shouldn't need to care about. Ideally, we'd treat that +// as an assumption when proving `&'!0 T: Marker`... +impl FnMarker for fn(T) {} +impl FnMarker for fn(&T) {} +//[explicit]~^ ERROR conflicting implementations of trait `FnMarker` for type `fn(&_)` +//[explicit]~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + +fn main() {} diff --git a/tests/ui/consts/const-int-unchecked.stderr b/tests/ui/consts/const-int-unchecked.stderr index ad880d56d904d..ad14c8f68f8cb 100644 --- a/tests/ui/consts/const-int-unchecked.stderr +++ b/tests/ui/consts/const-int-unchecked.stderr @@ -62,61 +62,61 @@ error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:41:33 | LL | const SHL_I8_NEG: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 255 in `unchecked_shl` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -1 in `unchecked_shl` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:43:35 | LL | const SHL_I16_NEG: i16 = unsafe { intrinsics::unchecked_shl(5_16, -1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 65535 in `unchecked_shl` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -1 in `unchecked_shl` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:45:35 | LL | const SHL_I32_NEG: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 4294967295 in `unchecked_shl` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -1 in `unchecked_shl` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:47:35 | LL | const SHL_I64_NEG: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 18446744073709551615 in `unchecked_shl` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -1 in `unchecked_shl` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:49:37 | LL | const SHL_I128_NEG: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 340282366920938463463374607431768211455 in `unchecked_shl` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -1 in `unchecked_shl` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:55:40 | LL | const SHL_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shl(5_i8, -6) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 250 in `unchecked_shl` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -6 in `unchecked_shl` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:57:42 | LL | const SHL_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shl(5_16, -13) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 65523 in `unchecked_shl` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -13 in `unchecked_shl` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:59:42 | LL | const SHL_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shl(5_i32, -25) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 4294967271 in `unchecked_shl` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -25 in `unchecked_shl` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:61:42 | LL | const SHL_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shl(5_i64, -30) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 18446744073709551586 in `unchecked_shl` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -30 in `unchecked_shl` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:63:44 | LL | const SHL_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shl(5_i128, -93) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 340282366920938463463374607431768211363 in `unchecked_shl` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -93 in `unchecked_shl` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:70:29 @@ -182,61 +182,61 @@ error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:96:33 | LL | const SHR_I8_NEG: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 255 in `unchecked_shr` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -1 in `unchecked_shr` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:98:35 | LL | const SHR_I16_NEG: i16 = unsafe { intrinsics::unchecked_shr(5_16, -1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 65535 in `unchecked_shr` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -1 in `unchecked_shr` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:100:35 | LL | const SHR_I32_NEG: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 4294967295 in `unchecked_shr` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -1 in `unchecked_shr` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:102:35 | LL | const SHR_I64_NEG: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 18446744073709551615 in `unchecked_shr` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -1 in `unchecked_shr` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:104:37 | LL | const SHR_I128_NEG: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -1) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 340282366920938463463374607431768211455 in `unchecked_shr` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -1 in `unchecked_shr` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:110:40 | LL | const SHR_I8_NEG_RANDOM: i8 = unsafe { intrinsics::unchecked_shr(5_i8, -6) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 250 in `unchecked_shr` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -6 in `unchecked_shr` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:112:42 | LL | const SHR_I16_NEG_RANDOM: i16 = unsafe { intrinsics::unchecked_shr(5_16, -13) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 65523 in `unchecked_shr` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -13 in `unchecked_shr` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:114:42 | LL | const SHR_I32_NEG_RANDOM: i32 = unsafe { intrinsics::unchecked_shr(5_i32, -25) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 4294967271 in `unchecked_shr` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -25 in `unchecked_shr` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:116:42 | LL | const SHR_I64_NEG_RANDOM: i64 = unsafe { intrinsics::unchecked_shr(5_i64, -30) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 18446744073709551586 in `unchecked_shr` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -30 in `unchecked_shr` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:118:44 | LL | const SHR_I128_NEG_RANDOM: i128 = unsafe { intrinsics::unchecked_shr(5_i128, -93) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by 340282366920938463463374607431768211363 in `unchecked_shr` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflowing shift by -93 in `unchecked_shr` error[E0080]: evaluation of constant value failed --> $DIR/const-int-unchecked.rs:123:25 diff --git a/tests/ui/diagnostic-width/flag-json.stderr b/tests/ui/diagnostic-width/flag-json.stderr index b21391d1640ef..16c17526809d6 100644 --- a/tests/ui/diagnostic-width/flag-json.stderr +++ b/tests/ui/diagnostic-width/flag-json.stderr @@ -1,4 +1,4 @@ -{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. +{"$message_type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. Erroneous code examples: @@ -33,8 +33,8 @@ LL | ..._: () = 42; | expected due to this "} -{"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error +{"$message_type":"diagnostic","message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error "} -{"message":"For more information about this error, try `rustc --explain E0308`.","code":null,"level":"failure-note","spans":[],"children":[],"rendered":"For more information about this error, try `rustc --explain E0308`. +{"$message_type":"diagnostic","message":"For more information about this error, try `rustc --explain E0308`.","code":null,"level":"failure-note","spans":[],"children":[],"rendered":"For more information about this error, try `rustc --explain E0308`. "} diff --git a/tests/ui/json/json-bom-plus-crlf-multifile.stderr b/tests/ui/json/json-bom-plus-crlf-multifile.stderr index 84040e8050e96..0c6c654d60a15 100644 --- a/tests/ui/json/json-bom-plus-crlf-multifile.stderr +++ b/tests/ui/json/json-bom-plus-crlf-multifile.stderr @@ -1,4 +1,4 @@ -{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. +{"$message_type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. Erroneous code examples: @@ -26,7 +26,7 @@ most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":612,"byte_end":618,"line_start":17,"line_end":17,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":622,"byte_end":622,"line_start":17,"line_end":17,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:17:22: error[E0308]: mismatched types "} -{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. +{"$message_type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. Erroneous code examples: @@ -54,7 +54,7 @@ most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":672,"byte_end":678,"line_start":19,"line_end":19,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":682,"byte_end":682,"line_start":19,"line_end":19,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:19:22: error[E0308]: mismatched types "} -{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. +{"$message_type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. Erroneous code examples: @@ -82,7 +82,7 @@ most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":735,"byte_end":741,"line_start":22,"line_end":22,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":746,"byte_end":746,"line_start":23,"line_end":23,"column_start":2,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":2,"highlight_end":2}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:23:1: error[E0308]: mismatched types "} -{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. +{"$message_type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. Erroneous code examples: @@ -110,5 +110,5 @@ most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":801,"byte_end":809,"line_start":25,"line_end":26,"column_start":22,"column_end":6,"is_primary":true,"text":[{"text":" let s : String = (","highlight_start":22,"highlight_end":23},{"text":" ); // Error spanning the newline.","highlight_start":1,"highlight_end":6}],"label":"expected `String`, found `()`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":792,"byte_end":798,"line_start":25,"line_end":25,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = (","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:25:22: error[E0308]: mismatched types "} -{"message":"aborting due to 4 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 4 previous errors +{"$message_type":"diagnostic","message":"aborting due to 4 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 4 previous errors "} diff --git a/tests/ui/json/json-bom-plus-crlf.stderr b/tests/ui/json/json-bom-plus-crlf.stderr index b0f450e9ecc14..31dbacb59e1ee 100644 --- a/tests/ui/json/json-bom-plus-crlf.stderr +++ b/tests/ui/json/json-bom-plus-crlf.stderr @@ -1,4 +1,4 @@ -{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. +{"$message_type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. Erroneous code examples: @@ -26,7 +26,7 @@ most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":597,"byte_end":603,"line_start":16,"line_end":16,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":607,"byte_end":607,"line_start":16,"line_end":16,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:16:22: error[E0308]: mismatched types "} -{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. +{"$message_type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. Erroneous code examples: @@ -54,7 +54,7 @@ most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":657,"byte_end":663,"line_start":18,"line_end":18,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":667,"byte_end":667,"line_start":18,"line_end":18,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:18:22: error[E0308]: mismatched types "} -{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. +{"$message_type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. Erroneous code examples: @@ -82,7 +82,7 @@ most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":720,"byte_end":726,"line_start":21,"line_end":21,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":731,"byte_end":731,"line_start":22,"line_end":22,"column_start":2,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":2,"highlight_end":2}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:22:1: error[E0308]: mismatched types "} -{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. +{"$message_type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type. Erroneous code examples: @@ -110,5 +110,5 @@ most common being when calling a function and passing an argument which has a different type than the matching type in the function declaration. "},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":786,"byte_end":794,"line_start":24,"line_end":25,"column_start":22,"column_end":6,"is_primary":true,"text":[{"text":" let s : String = (","highlight_start":22,"highlight_end":23},{"text":" ); // Error spanning the newline.","highlight_start":1,"highlight_end":6}],"label":"expected `String`, found `()`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":777,"byte_end":783,"line_start":24,"line_end":24,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = (","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-bom-plus-crlf.rs:24:22: error[E0308]: mismatched types "} -{"message":"aborting due to 4 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 4 previous errors +{"$message_type":"diagnostic","message":"aborting due to 4 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 4 previous errors "} diff --git a/tests/ui/json/json-multiple.stderr b/tests/ui/json/json-multiple.stderr index 55ccfd5fa70de..7689fb94a6c8d 100644 --- a/tests/ui/json/json-multiple.stderr +++ b/tests/ui/json/json-multiple.stderr @@ -1 +1 @@ -{"artifact":"$TEST_BUILD_DIR/json/json-multiple/libjson_multiple.rlib","emit":"link"} +{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/json/json-multiple/libjson_multiple.rlib","emit":"link"} diff --git a/tests/ui/json/json-options.stderr b/tests/ui/json/json-options.stderr index 645a26f5ad407..668fc18097f0d 100644 --- a/tests/ui/json/json-options.stderr +++ b/tests/ui/json/json-options.stderr @@ -1 +1 @@ -{"artifact":"$TEST_BUILD_DIR/json/json-options/libjson_options.rlib","emit":"link"} +{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/json/json-options/libjson_options.rlib","emit":"link"} diff --git a/tests/ui/json/json-short.stderr b/tests/ui/json/json-short.stderr index 3bd85b083d002..030af0c5ada61 100644 --- a/tests/ui/json/json-short.stderr +++ b/tests/ui/json/json-short.stderr @@ -1,4 +1,4 @@ -{"message":"`main` function not found in crate `json_short`","code":{"code":"E0601","explanation":"No `main` function was found in a binary crate. +{"$message_type":"diagnostic","message":"`main` function not found in crate `json_short`","code":{"code":"E0601","explanation":"No `main` function was found in a binary crate. To fix this error, add a `main` function: @@ -15,5 +15,5 @@ If you don't know the basics of Rust, you can look at the [rust-book]: https://doc.rust-lang.org/book/ "},"level":"error","spans":[{"file_name":"$DIR/json-short.rs","byte_start":62,"byte_end":62,"line_start":1,"line_end":1,"column_start":63,"column_end":63,"is_primary":true,"text":[{"text":"// compile-flags: --json=diagnostic-short --error-format=json","highlight_start":63,"highlight_end":63}],"label":"consider adding a `main` function to `$DIR/json-short.rs`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-short.rs:1:63: error[E0601]: `main` function not found in crate `json_short` "} -{"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error +{"$message_type":"diagnostic","message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error "} diff --git a/tests/ui/lint/future-incompat-json-test.rs b/tests/ui/lint/future-incompat-json-test.rs new file mode 100644 index 0000000000000..6ccd670294c60 --- /dev/null +++ b/tests/ui/lint/future-incompat-json-test.rs @@ -0,0 +1,10 @@ +// compile-flags: -Zfuture-incompat-test --json=future-incompat --error-format=json +// check-pass + +// The `-Zfuture-incompat-test flag causes any normal warning to be included +// in the future-incompatible report. The stderr output here should mention +// the future incompatible report (as extracted by compiletest). + +fn main() { + let x = 1; +} diff --git a/tests/ui/lint/future-incompat-json-test.stderr b/tests/ui/lint/future-incompat-json-test.stderr new file mode 100644 index 0000000000000..c4ab5a00d16cc --- /dev/null +++ b/tests/ui/lint/future-incompat-json-test.stderr @@ -0,0 +1,10 @@ +{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`-A unused-variables` implied by `-A unused`","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"to override `-A unused` add `#[allow(unused_variables)]`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x` + --> $DIR/future-incompat-json-test.rs:9:9 + | +LL | let x = 1; + | ^ help: if this is intentional, prefix it with an underscore: `_x` + | + = note: `-A unused-variables` implied by `-A unused` + = help: to override `-A unused` add `#[allow(unused_variables)]` + +"}}]} diff --git a/tests/ui/lint/unused_parens_json_suggestion.stderr b/tests/ui/lint/unused_parens_json_suggestion.stderr index ea19e0cdc0cb3..ac3b2b5b21a71 100644 --- a/tests/ui/lint/unused_parens_json_suggestion.stderr +++ b/tests/ui/lint/unused_parens_json_suggestion.stderr @@ -1,4 +1,4 @@ -{"message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":577,"byte_end":578,"line_start":16,"line_end":16,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":" let _a = (1 / (2 + 3)); +{"$message_type":"diagnostic","message":"unnecessary parentheses around assigned value","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_json_suggestion.rs","byte_start":577,"byte_end":578,"line_start":16,"line_end":16,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":" let _a = (1 / (2 + 3)); --> $DIR/unused_parens_json_suggestion.rs:16:14 | LL | let _a = (1 / (2 + 3)); @@ -16,6 +16,6 @@ LL + let _a = 1 / (2 + 3); | "} -{"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error +{"$message_type":"diagnostic","message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error "} diff --git a/tests/ui/lint/unused_parens_remove_json_suggestion.stderr b/tests/ui/lint/unused_parens_remove_json_suggestion.stderr index f4c6ceaf1dc1b..7521d41cc939d 100644 --- a/tests/ui/lint/unused_parens_remove_json_suggestion.stderr +++ b/tests/ui/lint/unused_parens_remove_json_suggestion.stderr @@ -1,4 +1,4 @@ -{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":481,"byte_end":482,"line_start":17,"line_end":17,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":" if (_b) { +{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":481,"byte_end":482,"line_start":17,"line_end":17,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":" if (_b) { --> $DIR/unused_parens_remove_json_suggestion.rs:17:8 | LL | if (_b) { @@ -16,7 +16,7 @@ LL + if _b { | "} -{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":612,"byte_end":613,"line_start":28,"line_end":28,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":" if(c) { +{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":612,"byte_end":613,"line_start":28,"line_end":28,"column_start":7,"column_end":8,"is_primary":true,"text":[{"text":" if(c) { --> $DIR/unused_parens_remove_json_suggestion.rs:28:7 | LL | if(c) { @@ -29,7 +29,7 @@ LL + if c { | "} -{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":692,"byte_end":693,"line_start":32,"line_end":32,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":" if (c){ +{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":692,"byte_end":693,"line_start":32,"line_end":32,"column_start":8,"column_end":9,"is_primary":true,"text":[{"text":" if (c){ --> $DIR/unused_parens_remove_json_suggestion.rs:32:8 | LL | if (c){ @@ -42,7 +42,7 @@ LL + if c { | "} -{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":774,"byte_end":775,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":788,"byte_end":789,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":774,"byte_end":775,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":788,"byte_end":789,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition +{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":774,"byte_end":775,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":788,"byte_end":789,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"remove these parentheses","code":null,"level":"help","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":774,"byte_end":775,"line_start":36,"line_end":36,"column_start":11,"column_end":12,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":11,"highlight_end":12}],"label":null,"suggested_replacement":"","suggestion_applicability":"MachineApplicable","expansion":null},{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":788,"byte_end":789,"line_start":36,"line_end":36,"column_start":25,"column_end":26,"is_primary":true,"text":[{"text":" while (false && true){","highlight_start":25,"highlight_end":26}],"label":null,"suggested_replacement":" ","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"error: unnecessary parentheses around `while` condition --> $DIR/unused_parens_remove_json_suggestion.rs:36:11 | LL | while (false && true){ @@ -55,7 +55,7 @@ LL + while false && true { | "} -{"message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":802,"byte_end":803,"line_start":37,"line_end":37,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":" if (c) { +{"$message_type":"diagnostic","message":"unnecessary parentheses around `if` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":802,"byte_end":803,"line_start":37,"line_end":37,"column_start":12,"column_end":13,"is_primary":true,"text":[{"text":" if (c) { --> $DIR/unused_parens_remove_json_suggestion.rs:37:12 | LL | if (c) { @@ -68,7 +68,7 @@ LL + if c { | "} -{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":899,"byte_end":900,"line_start":43,"line_end":43,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":" while(true && false) { +{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":899,"byte_end":900,"line_start":43,"line_end":43,"column_start":10,"column_end":11,"is_primary":true,"text":[{"text":" while(true && false) { --> $DIR/unused_parens_remove_json_suggestion.rs:43:10 | LL | while(true && false) { @@ -81,7 +81,7 @@ LL + while true && false { | "} -{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":968,"byte_end":969,"line_start":44,"line_end":44,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":" for _ in (0 .. 3){ +{"$message_type":"diagnostic","message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":968,"byte_end":969,"line_start":44,"line_end":44,"column_start":18,"column_end":19,"is_primary":true,"text":[{"text":" for _ in (0 .. 3){ --> $DIR/unused_parens_remove_json_suggestion.rs:44:18 | LL | for _ in (0 .. 3){ @@ -94,7 +94,7 @@ LL + for _ in 0 .. 3 { | "} -{"message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1069,"byte_end":1070,"line_start":49,"line_end":49,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":" for _ in (0 .. 3) { +{"$message_type":"diagnostic","message":"unnecessary parentheses around `for` iterator expression","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1069,"byte_end":1070,"line_start":49,"line_end":49,"column_start":14,"column_end":15,"is_primary":true,"text":[{"text":" for _ in (0 .. 3) { --> $DIR/unused_parens_remove_json_suggestion.rs:49:14 | LL | for _ in (0 .. 3) { @@ -107,7 +107,7 @@ LL + for _ in 0 .. 3 { | "} -{"message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1128,"byte_end":1129,"line_start":50,"line_end":50,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":" while (true && false) { +{"$message_type":"diagnostic","message":"unnecessary parentheses around `while` condition","code":{"code":"unused_parens","explanation":null},"level":"error","spans":[{"file_name":"$DIR/unused_parens_remove_json_suggestion.rs","byte_start":1128,"byte_end":1129,"line_start":50,"line_end":50,"column_start":15,"column_end":16,"is_primary":true,"text":[{"text":" while (true && false) { --> $DIR/unused_parens_remove_json_suggestion.rs:50:15 | LL | while (true && false) { @@ -120,6 +120,6 @@ LL + while true && false { | "} -{"message":"aborting due to 9 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 9 previous errors +{"$message_type":"diagnostic","message":"aborting due to 9 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 9 previous errors "} diff --git a/tests/ui/lint/use_suggestion_json.stderr b/tests/ui/lint/use_suggestion_json.stderr index d17514303abf6..7dfd269a4e247 100644 --- a/tests/ui/lint/use_suggestion_json.stderr +++ b/tests/ui/lint/use_suggestion_json.stderr @@ -1,3 +1,3 @@ -{"message":"`--error-format=pretty-json` is unstable","code":null,"level":"error","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: `--error-format=pretty-json` is unstable\u001b[0m +{"$message_type":"diagnostic","message":"`--error-format=pretty-json` is unstable","code":null,"level":"error","spans":[],"children":[],"rendered":"\u001b[0m\u001b[1m\u001b[38;5;9merror\u001b[0m\u001b[0m\u001b[1m: `--error-format=pretty-json` is unstable\u001b[0m "} diff --git a/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.rs b/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.rs new file mode 100644 index 0000000000000..fe363a6887f58 --- /dev/null +++ b/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.rs @@ -0,0 +1,9 @@ +trait Trait {} + +fn test(_: &for<'a> dyn Trait) {} +//~^ ERROR `for<...>` expected after `dyn`, not before + +fn test2(_: for<'a> impl Trait) {} +//~^ ERROR `for<...>` expected after `impl`, not before + +fn main() {} diff --git a/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.stderr b/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.stderr new file mode 100644 index 0000000000000..6fc1259b91061 --- /dev/null +++ b/tests/ui/parser/recover-hrtb-before-dyn-impl-kw.stderr @@ -0,0 +1,26 @@ +error: `for<...>` expected after `dyn`, not before + --> $DIR/recover-hrtb-before-dyn-impl-kw.rs:3:21 + | +LL | fn test(_: &for<'a> dyn Trait) {} + | ^^^ + | +help: move `dyn` before the `for<...>` + | +LL - fn test(_: &for<'a> dyn Trait) {} +LL + fn test(_: &dyn for<'a> Trait) {} + | + +error: `for<...>` expected after `impl`, not before + --> $DIR/recover-hrtb-before-dyn-impl-kw.rs:6:21 + | +LL | fn test2(_: for<'a> impl Trait) {} + | ^^^^ + | +help: move `impl` before the `for<...>` + | +LL - fn test2(_: for<'a> impl Trait) {} +LL + fn test2(_: impl for<'a> Trait) {} + | + +error: aborting due to 2 previous errors + diff --git a/tests/ui/rmeta/emit-artifact-notifications.stderr b/tests/ui/rmeta/emit-artifact-notifications.stderr index b2f0aa7575c06..4f68a2d74ed31 100644 --- a/tests/ui/rmeta/emit-artifact-notifications.stderr +++ b/tests/ui/rmeta/emit-artifact-notifications.stderr @@ -1 +1 @@ -{"artifact":"$TEST_BUILD_DIR/rmeta/emit-artifact-notifications/libemit_artifact_notifications.rmeta","emit":"metadata"} +{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/rmeta/emit-artifact-notifications/libemit_artifact_notifications.rmeta","emit":"metadata"} diff --git a/tests/ui/unused-crate-deps/deny-cmdline-json-silent.stderr b/tests/ui/unused-crate-deps/deny-cmdline-json-silent.stderr index 595619f3a8a4e..f6594fdaa911e 100644 --- a/tests/ui/unused-crate-deps/deny-cmdline-json-silent.stderr +++ b/tests/ui/unused-crate-deps/deny-cmdline-json-silent.stderr @@ -1 +1 @@ -{"lint_level":"deny","unused_extern_names":["bar"]} +{"$message_type":"unused_extern","lint_level":"deny","unused_extern_names":["bar"]} diff --git a/tests/ui/unused-crate-deps/deny-cmdline-json.stderr b/tests/ui/unused-crate-deps/deny-cmdline-json.stderr index 595619f3a8a4e..f6594fdaa911e 100644 --- a/tests/ui/unused-crate-deps/deny-cmdline-json.stderr +++ b/tests/ui/unused-crate-deps/deny-cmdline-json.stderr @@ -1 +1 @@ -{"lint_level":"deny","unused_extern_names":["bar"]} +{"$message_type":"unused_extern","lint_level":"deny","unused_extern_names":["bar"]} diff --git a/tests/ui/unused-crate-deps/warn-cmdline-json.stderr b/tests/ui/unused-crate-deps/warn-cmdline-json.stderr index 98dbd763927e6..ef99f986eb1d7 100644 --- a/tests/ui/unused-crate-deps/warn-cmdline-json.stderr +++ b/tests/ui/unused-crate-deps/warn-cmdline-json.stderr @@ -1 +1 @@ -{"lint_level":"warn","unused_extern_names":["bar"]} +{"$message_type":"unused_extern","lint_level":"warn","unused_extern_names":["bar"]}