From 255bee177797cd5c35729acf02c6a43b5dd1f73d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Wed, 10 Apr 2024 15:21:16 +0000 Subject: [PATCH 1/9] run-make-support: add clang and llvm-readobj command wrappers --- src/tools/run-make-support/src/clang.rs | 73 +++++++++++++++++++ src/tools/run-make-support/src/lib.rs | 4 + .../run-make-support/src/llvm_readobj.rs | 44 +++++++++++ 3 files changed, 121 insertions(+) create mode 100644 src/tools/run-make-support/src/clang.rs create mode 100644 src/tools/run-make-support/src/llvm_readobj.rs diff --git a/src/tools/run-make-support/src/clang.rs b/src/tools/run-make-support/src/clang.rs new file mode 100644 index 0000000000000..ed9f8383dc3ae --- /dev/null +++ b/src/tools/run-make-support/src/clang.rs @@ -0,0 +1,73 @@ +use std::env; +use std::path::Path; +use std::process::Command; + +use crate::{bin_name, handle_failed_output, tmp_dir}; + +/// Construct a new `clang` invocation. `clang` is not always available for all targets. +pub fn clang() -> Clang { + Clang::new() +} + +/// A `clang` invocation builder. +#[derive(Debug)] +pub struct Clang { + cmd: Command, +} + +crate::impl_common_helpers!(Clang); + +impl Clang { + /// Construct a new `clang` invocation. `clang` is not always available for all targets. + pub fn new() -> Self { + let clang = + env::var("CLANG").expect("`CLANG` not specified, but this is required to find `clang`"); + let cmd = Command::new(clang); + Self { cmd } + } + + /// Provide an input file. + pub fn input>(&mut self, path: P) -> &mut Self { + self.cmd.arg(path.as_ref()); + self + } + + /// Specify the name of the executable. The executable will be placed under `$TMPDIR`, and the + /// extension will be determined by [`bin_name`]. + pub fn out_exe(&mut self, name: &str) -> &mut Self { + self.cmd.arg("-o"); + self.cmd.arg(tmp_dir().join(bin_name(name))); + self + } + + /// Specify which target triple clang should target. + pub fn target(&mut self, target_triple: &str) -> &mut Self { + self.cmd.arg("-target"); + self.cmd.arg(target_triple); + self + } + + /// Pass `-nostdlib` to disable linking the C standard library. + pub fn no_stdlib(&mut self) -> &mut Self { + self.cmd.arg("-nostdlib"); + self + } + + /// Specify architecture. + pub fn arch(&mut self, arch: &str) -> &mut Self { + self.cmd.arg(format!("-march={arch}")); + self + } + + /// Specify LTO settings. + pub fn lto(&mut self, lto: &str) -> &mut Self { + self.cmd.arg(format!("-flto={lto}")); + self + } + + /// Specify which ld to use. + pub fn use_ld(&mut self, ld: &str) -> &mut Self { + self.cmd.arg(format!("-fuse-ld={ld}")); + self + } +} diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 9a4fdff5d1526..e723e824ed6c8 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -4,6 +4,8 @@ //! as `object` or `wasmparser`, they can be re-exported and be made available through this library. pub mod cc; +pub mod clang; +pub mod llvm_readobj; pub mod run; pub mod rustc; pub mod rustdoc; @@ -17,6 +19,8 @@ pub use regex; pub use wasmparser; pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc}; +pub use clang::{clang, Clang}; +pub use llvm_readobj::{llvm_readobj, LlvmReadobj}; pub use run::{run, run_fail}; pub use rustc::{aux_build, rustc, Rustc}; pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc}; diff --git a/src/tools/run-make-support/src/llvm_readobj.rs b/src/tools/run-make-support/src/llvm_readobj.rs new file mode 100644 index 0000000000000..32ea07e932ed8 --- /dev/null +++ b/src/tools/run-make-support/src/llvm_readobj.rs @@ -0,0 +1,44 @@ +use std::env; +use std::path::{Path, PathBuf}; +use std::process::Command; + +use crate::handle_failed_output; + +/// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available +/// at `$LLVM_BIN_DIR/llvm-readobj`. +pub fn llvm_readobj() -> LlvmReadobj { + LlvmReadobj::new() +} + +/// A `llvm-readobj` invocation builder. +#[derive(Debug)] +pub struct LlvmReadobj { + cmd: Command, +} + +crate::impl_common_helpers!(LlvmReadobj); + +impl LlvmReadobj { + /// Construct a new `llvm-readobj` invocation. This assumes that `llvm-readobj` is available + /// at `$LLVM_BIN_DIR/llvm-readobj`. + pub fn new() -> Self { + let llvm_bin_dir = env::var("LLVM_BIN_DIR") + .expect("`LLVM_BIN_DIR` not specified, but this is required to find `llvm-readobj`"); + let llvm_bin_dir = PathBuf::from(llvm_bin_dir); + let llvm_readobj = llvm_bin_dir.join("llvm-readobj"); + let cmd = Command::new(llvm_readobj); + Self { cmd } + } + + /// Provide an input file. + pub fn input>(&mut self, path: P) -> &mut Self { + self.cmd.arg(path.as_ref()); + self + } + + /// Pass `--file-header` to display file headers. + pub fn file_header(&mut self) -> &mut Self { + self.cmd.arg("--file-header"); + self + } +} From ca945e9ed83a76921ba29d27d4640afe0e278a17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Wed, 10 Apr 2024 15:22:29 +0000 Subject: [PATCH 2/9] tests: update cross-lang-lto-riscv-abi to use command wrappers --- .../cross-lang-lto-riscv-abi/rmake.rs | 61 ++++++------------- 1 file changed, 19 insertions(+), 42 deletions(-) diff --git a/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs b/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs index 2f13cf17169fa..b534a99f8cfee 100644 --- a/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs +++ b/tests/run-make/cross-lang-lto-riscv-abi/rmake.rs @@ -1,10 +1,10 @@ //! Make sure that cross-language LTO works on riscv targets, -//! which requires extra abi metadata to be emitted. +//! which requires extra `target-abi` metadata to be emitted. //@ needs-matching-clang //@ needs-llvm-components riscv extern crate run_make_support; -use run_make_support::{bin_name, rustc, tmp_dir}; +use run_make_support::{bin_name, clang, llvm_readobj, rustc, tmp_dir}; use std::{ env, path::PathBuf, @@ -12,13 +12,6 @@ use std::{ str, }; -fn handle_failed_output(output: Output) { - eprintln!("output status: `{}`", output.status); - eprintln!("=== STDOUT ===\n{}\n\n", String::from_utf8(output.stdout).unwrap()); - eprintln!("=== STDERR ===\n{}\n\n", String::from_utf8(output.stderr).unwrap()); - std::process::exit(1) -} - fn check_target(target: &str, clang_target: &str, carch: &str, is_double_float: bool) { eprintln!("Checking target {target}"); // Rust part @@ -30,40 +23,24 @@ fn check_target(target: &str, clang_target: &str, carch: &str, is_double_float: .linker_plugin_lto("on") .run(); // C part - let clang = env::var("CLANG").unwrap(); - let mut cmd = Command::new(clang); - let executable = tmp_dir().join("riscv-xlto"); - cmd.arg("-target") - .arg(clang_target) - .arg(format!("-march={carch}")) - .arg(format!("-flto=thin")) - .arg(format!("-fuse-ld=lld")) - .arg("-nostdlib") - .arg("-o") - .arg(&executable) - .arg("cstart.c") - .arg(tmp_dir().join("libriscv_xlto.rlib")); - eprintln!("{cmd:?}"); - let output = cmd.output().unwrap(); - if !output.status.success() { - handle_failed_output(output); - } + clang() + .target(clang_target) + .arch(carch) + .lto("thin") + .use_ld("lld") + .no_stdlib() + .out_exe("riscv-xlto") + .input("cstart.c") + .input(tmp_dir().join("libriscv_xlto.rlib")) + .run(); + // Check that the built binary has correct float abi - let llvm_readobj = - PathBuf::from(env::var("LLVM_BIN_DIR").unwrap()).join(bin_name("llvm-readobj")); - let mut cmd = Command::new(llvm_readobj); - cmd.arg("--file-header").arg(executable); - eprintln!("{cmd:?}"); - let output = cmd.output().unwrap(); - if output.status.success() { - assert!( - !(is_double_float - ^ dbg!(str::from_utf8(&output.stdout).unwrap()) - .contains("EF_RISCV_FLOAT_ABI_DOUBLE")) - ) - } else { - handle_failed_output(output); - } + let executable = tmp_dir().join(bin_name("riscv-xlto")); + let output = llvm_readobj().input(&executable).file_header().run(); + let stdout = String::from_utf8_lossy(&output.stdout); + eprintln!("obj:\n{}", stdout); + + assert!(!(is_double_float ^ stdout.contains("EF_RISCV_FLOAT_ABI_DOUBLE"))); } fn main() { From ffb42065774b5d500ef5649d4caa91e9e344ff46 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 17 Apr 2024 21:58:27 -0400 Subject: [PATCH 3/9] Don't repeatedly duplicate TAIT lifetimes for each subsequently nested TAIT --- .../src/collect/generics_of.rs | 15 +++-- tests/ui/type-alias-impl-trait/variance.rs | 24 ++++++++ .../ui/type-alias-impl-trait/variance.stderr | 56 ++++++++++++++++++- 3 files changed, 88 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 4d6a02f50bfcc..f83ddc51c76e2 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -195,16 +195,19 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics { } Some(fn_def_id.to_def_id()) } - ItemKind::OpaqueTy(hir::OpaqueTy { - origin: hir::OpaqueTyOrigin::TyAlias { .. }, + ItemKind::OpaqueTy(&hir::OpaqueTy { + origin: hir::OpaqueTyOrigin::TyAlias { parent, in_assoc_ty }, .. }) => { - let parent_id = tcx.hir().get_parent_item(hir_id); - assert_ne!(parent_id, hir::CRATE_OWNER_ID); - debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id); + if in_assoc_ty { + assert!(matches!(tcx.def_kind(parent), DefKind::AssocTy)); + } else { + assert!(matches!(tcx.def_kind(parent), DefKind::TyAlias)); + } + debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent); // Opaque types are always nested within another item, and // inherit the generics of the item. - Some(parent_id.to_def_id()) + Some(parent.to_def_id()) } _ => None, }, diff --git a/tests/ui/type-alias-impl-trait/variance.rs b/tests/ui/type-alias-impl-trait/variance.rs index 4b9fa67fd64c7..ba52eaa035971 100644 --- a/tests/ui/type-alias-impl-trait/variance.rs +++ b/tests/ui/type-alias-impl-trait/variance.rs @@ -52,4 +52,28 @@ impl<'i> Foo<'i> for () { //~^ ERROR: unconstrained opaque type } +trait Nesting<'a> { + type Output; +} +impl<'a> Nesting<'a> for &'a () { + type Output = &'a (); +} +type NestedDeeply<'a> = + impl Nesting< //~ [*, o] + 'a, + Output = impl Nesting< //~ [*, o] + 'a, + Output = impl Nesting< //~ [*, o] + 'a, + Output = impl Nesting< //~ [*, o] + 'a, + Output = impl Nesting<'a> //~ [*, o] + > + >, + >, + >; +fn test<'a>() -> NestedDeeply<'a> { + &() +} + fn main() {} diff --git a/tests/ui/type-alias-impl-trait/variance.stderr b/tests/ui/type-alias-impl-trait/variance.stderr index 1aaf36223b7f5..e5ced7a498171 100644 --- a/tests/ui/type-alias-impl-trait/variance.stderr +++ b/tests/ui/type-alias-impl-trait/variance.stderr @@ -176,6 +176,60 @@ error: [*, *, o, o] LL | type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 24 previous errors +error: [*, o] + --> $DIR/variance.rs:62:5 + | +LL | / impl Nesting< +LL | | 'a, +LL | | Output = impl Nesting< +LL | | 'a, +... | +LL | | >, +LL | | >; + | |_____^ + +error: [*, o] + --> $DIR/variance.rs:64:18 + | +LL | Output = impl Nesting< + | __________________^ +LL | | 'a, +LL | | Output = impl Nesting< +LL | | 'a, +... | +LL | | >, +LL | | >, + | |_________^ + +error: [*, o] + --> $DIR/variance.rs:66:22 + | +LL | Output = impl Nesting< + | ______________________^ +LL | | 'a, +LL | | Output = impl Nesting< +LL | | 'a, +LL | | Output = impl Nesting<'a> +LL | | > +LL | | >, + | |_____________^ + +error: [*, o] + --> $DIR/variance.rs:68:26 + | +LL | Output = impl Nesting< + | __________________________^ +LL | | 'a, +LL | | Output = impl Nesting<'a> +LL | | > + | |_________________^ + +error: [*, o] + --> $DIR/variance.rs:70:30 + | +LL | Output = impl Nesting<'a> + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 29 previous errors For more information about this error, try `rustc --explain E0657`. From 2e7d9e9acbdb48620e347529796bf1e35fd97c19 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 18 Apr 2024 22:20:08 -0700 Subject: [PATCH 4/9] rustdoc-search: fix description on aliases in results This needs to start downloading the descriptions after aliases have been added to the result set. --- src/librustdoc/html/static/js/search.js | 21 +++++++++++---------- tests/rustdoc-js-std/alias-1.js | 6 +++++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 0a43e9765e2b9..41a9897de6dfb 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1464,16 +1464,7 @@ function initSearch(rawSearchIndex) { return 0; }); - const transformed = transformResults(result_list); - const descs = await Promise.all(transformed.map(result => { - return searchIndexEmptyDesc.get(result.crate).contains(result.bitIndex) ? - "" : - searchState.loadDesc(result); - })); - for (const [i, result] of transformed.entries()) { - result.desc = descs[i]; - } - return transformed; + return transformResults(result_list); } /** @@ -2517,6 +2508,16 @@ function initSearch(rawSearchIndex) { sorted_others, parsedQuery); handleAliases(ret, parsedQuery.original.replace(/"/g, ""), filterCrates, currentCrate); + await Promise.all([ret.others, ret.returned, ret.in_args].map(async list => { + const descs = await Promise.all(list.map(result => { + return searchIndexEmptyDesc.get(result.crate).contains(result.bitIndex) ? + "" : + searchState.loadDesc(result); + })); + for (const [i, result] of list.entries()) { + result.desc = descs[i]; + } + })); if (parsedQuery.error !== null && ret.others.length !== 0) { // It means some doc aliases were found so let's "remove" the error! ret.query.error = null; diff --git a/tests/rustdoc-js-std/alias-1.js b/tests/rustdoc-js-std/alias-1.js index b27b3da217966..c31d1a3b1ad7d 100644 --- a/tests/rustdoc-js-std/alias-1.js +++ b/tests/rustdoc-js-std/alias-1.js @@ -1,6 +1,10 @@ const EXPECTED = { 'query': '&', 'others': [ - { 'path': 'std', 'name': 'reference' }, + { + 'path': 'std', + 'name': 'reference', + 'desc': "References, &T and &mut T.", + }, ], }; From 6612ad796c8d035984694368e5c0924933bdae9e Mon Sep 17 00:00:00 2001 From: klensy Date: Fri, 19 Apr 2024 12:07:07 +0300 Subject: [PATCH 5/9] bootstrap: don't use rayon for sysinfo It's looks overkill to use rayon to collect cpu usage --- src/bootstrap/Cargo.lock | 27 --------------------------- src/bootstrap/Cargo.toml | 2 +- 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index e2c90cc8c8474..9c2b7500a20f7 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -236,12 +236,6 @@ dependencies = [ "crypto-common", ] -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - [[package]] name = "errno" version = "0.3.8" @@ -448,26 +442,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rayon" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -598,7 +572,6 @@ dependencies = [ "libc", "ntapi", "once_cell", - "rayon", "windows", ] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index b232885c590ee..c7a513d08908a 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -64,7 +64,7 @@ walkdir = "2.4" xz2 = "0.1" # Dependencies needed by the build-metrics feature -sysinfo = { version = "0.30", optional = true } +sysinfo = { version = "0.30", default-features = false, optional = true } [target.'cfg(windows)'.dependencies.junction] version = "1.0.0" From 662d276573765f70dff70d758ca9179766b19f08 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sat, 6 Apr 2024 17:18:25 +0000 Subject: [PATCH 6/9] Add regression test for issue 120600 --- tests/ui/never_type/eq-never-types.rs | 22 ++++++++++++++++++++++ tests/ui/never_type/eq-never-types.stderr | 20 ++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 tests/ui/never_type/eq-never-types.rs create mode 100644 tests/ui/never_type/eq-never-types.stderr diff --git a/tests/ui/never_type/eq-never-types.rs b/tests/ui/never_type/eq-never-types.rs new file mode 100644 index 0000000000000..00e55c100bdd3 --- /dev/null +++ b/tests/ui/never_type/eq-never-types.rs @@ -0,0 +1,22 @@ +//@ known-bug: #120600 +// +// issue: rust-lang/rust#120600 + +//@ failure-status: 101 +//@ normalize-stderr-test: "DefId\(.*?\]::" -> "DefId(" +//@ normalize-stderr-test: "(?m)note: we would appreciate a bug report.*\n\n" -> "" +//@ normalize-stderr-test: "(?m)note: rustc.*running on.*\n\n" -> "" +//@ normalize-stderr-test: "(?m)note: compiler flags.*\n\n" -> "" +//@ normalize-stderr-test: "(?m)note: delayed at.*$" -> "" +//@ normalize-stderr-test: "(?m)^ *\d+: .*\n" -> "" +//@ normalize-stderr-test: "(?m)^ *at .*\n" -> "" + +#![allow(internal_features)] +#![feature(never_type, rustc_attrs)] +#![rustc_never_type_options(fallback = "never")] + +fn ice(a: !) { + a == a; +} + +fn main() {} diff --git a/tests/ui/never_type/eq-never-types.stderr b/tests/ui/never_type/eq-never-types.stderr new file mode 100644 index 0000000000000..61c3f430b9a5d --- /dev/null +++ b/tests/ui/never_type/eq-never-types.stderr @@ -0,0 +1,20 @@ +note: no errors encountered even though delayed bugs were created + +note: those delayed bugs will now be shown as internal compiler errors + +error: internal compiler error: broken MIR in DefId(ice) (Terminator { source_info: SourceInfo { span: $DIR/eq-never-types.rs:19:5: 19:11 (#0), scope: scope[0] }, kind: _3 = ::eq(move _4, move _5) -> [return: bb1, unwind: bb2] }): bad arg #0 (&'?4 ! <- !): NoSolution + --> $DIR/eq-never-types.rs:19:10 + | +LL | a == a; + | ^ + | + + --> $DIR/eq-never-types.rs:19:10 + | +LL | a == a; + | ^ + +note: using internal features is not supported and expected to cause internal compiler errors when used incorrectly + +query stack during panic: +end of query stack From 4d749cad25859c92975e7331bd242c2b510096ac Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sat, 6 Apr 2024 20:29:36 +0000 Subject: [PATCH 7/9] Add a test for `a == b` where `a: !, b: !` (this currently produces malformed mir: we call `eq` with first argument not being a reference) --- .../building/eq_never_type._f.built.after.mir | 53 +++++++++++++++++++ tests/mir-opt/building/eq_never_type.rs | 13 +++++ 2 files changed, 66 insertions(+) create mode 100644 tests/mir-opt/building/eq_never_type._f.built.after.mir create mode 100644 tests/mir-opt/building/eq_never_type.rs diff --git a/tests/mir-opt/building/eq_never_type._f.built.after.mir b/tests/mir-opt/building/eq_never_type._f.built.after.mir new file mode 100644 index 0000000000000..29e93a29aab4b --- /dev/null +++ b/tests/mir-opt/building/eq_never_type._f.built.after.mir @@ -0,0 +1,53 @@ +// MIR for `_f` after built + +fn _f(_1: !, _2: !) -> () { + debug a => _1; + debug b => _2; + let mut _0: (); + let mut _3: !; + let _4: bool; + let mut _5: (); + let mut _6: !; + let mut _7: &(); + let _8: (); + let mut _9: !; + + bb0: { + StorageLive(_4); + StorageLive(_5); + StorageLive(_6); + _6 = _1; + unreachable; + } + + bb1: { + StorageDead(_6); + StorageLive(_7); + StorageLive(_8); + StorageLive(_9); + _9 = _2; + unreachable; + } + + bb2: { + _7 = &_8; + StorageDead(_9); + _4 = <() as PartialEq>::eq(move _5, move _7) -> [return: bb3, unwind: bb5]; + } + + bb3: { + StorageDead(_7); + StorageDead(_5); + StorageDead(_8); + StorageDead(_4); + unreachable; + } + + bb4: { + return; + } + + bb5 (cleanup): { + resume; + } +} diff --git a/tests/mir-opt/building/eq_never_type.rs b/tests/mir-opt/building/eq_never_type.rs new file mode 100644 index 0000000000000..90e2e69753531 --- /dev/null +++ b/tests/mir-opt/building/eq_never_type.rs @@ -0,0 +1,13 @@ +// skip-filecheck +#![feature(never_type)] +#![allow(unreachable_code)] + +// EMIT_MIR eq_never_type._f.built.after.mir +fn _f(a: !, b: !) { + // Both arguments must be references (i.e. == should auto-borrow/coerce-to-ref both arguments) + // (this previously was buggy due to `NeverToAny` coercion incorrectly throwing out other + // coercions) + a == b; +} + +fn main() {} From 0bbe362901b799c1a8df1e503190c647d8374777 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sat, 6 Apr 2024 20:52:32 +0000 Subject: [PATCH 8/9] Correctly change type when adding adjustments on top of `NeverToAny` --- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 33 +++++++++++++------ .../building/eq_never_type._f.built.after.mir | 2 +- tests/ui/never_type/eq-never-types.rs | 11 +------ tests/ui/never_type/eq-never-types.stderr | 20 ----------- 4 files changed, 25 insertions(+), 41 deletions(-) delete mode 100644 tests/ui/never_type/eq-never-types.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 786754ed12f09..bd2454f6368d3 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -279,13 +279,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } Entry::Occupied(mut entry) => { debug!(" - composing on top of {:?}", entry.get()); - match (&entry.get()[..], &adj[..]) { - // Applying any adjustment on top of a NeverToAny - // is a valid NeverToAny adjustment, because it can't - // be reached. - (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return, + match (&mut entry.get_mut()[..], &adj[..]) { ( - &[ + [Adjustment { kind: Adjust::NeverToAny, target }], + &[.., Adjustment { target: new_target, .. }], + ) => { + // NeverToAny coercion can target any type, so instead of adding a new + // adjustment on top we can change the target. + // + // This is required for things like `a == a` (where `a: !`) to produce + // valid MIR -- we need borrow adjustment from things like `==` to change + // the type to `&!` (or `&()` depending on the fallback). This might be + // relevant even in unreachable code. + *target = new_target; + } + + ( + &mut [ Adjustment { kind: Adjust::Deref(_), .. }, Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. }, ], @@ -294,11 +304,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .., // Any following adjustments are allowed. ], ) => { - // A reborrow has no effect before a dereference. + // A reborrow has no effect before a dereference, so we can safely replace adjustments. + *entry.get_mut() = adj; } - // FIXME: currently we never try to compose autoderefs - // and ReifyFnPointer/UnsafeFnPointer, but we could. + _ => { + // FIXME: currently we never try to compose autoderefs + // and ReifyFnPointer/UnsafeFnPointer, but we could. self.dcx().span_delayed_bug( expr.span, format!( @@ -308,9 +320,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { adj ), ); + + *entry.get_mut() = adj; } } - *entry.get_mut() = adj; } } diff --git a/tests/mir-opt/building/eq_never_type._f.built.after.mir b/tests/mir-opt/building/eq_never_type._f.built.after.mir index 29e93a29aab4b..39438258c2ebb 100644 --- a/tests/mir-opt/building/eq_never_type._f.built.after.mir +++ b/tests/mir-opt/building/eq_never_type._f.built.after.mir @@ -6,7 +6,7 @@ fn _f(_1: !, _2: !) -> () { let mut _0: (); let mut _3: !; let _4: bool; - let mut _5: (); + let mut _5: &(); let mut _6: !; let mut _7: &(); let _8: (); diff --git a/tests/ui/never_type/eq-never-types.rs b/tests/ui/never_type/eq-never-types.rs index 00e55c100bdd3..19717fcf4433c 100644 --- a/tests/ui/never_type/eq-never-types.rs +++ b/tests/ui/never_type/eq-never-types.rs @@ -1,16 +1,7 @@ -//@ known-bug: #120600 +//@ check-pass // // issue: rust-lang/rust#120600 -//@ failure-status: 101 -//@ normalize-stderr-test: "DefId\(.*?\]::" -> "DefId(" -//@ normalize-stderr-test: "(?m)note: we would appreciate a bug report.*\n\n" -> "" -//@ normalize-stderr-test: "(?m)note: rustc.*running on.*\n\n" -> "" -//@ normalize-stderr-test: "(?m)note: compiler flags.*\n\n" -> "" -//@ normalize-stderr-test: "(?m)note: delayed at.*$" -> "" -//@ normalize-stderr-test: "(?m)^ *\d+: .*\n" -> "" -//@ normalize-stderr-test: "(?m)^ *at .*\n" -> "" - #![allow(internal_features)] #![feature(never_type, rustc_attrs)] #![rustc_never_type_options(fallback = "never")] diff --git a/tests/ui/never_type/eq-never-types.stderr b/tests/ui/never_type/eq-never-types.stderr deleted file mode 100644 index 61c3f430b9a5d..0000000000000 --- a/tests/ui/never_type/eq-never-types.stderr +++ /dev/null @@ -1,20 +0,0 @@ -note: no errors encountered even though delayed bugs were created - -note: those delayed bugs will now be shown as internal compiler errors - -error: internal compiler error: broken MIR in DefId(ice) (Terminator { source_info: SourceInfo { span: $DIR/eq-never-types.rs:19:5: 19:11 (#0), scope: scope[0] }, kind: _3 = ::eq(move _4, move _5) -> [return: bb1, unwind: bb2] }): bad arg #0 (&'?4 ! <- !): NoSolution - --> $DIR/eq-never-types.rs:19:10 - | -LL | a == a; - | ^ - | - - --> $DIR/eq-never-types.rs:19:10 - | -LL | a == a; - | ^ - -note: using internal features is not supported and expected to cause internal compiler errors when used incorrectly - -query stack during panic: -end of query stack From e5a6d8d0cda44aeaad81da3c283bd2564a127ce2 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 19 Apr 2024 11:34:37 +0000 Subject: [PATCH 9/9] Remove old ICE tests that no longer ICE (yay!) --- tests/crashes/120600-2.rs | 13 ------------- tests/crashes/120600.rs | 11 ----------- 2 files changed, 24 deletions(-) delete mode 100644 tests/crashes/120600-2.rs delete mode 100644 tests/crashes/120600.rs diff --git a/tests/crashes/120600-2.rs b/tests/crashes/120600-2.rs deleted file mode 100644 index aa1785eea84c4..0000000000000 --- a/tests/crashes/120600-2.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: #120600 -#![feature(never_type, never_type_fallback)] - -enum E { Bar(!) } - -fn f(a: &E, b: &E) { - match (a, b) { - (E::Bar(a), E::Bar(b)) => { *a == *b; } - _ => {} - } -} - -pub fn main() {} diff --git a/tests/crashes/120600.rs b/tests/crashes/120600.rs deleted file mode 100644 index 1be51a8da1602..0000000000000 --- a/tests/crashes/120600.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #120600 -#![feature(never_type)] -#![feature(never_type_fallback)] - -#[derive(Ord, Eq, PartialOrd, PartialEq)] -enum E { - Foo, - Bar(!, i32, i32), -} - -fn main() {}