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/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/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" 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/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 + } +} 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() {} 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..39438258c2ebb --- /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() {} 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() { 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.", + }, ], }; 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..19717fcf4433c --- /dev/null +++ b/tests/ui/never_type/eq-never-types.rs @@ -0,0 +1,13 @@ +//@ check-pass +// +// issue: rust-lang/rust#120600 + +#![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/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`.