From 930c39aa8fa73f915894bf6f3330c2880e8a1547 Mon Sep 17 00:00:00 2001 From: b-naber Date: Fri, 28 Apr 2023 07:17:19 +0000 Subject: [PATCH 01/52] dont expect normalization to succeed in elaborate_drops --- compiler/rustc_mir_dataflow/src/elaborate_drops.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 2e68c794356..e2f538e22b7 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -272,10 +272,16 @@ where let field = FieldIdx::new(i); let subpath = self.elaborator.field_subpath(variant_path, field); let tcx = self.tcx(); - assert_eq!(self.elaborator.param_env().reveal(), Reveal::All); - let field_ty = - tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs)); + + let fty = f.ty(tcx, substs); + let field_ty = match tcx + .try_normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs)) + { + Ok(f_ty) => f_ty, + Err(_) => fty, + }; + (tcx.mk_place_field(base_place, field, field_ty), subpath) }) .collect() From 5a0419352ce3b1eec3ea080dcb81d65409763054 Mon Sep 17 00:00:00 2001 From: John Millikin Date: Mon, 1 May 2023 10:51:41 +0900 Subject: [PATCH 02/52] Stabilize feature `cstr_is_empty` --- library/core/src/ffi/c_str.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index bd2b2c36c43..26b88d1e695 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -517,8 +517,6 @@ impl CStr { /// # Examples /// /// ``` - /// #![feature(cstr_is_empty)] - /// /// use std::ffi::CStr; /// # use std::ffi::FromBytesWithNulError; /// @@ -533,7 +531,8 @@ impl CStr { /// # } /// ``` #[inline] - #[unstable(feature = "cstr_is_empty", issue = "102444")] + #[stable(feature = "cstr_is_empty", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "cstr_is_empty", since = "CURRENT_RUSTC_VERSION")] pub const fn is_empty(&self) -> bool { // SAFETY: We know there is at least one byte; for empty strings it // is the NUL terminator. From c836c24994f0113effd0409d8d063b4f4e68f5b6 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 4 May 2023 17:20:49 -0700 Subject: [PATCH 03/52] Remove the ThinLTO CU hack This reverts #46722, commit e0ab5d5feb4eb2d8af11b8dd9446c2b45fada8af. Since #111167, commit 10b69dde3fd15334ea2382d2dc9e9a261de1afaf, we are generating DWARF subprograms in a way that is meant to be more compatible with LLVM's expectations, so hopefully we don't need this workaround rewriting CUs anymore. --- compiler/rustc_codegen_llvm/src/back/lto.rs | 49 ---------------- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 6 -- .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 57 ------------------- 3 files changed, 112 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index d2e01708a37..604f68eb6a4 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -25,7 +25,6 @@ use std::fs::File; use std::io; use std::iter; use std::path::Path; -use std::ptr; use std::slice; use std::sync::Arc; @@ -709,17 +708,6 @@ pub unsafe fn optimize_thin_module( let llmod = module.module_llvm.llmod(); save_temp_bitcode(cgcx, &module, "thin-lto-input"); - // Before we do much else find the "main" `DICompileUnit` that we'll be - // using below. If we find more than one though then rustc has changed - // in a way we're not ready for, so generate an ICE by returning - // an error. - let mut cu1 = ptr::null_mut(); - let mut cu2 = ptr::null_mut(); - llvm::LLVMRustThinLTOGetDICompileUnit(llmod, &mut cu1, &mut cu2); - if !cu2.is_null() { - return Err(write::llvm_err(&diag_handler, LlvmError::MultipleSourceDiCompileUnit)); - } - // Up next comes the per-module local analyses that we do for Thin LTO. // Each of these functions is basically copied from the LLVM // implementation and then tailored to suit this implementation. Ideally @@ -766,43 +754,6 @@ pub unsafe fn optimize_thin_module( save_temp_bitcode(cgcx, &module, "thin-lto-after-import"); } - // Ok now this is a bit unfortunate. This is also something you won't - // find upstream in LLVM's ThinLTO passes! This is a hack for now to - // work around bugs in LLVM. - // - // First discovered in #45511 it was found that as part of ThinLTO - // importing passes LLVM will import `DICompileUnit` metadata - // information across modules. This means that we'll be working with one - // LLVM module that has multiple `DICompileUnit` instances in it (a - // bunch of `llvm.dbg.cu` members). Unfortunately there's a number of - // bugs in LLVM's backend which generates invalid DWARF in a situation - // like this: - // - // https://bugs.llvm.org/show_bug.cgi?id=35212 - // https://bugs.llvm.org/show_bug.cgi?id=35562 - // - // While the first bug there is fixed the second ended up causing #46346 - // which was basically a resurgence of #45511 after LLVM's bug 35212 was - // fixed. - // - // This function below is a huge hack around this problem. The function - // below is defined in `PassWrapper.cpp` and will basically "merge" - // all `DICompileUnit` instances in a module. Basically it'll take all - // the objects, rewrite all pointers of `DISubprogram` to point to the - // first `DICompileUnit`, and then delete all the other units. - // - // This is probably mangling to the debug info slightly (but hopefully - // not too much) but for now at least gets LLVM to emit valid DWARF (or - // so it appears). Hopefully we can remove this once upstream bugs are - // fixed in LLVM. - { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_thin_lto_patch_debuginfo", thin_module.name()); - llvm::LLVMRustThinLTOPatchDICompileUnit(llmod, cu1); - save_temp_bitcode(cgcx, &module, "thin-lto-after-patch"); - } - // Alright now that we've done everything related to the ThinLTO // analysis it's time to run some optimizations! Here we use the same // `run_pass_manager` as the "fat" LTO above except that we tell it to diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 61365e6dc4b..d5be678c1bb 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2480,12 +2480,6 @@ extern "C" { len: usize, out_len: &mut usize, ) -> *const u8; - pub fn LLVMRustThinLTOGetDICompileUnit( - M: &Module, - CU1: &mut *mut c_void, - CU2: &mut *mut c_void, - ); - pub fn LLVMRustThinLTOPatchDICompileUnit(M: &Module, CU: *mut c_void); pub fn LLVMRustLinkerNew(M: &Module) -> &mut Linker<'_>; pub fn LLVMRustLinkerAdd( diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index 5ec3b95225d..fc28f6efa44 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -1460,63 +1460,6 @@ LLVMRustGetBitcodeSliceFromObjectData(const char *data, return BitcodeOrError->getBufferStart(); } -// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See -// the comment in `back/lto.rs` for why this exists. -extern "C" void -LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod, - DICompileUnit **A, - DICompileUnit **B) { - Module *M = unwrap(Mod); - DICompileUnit **Cur = A; - DICompileUnit **Next = B; - for (DICompileUnit *CU : M->debug_compile_units()) { - *Cur = CU; - Cur = Next; - Next = nullptr; - if (Cur == nullptr) - break; - } -} - -// Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See -// the comment in `back/lto.rs` for why this exists. -extern "C" void -LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) { - Module *M = unwrap(Mod); - - // If the original source module didn't have a `DICompileUnit` then try to - // merge all the existing compile units. If there aren't actually any though - // then there's not much for us to do so return. - if (Unit == nullptr) { - for (DICompileUnit *CU : M->debug_compile_units()) { - Unit = CU; - break; - } - if (Unit == nullptr) - return; - } - - // Use LLVM's built-in `DebugInfoFinder` to find a bunch of debuginfo and - // process it recursively. Note that we used to specifically iterate over - // instructions to ensure we feed everything into it, but `processModule` - // started doing this the same way in LLVM 7 (commit d769eb36ab2b8). - DebugInfoFinder Finder; - Finder.processModule(*M); - - // After we've found all our debuginfo, rewrite all subprograms to point to - // the same `DICompileUnit`. - for (auto &F : Finder.subprograms()) { - F->replaceUnit(Unit); - } - - // Erase any other references to other `DICompileUnit` instances, the verifier - // will later ensure that we don't actually have any other stale references to - // worry about. - auto *MD = M->getNamedMetadata("llvm.dbg.cu"); - MD->clearOperands(); - MD->addOperand(Unit); -} - // Computes the LTO cache key for the provided 'ModId' in the given 'Data', // storing the result in 'KeyOut'. // Currently, this cache key is a SHA-1 hash of anything that could affect From 7c1bc0353b8c13edc6e3cb8e0a37e876f06da7b7 Mon Sep 17 00:00:00 2001 From: bohan Date: Wed, 10 May 2023 22:35:01 +0800 Subject: [PATCH 04/52] refactor(resolve): clean up the early error return caused by non-call --- compiler/rustc_resolve/src/late.rs | 4 ---- .../equality-bound.stderr | 5 ++++- .../ui/macros/builtin-prelude-no-accidents.stderr | 15 +++++++++------ tests/ui/parser/dyn-trait-compatibility.stderr | 12 ++++++------ tests/ui/pattern/pattern-error-continue.stderr | 15 +++++++++------ tests/ui/resolve/issue-109250.rs | 3 +++ tests/ui/resolve/issue-109250.stderr | 14 ++++++++++++++ .../ui/resolve/resolve-variant-assoc-item.stderr | 14 ++++++++++++++ tests/ui/type/type-path-err-node-types.stderr | 12 ++++++------ 9 files changed, 65 insertions(+), 29 deletions(-) create mode 100644 tests/ui/resolve/issue-109250.rs create mode 100644 tests/ui/resolve/issue-109250.stderr diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 2a8287d5554..7129a58b71c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3528,10 +3528,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { // // Similar thing, for types, happens in `report_errors` above. let report_errors_for_call = |this: &mut Self, parent_err: Spanned>| { - if !source.is_call() { - return Some(parent_err); - } - // Before we start looking for candidates, we have to get our hands // on the type user is trying to perform invocation on; basically: // we're transforming `HashMap::new` into just `HashMap`. diff --git a/tests/ui/generic-associated-types/equality-bound.stderr b/tests/ui/generic-associated-types/equality-bound.stderr index d78f7a7fbce..b21ff30a27d 100644 --- a/tests/ui/generic-associated-types/equality-bound.stderr +++ b/tests/ui/generic-associated-types/equality-bound.stderr @@ -36,7 +36,10 @@ error[E0433]: failed to resolve: use of undeclared type `I` --> $DIR/equality-bound.rs:9:41 | LL | fn sum3(i: J) -> i32 where I::Item = i32 { - | ^ use of undeclared type `I` + | ^ + | | + | use of undeclared type `I` + | help: a type parameter with a similar name exists: `J` error: aborting due to 4 previous errors diff --git a/tests/ui/macros/builtin-prelude-no-accidents.stderr b/tests/ui/macros/builtin-prelude-no-accidents.stderr index 56af618d484..8cd9a63b808 100644 --- a/tests/ui/macros/builtin-prelude-no-accidents.stderr +++ b/tests/ui/macros/builtin-prelude-no-accidents.stderr @@ -4,18 +4,21 @@ error[E0433]: failed to resolve: use of undeclared crate or module `env` LL | env::current_dir; | ^^^ use of undeclared crate or module `env` +error[E0433]: failed to resolve: use of undeclared crate or module `vec` + --> $DIR/builtin-prelude-no-accidents.rs:7:14 + | +LL | type B = vec::Vec; + | ^^^ + | | + | use of undeclared crate or module `vec` + | help: a struct with a similar name exists (notice the capitalization): `Vec` + error[E0433]: failed to resolve: use of undeclared crate or module `panic` --> $DIR/builtin-prelude-no-accidents.rs:6:14 | LL | type A = panic::PanicInfo; | ^^^^^ use of undeclared crate or module `panic` -error[E0433]: failed to resolve: use of undeclared crate or module `vec` - --> $DIR/builtin-prelude-no-accidents.rs:7:14 - | -LL | type B = vec::Vec; - | ^^^ use of undeclared crate or module `vec` - error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/parser/dyn-trait-compatibility.stderr b/tests/ui/parser/dyn-trait-compatibility.stderr index 653be5b3b71..e34d855a9d4 100644 --- a/tests/ui/parser/dyn-trait-compatibility.stderr +++ b/tests/ui/parser/dyn-trait-compatibility.stderr @@ -1,9 +1,3 @@ -error[E0433]: failed to resolve: use of undeclared crate or module `dyn` - --> $DIR/dyn-trait-compatibility.rs:3:11 - | -LL | type A1 = dyn::dyn; - | ^^^ use of undeclared crate or module `dyn` - error[E0412]: cannot find type `dyn` in this scope --> $DIR/dyn-trait-compatibility.rs:1:11 | @@ -46,6 +40,12 @@ error[E0412]: cannot find type `dyn` in this scope LL | type A3 = dyn<::dyn>; | ^^^ not found in this scope +error[E0433]: failed to resolve: use of undeclared crate or module `dyn` + --> $DIR/dyn-trait-compatibility.rs:3:11 + | +LL | type A1 = dyn::dyn; + | ^^^ use of undeclared crate or module `dyn` + error: aborting due to 8 previous errors Some errors have detailed explanations: E0405, E0412, E0433. diff --git a/tests/ui/pattern/pattern-error-continue.stderr b/tests/ui/pattern/pattern-error-continue.stderr index e1349fb02ea..10fcccb0301 100644 --- a/tests/ui/pattern/pattern-error-continue.stderr +++ b/tests/ui/pattern/pattern-error-continue.stderr @@ -1,9 +1,3 @@ -error[E0433]: failed to resolve: use of undeclared type `E` - --> $DIR/pattern-error-continue.rs:33:9 - | -LL | E::V => {} - | ^ use of undeclared type `E` - error[E0532]: expected tuple struct or tuple variant, found unit variant `A::D` --> $DIR/pattern-error-continue.rs:18:9 | @@ -56,6 +50,15 @@ note: function defined here LL | fn f(_c: char) {} | ^ -------- +error[E0433]: failed to resolve: use of undeclared type `E` + --> $DIR/pattern-error-continue.rs:33:9 + | +LL | E::V => {} + | ^ + | | + | use of undeclared type `E` + | help: an enum with a similar name exists: `A` + error: aborting due to 5 previous errors Some errors have detailed explanations: E0023, E0308, E0433, E0532. diff --git a/tests/ui/resolve/issue-109250.rs b/tests/ui/resolve/issue-109250.rs new file mode 100644 index 00000000000..68e33f693ce --- /dev/null +++ b/tests/ui/resolve/issue-109250.rs @@ -0,0 +1,3 @@ +fn main() { //~ HELP consider importing + HashMap::new; //~ ERROR failed to resolve: use of undeclared type `HashMap` +} diff --git a/tests/ui/resolve/issue-109250.stderr b/tests/ui/resolve/issue-109250.stderr new file mode 100644 index 00000000000..d5b8c08ced7 --- /dev/null +++ b/tests/ui/resolve/issue-109250.stderr @@ -0,0 +1,14 @@ +error[E0433]: failed to resolve: use of undeclared type `HashMap` + --> $DIR/issue-109250.rs:2:5 + | +LL | HashMap::new; + | ^^^^^^^ use of undeclared type `HashMap` + | +help: consider importing this struct + | +LL + use std::collections::HashMap; + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0433`. diff --git a/tests/ui/resolve/resolve-variant-assoc-item.stderr b/tests/ui/resolve/resolve-variant-assoc-item.stderr index 4be1019968b..ed157197d17 100644 --- a/tests/ui/resolve/resolve-variant-assoc-item.stderr +++ b/tests/ui/resolve/resolve-variant-assoc-item.stderr @@ -3,12 +3,26 @@ error[E0433]: failed to resolve: `V` is a variant, not a module | LL | E::V::associated_item; | ^ `V` is a variant, not a module + | +help: there is an enum variant `E::V`; try using the variant's enum + | +LL | E; + | ~ error[E0433]: failed to resolve: `V` is a variant, not a module --> $DIR/resolve-variant-assoc-item.rs:6:5 | LL | V::associated_item; | ^ `V` is a variant, not a module + | +help: there is an enum variant `E::V`; try using the variant's enum + | +LL | E; + | ~ +help: an enum with a similar name exists + | +LL | E::associated_item; + | ~ error: aborting due to 2 previous errors diff --git a/tests/ui/type/type-path-err-node-types.stderr b/tests/ui/type/type-path-err-node-types.stderr index 1aed1dbe4ba..8b12aa1a393 100644 --- a/tests/ui/type/type-path-err-node-types.stderr +++ b/tests/ui/type/type-path-err-node-types.stderr @@ -1,9 +1,3 @@ -error[E0433]: failed to resolve: use of undeclared type `NonExistent` - --> $DIR/type-path-err-node-types.rs:15:5 - | -LL | NonExistent::Assoc::; - | ^^^^^^^^^^^ use of undeclared type `NonExistent` - error[E0412]: cannot find type `Nonexistent` in this scope --> $DIR/type-path-err-node-types.rs:7:12 | @@ -22,6 +16,12 @@ error[E0425]: cannot find value `nonexistent` in this scope LL | nonexistent.nonexistent::(); | ^^^^^^^^^^^ not found in this scope +error[E0433]: failed to resolve: use of undeclared type `NonExistent` + --> $DIR/type-path-err-node-types.rs:15:5 + | +LL | NonExistent::Assoc::; + | ^^^^^^^^^^^ use of undeclared type `NonExistent` + error[E0282]: type annotations needed --> $DIR/type-path-err-node-types.rs:23:14 | From 7871bec7aaad47e8bfaca4fc06c5cb96c466917f Mon Sep 17 00:00:00 2001 From: b-naber Date: Fri, 28 Apr 2023 07:17:29 +0000 Subject: [PATCH 05/52] add test --- tests/ui/drop/issue-110682.rs | 92 +++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 tests/ui/drop/issue-110682.rs diff --git a/tests/ui/drop/issue-110682.rs b/tests/ui/drop/issue-110682.rs new file mode 100644 index 00000000000..35f9c7e8d9b --- /dev/null +++ b/tests/ui/drop/issue-110682.rs @@ -0,0 +1,92 @@ +// build-pass +// compile-flags: -Zmir-opt-level=3 + +use std::fmt::Debug; +use std::mem::ManuallyDrop; +use std::ptr; + +pub trait BitRegister {} + +macro_rules! register { + ($($t:ty),+ $(,)?) => { $( + impl BitRegister for $t { + } + )* }; +} + +register!(u8, u16, u32); + +pub trait BitStore: Sized + Debug { + /// The register type that the implementor describes. + type Mem: BitRegister + Into; +} + +macro_rules! store { + ($($t:ty),+ $(,)?) => { $( + impl BitStore for $t { + type Mem = Self; + } + )+ }; +} + +store!(u8, u16, u32,); + +#[repr(C)] +pub struct BitVec +where + T: BitStore, +{ + /// Region pointer describing the live portion of the owned buffer. + pointer: ptr::NonNull, + /// Allocated capacity, in elements `T`, of the owned buffer. + capacity: usize, +} + +impl BitVec +where + T: BitStore, +{ + pub fn new() -> Self { + let pointer = ptr::NonNull::::new(ptr::null_mut()).unwrap(); + + BitVec { pointer, capacity: 10 } + } + + pub fn clear(&mut self) { + unsafe { + self.set_len(0); + } + } + + #[inline] + pub unsafe fn set_len(&mut self, new_len: usize) {} + + fn with_vec(&mut self, func: F) -> R + where + F: FnOnce(&mut ManuallyDrop>) -> R, + { + let cap = self.capacity; + let elts = 10; + let mut vec = ManuallyDrop::new(unsafe { Vec::from_raw_parts(ptr::null_mut(), elts, cap) }); + let out = func(&mut vec); + + out + } +} + +impl Drop for BitVec +where + T: BitStore, +{ + #[inline] + fn drop(&mut self) { + // The buffer elements do not have destructors. + self.clear(); + // Run the `Vec` destructor to deƤllocate the buffer. + self.with_vec(|vec| unsafe { ManuallyDrop::drop(vec) }); + } +} + +fn main() { + let bitvec = BitVec::::new(); +} From e7a2f52ba163a47e751b6e6d666b52c2acdd0949 Mon Sep 17 00:00:00 2001 From: b-naber Date: Thu, 4 May 2023 21:03:57 +0000 Subject: [PATCH 06/52] don't inline polymorphic adt instances whose fields contain projections in DropGlue. --- .../rustc_mir_dataflow/src/elaborate_drops.rs | 11 +++----- compiler/rustc_mir_transform/src/inline.rs | 27 ++++++++++++++++++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index e2f538e22b7..18895072c3b 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -272,15 +272,10 @@ where let field = FieldIdx::new(i); let subpath = self.elaborator.field_subpath(variant_path, field); let tcx = self.tcx(); - assert_eq!(self.elaborator.param_env().reveal(), Reveal::All); - let fty = f.ty(tcx, substs); - let field_ty = match tcx - .try_normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs)) - { - Ok(f_ty) => f_ty, - Err(_) => fty, - }; + assert_eq!(self.elaborator.param_env().reveal(), Reveal::All); + let field_ty = + tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs)); (tcx.mk_place_field(base_place, field, field_ty), subpath) }) diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 71bdfd5aae1..092bbcea0ca 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -7,6 +7,7 @@ use rustc_index::Idx; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_session::config::OptLevel; use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span}; @@ -168,7 +169,7 @@ impl<'tcx> Inliner<'tcx> { let callee_attrs = self.tcx.codegen_fn_attrs(callsite.callee.def_id()); self.check_codegen_attributes(callsite, callee_attrs)?; self.check_mir_is_available(caller_body, &callsite.callee)?; - let callee_body = self.tcx.instance_mir(callsite.callee.def); + let callee_body = try_instance_mir(self.tcx, callsite.callee.def)?; self.check_mir_body(callsite, callee_body, callee_attrs)?; if !self.tcx.consider_optimizing(|| { @@ -1124,3 +1125,27 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> { } } } + +#[instrument(skip(tcx), level = "debug")] +fn try_instance_mir<'tcx>( + tcx: TyCtxt<'tcx>, + instance: InstanceDef<'tcx>, +) -> Result<&'tcx Body<'tcx>, &'static str> { + match instance { + ty::InstanceDef::DropGlue(_, Some(ty)) => match ty.kind() { + ty::Adt(def, substs) => { + let fields = def.all_fields(); + for field in fields { + let field_ty = field.ty(tcx, substs); + if field_ty.has_param() && field_ty.has_projections() { + return Err("cannot build drop shim for polymorphic type"); + } + } + + Ok(tcx.instance_mir(instance)) + } + _ => Ok(tcx.instance_mir(instance)), + }, + _ => Ok(tcx.instance_mir(instance)), + } +} From 9dffb52738e0b2ccd15af36d4607a709b21e020c Mon Sep 17 00:00:00 2001 From: David Koloski Date: Thu, 11 May 2023 12:25:56 -0400 Subject: [PATCH 07/52] Get current target config from` --print=cfg` Compiletest was switched to querying all targets using `--print=all-target-specs-json` and `--print=target-spec-json` in #108905. This unintentionally prevented codegen flags like `-Cpanic` from being reflected in the current target configuration. This change gets the current compiletest target config using `--print=cfg` like it was previously while still using the faster prints for getting information on all other targets. Fixes #110850. --- src/tools/compiletest/src/common.rs | 89 +++++++++++++++++++++++++++-- 1 file changed, 84 insertions(+), 5 deletions(-) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 9059a145b43..ba68b5ee9d5 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -428,7 +428,6 @@ impl TargetCfgs { )) .unwrap(); - let mut current = None; let mut all_targets = HashSet::new(); let mut all_archs = HashSet::new(); let mut all_oses = HashSet::new(); @@ -449,14 +448,11 @@ impl TargetCfgs { } all_pointer_widths.insert(format!("{}bit", cfg.pointer_width)); - if target == config.target { - current = Some(cfg); - } all_targets.insert(target.into()); } Self { - current: current.expect("current target not found"), + current: Self::get_current_target_config(config), all_targets, all_archs, all_oses, @@ -467,6 +463,89 @@ impl TargetCfgs { all_pointer_widths, } } + + fn get_current_target_config(config: &Config) -> TargetCfg { + let mut arch = None; + let mut os = None; + let mut env = None; + let mut abi = None; + let mut families = Vec::new(); + let mut pointer_width = None; + let mut endian = None; + let mut panic = None; + + for config in + rustc_output(config, &["--print=cfg", "--target", &config.target]).trim().lines() + { + let (name, value) = config + .split_once("=\"") + .map(|(name, value)| { + ( + name, + Some( + value + .strip_suffix("\"") + .expect("key-value pair should be properly quoted"), + ), + ) + }) + .unwrap_or_else(|| (config, None)); + + match name { + "target_arch" => { + arch = Some(value.expect("target_arch should be a key-value pair").to_string()); + } + "target_os" => { + os = Some(value.expect("target_os sould be a key-value pair").to_string()); + } + "target_env" => { + env = Some(value.expect("target_env should be a key-value pair").to_string()); + } + "target_abi" => { + abi = Some(value.expect("target_abi should be a key-value pair").to_string()); + } + "target_family" => { + families + .push(value.expect("target_family should be a key-value pair").to_string()); + } + "target_pointer_width" => { + pointer_width = Some( + value + .expect("target_pointer_width should be a key-value pair") + .parse::() + .expect("target_pointer_width should be a valid u32"), + ); + } + "target_endian" => { + endian = Some(match value.expect("target_endian should be a key-value pair") { + "big" => Endian::Big, + "little" => Endian::Little, + _ => panic!("target_endian should be either 'big' or 'little'"), + }); + } + "panic" => { + panic = Some(match value.expect("panic should be a key-value pair") { + "abort" => PanicStrategy::Abort, + "unwind" => PanicStrategy::Unwind, + _ => panic!("panic should be either 'abort' or 'unwind'"), + }); + } + _ => (), + } + } + + TargetCfg { + arch: arch.expect("target configuration should specify target_arch"), + os: os.expect("target configuration should specify target_os"), + env: env.expect("target configuration should specify target_env"), + abi: abi.expect("target configuration should specify target_abi"), + families, + pointer_width: pointer_width + .expect("target configuration should specify target_pointer_width"), + endian: endian.expect("target configuration should specify target_endian"), + panic: panic.expect("target configuration should specify panic"), + } + } } #[derive(Clone, Debug, serde::Deserialize)] From f77971e221d4726520b18217eb2acb291fb74ce9 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 13 May 2023 13:19:01 +0100 Subject: [PATCH 08/52] Handle error body when in generator layout --- compiler/rustc_hir_analysis/src/check/check.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 7 +++++-- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 6 +++--- compiler/rustc_mir_transform/src/generator.rs | 5 +++-- .../src/traits/error_reporting/suggestions.rs | 3 +-- tests/ui/generator/drop-tracking-error-body.rs | 18 ++++++++++++++++++ .../generator/drop-tracking-error-body.stderr | 17 +++++++++++++++++ 8 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 tests/ui/generator/drop-tracking-error-body.rs create mode 100644 tests/ui/generator/drop-tracking-error-body.stderr diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 78ffe59679a..d3495d3dbd7 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -1514,8 +1514,8 @@ fn opaque_type_cycle_error( } if tcx.sess.opts.unstable_opts.drop_tracking_mir && let DefKind::Generator = tcx.def_kind(closure_def_id) + && let Some(generator_layout) = tcx.mir_generator_witnesses(closure_def_id) { - let generator_layout = tcx.mir_generator_witnesses(closure_def_id); for interior_ty in &generator_layout.field_tys { label_match(interior_ty.ty, interior_ty.source_info.span); } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 36be07f6205..0d7f9b75b22 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1516,8 +1516,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if encode_opt { record!(self.tables.optimized_mir[def_id.to_def_id()] <- tcx.optimized_mir(def_id)); - if tcx.sess.opts.unstable_opts.drop_tracking_mir && let DefKind::Generator = self.tcx.def_kind(def_id) { - record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- tcx.mir_generator_witnesses(def_id)); + if tcx.sess.opts.unstable_opts.drop_tracking_mir + && let DefKind::Generator = self.tcx.def_kind(def_id) + && let Some(witnesses) = tcx.mir_generator_witnesses(def_id) + { + record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- witnesses); } } if encode_const { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 5acdd68e60e..e4689fac8b5 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -446,7 +446,7 @@ rustc_queries! { } } - query mir_generator_witnesses(key: DefId) -> &'tcx mir::GeneratorLayout<'tcx> { + query mir_generator_witnesses(key: DefId) -> &'tcx Option> { arena_cache desc { |tcx| "generator witness types for `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 9bab693156b..22c5d68e9f9 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -667,10 +667,10 @@ impl<'tcx> TyCtxt<'tcx> { self, def_id: DefId, ) -> impl Iterator>> { - let generator_layout = &self.mir_generator_witnesses(def_id); + let generator_layout = self.mir_generator_witnesses(def_id); generator_layout - .field_tys - .iter() + .as_ref() + .map_or_else(|| [].iter(), |l| l.field_tys.iter()) .filter(|decl| !decl.ignore_for_traits) .map(|decl| ty::EarlyBinder(decl.ty)) } diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index c9144729145..891e446942e 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1397,7 +1397,7 @@ fn create_cases<'tcx>( pub(crate) fn mir_generator_witnesses<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, -) -> GeneratorLayout<'tcx> { +) -> Option> { assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir); let (body, _) = tcx.mir_promoted(def_id); @@ -1410,6 +1410,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>( // Get the interior types and substs which typeck computed let movable = match *gen_ty.kind() { ty::Generator(_, _, movability) => movability == hir::Movability::Movable, + ty::Error(_) => return None, _ => span_bug!(body.span, "unexpected generator type {}", gen_ty), }; @@ -1425,7 +1426,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>( check_suspend_tys(tcx, &generator_layout, &body); - generator_layout + Some(generator_layout) } impl<'tcx> MirPass<'tcx> for StateTransform { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 49b309abcda..ea17f23434b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2447,10 +2447,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { && generator_did.is_local() // Try to avoid cycles. && !generator_within_in_progress_typeck + && let Some(generator_info) = self.tcx.mir_generator_witnesses(generator_did) { - let generator_info = &self.tcx.mir_generator_witnesses(generator_did); debug!(?generator_info); - 'find_source: for (variant, source_info) in generator_info.variant_fields.iter().zip(&generator_info.variant_source_info) { diff --git a/tests/ui/generator/drop-tracking-error-body.rs b/tests/ui/generator/drop-tracking-error-body.rs new file mode 100644 index 00000000000..f99d9ab6bf8 --- /dev/null +++ b/tests/ui/generator/drop-tracking-error-body.rs @@ -0,0 +1,18 @@ +// compile-flags: -Zdrop-tracking-mir --edition=2021 + +#![feature(generators)] + +pub async fn async_bad_body() { + match true {} //~ ERROR non-exhaustive patterns: type `bool` is non-empty +} + +pub fn generator_bad_body() { + || { + // 'non-exhaustive pattern' only seems to be reported once, so this annotation doesn't work + // keep the function around so we can make sure it doesn't ICE + match true {}; // ERROR non-exhaustive patterns: type `bool` is non-empty + yield (); + }; +} + +fn main() {} diff --git a/tests/ui/generator/drop-tracking-error-body.stderr b/tests/ui/generator/drop-tracking-error-body.stderr new file mode 100644 index 00000000000..28a6892336f --- /dev/null +++ b/tests/ui/generator/drop-tracking-error-body.stderr @@ -0,0 +1,17 @@ +error[E0004]: non-exhaustive patterns: type `bool` is non-empty + --> $DIR/drop-tracking-error-body.rs:6:11 + | +LL | match true {} + | ^^^^ + | + = note: the matched value is of type `bool` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + | +LL ~ match true { +LL + _ => todo!(), +LL ~ } + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. From f40f23587993a3f1afd1405cbcc56bc4324dd378 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 14 May 2023 11:25:47 +0000 Subject: [PATCH 09/52] Merge return place with other locals in CopyProp. --- compiler/rustc_mir_transform/src/copy_prop.rs | 30 ++-- compiler/rustc_mir_transform/src/ssa.rs | 24 +++- tests/codegen/fewer-names.rs | 4 +- tests/codegen/mem-replace-big-type.rs | 7 +- tests/codegen/var-names.rs | 4 +- ...copy_propagation_arg.arg_src.CopyProp.diff | 12 +- .../inline_into_box_place.main.Inline.diff | 12 +- ...67_inline_as_ref_as_mut.b.Inline.after.mir | 14 +- ...67_inline_as_ref_as_mut.d.Inline.after.mir | 14 +- ...unchecked_shl_unsigned_smaller.Inline.diff | 129 ++++++++++++++++-- ..._shl_unsigned_smaller.PreCodegen.after.mir | 120 ++++++++++++++-- ...s.unchecked_shr_signed_smaller.Inline.diff | 129 ++++++++++++++++-- ...ed_shr_signed_smaller.PreCodegen.after.mir | 120 ++++++++++++++-- ...rap_unchecked.unwrap_unchecked.Inline.diff | 8 +- ...cked.unwrap_unchecked.PreCodegen.after.mir | 8 +- ...eplace.manual_replace.PreCodegen.after.mir | 8 +- ...m_replace.mem_replace.PreCodegen.after.mir | 42 +++--- ...t_unchecked_mut_range.PreCodegen.after.mir | 122 ++++++++--------- ...dex.slice_index_range.PreCodegen.after.mir | 12 +- 19 files changed, 601 insertions(+), 218 deletions(-) diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index c565d6f13b1..319f3a79705 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -162,20 +162,22 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { } fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, loc: Location) { - match stmt.kind { - // When removing storage statements, we need to remove both (#107511). - StatementKind::StorageLive(l) | StatementKind::StorageDead(l) - if self.storage_to_remove.contains(l) => - { - stmt.make_nop() - } - StatementKind::Assign(box (ref place, ref mut rvalue)) - if place.as_local().is_some() => - { - // Do not replace assignments. - self.visit_rvalue(rvalue, loc) - } - _ => self.super_statement(stmt, loc), + // When removing storage statements, we need to remove both (#107511). + if let StatementKind::StorageLive(l) | StatementKind::StorageDead(l) = stmt.kind + && self.storage_to_remove.contains(l) + { + stmt.make_nop(); + return + } + + self.super_statement(stmt, loc); + + // Do not leave tautological assignments around. + if let StatementKind::Assign(box (lhs, ref rhs)) = stmt.kind + && let Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)) | Rvalue::CopyForDeref(rhs) = *rhs + && lhs == rhs + { + stmt.make_nop(); } } } diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index a7b45366662..e5877feb8b2 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -267,11 +267,6 @@ fn compute_copy_classes(ssa: &mut SsaVisitor, body: &Body<'_>) -> IndexVec) -> IndexVec) -> IndexVec u32 { // NO-LABEL: define{{.*}}i32 @sum(i32 noundef %x, i32 noundef %y) // NO-NEXT: start: - // NO-NEXT: %z = add i32 %y, %x - // NO-NEXT: ret i32 %z + // NO-NEXT: %0 = add i32 %y, %x + // NO-NEXT: ret i32 %0 let z = x + y; z } diff --git a/tests/codegen/mem-replace-big-type.rs b/tests/codegen/mem-replace-big-type.rs index acf759ebe54..c6b920cf599 100644 --- a/tests/codegen/mem-replace-big-type.rs +++ b/tests/codegen/mem-replace-big-type.rs @@ -13,8 +13,7 @@ pub struct Big([u64; 7]); pub fn replace_big(dst: &mut Big, src: Big) -> Big { // Back in 1.68, this emitted six `memcpy`s. // `read_via_copy` in 1.69 got that down to three. - // `write_via_move` it was originally down to the essential two, however - // with nrvo disabled it is back at 3 + // `write_via_move` and nvro get this down to the essential two. std::mem::replace(dst, src) } @@ -26,11 +25,9 @@ pub fn replace_big(dst: &mut Big, src: Big) -> Big { // For a large type, we expect exactly three `memcpy`s // CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big) // CHECK-NOT: call void @llvm.memcpy -// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %result, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false) +// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %0, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false) // CHECK-NOT: call void @llvm.memcpy // CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %dest, {{i8\*|ptr}} align 8 %src, i{{.*}} 56, i1 false) // CHECK-NOT: call void @llvm.memcpy -// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %0, {{i8\*|ptr}} align 8 %result, i{{.*}} 56, i1 false) -// CHECK-NOT: call void @llvm.memcpy // CHECK-NOT: call void @llvm.memcpy diff --git a/tests/codegen/var-names.rs b/tests/codegen/var-names.rs index d4715efad73..53841df32e8 100644 --- a/tests/codegen/var-names.rs +++ b/tests/codegen/var-names.rs @@ -9,7 +9,7 @@ pub fn test(a: u32, b: u32) -> u32 { // CHECK: %c = add i32 %a, %b let d = c; let e = d * a; - // CHECK-NEXT: %e = mul i32 %c, %a + // CHECK-NEXT: %0 = mul i32 %c, %a e - // CHECK-NEXT: ret i32 %e + // CHECK-NEXT: ret i32 %0 } diff --git a/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff b/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff index 69acebf7642..1c7b6494d6d 100644 --- a/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff +++ b/tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff @@ -6,15 +6,17 @@ let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:27: +0:30 let _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 scope 1 { - debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 +- debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 ++ debug y => _0; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 } bb0: { - StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 - _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 +- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10 +- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 ++ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14 _1 = const 123_i32; // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12 - _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6 - StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2 +- _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6 +- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2 return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff index 94f24b50ab7..a5129e0e8c8 100644 --- a/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff +++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff @@ -16,8 +16,7 @@ + let mut _4: usize; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _5: usize; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _6: *mut u8; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL -+ let mut _7: std::boxed::Box>; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL -+ let mut _8: *const std::vec::Vec; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ let mut _7: *const std::vec::Vec; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + scope 4 { + } + } @@ -66,12 +65,9 @@ bb3: { - StorageDead(_1); // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2 - return; // scope 0 at $DIR/inline_into_box_place.rs:+2:2: +2:2 -+ StorageLive(_7); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL -+ _7 = ShallowInitBox(move _6, std::vec::Vec); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL -+ _8 = (((_7.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: *const std::vec::Vec); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL -+ (*_8) = move _2; // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL -+ _1 = move _7; // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL -+ StorageDead(_7); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ _1 = ShallowInitBox(move _6, std::vec::Vec); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ _7 = (((_1.0: std::ptr::Unique>).0: std::ptr::NonNull>).0: *const std::vec::Vec); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL ++ (*_7) = move _2; // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + StorageDead(_2); // scope 0 at $DIR/inline_into_box_place.rs:+1:48: +1:49 + _0 = const (); // scope 0 at $DIR/inline_into_box_place.rs:+0:11: +2:2 + drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2 diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir index 8c4ab2557a5..21570a88a6b 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -8,9 +8,8 @@ fn b(_1: &mut Box) -> &mut T { let mut _4: &mut std::boxed::Box; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 scope 1 (inlined as AsMut>::as_mut) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:8:7: 8:15 debug self => _4; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _5: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _6: std::boxed::Box; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _7: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _5: std::boxed::Box; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _6: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL } bb0: { @@ -18,12 +17,9 @@ fn b(_1: &mut Box) -> &mut T { StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 StorageLive(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 _4 = &mut (*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 - StorageLive(_5); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:7: +1:15 - _6 = deref_copy (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _7 = (((_6.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _5 = &mut (*_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _3 = _5; // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageDead(_5); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:7: +1:15 + _5 = deref_copy (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _6 = (((_5.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _3 = &mut (*_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _2 = &mut (*_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 StorageDead(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15 _0 = &mut (*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 diff --git a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir index b18a41b622e..4f9342247d7 100644 --- a/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir +++ b/tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -7,21 +7,17 @@ fn d(_1: &Box) -> &T { let mut _3: &std::boxed::Box; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 scope 1 (inlined as AsRef>::as_ref) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:18:7: 18:15 debug self => _3; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let _4: &T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _5: std::boxed::Box; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - let mut _6: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _4: std::boxed::Box; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _5: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL } bb0: { StorageLive(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 _3 = &(*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 - StorageLive(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _5 = deref_copy (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _6 = (((_5.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _4 = &(*_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _2 = _4; // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - StorageDead(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _4 = deref_copy (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _5 = (((_4.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _2 = &(*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _0 = &(*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15 StorageDead(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15 StorageDead(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2 diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff index 473e02f1cb1..d76cd0e2bb8 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff @@ -12,7 +12,51 @@ + debug rhs => _4; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + let mut _5: u16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _6: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _7: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 2 { ++ scope 3 (inlined core::num::::unchecked_shl::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug x => _7; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _8: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _9: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ scope 4 { ++ scope 5 (inlined >::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _7; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ scope 6 (inlined convert::num:: for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ debug u => _7; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _10: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _11: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _12: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ } ++ scope 7 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _9; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let mut _13: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let _14: u16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 8 { ++ debug x => _14; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ } ++ scope 9 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _8; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _15: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _16: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 10 { ++ debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ scope 11 { ++ scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 14 { ++ scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ } ++ } ++ } ++ scope 12 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _15; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ } ++ } ++ } + } + } @@ -22,30 +66,87 @@ StorageLive(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 _4 = _2; // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 - _0 = core::num::::unchecked_shl(move _3, move _4) -> bb1; // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:23 +- // mir::Constant +- // + span: $DIR/unchecked_shifts.rs:11:7: 11:20 +- // + literal: Const { ty: unsafe fn(u16, u32) -> u16 {core::num::::unchecked_shl}, val: Value() } + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _6 = (_4,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _5 = core::num::::unchecked_shl::conv(move (_6.0: u32)) -> bb1; // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - // mir::Constant -- // + span: $DIR/unchecked_shifts.rs:11:7: 11:20 -- // + literal: Const { ty: unsafe fn(u16, u32) -> u16 {core::num::::unchecked_shl}, val: Value() } -+ // + span: $SRC_DIR/core/src/num/mod.rs:LL:COL -+ // + literal: Const { ty: fn(u32) -> u16 {core::num::::unchecked_shl::conv}, val: Value() } ++ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _7 = move (_6.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _11 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _10 = Gt(_7, move _11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ switchInt(move _10) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { -+ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _0 = unchecked_shl::(_3, move _5) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ // mir::Constant -+ // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL -+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::}, val: Value() } -+ } -+ -+ bb2: { + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 ++ } ++ ++ bb2: { ++ _9 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: TryFromIntError, val: Value() } ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ ++ bb3: { ++ StorageLive(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _12 = _7 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _9 = Result::::Ok(move _12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ ++ bb4: { ++ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _13 = discriminant(_9); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _13) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb5: { ++ _8 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb6: { ++ unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb7: { ++ _14 = move ((_9 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ _8 = Option::::Some(move _14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb8: { ++ StorageDead(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _16 = discriminant(_8); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _16) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ ++ bb9: { ++ _5 = move ((_8 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _0 = unchecked_shl::(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ // mir::Constant ++ // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::}, val: Value() } } } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir index 9b7b11ef659..3c175ed1504 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir @@ -9,7 +9,51 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL let mut _3: u16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL let mut _4: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _5: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL scope 2 { + scope 3 (inlined core::num::::unchecked_shl::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug x => _5; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _6: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _7: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 4 { + scope 5 (inlined >::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _5; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + scope 6 (inlined convert::num:: for u16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL + debug u => _5; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _8: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _9: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _10: u16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + } + scope 7 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _7; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let _12: u16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + scope 8 { + debug x => _12; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + scope 9 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _13: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + scope 10 { + debug val => _3; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 11 { + scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL + scope 14 { + scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } + } + } + scope 12 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + } + } } } @@ -17,22 +61,78 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL _4 = (_2,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _3 = core::num::::unchecked_shl::conv(move (_4.0: u32)) -> bb1; // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/num/mod.rs:LL:COL - // + literal: Const { ty: fn(u32) -> u16 {core::num::::unchecked_shl::conv}, val: Value() } + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _5 = move (_4.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _9 = const 65535_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _8 = Gt(_5, move _9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { + StorageDead(_3); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 + } + + bb2: { + _7 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: TryFromIntError, val: Value() } + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb3: { + StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _10 = _5 as u16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _7 = Result::::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb4: { + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _11 = discriminant(_7); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { + _6 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb6: { + unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb7: { + _12 = move ((_7 as Ok).0: u16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _6 = Option::::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb8: { + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb9: { + _3 = move ((_6 as Some).0: u16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _0 = unchecked_shl::(_1, move _3) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + _0 = unchecked_shl::(_1, move _3) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::}, val: Value() } } - - bb2: { - StorageDead(_3); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL - return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 - } } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff index 9638ddda46b..f3d3e6090bb 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff @@ -12,7 +12,51 @@ + debug rhs => _4; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + let mut _5: i16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _6: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _7: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 2 { ++ scope 3 (inlined core::num::::unchecked_shr::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug x => _7; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _8: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ let mut _9: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ scope 4 { ++ scope 5 (inlined >::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _7; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ scope 6 (inlined convert::num:: for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL ++ debug u => _7; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _10: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _11: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ let mut _12: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ } ++ scope 7 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _9; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let mut _13: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ let _14: i16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 8 { ++ debug x => _14; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ } ++ scope 9 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ debug self => _8; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _15: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _16: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 10 { ++ debug val => _5; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ scope 11 { ++ scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 14 { ++ scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ } ++ } ++ } ++ scope 12 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _15; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ } ++ } ++ } + } + } @@ -22,30 +66,87 @@ StorageLive(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 _4 = _2; // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 - _0 = core::num::::unchecked_shr(move _3, move _4) -> bb1; // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:23 +- // mir::Constant +- // + span: $DIR/unchecked_shifts.rs:17:7: 17:20 +- // + literal: Const { ty: unsafe fn(i16, u32) -> i16 {core::num::::unchecked_shr}, val: Value() } + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _6 = (_4,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _5 = core::num::::unchecked_shr::conv(move (_6.0: u32)) -> bb1; // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - // mir::Constant -- // + span: $DIR/unchecked_shifts.rs:17:7: 17:20 -- // + literal: Const { ty: unsafe fn(i16, u32) -> i16 {core::num::::unchecked_shr}, val: Value() } -+ // + span: $SRC_DIR/core/src/num/mod.rs:LL:COL -+ // + literal: Const { ty: fn(u32) -> i16 {core::num::::unchecked_shr::conv}, val: Value() } ++ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _7 = move (_6.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _11 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _10 = Gt(_7, move _11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_11); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ switchInt(move _10) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { -+ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL -+ _0 = unchecked_shr::(_3, move _5) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ // mir::Constant -+ // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL -+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::}, val: Value() } -+ } -+ -+ bb2: { + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 ++ } ++ ++ bb2: { ++ _9 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ // mir::Constant ++ // + span: no-location ++ // + literal: Const { ty: TryFromIntError, val: Value() } ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ ++ bb3: { ++ StorageLive(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _12 = _7 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ _9 = Result::::Ok(move _12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageDead(_12); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ } ++ ++ bb4: { ++ StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL ++ StorageLive(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _13 = discriminant(_9); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _13) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb5: { ++ _8 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb6: { ++ unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb7: { ++ _14 = move ((_9 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ _8 = Option::::Some(move _14); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb8: { ++ StorageDead(_14); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_9); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageLive(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _16 = discriminant(_8); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _16) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ ++ bb9: { ++ _5 = move ((_8 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_15); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_8); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL ++ _0 = unchecked_shr::(_3, move _5) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ // mir::Constant ++ // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::}, val: Value() } } } diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir index afe6d08741b..724b3c56723 100644 --- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir @@ -9,7 +9,51 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL let mut _3: i16; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL let mut _4: (u32,); // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _5: u32; // in scope 1 at $SRC_DIR/core/src/num/mod.rs:LL:COL scope 2 { + scope 3 (inlined core::num::::unchecked_shr::conv) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug x => _5; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _6: std::option::Option; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + let mut _7: std::result::Result; // in scope 3 at $SRC_DIR/core/src/num/mod.rs:LL:COL + scope 4 { + scope 5 (inlined >::try_into) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _5; // in scope 5 at $SRC_DIR/core/src/convert/mod.rs:LL:COL + scope 6 (inlined convert::num:: for i16>::try_from) { // at $SRC_DIR/core/src/convert/mod.rs:LL:COL + debug u => _5; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _8: bool; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _9: u32; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + let mut _10: i16; // in scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + } + scope 7 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _7; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + let _12: i16; // in scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + scope 8 { + debug x => _12; // in scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + scope 9 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/mod.rs:LL:COL + debug self => _6; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _13: &std::option::Option; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _14: isize; // in scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + scope 10 { + debug val => _3; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 11 { + scope 13 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL + scope 14 { + scope 15 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } + } + } + scope 12 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _13; // in scope 12 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + } + } } } @@ -17,22 +61,78 @@ fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL _4 = (_2,); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _3 = core::num::::unchecked_shr::conv(move (_4.0: u32)) -> bb1; // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - // mir::Constant - // + span: $SRC_DIR/core/src/num/mod.rs:LL:COL - // + literal: Const { ty: fn(u32) -> i16 {core::num::::unchecked_shr::conv}, val: Value() } + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _5 = move (_4.0: u32); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _9 = const 32767_u32; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _8 = Gt(_5, move _9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_9); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + switchInt(move _8) -> [0: bb3, otherwise: bb2]; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL } bb1: { + StorageDead(_3); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 + } + + bb2: { + _7 = Result::::Err(const TryFromIntError(())); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + // mir::Constant + // + span: no-location + // + literal: Const { ty: TryFromIntError, val: Value() } + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb3: { + StorageLive(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _10 = _5 as i16 (IntToInt); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + _7 = Result::::Ok(move _10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageDead(_10); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + goto -> bb4; // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + } + + bb4: { + StorageDead(_8); // scope 6 at $SRC_DIR/core/src/convert/num.rs:LL:COL + StorageLive(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _11 = discriminant(_7); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _11) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { + _6 = Option::::None; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb6: { + unreachable; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb7: { + _12 = move ((_7 as Ok).0: i16); // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + _6 = Option::::Some(move _12); // scope 8 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb8; // scope 7 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb8: { + StorageDead(_12); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_7); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageLive(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + _14 = discriminant(_6); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _14) -> [1: bb9, otherwise: bb6]; // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb9: { + _3 = move ((_6 as Some).0: i16); // scope 9 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_13); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_6); // scope 4 at $SRC_DIR/core/src/num/mod.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/mod.rs:LL:COL - _0 = unchecked_shr::(_1, move _3) -> [return: bb2, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + _0 = unchecked_shr::(_1, move _3) -> [return: bb1, unwind unreachable]; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::}, val: Value() } } - - bb2: { - StorageDead(_3); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL - return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 - } } diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff index 778ecc46d73..8a8cd896e85 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff @@ -9,9 +9,8 @@ + debug self => _2; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _3: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _4: isize; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL -+ let _5: T; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + scope 2 { -+ debug val => _5; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL ++ debug val => _0; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 3 { + scope 5 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL @@ -47,10 +46,7 @@ - bb2 (cleanup): { - resume; // scope 0 at $DIR/unwrap_unchecked.rs:+0:1: +2:2 + bb2: { -+ StorageLive(_5); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL -+ _5 = move ((_2 as Some).0: T); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL -+ _0 = move _5; // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL -+ StorageDead(_5); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ _0 = move ((_2 as Some).0: T); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_3); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 + StorageDead(_2); // scope 0 at $DIR/unwrap_unchecked.rs:+1:26: +1:27 + return; // scope 0 at $DIR/unwrap_unchecked.rs:+2:2: +2:2 diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir index 5cdf4fa46e3..c5e2469fc27 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir @@ -7,9 +7,8 @@ fn unwrap_unchecked(_1: Option) -> T { debug self => _1; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL let mut _2: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL let mut _3: isize; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL - let _4: T; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL scope 2 { - debug val => _4; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + debug val => _0; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL } scope 3 { scope 5 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL @@ -35,10 +34,7 @@ fn unwrap_unchecked(_1: Option) -> T { } bb2: { - StorageLive(_4); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL - _4 = move ((_1 as Some).0: T); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL - _0 = move _4; // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL - StorageDead(_4); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + _0 = move ((_1 as Some).0: T); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL StorageDead(_2); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 return; // scope 0 at $DIR/unwrap_unchecked.rs:+2:2: +2:2 } diff --git a/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir index 4fddd50702c..1d23871029d 100644 --- a/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir @@ -4,17 +4,13 @@ fn manual_replace(_1: &mut u32, _2: u32) -> u32 { debug r => _1; // in scope 0 at $DIR/mem_replace.rs:+0:23: +0:24 debug v => _2; // in scope 0 at $DIR/mem_replace.rs:+0:36: +0:37 let mut _0: u32; // return place in scope 0 at $DIR/mem_replace.rs:+0:47: +0:50 - let _3: u32; // in scope 0 at $DIR/mem_replace.rs:+1:9: +1:13 scope 1 { - debug temp => _3; // in scope 1 at $DIR/mem_replace.rs:+1:9: +1:13 + debug temp => _0; // in scope 1 at $DIR/mem_replace.rs:+1:9: +1:13 } bb0: { - StorageLive(_3); // scope 0 at $DIR/mem_replace.rs:+1:9: +1:13 - _3 = (*_1); // scope 0 at $DIR/mem_replace.rs:+1:16: +1:18 + _0 = (*_1); // scope 0 at $DIR/mem_replace.rs:+1:16: +1:18 (*_1) = _2; // scope 1 at $DIR/mem_replace.rs:+2:5: +2:11 - _0 = _3; // scope 1 at $DIR/mem_replace.rs:+3:5: +3:9 - StorageDead(_3); // scope 0 at $DIR/mem_replace.rs:+4:1: +4:2 return; // scope 0 at $DIR/mem_replace.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir index 619db12c48b..50e0538c133 100644 --- a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir @@ -7,29 +7,28 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 { scope 1 (inlined std::mem::replace::) { // at $DIR/mem_replace.rs:16:5: 16:28 debug dest => _1; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL debug src => _2; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - let mut _4: *const u32; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - let mut _5: *mut u32; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + let mut _3: *const u32; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + let mut _4: *mut u32; // in scope 1 at $SRC_DIR/core/src/mem/mod.rs:LL:COL scope 2 { - let _3: u32; // in scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL scope 3 { - debug result => _3; // in scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + debug result => _0; // in scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL scope 7 (inlined std::ptr::write::) { // at $SRC_DIR/core/src/mem/mod.rs:LL:COL - debug dst => _5; // in scope 7 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + debug dst => _4; // in scope 7 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL debug src => _2; // in scope 7 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - let mut _7: *mut u32; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + let mut _6: *mut u32; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 8 { scope 9 (inlined std::ptr::write::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug dst => _7; // in scope 9 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug dst => _6; // in scope 9 at $SRC_DIR/core/src/intrinsics.rs:LL:COL } } } } scope 4 (inlined std::ptr::read::) { // at $SRC_DIR/core/src/mem/mod.rs:LL:COL - debug src => _4; // in scope 4 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - let mut _6: *const u32; // in scope 4 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug src => _3; // in scope 4 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + let mut _5: *const u32; // in scope 4 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 5 { scope 6 (inlined std::ptr::read::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug src => _6; // in scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug src => _5; // in scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL } } } @@ -38,20 +37,17 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 { bb0: { StorageLive(_3); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - StorageLive(_4); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - _4 = &raw const (*_1); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - StorageLive(_6); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - _3 = (*_4); // scope 5 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - StorageDead(_6); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - StorageDead(_4); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - StorageLive(_5); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - _5 = &raw mut (*_1); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - StorageLive(_7); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - (*_5) = _2; // scope 8 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - StorageDead(_7); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - StorageDead(_5); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL - _0 = move _3; // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + _3 = &raw const (*_1); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + _0 = (*_3); // scope 5 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL StorageDead(_3); // scope 2 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + StorageLive(_4); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + _4 = &raw mut (*_1); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + StorageLive(_6); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + (*_4) = _2; // scope 8 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_6); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL + StorageDead(_4); // scope 3 at $SRC_DIR/core/src/mem/mod.rs:LL:COL return; // scope 0 at $DIR/mem_replace.rs:+2:2: +2:2 } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir index 7d4766ee5cc..7a10b929ebd 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.mir @@ -7,63 +7,62 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> scope 1 (inlined core::slice::::get_unchecked_mut::>) { // at $DIR/slice_index.rs:26:11: 26:35 debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL debug index => _2; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - let mut _3: &mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + let mut _3: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL let mut _4: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - let mut _5: *mut [u32]; // in scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL scope 2 { scope 3 (inlined as SliceIndex<[u32]>>::get_unchecked_mut) { // at $SRC_DIR/core/src/slice/mod.rs:LL:COL debug self => _2; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - debug slice => _5; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let _6: std::ops::Range; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug slice => _4; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let _5: std::ops::Range; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _7: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL let mut _8: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let mut _9: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _9: *mut u32; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL let mut _10: *mut u32; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let mut _11: *mut u32; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let mut _11: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL let mut _12: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let mut _13: usize; // in scope 3 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let mut _14: std::ops::Range; // in scope 3 at $SRC_DIR/core/src/intrinsics.rs:LL:COL - let mut _15: *mut [u32]; // in scope 3 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + let mut _13: std::ops::Range; // in scope 3 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + let mut _14: *mut [u32]; // in scope 3 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 4 { - debug this => _6; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug this => _5; // in scope 4 at $SRC_DIR/core/src/slice/index.rs:LL:COL scope 5 { - let _7: usize; // in scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let _6: usize; // in scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL scope 6 { - debug new_len => _7; // in scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + debug new_len => _6; // in scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL scope 11 (inlined ptr::mut_ptr::::as_mut_ptr) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL - debug self => _5; // in scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _4; // in scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL } scope 12 (inlined ptr::mut_ptr::::add) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL - debug self => _11; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - debug count => _12; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _10; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug count => _11; // in scope 12 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL scope 13 { } } scope 14 (inlined slice_from_raw_parts_mut::) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL - debug data => _10; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - debug len => _13; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + debug data => _9; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + debug len => _12; // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + let mut _16: *mut (); // in scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL scope 15 (inlined ptr::mut_ptr::::cast::<()>) { // at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - debug self => _10; // in scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - let mut _17: *mut (); // in scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _9; // in scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL } scope 16 (inlined std::ptr::from_raw_parts_mut::<[u32]>) { // at $SRC_DIR/core/src/ptr/mod.rs:LL:COL - debug data_address => _17; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - debug metadata => _13; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - let mut _18: std::ptr::metadata::PtrRepr<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - let mut _19: std::ptr::metadata::PtrComponents<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - let mut _20: *const (); // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + debug data_address => _16; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + debug metadata => _12; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + let mut _17: std::ptr::metadata::PtrRepr<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + let mut _18: std::ptr::metadata::PtrComponents<[u32]>; // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + let mut _19: *const (); // in scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL scope 17 { } } } } scope 7 (inlined as SliceIndex<[T]>>::get_unchecked_mut::runtime::) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug this => _14; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL - debug slice => _15; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug this => _13; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + debug slice => _14; // in scope 7 at $SRC_DIR/core/src/intrinsics.rs:LL:COL scope 8 (inlined ptr::mut_ptr::::len) { // at $SRC_DIR/core/src/slice/index.rs:LL:COL - debug self => _15; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - let mut _16: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + debug self => _14; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + let mut _15: *const [u32]; // in scope 8 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL scope 9 (inlined std::ptr::metadata::<[u32]>) { // at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - debug ptr => _16; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + debug ptr => _15; // in scope 9 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL scope 10 { } } @@ -76,61 +75,60 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range) -> } bb0: { + StorageLive(_3); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageLive(_4); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _4 = &raw mut (*_1); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageLive(_5); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - _5 = &raw mut (*_1); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageLive(_6); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_13); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageLive(_14); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageLive(_15); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageLive(_16); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageLive(_6); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL StorageLive(_7); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _7 = (_2.1: usize); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL StorageLive(_8); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _8 = (_2.1: usize); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_9); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _9 = (_2.0: usize); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _7 = unchecked_sub::(move _8, move _9) -> [return: bb1, unwind unreachable]; // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _8 = (_2.0: usize); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _6 = unchecked_sub::(move _7, move _8) -> [return: bb1, unwind unreachable]; // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/slice/index.rs:LL:COL // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(usize, usize) -> usize {unchecked_sub::}, val: Value() } } bb1: { - StorageDead(_9); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL StorageDead(_8); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_7); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_9); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL StorageLive(_10); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _10 = _4 as *mut u32 (PtrToPtr); // scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL StorageLive(_11); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _11 = _5 as *mut u32 (PtrToPtr); // scope 11 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - StorageLive(_12); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _12 = (_2.0: usize); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _10 = Offset(_11, _12); // scope 13 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL - StorageDead(_12); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _11 = (_2.0: usize); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _9 = Offset(_10, _11); // scope 13 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL StorageDead(_11); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_13); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _13 = _7; // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageLive(_17); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _17 = _10 as *mut () (PtrToPtr); // scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + StorageDead(_10); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_12); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _12 = _6; // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_16); // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + _16 = _9 as *mut () (PtrToPtr); // scope 15 at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL + StorageLive(_17); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL StorageLive(_18); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL StorageLive(_19); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - StorageLive(_20); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - _20 = _17 as *const () (Pointer(MutToConstPointer)); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - _19 = ptr::metadata::PtrComponents::<[u32]> { data_address: move _20, metadata: _13 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - StorageDead(_20); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - _18 = ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _19 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _19 = _16 as *const () (Pointer(MutToConstPointer)); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _18 = ptr::metadata::PtrComponents::<[u32]> { data_address: move _19, metadata: _12 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL StorageDead(_19); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - _4 = (_18.1: *mut [u32]); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - StorageDead(_18); // scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL - StorageDead(_17); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageDead(_13); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageDead(_10); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageDead(_7); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageDead(_16); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _17 = ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _18 }; // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_18); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + _3 = (_17.1: *mut [u32]); // scope 17 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_17); // scope 16 at $SRC_DIR/core/src/ptr/metadata.rs:LL:COL + StorageDead(_16); // scope 14 at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + StorageDead(_12); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_9); // scope 6 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_6); // scope 5 at $SRC_DIR/core/src/slice/index.rs:LL:COL StorageDead(_15); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageDead(_14); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageDead(_6); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_13); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL StorageDead(_5); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - _3 = &mut (*_4); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - StorageDead(_4); // scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL - _0 = _3; // scope 0 at $DIR/slice_index.rs:+1:5: +1:35 + StorageDead(_4); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + _0 = &mut (*_3); // scope 2 at $SRC_DIR/core/src/slice/mod.rs:LL:COL + StorageDead(_3); // scope 1 at $SRC_DIR/core/src/slice/mod.rs:LL:COL return; // scope 0 at $DIR/slice_index.rs:+2:2: +2:2 } } diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir index d3b59e265b2..dcf79a4a4e7 100644 --- a/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.mir @@ -4,25 +4,23 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range) -> &[u32] { debug slice => _1; // in scope 0 at $DIR/slice_index.rs:+0:26: +0:31 debug index => _2; // in scope 0 at $DIR/slice_index.rs:+0:41: +0:46 let mut _0: &[u32]; // return place in scope 0 at $DIR/slice_index.rs:+0:65: +0:71 - let _3: &[u32]; // in scope 0 at $DIR/slice_index.rs:+1:6: +1:18 scope 1 (inlined #[track_caller] core::slice::index::> for [u32]>::index) { // at $DIR/slice_index.rs:21:6: 21:18 debug self => _1; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL debug index => _2; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL - let _4: &[u32]; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + let _3: &[u32]; // in scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL } bb0: { - StorageLive(_4); // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _4 = as SliceIndex<[u32]>>::index(move _2, _1) -> bb1; // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageLive(_3); // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + _3 = as SliceIndex<[u32]>>::index(move _2, _1) -> bb1; // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/slice/index.rs:LL:COL // + literal: Const { ty: for<'a> fn(std::ops::Range, &'a [u32]) -> &'a as SliceIndex<[u32]>>::Output { as SliceIndex<[u32]>>::index}, val: Value() } } bb1: { - _3 = _4; // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL - StorageDead(_4); // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL - _0 = _3; // scope 0 at $DIR/slice_index.rs:+1:5: +1:18 + _0 = _3; // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL + StorageDead(_3); // scope 1 at $SRC_DIR/core/src/slice/index.rs:LL:COL return; // scope 0 at $DIR/slice_index.rs:+2:2: +2:2 } } From adfffc7e123a0cca1fefdfc48a7c7860a428c7f4 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 14 May 2023 12:10:24 +0000 Subject: [PATCH 10/52] Simplify implementation. --- compiler/rustc_mir_transform/src/ssa.rs | 38 +++++++++++-------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index e5877feb8b2..2b404efccc7 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -101,14 +101,15 @@ impl SsaLocals { .retain(|&local| matches!(visitor.assignments[local], Set1::One(_))); debug!(?visitor.assignment_order); - let copy_classes = compute_copy_classes(&mut visitor, body); - - SsaLocals { + let mut ssa = SsaLocals { assignments: visitor.assignments, assignment_order: visitor.assignment_order, direct_uses: visitor.direct_uses, - copy_classes, - } + // This is filled by `compute_copy_classes`. + copy_classes: IndexVec::default(), + }; + compute_copy_classes(&mut ssa, body); + ssa } pub fn num_locals(&self) -> usize { @@ -261,27 +262,19 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor { } #[instrument(level = "trace", skip(ssa, body))] -fn compute_copy_classes(ssa: &mut SsaVisitor, body: &Body<'_>) -> IndexVec { +fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) { + let mut direct_uses = std::mem::take(&mut ssa.direct_uses); let mut copies = IndexVec::from_fn_n(|l| l, body.local_decls.len()); - for &local in &ssa.assignment_order { - debug!(?local); - - // This is not SSA: mark that we don't know the value. - debug!(assignments = ?ssa.assignments[local]); - let Set1::One(LocationExtended::Plain(loc)) = ssa.assignments[local] else { continue }; - - // `loc` must point to a direct assignment to `local`. - let Either::Left(stmt) = body.stmt_at(loc) else { bug!() }; - let Some((_target, rvalue)) = stmt.kind.as_assign() else { bug!() }; - assert_eq!(_target.as_local(), Some(local)); - + for (local, rvalue, _) in ssa.assignments(body) { let (Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) | Rvalue::CopyForDeref(place)) = rvalue else { continue }; let Some(rhs) = place.as_local() else { continue }; - let Set1::One(_) = ssa.assignments[rhs] else { continue }; + if !ssa.is_ssa(rhs) { + continue; + } // We visit in `assignment_order`, ie. reverse post-order, so `rhs` has been // visited before `local`, and we just have to copy the representing local. @@ -302,11 +295,11 @@ fn compute_copy_classes(ssa: &mut SsaVisitor, body: &Body<'_>) -> IndexVec) -> IndexVec Date: Sun, 14 May 2023 12:48:32 +0000 Subject: [PATCH 11/52] Revert "Validate resolution for SelfCtor too." This reverts commit 83453408a0ce91b9e3d3ae6e7f117b1fd28b487d. --- compiler/rustc_resolve/src/diagnostics.rs | 2 +- compiler/rustc_resolve/src/ident.rs | 5 +--- tests/ui/self/self-ctor-inner-const.rs | 17 ----------- tests/ui/self/self-ctor-inner-const.stderr | 33 ---------------------- 4 files changed, 2 insertions(+), 55 deletions(-) delete mode 100644 tests/ui/self/self-ctor-inner-const.rs delete mode 100644 tests/ui/self/self-ctor-inner-const.stderr diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 6675b8ed59b..59eda9db97f 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -550,7 +550,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let sm = self.tcx.sess.source_map(); let def_id = match outer_res { - Res::SelfTyParam { .. } | Res::SelfCtor(_) => { + Res::SelfTyParam { .. } => { err.span_label(span, "can't use `Self` here"); return err; } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 755acdd81fe..f065c4ddd2e 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1174,10 +1174,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { return Res::Err; } } - Res::Def(DefKind::TyParam, _) - | Res::SelfTyParam { .. } - | Res::SelfTyAlias { .. } - | Res::SelfCtor(_) => { + Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => { for rib in ribs { let has_generic_params: HasGenericParams = match rib.kind { RibKind::Normal diff --git a/tests/ui/self/self-ctor-inner-const.rs b/tests/ui/self/self-ctor-inner-const.rs deleted file mode 100644 index b015397a5bc..00000000000 --- a/tests/ui/self/self-ctor-inner-const.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Verify that we ban usage of `Self` as constructor from inner items. - -struct S0(T); - -impl S0 { - fn foo() { - const C: S0 = Self(0); - //~^ ERROR can't use generic parameters from outer function - fn bar() -> Self { - //~^ ERROR can't use generic parameters from outer function - Self(0) - //~^ ERROR can't use generic parameters from outer function - } - } -} - -fn main() {} diff --git a/tests/ui/self/self-ctor-inner-const.stderr b/tests/ui/self/self-ctor-inner-const.stderr deleted file mode 100644 index 7287c64c659..00000000000 --- a/tests/ui/self/self-ctor-inner-const.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0401]: can't use generic parameters from outer function - --> $DIR/self-ctor-inner-const.rs:7:27 - | -LL | const C: S0 = Self(0); - | ^^^^ - | | - | use of generic parameter from outer function - | can't use `Self` here - -error[E0401]: can't use generic parameters from outer function - --> $DIR/self-ctor-inner-const.rs:9:21 - | -LL | impl S0 { - | ---- `Self` type implicitly declared here, by this `impl` -... -LL | fn bar() -> Self { - | ^^^^ - | | - | use of generic parameter from outer function - | use a type here instead - -error[E0401]: can't use generic parameters from outer function - --> $DIR/self-ctor-inner-const.rs:11:13 - | -LL | Self(0) - | ^^^^ - | | - | use of generic parameter from outer function - | can't use `Self` here - -error: aborting due to 3 previous errors - -For more information about this error, try `rustc --explain E0401`. From 33ec632381cb0732dd7db3836116e5e273ab908b Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 14 May 2023 12:48:57 +0000 Subject: [PATCH 12/52] Add test. --- tests/ui/self/self-ctor-nongeneric.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 tests/ui/self/self-ctor-nongeneric.rs diff --git a/tests/ui/self/self-ctor-nongeneric.rs b/tests/ui/self/self-ctor-nongeneric.rs new file mode 100644 index 00000000000..0ae7f8da4b4 --- /dev/null +++ b/tests/ui/self/self-ctor-nongeneric.rs @@ -0,0 +1,15 @@ +// `Self` as a constructor is currently allowed when the outer item is not generic. +// check-pass + +struct S0(usize); + +impl S0 { + fn foo() { + const C: S0 = Self(0); + fn bar() -> S0 { + Self(0) + } + } +} + +fn main() {} From 363c202581e505b79bd6627d40f2fc133e9a41d4 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 14 May 2023 11:46:07 -0700 Subject: [PATCH 13/52] Stop turning transmutes into discriminants in mir-opt Partially reverts 109612, as after 109993 these aren't actually equivalent any more, and I'm no longer confident this was ever an improvement in the first place. --- .../rustc_mir_transform/src/instsimplify.rs | 13 -- ...ransmutes.adt_transmutes.InstSimplify.diff | 166 ++++++------------ tests/mir-opt/combine_transmutes.rs | 22 --- 3 files changed, 49 insertions(+), 152 deletions(-) diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 6bff535586a..e4dc617620e 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -5,7 +5,6 @@ use crate::MirPass; use rustc_hir::Mutability; use rustc_middle::mir::*; use rustc_middle::ty::layout::ValidityRequirement; -use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt}; use rustc_span::symbol::Symbol; use rustc_target::abi::FieldIdx; @@ -163,18 +162,6 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { return; } - // Transmuting a fieldless enum to its repr is a discriminant read - if let ty::Adt(adt_def, ..) = operand_ty.kind() - && adt_def.is_enum() - && adt_def.is_payloadfree() - && let Some(place) = operand.place() - && let Some(repr_int) = adt_def.repr().int - && repr_int.to_ty(self.tcx) == *cast_ty - { - *rvalue = Rvalue::Discriminant(place); - return; - } - // Transmuting a transparent struct/union to a field's type is a projection if let ty::Adt(adt_def, substs) = operand_ty.kind() && adt_def.repr().transparent() diff --git a/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff b/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff index c5907e7cf18..15117ea890e 100644 --- a/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff +++ b/tests/mir-opt/combine_transmutes.adt_transmutes.InstSimplify.diff @@ -4,59 +4,29 @@ fn adt_transmutes() -> () { let mut _0: (); // return place in scope 0 at $DIR/combine_transmutes.rs:+0:32: +0:32 let _1: u8; // in scope 0 at $DIR/combine_transmutes.rs:+1:9: +1:11 - let mut _2: EnumNoRepr; // in scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41 - let mut _4: EnumNoRepr; // in scope 0 at $DIR/combine_transmutes.rs:+2:28: +2:41 - let mut _6: EnumReprIsize; // in scope 0 at $DIR/combine_transmutes.rs:+3:31: +3:47 - let mut _8: EnumReprIsize; // in scope 0 at $DIR/combine_transmutes.rs:+4:31: +4:47 - let mut _10: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+5:28: +5:52 - let mut _12: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+6:28: +6:52 - let mut _14: std::option::Option; // in scope 0 at $DIR/combine_transmutes.rs:+7:28: +7:58 - let mut _16: std::num::Wrapping; // in scope 0 at $DIR/combine_transmutes.rs:+8:29: +8:54 - let mut _18: std::num::Wrapping; // in scope 0 at $DIR/combine_transmutes.rs:+9:29: +9:54 - let mut _20: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+10:29: +10:47 - let mut _22: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+11:29: +11:47 - let mut _24: std::mem::MaybeUninit; // in scope 0 at $DIR/combine_transmutes.rs:+12:46: +12:77 + let mut _2: std::option::Option; // in scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:58 + let mut _4: std::num::Wrapping; // in scope 0 at $DIR/combine_transmutes.rs:+2:29: +2:54 + let mut _6: std::num::Wrapping; // in scope 0 at $DIR/combine_transmutes.rs:+3:29: +3:54 + let mut _8: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+4:29: +4:47 + let mut _10: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+5:29: +5:47 + let mut _12: std::mem::MaybeUninit; // in scope 0 at $DIR/combine_transmutes.rs:+6:46: +6:77 scope 1 { debug _a => _1; // in scope 1 at $DIR/combine_transmutes.rs:+1:9: +1:11 - let _3: i8; // in scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11 + let _3: i16; // in scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11 scope 2 { debug _a => _3; // in scope 2 at $DIR/combine_transmutes.rs:+2:9: +2:11 - let _5: usize; // in scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11 + let _5: u16; // in scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11 scope 3 { debug _a => _5; // in scope 3 at $DIR/combine_transmutes.rs:+3:9: +3:11 - let _7: isize; // in scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11 + let _7: u32; // in scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11 scope 4 { debug _a => _7; // in scope 4 at $DIR/combine_transmutes.rs:+4:9: +4:11 - let _9: u8; // in scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11 + let _9: i32; // in scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11 scope 5 { debug _a => _9; // in scope 5 at $DIR/combine_transmutes.rs:+5:9: +5:11 - let _11: i8; // in scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11 + let _11: std::mem::ManuallyDrop; // in scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11 scope 6 { debug _a => _11; // in scope 6 at $DIR/combine_transmutes.rs:+6:9: +6:11 - let _13: u8; // in scope 6 at $DIR/combine_transmutes.rs:+7:9: +7:11 - scope 7 { - debug _a => _13; // in scope 7 at $DIR/combine_transmutes.rs:+7:9: +7:11 - let _15: i16; // in scope 7 at $DIR/combine_transmutes.rs:+8:9: +8:11 - scope 8 { - debug _a => _15; // in scope 8 at $DIR/combine_transmutes.rs:+8:9: +8:11 - let _17: u16; // in scope 8 at $DIR/combine_transmutes.rs:+9:9: +9:11 - scope 9 { - debug _a => _17; // in scope 9 at $DIR/combine_transmutes.rs:+9:9: +9:11 - let _19: u32; // in scope 9 at $DIR/combine_transmutes.rs:+10:9: +10:11 - scope 10 { - debug _a => _19; // in scope 10 at $DIR/combine_transmutes.rs:+10:9: +10:11 - let _21: i32; // in scope 10 at $DIR/combine_transmutes.rs:+11:9: +11:11 - scope 11 { - debug _a => _21; // in scope 11 at $DIR/combine_transmutes.rs:+11:9: +11:11 - let _23: std::mem::ManuallyDrop; // in scope 11 at $DIR/combine_transmutes.rs:+12:9: +12:11 - scope 12 { - debug _a => _23; // in scope 12 at $DIR/combine_transmutes.rs:+12:9: +12:11 - } - } - } - } - } - } } } } @@ -66,93 +36,55 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/combine_transmutes.rs:+1:9: +1:11 - StorageLive(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41 - _2 = EnumNoRepr::A; // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41 - _1 = move _2 as u8 (Transmute); // scope 0 at $DIR/combine_transmutes.rs:+1:18: +1:42 - StorageDead(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:41: +1:42 + StorageLive(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:58 + _2 = Option::::Some(const _); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:58 + // mir::Constant + // + span: $DIR/combine_transmutes.rs:35:33: 35:57 + // + literal: Const { ty: NonZeroU8, val: Unevaluated(NonZeroU8::MAX, [], None) } + _1 = move _2 as u8 (Transmute); // scope 0 at $DIR/combine_transmutes.rs:+1:18: +1:59 + StorageDead(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:58: +1:59 StorageLive(_3); // scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11 - StorageLive(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:28: +2:41 - _4 = EnumNoRepr::B; // scope 1 at $DIR/combine_transmutes.rs:+2:28: +2:41 - _3 = move _4 as i8 (Transmute); // scope 1 at $DIR/combine_transmutes.rs:+2:18: +2:42 - StorageDead(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:41: +2:42 + StorageLive(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:29: +2:54 + _4 = Wrapping::(const 0_i16); // scope 1 at $DIR/combine_transmutes.rs:+2:29: +2:54 +- _3 = move _4 as i16 (Transmute); // scope 1 at $DIR/combine_transmutes.rs:+2:19: +2:55 ++ _3 = move (_4.0: i16); // scope 1 at $DIR/combine_transmutes.rs:+2:19: +2:55 + StorageDead(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:54: +2:55 StorageLive(_5); // scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11 - StorageLive(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:31: +3:47 - _6 = EnumReprIsize::A; // scope 2 at $DIR/combine_transmutes.rs:+3:31: +3:47 - _5 = move _6 as usize (Transmute); // scope 2 at $DIR/combine_transmutes.rs:+3:21: +3:48 - StorageDead(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:47: +3:48 + StorageLive(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:29: +3:54 + _6 = Wrapping::(const 0_i16); // scope 2 at $DIR/combine_transmutes.rs:+3:29: +3:54 + _5 = move _6 as u16 (Transmute); // scope 2 at $DIR/combine_transmutes.rs:+3:19: +3:55 + StorageDead(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:54: +3:55 StorageLive(_7); // scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11 - StorageLive(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:31: +4:47 - _8 = EnumReprIsize::B; // scope 3 at $DIR/combine_transmutes.rs:+4:31: +4:47 -- _7 = move _8 as isize (Transmute); // scope 3 at $DIR/combine_transmutes.rs:+4:21: +4:48 -+ _7 = discriminant(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:21: +4:48 + StorageLive(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:29: +4:47 + _8 = Union32 { u32: const 0_i32 }; // scope 3 at $DIR/combine_transmutes.rs:+4:29: +4:47 + _7 = move _8 as u32 (Transmute); // scope 3 at $DIR/combine_transmutes.rs:+4:19: +4:48 StorageDead(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:47: +4:48 StorageLive(_9); // scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11 - StorageLive(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:28: +5:52 - _10 = Less; // scope 4 at $DIR/combine_transmutes.rs:+5:28: +5:52 - _9 = move _10 as u8 (Transmute); // scope 4 at $DIR/combine_transmutes.rs:+5:18: +5:53 - StorageDead(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:52: +5:53 + StorageLive(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:29: +5:47 + _10 = Union32 { u32: const 0_u32 }; // scope 4 at $DIR/combine_transmutes.rs:+5:29: +5:47 + _9 = move _10 as i32 (Transmute); // scope 4 at $DIR/combine_transmutes.rs:+5:19: +5:48 + StorageDead(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:47: +5:48 StorageLive(_11); // scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11 - StorageLive(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:28: +6:52 - _12 = Less; // scope 5 at $DIR/combine_transmutes.rs:+6:28: +6:52 -- _11 = move _12 as i8 (Transmute); // scope 5 at $DIR/combine_transmutes.rs:+6:18: +6:53 -+ _11 = discriminant(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:18: +6:53 - StorageDead(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:52: +6:53 - StorageLive(_13); // scope 6 at $DIR/combine_transmutes.rs:+7:9: +7:11 - StorageLive(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58 - _14 = Option::::Some(const _); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58 + StorageLive(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:46: +6:77 + _12 = MaybeUninit::::uninit() -> [return: bb1, unwind unreachable]; // scope 5 at $DIR/combine_transmutes.rs:+6:46: +6:77 // mir::Constant - // + span: $DIR/combine_transmutes.rs:41:33: 41:57 - // + literal: Const { ty: NonZeroU8, val: Unevaluated(NonZeroU8::MAX, [], None) } - _13 = move _14 as u8 (Transmute); // scope 6 at $DIR/combine_transmutes.rs:+7:18: +7:59 - StorageDead(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:58: +7:59 - StorageLive(_15); // scope 7 at $DIR/combine_transmutes.rs:+8:9: +8:11 - StorageLive(_16); // scope 7 at $DIR/combine_transmutes.rs:+8:29: +8:54 - _16 = Wrapping::(const 0_i16); // scope 7 at $DIR/combine_transmutes.rs:+8:29: +8:54 -- _15 = move _16 as i16 (Transmute); // scope 7 at $DIR/combine_transmutes.rs:+8:19: +8:55 -+ _15 = move (_16.0: i16); // scope 7 at $DIR/combine_transmutes.rs:+8:19: +8:55 - StorageDead(_16); // scope 7 at $DIR/combine_transmutes.rs:+8:54: +8:55 - StorageLive(_17); // scope 8 at $DIR/combine_transmutes.rs:+9:9: +9:11 - StorageLive(_18); // scope 8 at $DIR/combine_transmutes.rs:+9:29: +9:54 - _18 = Wrapping::(const 0_i16); // scope 8 at $DIR/combine_transmutes.rs:+9:29: +9:54 - _17 = move _18 as u16 (Transmute); // scope 8 at $DIR/combine_transmutes.rs:+9:19: +9:55 - StorageDead(_18); // scope 8 at $DIR/combine_transmutes.rs:+9:54: +9:55 - StorageLive(_19); // scope 9 at $DIR/combine_transmutes.rs:+10:9: +10:11 - StorageLive(_20); // scope 9 at $DIR/combine_transmutes.rs:+10:29: +10:47 - _20 = Union32 { u32: const 0_i32 }; // scope 9 at $DIR/combine_transmutes.rs:+10:29: +10:47 - _19 = move _20 as u32 (Transmute); // scope 9 at $DIR/combine_transmutes.rs:+10:19: +10:48 - StorageDead(_20); // scope 9 at $DIR/combine_transmutes.rs:+10:47: +10:48 - StorageLive(_21); // scope 10 at $DIR/combine_transmutes.rs:+11:9: +11:11 - StorageLive(_22); // scope 10 at $DIR/combine_transmutes.rs:+11:29: +11:47 - _22 = Union32 { u32: const 0_u32 }; // scope 10 at $DIR/combine_transmutes.rs:+11:29: +11:47 - _21 = move _22 as i32 (Transmute); // scope 10 at $DIR/combine_transmutes.rs:+11:19: +11:48 - StorageDead(_22); // scope 10 at $DIR/combine_transmutes.rs:+11:47: +11:48 - StorageLive(_23); // scope 11 at $DIR/combine_transmutes.rs:+12:9: +12:11 - StorageLive(_24); // scope 11 at $DIR/combine_transmutes.rs:+12:46: +12:77 - _24 = MaybeUninit::::uninit() -> [return: bb1, unwind unreachable]; // scope 11 at $DIR/combine_transmutes.rs:+12:46: +12:77 - // mir::Constant - // + span: $DIR/combine_transmutes.rs:46:46: 46:75 - // + user_ty: UserType(23) + // + span: $DIR/combine_transmutes.rs:40:46: 40:75 + // + user_ty: UserType(11) // + literal: Const { ty: fn() -> MaybeUninit {MaybeUninit::::uninit}, val: Value() } } bb1: { -- _23 = move _24 as std::mem::ManuallyDrop (Transmute); // scope 11 at $DIR/combine_transmutes.rs:+12:36: +12:78 -+ _23 = move (_24.1: std::mem::ManuallyDrop); // scope 11 at $DIR/combine_transmutes.rs:+12:36: +12:78 - StorageDead(_24); // scope 11 at $DIR/combine_transmutes.rs:+12:77: +12:78 - _0 = const (); // scope 0 at $DIR/combine_transmutes.rs:+0:32: +13:2 - StorageDead(_23); // scope 11 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_21); // scope 10 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_19); // scope 9 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_17); // scope 8 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_15); // scope 7 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_13); // scope 6 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_11); // scope 5 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_9); // scope 4 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_7); // scope 3 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_5); // scope 2 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_3); // scope 1 at $DIR/combine_transmutes.rs:+13:1: +13:2 - StorageDead(_1); // scope 0 at $DIR/combine_transmutes.rs:+13:1: +13:2 - return; // scope 0 at $DIR/combine_transmutes.rs:+13:2: +13:2 +- _11 = move _12 as std::mem::ManuallyDrop (Transmute); // scope 5 at $DIR/combine_transmutes.rs:+6:36: +6:78 ++ _11 = move (_12.1: std::mem::ManuallyDrop); // scope 5 at $DIR/combine_transmutes.rs:+6:36: +6:78 + StorageDead(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:77: +6:78 + _0 = const (); // scope 0 at $DIR/combine_transmutes.rs:+0:32: +7:2 + StorageDead(_11); // scope 5 at $DIR/combine_transmutes.rs:+7:1: +7:2 + StorageDead(_9); // scope 4 at $DIR/combine_transmutes.rs:+7:1: +7:2 + StorageDead(_7); // scope 3 at $DIR/combine_transmutes.rs:+7:1: +7:2 + StorageDead(_5); // scope 2 at $DIR/combine_transmutes.rs:+7:1: +7:2 + StorageDead(_3); // scope 1 at $DIR/combine_transmutes.rs:+7:1: +7:2 + StorageDead(_1); // scope 0 at $DIR/combine_transmutes.rs:+7:1: +7:2 + return; // scope 0 at $DIR/combine_transmutes.rs:+7:2: +7:2 } } diff --git a/tests/mir-opt/combine_transmutes.rs b/tests/mir-opt/combine_transmutes.rs index 7088488c1b8..403f9356ce2 100644 --- a/tests/mir-opt/combine_transmutes.rs +++ b/tests/mir-opt/combine_transmutes.rs @@ -32,12 +32,6 @@ pub unsafe fn integer_transmutes() { // EMIT_MIR combine_transmutes.adt_transmutes.InstSimplify.diff pub unsafe fn adt_transmutes() { - let _a: u8 = transmute(EnumNoRepr::A); - let _a: i8 = transmute(EnumNoRepr::B); - let _a: usize = transmute(EnumReprIsize::A); - let _a: isize = transmute(EnumReprIsize::B); - let _a: u8 = transmute(std::cmp::Ordering::Less); - let _a: i8 = transmute(std::cmp::Ordering::Less); let _a: u8 = transmute(Some(std::num::NonZeroU8::MAX)); let _a: i16 = transmute(std::num::Wrapping(0_i16)); let _a: u16 = transmute(std::num::Wrapping(0_i16)); @@ -46,20 +40,4 @@ pub unsafe fn adt_transmutes() { let _a: ManuallyDrop = transmute(MaybeUninit::::uninit()); } -#[inline(always)] -#[custom_mir(dialect = "runtime", phase = "initial")] -const unsafe fn mir_transmute(x: T) -> U { - mir!{ - { - RET = CastTransmute(x); - Return() - } - } -} - -pub enum EnumNoRepr { A, B, C } - -#[repr(isize)] -pub enum EnumReprIsize { A, B, C } - pub union Union32 { u32: u32, i32: i32 } From 882a9684f9bc94afa7c97fdb5724511cd04e16fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 14 May 2023 21:53:05 +0200 Subject: [PATCH 14/52] Specialize query execution for incremental and non-incremental --- compiler/rustc_interface/src/passes.rs | 3 ++ compiler/rustc_query_impl/src/lib.rs | 6 ++- compiler/rustc_query_impl/src/plumbing.rs | 38 +++++++++++++-- .../rustc_query_system/src/query/plumbing.rs | 46 +++++++++++++++---- 4 files changed, 76 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index d3af01474b8..6fd95003072 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -691,6 +691,8 @@ pub fn create_global_ctxt<'tcx>( callback(sess, &mut local_providers, &mut extern_providers); } + let incremental = dep_graph.is_fully_enabled(); + sess.time("setup_global_ctxt", || { gcx_cell.get_or_init(move || { TyCtxt::create_global_ctxt( @@ -705,6 +707,7 @@ pub fn create_global_ctxt<'tcx>( local_providers, extern_providers, query_result_on_disk_cache, + incremental, ), ) }) diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 39ca4659541..5a058bbfd9d 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -34,7 +34,8 @@ use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::SerializedDepNodeIndex; use rustc_query_system::ich::StableHashingContext; use rustc_query_system::query::{ - get_query, HashResult, QueryCache, QueryConfig, QueryInfo, QueryMap, QueryMode, QueryState, + get_query_incr, get_query_non_incr, HashResult, QueryCache, QueryConfig, QueryInfo, QueryMap, + QueryMode, QueryState, }; use rustc_query_system::HandleCycleError; use rustc_query_system::Value; @@ -203,6 +204,7 @@ pub fn query_system<'tcx>( local_providers: Providers, extern_providers: ExternProviders, on_disk_cache: Option>, + incremental: bool, ) -> QuerySystem<'tcx> { QuerySystem { states: Default::default(), @@ -211,7 +213,7 @@ pub fn query_system<'tcx>( dynamic_queries: dynamic_queries(), on_disk_cache, fns: QuerySystemFns { - engine: engine(), + engine: engine(incremental), local_providers, extern_providers, query_structs: make_dep_kind_array!(query_structs).to_vec(), diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 74924e8113e..5acfeb47a12 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -494,7 +494,7 @@ macro_rules! define_queries { ( $($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => { - mod get_query { + mod get_query_incr { use super::*; $( @@ -506,7 +506,7 @@ macro_rules! define_queries { key: query_keys::$name<'tcx>, mode: QueryMode, ) -> Option>> { - get_query( + get_query_incr( queries::$name::config(tcx), QueryCtxt::new(tcx), span, @@ -517,9 +517,37 @@ macro_rules! define_queries { )* } - pub(crate) fn engine() -> QueryEngine { - QueryEngine { - $($name: get_query::$name,)* + mod get_query_non_incr { + use super::*; + + $( + #[inline(always)] + #[tracing::instrument(level = "trace", skip(tcx))] + pub(super) fn $name<'tcx>( + tcx: TyCtxt<'tcx>, + span: Span, + key: query_keys::$name<'tcx>, + __mode: QueryMode, + ) -> Option>> { + Some(get_query_non_incr( + queries::$name::config(tcx), + QueryCtxt::new(tcx), + span, + key, + )) + } + )* + } + + pub(crate) fn engine(incremental: bool) -> QueryEngine { + if incremental { + QueryEngine { + $($name: get_query_incr::$name,)* + } + } else { + QueryEngine { + $($name: get_query_non_incr::$name,)* + } } } diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 4aaedc7a6c1..dbfe62ae6e9 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -312,7 +312,7 @@ where } #[inline(never)] -fn try_execute_query( +fn try_execute_query( query: Q, qcx: Qcx, span: Span, @@ -355,7 +355,7 @@ where // Drop the lock before we start executing the query drop(state_lock); - execute_job(query, qcx, state, key, id, dep_node) + execute_job::<_, _, INCR>(query, qcx, state, key, id, dep_node) } Entry::Occupied(mut entry) => { match entry.get_mut() { @@ -383,7 +383,7 @@ where } #[inline(always)] -fn execute_job( +fn execute_job( query: Q, qcx: Qcx, state: &QueryState, @@ -398,9 +398,19 @@ where // Use `JobOwner` so the query will be poisoned if executing it panics. let job_owner = JobOwner { state, key }; - let (result, dep_node_index) = match qcx.dep_context().dep_graph().data() { - None => execute_job_non_incr(query, qcx, key, id), - Some(data) => execute_job_incr(query, qcx, data, key, dep_node, id), + debug_assert_eq!(qcx.dep_context().dep_graph().is_fully_enabled(), INCR); + + let (result, dep_node_index) = if INCR { + execute_job_incr( + query, + qcx, + qcx.dep_context().dep_graph().data().unwrap(), + key, + dep_node, + id, + ) + } else { + execute_job_non_incr(query, qcx, key, id) }; let cache = query.query_cache(qcx); @@ -784,7 +794,18 @@ pub enum QueryMode { } #[inline(always)] -pub fn get_query( +pub fn get_query_non_incr(query: Q, qcx: Qcx, span: Span, key: Q::Key) -> Q::Value +where + Q: QueryConfig, + Qcx: QueryContext, +{ + debug_assert!(!qcx.dep_context().dep_graph().is_fully_enabled()); + + ensure_sufficient_stack(|| try_execute_query::(query, qcx, span, key, None).0) +} + +#[inline(always)] +pub fn get_query_incr( query: Q, qcx: Qcx, span: Span, @@ -795,6 +816,8 @@ where Q: QueryConfig, Qcx: QueryContext, { + debug_assert!(qcx.dep_context().dep_graph().is_fully_enabled()); + let dep_node = if let QueryMode::Ensure { check_cache } = mode { let (must_run, dep_node) = ensure_must_run(query, qcx, &key, check_cache); if !must_run { @@ -805,8 +828,9 @@ where None }; - let (result, dep_node_index) = - ensure_sufficient_stack(|| try_execute_query(query, qcx, span, key, dep_node)); + let (result, dep_node_index) = ensure_sufficient_stack(|| { + try_execute_query::<_, _, true>(query, qcx, span, key, dep_node) + }); if let Some(dep_node_index) = dep_node_index { qcx.dep_context().dep_graph().read_index(dep_node_index) } @@ -831,5 +855,7 @@ pub fn force_query( debug_assert!(!query.anon()); - ensure_sufficient_stack(|| try_execute_query(query, qcx, DUMMY_SP, key, Some(dep_node))); + ensure_sufficient_stack(|| { + try_execute_query::<_, _, true>(query, qcx, DUMMY_SP, key, Some(dep_node)) + }); } From 980b39237f267a5013bc37688de580435bbbd1f5 Mon Sep 17 00:00:00 2001 From: Kevin Reid Date: Sun, 14 May 2023 16:07:54 -0700 Subject: [PATCH 15/52] Document that `missing_copy_implementations` and `missing_debug_implementations` only apply to public items. --- compiler/rustc_lint/src/builtin.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 9b74d108546..6601a80920b 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -611,7 +611,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { declare_lint! { /// The `missing_copy_implementations` lint detects potentially-forgotten - /// implementations of [`Copy`]. + /// implementations of [`Copy`] for public types. /// /// [`Copy`]: https://doc.rust-lang.org/std/marker/trait.Copy.html /// @@ -729,7 +729,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { declare_lint! { /// The `missing_debug_implementations` lint detects missing - /// implementations of [`fmt::Debug`]. + /// implementations of [`fmt::Debug`] for public types. /// /// [`fmt::Debug`]: https://doc.rust-lang.org/std/fmt/trait.Debug.html /// From bd31d9ee9c772e10fb256ba177b738170862ac9e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 14 May 2023 23:22:27 +0000 Subject: [PATCH 16/52] Erase ReError properly --- compiler/rustc_middle/src/ty/sty.rs | 4 +++- .../erase-error-in-mir-drop-tracking.rs | 23 ++++++++++++++++++ .../erase-error-in-mir-drop-tracking.stderr | 24 +++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs create mode 100644 tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d175cf72d67..e6d51c4ec97 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1708,7 +1708,9 @@ impl<'tcx> Region<'tcx> { ty::ReErased => { flags = flags | TypeFlags::HAS_RE_ERASED; } - ty::ReError(_) => {} + ty::ReError(_) => { + flags = flags | TypeFlags::HAS_FREE_REGIONS; + } } debug!("type_flags({:?}) = {:?}", self, flags); diff --git a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs new file mode 100644 index 00000000000..addbe5d658a --- /dev/null +++ b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs @@ -0,0 +1,23 @@ +// compile-flags: -Zdrop-tracking-mir +// edition:2021 + +use std::future::Future; + +trait Client { + type Connecting<'a>: Future + Send + where + Self: 'a; + + fn connect(&'_ self) -> Self::Connecting<'a>; + //~^ ERROR use of undeclared lifetime name `'a` +} + +fn call_connect(c: &'_ C) -> impl '_ + Future + Send +where + C: Client + Send + Sync, +{ + async move { c.connect().await } + //~^ ERROR `C` does not live long enough +} + +fn main() {} diff --git a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr new file mode 100644 index 00000000000..53abe3dc952 --- /dev/null +++ b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr @@ -0,0 +1,24 @@ +error[E0261]: use of undeclared lifetime name `'a` + --> $DIR/erase-error-in-mir-drop-tracking.rs:11:46 + | +LL | fn connect(&'_ self) -> Self::Connecting<'a>; + | ^^ undeclared lifetime + | +help: consider introducing lifetime `'a` here + | +LL | fn connect<'a>(&'_ self) -> Self::Connecting<'a>; + | ++++ +help: consider introducing lifetime `'a` here + | +LL | trait Client<'a> { + | ++++ + +error: `C` does not live long enough + --> $DIR/erase-error-in-mir-drop-tracking.rs:19:5 + | +LL | async move { c.connect().await } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0261`. From 67f455afe1496a46171099b711bf067d7095395b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Mon, 15 May 2023 00:00:00 +0000 Subject: [PATCH 17/52] Suppress "erroneous constant used" for constants tainted by errors When constant evaluation fails because its MIR is tainted by errors, suppress note indicating that erroneous constant was used, since those errors have to be fixed regardless of the constant being used or not. --- .../rustc_const_eval/src/const_eval/error.rs | 4 +- .../src/const_eval/machine.rs | 2 +- .../src/interpret/eval_context.rs | 8 +- .../rustc_const_eval/src/interpret/operand.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 2 +- .../rustc_middle/src/mir/interpret/error.rs | 46 ++++++++-- .../rustc_middle/src/mir/interpret/mod.rs | 4 +- .../rustc_middle/src/mir/interpret/queries.rs | 4 +- compiler/rustc_middle/src/mir/mod.rs | 2 +- compiler/rustc_middle/src/ty/consts/kind.rs | 4 +- .../src/traits/auto_trait.rs | 2 +- .../src/traits/const_evaluatable.rs | 4 +- .../src/traits/fulfill.rs | 2 +- src/tools/miri/src/diagnostics.rs | 2 +- src/tools/miri/src/lib.rs | 1 - tests/ui/consts/const-eval/format.stderr | 56 ------------ tests/ui/consts/const-integer-bool-ops.rs | 10 --- tests/ui/consts/const-integer-bool-ops.stderr | 90 ++++--------------- .../const-mut-refs/issue-76510.32bit.stderr | 6 -- .../const-mut-refs/issue-76510.64bit.stderr | 6 -- tests/ui/consts/const-mut-refs/issue-76510.rs | 1 - tests/ui/consts/const-tup-index-span.rs | 1 - tests/ui/consts/const-tup-index-span.stderr | 6 -- tests/ui/consts/issue-54954.rs | 2 - tests/ui/consts/issue-54954.stderr | 12 --- tests/ui/consts/issue-56164.stderr | 12 --- tests/ui/consts/issue-66693.stderr | 12 --- tests/ui/enum-discriminant/issue-41394.rs | 1 - tests/ui/enum-discriminant/issue-41394.stderr | 6 -- tests/ui/resolve/issue-50599.rs | 1 - tests/ui/resolve/issue-50599.stderr | 6 -- .../ui/type/type-dependent-def-issue-49241.rs | 1 - .../type-dependent-def-issue-49241.stderr | 6 -- 33 files changed, 76 insertions(+), 248 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index cdef3fb2339..5037c210e7d 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -169,14 +169,14 @@ impl<'tcx> ConstEvalErr<'tcx> { // See . let mut err = struct_error(tcx, &self.error.to_string()); self.decorate(&mut err, decorate); - ErrorHandled::Reported(err.emit()) + ErrorHandled::Reported(err.emit().into()) } _ => { // Report as hard error. let mut err = struct_error(tcx, message); err.span_label(self.span, self.error.to_string()); self.decorate(&mut err, decorate); - ErrorHandled::Reported(err.emit()) + ErrorHandled::Reported(err.emit().into()) } } } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 814b67b46ec..58b5755af07 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -382,7 +382,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, rustc_span::DUMMY_SP, "This is likely a const item that is missing from its impl", ); - throw_inval!(AlreadyReported(guar)); + throw_inval!(AlreadyReported(guar.into())); } else { // `find_mir_or_eval_fn` checks that this is a const fn before even calling us, // so this should be unreachable. diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index b2197a0aabb..2fa63dc8c93 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -7,7 +7,7 @@ use either::{Either, Left, Right}; use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; use rustc_index::IndexVec; use rustc_middle::mir; -use rustc_middle::mir::interpret::{ErrorHandled, InterpError}; +use rustc_middle::mir::interpret::{ErrorHandled, InterpError, ReportedErrorInfo}; use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout, @@ -470,7 +470,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; // do not continue if typeck errors occurred (can only occur in local crate) if let Some(err) = body.tainted_by_errors { - throw_inval!(AlreadyReported(err)); + throw_inval!(AlreadyReported(ReportedErrorInfo::tainted_by_errors(err))); } Ok(body) } @@ -517,7 +517,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(None) => throw_inval!(TooGeneric), // FIXME(eddyb) this could be a bit more specific than `AlreadyReported`. - Err(error_reported) => throw_inval!(AlreadyReported(error_reported)), + Err(error_reported) => throw_inval!(AlreadyReported(error_reported.into())), } } @@ -905,7 +905,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { query(self.tcx.at(span.unwrap_or_else(|| self.cur_span()))).map_err(|err| { match err { ErrorHandled::Reported(err) => { - if let Some(span) = span { + if !err.is_tainted_by_errors() && let Some(span) = span { // To make it easier to figure out where this error comes from, also add a note at the current location. self.tcx.sess.span_note_without_error(span, "erroneous constant used"); } diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index a7f66071fe2..e30af165501 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -595,7 +595,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // FIXME(generic_const_exprs): `ConstKind::Expr` should be able to be evaluated ty::ConstKind::Expr(_) => throw_inval!(TooGeneric), ty::ConstKind::Error(reported) => { - throw_inval!(AlreadyReported(reported)) + throw_inval!(AlreadyReported(reported.into())) } ty::ConstKind::Unevaluated(uv) => { let instance = self.resolve(uv.def, uv.substs)?; diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 9a95a9c8375..d49a69dfba5 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1533,7 +1533,7 @@ impl<'tcx> InferCtxt<'tcx> { if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? { let ct = tcx.expand_abstract_consts(ct.subst(tcx, substs)); if let Err(e) = ct.error_reported() { - return Err(ErrorHandled::Reported(e)); + return Err(ErrorHandled::Reported(e.into())); } else if ct.has_non_region_infer() || ct.has_non_region_param() { return Err(ErrorHandled::TooGeneric); } else { diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index e45284ca506..d65ceef2472 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -15,15 +15,49 @@ use std::{any::Any, backtrace::Backtrace, fmt}; pub enum ErrorHandled { /// Already reported an error for this evaluation, and the compilation is /// *guaranteed* to fail. Warnings/lints *must not* produce `Reported`. - Reported(ErrorGuaranteed), + Reported(ReportedErrorInfo), /// Don't emit an error, the evaluation failed because the MIR was generic /// and the substs didn't fully monomorphize it. TooGeneric, } impl From for ErrorHandled { - fn from(err: ErrorGuaranteed) -> ErrorHandled { - ErrorHandled::Reported(err) + #[inline] + fn from(error: ErrorGuaranteed) -> ErrorHandled { + ErrorHandled::Reported(error.into()) + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)] +pub struct ReportedErrorInfo { + error: ErrorGuaranteed, + is_tainted_by_errors: bool, +} + +impl ReportedErrorInfo { + #[inline] + pub fn tainted_by_errors(error: ErrorGuaranteed) -> ReportedErrorInfo { + ReportedErrorInfo { is_tainted_by_errors: true, error } + } + + /// Returns true if evaluation failed because MIR was tainted by errors. + #[inline] + pub fn is_tainted_by_errors(self) -> bool { + self.is_tainted_by_errors + } +} + +impl From for ReportedErrorInfo { + #[inline] + fn from(error: ErrorGuaranteed) -> ReportedErrorInfo { + ReportedErrorInfo { is_tainted_by_errors: false, error } + } +} + +impl Into for ReportedErrorInfo { + #[inline] + fn into(self) -> ErrorGuaranteed { + self.error } } @@ -89,7 +123,7 @@ fn print_backtrace(backtrace: &Backtrace) { impl From for InterpErrorInfo<'_> { fn from(err: ErrorGuaranteed) -> Self { - InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err)).into() + InterpError::InvalidProgram(InvalidProgramInfo::AlreadyReported(err.into())).into() } } @@ -125,7 +159,7 @@ pub enum InvalidProgramInfo<'tcx> { /// Resolution can fail if we are in a too generic context. TooGeneric, /// Abort in case errors are already reported. - AlreadyReported(ErrorGuaranteed), + AlreadyReported(ReportedErrorInfo), /// An error occurred during layout computation. Layout(layout::LayoutError<'tcx>), /// An error occurred during FnAbi computation: the passed --target lacks FFI support @@ -144,7 +178,7 @@ impl fmt::Display for InvalidProgramInfo<'_> { use InvalidProgramInfo::*; match self { TooGeneric => write!(f, "encountered overly generic constant"), - AlreadyReported(ErrorGuaranteed { .. }) => { + AlreadyReported(_) => { write!( f, "an error has already been reported elsewhere (this should not usually be printed)" diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs index e5a9766c84d..3620385fab1 100644 --- a/compiler/rustc_middle/src/mir/interpret/mod.rs +++ b/compiler/rustc_middle/src/mir/interpret/mod.rs @@ -120,8 +120,8 @@ use crate::ty::{self, Instance, Ty, TyCtxt}; pub use self::error::{ struct_error, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, InterpError, InterpErrorInfo, InterpResult, InvalidProgramInfo, - MachineStopType, ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo, - UninitBytesAccess, UnsupportedOpInfo, + MachineStopType, ReportedErrorInfo, ResourceExhaustionInfo, ScalarSizeMismatch, + UndefinedBehaviorInfo, UninitBytesAccess, UnsupportedOpInfo, }; pub use self::value::{get_slice_bytes, ConstAlloc, ConstValue, Scalar}; diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index ed4ee93e97d..ce11dabc195 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -61,7 +61,7 @@ impl<'tcx> TyCtxt<'tcx> { self.const_eval_global_id(param_env, cid, span) } Ok(None) => Err(ErrorHandled::TooGeneric), - Err(error_reported) => Err(ErrorHandled::Reported(error_reported)), + Err(err) => Err(ErrorHandled::Reported(err.into())), } } @@ -110,7 +110,7 @@ impl<'tcx> TyCtxt<'tcx> { }) } Ok(None) => Err(ErrorHandled::TooGeneric), - Err(error_reported) => Err(ErrorHandled::Reported(error_reported)), + Err(err) => Err(ErrorHandled::Reported(err.into())), } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 2f18b6cc90a..1da94dd7917 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2342,7 +2342,7 @@ impl<'tcx> ConstantKind<'tcx> { match tcx.const_eval_resolve(param_env, uneval, None) { Ok(val) => Self::Val(val, ty), Err(ErrorHandled::TooGeneric) => self, - Err(ErrorHandled::Reported(guar)) => Self::Ty(tcx.const_error(ty, guar)), + Err(ErrorHandled::Reported(guar)) => Self::Ty(tcx.const_error(ty, guar.into())), } } } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 1ac2cd13982..a108f6c8947 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -245,7 +245,7 @@ impl<'tcx> ConstKind<'tcx> { // can leak through `val` into the const we return. Ok(val) => Some(Ok(EvalResult::ValTree(val?))), Err(ErrorHandled::TooGeneric) => None, - Err(ErrorHandled::Reported(e)) => Some(Err(e)), + Err(ErrorHandled::Reported(e)) => Some(Err(e.into())), } } EvalMode::Mir => { @@ -256,7 +256,7 @@ impl<'tcx> ConstKind<'tcx> { // can leak through `val` into the const we return. Ok(val) => Some(Ok(EvalResult::ConstVal(val))), Err(ErrorHandled::TooGeneric) => None, - Err(ErrorHandled::Reported(e)) => Some(Err(e)), + Err(ErrorHandled::Reported(e)) => Some(Err(e.into())), } } } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 6b080a132f3..183c2401fc3 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -801,7 +801,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { span: tcx.def_span(unevaluated.def), unevaluated: unevaluated, }); - Err(ErrorHandled::Reported(reported)) + Err(ErrorHandled::Reported(reported.into())) } Err(err) => Err(err), } diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index 9d99d30d45c..bd1ea43a78e 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -79,7 +79,7 @@ pub fn is_const_evaluatable<'tcx>( "Missing value for constant, but no error reported?", ))) } - Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), + Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e.into())), Ok(_) => Ok(()), } } @@ -147,7 +147,7 @@ pub fn is_const_evaluatable<'tcx>( Err(err) } - Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)), + Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e.into())), Ok(_) => Ok(()), } } diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 43196d1e629..2f85c32b575 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -615,7 +615,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { (Err(ErrorHandled::Reported(reported)), _) | (_, Err(ErrorHandled::Reported(reported))) => ProcessResult::Error( CodeSelectionError(SelectionError::NotConstEvaluatable( - NotConstEvaluatable::Error(reported), + NotConstEvaluatable::Error(reported.into()), )), ), (Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => { diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs index a93f3eb84f2..e3f81a78eea 100644 --- a/src/tools/miri/src/diagnostics.rs +++ b/src/tools/miri/src/diagnostics.rs @@ -289,7 +289,7 @@ pub fn report_error<'tcx, 'mir>( (None, format!("see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information")), ], InvalidProgram( - InvalidProgramInfo::AlreadyReported(rustc_errors::ErrorGuaranteed { .. }) + InvalidProgramInfo::AlreadyReported(_) ) => { // This got already reported. No point in reporting it again. return None; diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index fc938080a0e..893a4dbd4c8 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -47,7 +47,6 @@ extern crate rustc_ast; extern crate rustc_middle; extern crate rustc_const_eval; extern crate rustc_data_structures; -extern crate rustc_errors; extern crate rustc_hir; extern crate rustc_index; extern crate rustc_session; diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr index 70a1abb0a95..434b0744304 100644 --- a/tests/ui/consts/const-eval/format.stderr +++ b/tests/ui/consts/const-eval/format.stderr @@ -43,62 +43,6 @@ LL | println!("{:?}", 0); = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used - --> $DIR/format.rs:2:12 - | -LL | panic!("{:?}", 0); - | ^^^^^^ - -note: erroneous constant used - --> $DIR/format.rs:2:12 - | -LL | panic!("{:?}", 0); - | ^^^^^^ - -note: erroneous constant used - --> $DIR/format.rs:2:20 - | -LL | panic!("{:?}", 0); - | ^ - | - = note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: erroneous constant used - --> $DIR/format.rs:2:20 - | -LL | panic!("{:?}", 0); - | ^ - | - = note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: erroneous constant used - --> $DIR/format.rs:8:14 - | -LL | println!("{:?}", 0); - | ^^^^^^ - -note: erroneous constant used - --> $DIR/format.rs:8:14 - | -LL | println!("{:?}", 0); - | ^^^^^^ - -note: erroneous constant used - --> $DIR/format.rs:8:22 - | -LL | println!("{:?}", 0); - | ^ - | - = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: erroneous constant used - --> $DIR/format.rs:8:22 - | -LL | println!("{:?}", 0); - | ^ - | - = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) - error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-integer-bool-ops.rs b/tests/ui/consts/const-integer-bool-ops.rs index 4110ae3e456..35915a7a606 100644 --- a/tests/ui/consts/const-integer-bool-ops.rs +++ b/tests/ui/consts/const-integer-bool-ops.rs @@ -6,7 +6,6 @@ const X: usize = 42 && 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR: [i32; X] = [99; 34]; -//~^ constant const X1: usize = 42 || 39; //~^ ERROR mismatched types @@ -16,7 +15,6 @@ const X1: usize = 42 || 39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR1: [i32; X1] = [99; 47]; -//~^ constant const X2: usize = -42 || -39; //~^ ERROR mismatched types @@ -26,7 +24,6 @@ const X2: usize = -42 || -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR2: [i32; X2] = [99; 18446744073709551607]; -//~^ constant const X3: usize = -42 && -39; //~^ ERROR mismatched types @@ -36,43 +33,36 @@ const X3: usize = -42 && -39; //~| ERROR mismatched types //~| expected `usize`, found `bool` const ARR3: [i32; X3] = [99; 6]; -//~^ constant const Y: usize = 42.0 == 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR: [i32; Y] = [99; 1]; -//~^ constant const Y1: usize = 42.0 >= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR1: [i32; Y1] = [99; 1]; -//~^ constant const Y2: usize = 42.0 <= 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR2: [i32; Y2] = [99; 1]; -//~^ constant const Y3: usize = 42.0 > 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR3: [i32; Y3] = [99; 0]; -//~^ constant const Y4: usize = 42.0 < 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR4: [i32; Y4] = [99; 0]; -//~^ constant const Y5: usize = 42.0 != 42.0; //~^ ERROR mismatched types //~| expected `usize`, found `bool` const ARRR5: [i32; Y5] = [99; 0]; -//~^ constant fn main() { let _ = ARR; diff --git a/tests/ui/consts/const-integer-bool-ops.stderr b/tests/ui/consts/const-integer-bool-ops.stderr index b5c3b22fdbe..4e503e5a5c0 100644 --- a/tests/ui/consts/const-integer-bool-ops.stderr +++ b/tests/ui/consts/const-integer-bool-ops.stderr @@ -16,156 +16,96 @@ error[E0308]: mismatched types LL | const X: usize = 42 && 39; | ^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:8:18 - | -LL | const ARR: [i32; X] = [99; 34]; - | ^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:19 + --> $DIR/const-integer-bool-ops.rs:10:19 | LL | const X1: usize = 42 || 39; | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:25 + --> $DIR/const-integer-bool-ops.rs:10:25 | LL | const X1: usize = 42 || 39; | ^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:11:19 + --> $DIR/const-integer-bool-ops.rs:10:19 | LL | const X1: usize = 42 || 39; | ^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:18:19 - | -LL | const ARR1: [i32; X1] = [99; 47]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:19 + --> $DIR/const-integer-bool-ops.rs:19:19 | LL | const X2: usize = -42 || -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:26 + --> $DIR/const-integer-bool-ops.rs:19:26 | LL | const X2: usize = -42 || -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:21:19 + --> $DIR/const-integer-bool-ops.rs:19:19 | LL | const X2: usize = -42 || -39; | ^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used +error[E0308]: mismatched types --> $DIR/const-integer-bool-ops.rs:28:19 | -LL | const ARR2: [i32; X2] = [99; 18446744073709551607]; - | ^^ - -error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:19 - | LL | const X3: usize = -42 && -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:26 + --> $DIR/const-integer-bool-ops.rs:28:26 | LL | const X3: usize = -42 && -39; | ^^^ expected `bool`, found integer error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:31:19 + --> $DIR/const-integer-bool-ops.rs:28:19 | LL | const X3: usize = -42 && -39; | ^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:38:19 - | -LL | const ARR3: [i32; X3] = [99; 6]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:41:18 + --> $DIR/const-integer-bool-ops.rs:37:18 | LL | const Y: usize = 42.0 == 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:44:19 - | -LL | const ARRR: [i32; Y] = [99; 1]; - | ^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:47:19 + --> $DIR/const-integer-bool-ops.rs:42:19 | LL | const Y1: usize = 42.0 >= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:50:20 - | -LL | const ARRR1: [i32; Y1] = [99; 1]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:53:19 + --> $DIR/const-integer-bool-ops.rs:47:19 | LL | const Y2: usize = 42.0 <= 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:56:20 - | -LL | const ARRR2: [i32; Y2] = [99; 1]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:59:19 + --> $DIR/const-integer-bool-ops.rs:52:19 | LL | const Y3: usize = 42.0 > 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:62:20 - | -LL | const ARRR3: [i32; Y3] = [99; 0]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:65:19 + --> $DIR/const-integer-bool-ops.rs:57:19 | LL | const Y4: usize = 42.0 < 42.0; | ^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:68:20 - | -LL | const ARRR4: [i32; Y4] = [99; 0]; - | ^^ - error[E0308]: mismatched types - --> $DIR/const-integer-bool-ops.rs:71:19 + --> $DIR/const-integer-bool-ops.rs:62:19 | LL | const Y5: usize = 42.0 != 42.0; | ^^^^^^^^^^^^ expected `usize`, found `bool` -note: erroneous constant used - --> $DIR/const-integer-bool-ops.rs:74:20 - | -LL | const ARRR5: [i32; Y5] = [99; 0]; - | ^^ - error: aborting due to 18 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr b/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr index 109d15a8e4d..61b00be345f 100644 --- a/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr +++ b/tests/ui/consts/const-mut-refs/issue-76510.32bit.stderr @@ -19,12 +19,6 @@ error[E0596]: cannot borrow data in a `&` reference as mutable LL | const S: &'static mut str = &mut " hello "; | ^^^^^^^^^^^^^^ cannot borrow as mutable -note: erroneous constant used - --> $DIR/issue-76510.rs:11:70 - | -LL | let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); - | ^ - error: aborting due to 3 previous errors Some errors have detailed explanations: E0596, E0658, E0764. diff --git a/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr b/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr index 109d15a8e4d..61b00be345f 100644 --- a/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr +++ b/tests/ui/consts/const-mut-refs/issue-76510.64bit.stderr @@ -19,12 +19,6 @@ error[E0596]: cannot borrow data in a `&` reference as mutable LL | const S: &'static mut str = &mut " hello "; | ^^^^^^^^^^^^^^ cannot borrow as mutable -note: erroneous constant used - --> $DIR/issue-76510.rs:11:70 - | -LL | let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); - | ^ - error: aborting due to 3 previous errors Some errors have detailed explanations: E0596, E0658, E0764. diff --git a/tests/ui/consts/const-mut-refs/issue-76510.rs b/tests/ui/consts/const-mut-refs/issue-76510.rs index b853e2737f1..143d2fb6b9a 100644 --- a/tests/ui/consts/const-mut-refs/issue-76510.rs +++ b/tests/ui/consts/const-mut-refs/issue-76510.rs @@ -9,7 +9,6 @@ const S: &'static mut str = &mut " hello "; const fn trigger() -> [(); unsafe { let s = transmute::<(*const u8, usize), &ManuallyDrop>((S.as_ptr(), 3)); - //~^ constant 0 }] { [(); 0] diff --git a/tests/ui/consts/const-tup-index-span.rs b/tests/ui/consts/const-tup-index-span.rs index 18f4f59d378..e77d392e694 100644 --- a/tests/ui/consts/const-tup-index-span.rs +++ b/tests/ui/consts/const-tup-index-span.rs @@ -4,7 +4,6 @@ const TUP: (usize,) = 5usize << 64; //~^ ERROR mismatched types //~| expected `(usize,)`, found `usize` const ARR: [i32; TUP.0] = []; -//~^ constant fn main() { } diff --git a/tests/ui/consts/const-tup-index-span.stderr b/tests/ui/consts/const-tup-index-span.stderr index 65f0520f8a4..d5df0df9525 100644 --- a/tests/ui/consts/const-tup-index-span.stderr +++ b/tests/ui/consts/const-tup-index-span.stderr @@ -11,12 +11,6 @@ help: use a trailing comma to create a tuple with one element LL | const TUP: (usize,) = (5usize << 64,); | + ++ -note: erroneous constant used - --> $DIR/const-tup-index-span.rs:6:18 - | -LL | const ARR: [i32; TUP.0] = []; - | ^^^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/consts/issue-54954.rs b/tests/ui/consts/issue-54954.rs index 520bf508ff3..7bcfa057019 100644 --- a/tests/ui/consts/issue-54954.rs +++ b/tests/ui/consts/issue-54954.rs @@ -9,8 +9,6 @@ trait Tt { } fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - //~^ constant - //~| constant z } diff --git a/tests/ui/consts/issue-54954.stderr b/tests/ui/consts/issue-54954.stderr index 85055828737..b0701bab793 100644 --- a/tests/ui/consts/issue-54954.stderr +++ b/tests/ui/consts/issue-54954.stderr @@ -16,18 +16,6 @@ LL | | core::mem::size_of::() LL | | } | |_____- `Tt::const_val` defined here -note: erroneous constant used - --> $DIR/issue-54954.rs:11:15 - | -LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - | ^^^^^^^ - -note: erroneous constant used - --> $DIR/issue-54954.rs:11:34 - | -LL | fn f(z: [f32; ARR_LEN]) -> [f32; ARR_LEN] { - | ^^^^^^^ - error: aborting due to 2 previous errors Some errors have detailed explanations: E0379, E0790. diff --git a/tests/ui/consts/issue-56164.stderr b/tests/ui/consts/issue-56164.stderr index 003f8474463..e46c649faf0 100644 --- a/tests/ui/consts/issue-56164.stderr +++ b/tests/ui/consts/issue-56164.stderr @@ -28,18 +28,6 @@ error: function pointer calls are not allowed in constant functions LL | input() | ^^^^^^^ -note: erroneous constant used - --> $DIR/issue-56164.rs:1:18 - | -LL | const fn foo() { (||{})() } - | ^^^^^^ - -note: erroneous constant used - --> $DIR/issue-56164.rs:1:18 - | -LL | const fn foo() { (||{})() } - | ^^^^^^ - error: aborting due to 3 previous errors Some errors have detailed explanations: E0015, E0277. diff --git a/tests/ui/consts/issue-66693.stderr b/tests/ui/consts/issue-66693.stderr index e9a3fced61c..f4898fd9732 100644 --- a/tests/ui/consts/issue-66693.stderr +++ b/tests/ui/consts/issue-66693.stderr @@ -22,17 +22,5 @@ LL | panic!(&1); | = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) -note: erroneous constant used - --> $DIR/issue-66693.rs:11:12 - | -LL | panic!(&1); - | ^^ - -note: erroneous constant used - --> $DIR/issue-66693.rs:11:12 - | -LL | panic!(&1); - | ^^ - error: aborting due to 3 previous errors diff --git a/tests/ui/enum-discriminant/issue-41394.rs b/tests/ui/enum-discriminant/issue-41394.rs index 07cad8796e1..06a33081340 100644 --- a/tests/ui/enum-discriminant/issue-41394.rs +++ b/tests/ui/enum-discriminant/issue-41394.rs @@ -5,7 +5,6 @@ enum Foo { enum Bar { A = Foo::A as isize - //~^ const } fn main() {} diff --git a/tests/ui/enum-discriminant/issue-41394.stderr b/tests/ui/enum-discriminant/issue-41394.stderr index 1b5c64628a1..fa95ca9c18a 100644 --- a/tests/ui/enum-discriminant/issue-41394.stderr +++ b/tests/ui/enum-discriminant/issue-41394.stderr @@ -6,12 +6,6 @@ LL | A = "" + 1 | | | &str -note: erroneous constant used - --> $DIR/issue-41394.rs:7:9 - | -LL | A = Foo::A as isize - | ^^^^^^^^^^^^^^^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/resolve/issue-50599.rs b/tests/ui/resolve/issue-50599.rs index 72238a59198..00588735b9a 100644 --- a/tests/ui/resolve/issue-50599.rs +++ b/tests/ui/resolve/issue-50599.rs @@ -2,5 +2,4 @@ fn main() { const N: u32 = 1_000; const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; //~ ERROR cannot find value let mut digits = [0u32; M]; - //~^ constant } diff --git a/tests/ui/resolve/issue-50599.stderr b/tests/ui/resolve/issue-50599.stderr index d7419b64fac..d58b6ca5b5c 100644 --- a/tests/ui/resolve/issue-50599.stderr +++ b/tests/ui/resolve/issue-50599.stderr @@ -16,12 +16,6 @@ LL - const M: usize = (f64::from(N) * std::f64::LOG10_2) as usize; LL + const M: usize = (f64::from(N) * LOG10_2) as usize; | -note: erroneous constant used - --> $DIR/issue-50599.rs:4:29 - | -LL | let mut digits = [0u32; M]; - | ^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/type/type-dependent-def-issue-49241.rs b/tests/ui/type/type-dependent-def-issue-49241.rs index caf5bade5c7..4b6bc6124db 100644 --- a/tests/ui/type/type-dependent-def-issue-49241.rs +++ b/tests/ui/type/type-dependent-def-issue-49241.rs @@ -2,5 +2,4 @@ fn main() { let v = vec![0]; const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant let s: [u32; l] = v.into_iter().collect(); - //~^ constant } diff --git a/tests/ui/type/type-dependent-def-issue-49241.stderr b/tests/ui/type/type-dependent-def-issue-49241.stderr index af16a6e8f84..64c7687f7a8 100644 --- a/tests/ui/type/type-dependent-def-issue-49241.stderr +++ b/tests/ui/type/type-dependent-def-issue-49241.stderr @@ -6,12 +6,6 @@ LL | const l: usize = v.count(); | | | help: consider using `let` instead of `const`: `let l` -note: erroneous constant used - --> $DIR/type-dependent-def-issue-49241.rs:4:18 - | -LL | let s: [u32; l] = v.into_iter().collect(); - | ^ - error: aborting due to previous error For more information about this error, try `rustc --explain E0435`. From a9cb4822be753ef995a481cf77a4c3cbd41c9464 Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Mon, 15 May 2023 14:25:05 +0200 Subject: [PATCH 18/52] Change Vec examples to not assert exact capacity except where it is guaranteed --- library/alloc/src/vec/mod.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 97da6f06b70..82f30a26d41 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -646,14 +646,14 @@ impl Vec { /// /// // The vector contains no items, even though it has capacity for more /// assert_eq!(vec.len(), 0); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// /// // These are all done without reallocating... /// for i in 0..10 { /// vec.push(i); /// } /// assert_eq!(vec.len(), 10); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// /// // ...but this may make the vector reallocate /// vec.push(11); @@ -877,7 +877,7 @@ impl Vec { /// ``` /// let mut vec: Vec = Vec::with_capacity(10); /// vec.push(42); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -1028,7 +1028,7 @@ impl Vec { /// ``` /// let mut vec = Vec::with_capacity(10); /// vec.extend([1, 2, 3]); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// vec.shrink_to_fit(); /// assert!(vec.capacity() >= 3); /// ``` @@ -1055,7 +1055,7 @@ impl Vec { /// ``` /// let mut vec = Vec::with_capacity(10); /// vec.extend([1, 2, 3]); - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// vec.shrink_to(4); /// assert!(vec.capacity() >= 4); /// vec.shrink_to(0); @@ -1090,7 +1090,7 @@ impl Vec { /// let mut vec = Vec::with_capacity(10); /// vec.extend([1, 2, 3]); /// - /// assert_eq!(vec.capacity(), 10); + /// assert!(vec.capacity() >= 10); /// let slice = vec.into_boxed_slice(); /// assert_eq!(slice.into_vec().capacity(), 3); /// ``` From 8d00f762dd330ed44515bf7e95108f4cbf733e66 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 15 Dec 2022 14:39:25 +0000 Subject: [PATCH 19/52] Unnest a variable in prep for the next commit which needs access to the place --- compiler/rustc_mir_build/src/build/matches/test.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 4536ecf17b8..e28a39220e0 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -387,11 +387,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { make_target_blocks: impl FnOnce(&mut Self) -> Vec, source_info: SourceInfo, value: ConstantKind<'tcx>, - place: Place<'tcx>, + mut val: Place<'tcx>, mut ty: Ty<'tcx>, ) { let mut expect = self.literal_operand(source_info.span, value); - let mut val = Operand::Copy(place); // If we're using `b"..."` as a pattern, we need to insert an // unsizing coercion, as the byte string has the type `&[u8; N]`. @@ -421,9 +420,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block, source_info, temp, - Rvalue::Cast(CastKind::Pointer(PointerCast::Unsize), val, ty), + Rvalue::Cast( + CastKind::Pointer(PointerCast::Unsize), + Operand::Copy(val), + ty, + ), ); - val = Operand::Move(temp); + val = temp; } if opt_ref_test_ty.is_some() { let slice = self.temp(ty, source_info.span); @@ -463,7 +466,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { literal: method, })), - args: vec![val, expect], + args: vec![Operand::Copy(val), expect], destination: eq_result, target: Some(eq_block), unwind: UnwindAction::Continue, From ad424e65d8fda3b3f916da15d2bad5f3203714a1 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 15 Dec 2022 15:11:51 +0000 Subject: [PATCH 20/52] Always fall back to PartialEq when a constant in a pattern is not recursively structural-eq --- .../rustc_mir_build/src/build/matches/test.rs | 36 +++++++-- .../src/thir/pattern/const_to_pat.rs | 51 +++++-------- tests/ui/pattern/usefulness/consts-opaque.rs | 18 +++-- .../pattern/usefulness/consts-opaque.stderr | 75 ++++++++++--------- 4 files changed, 104 insertions(+), 76 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index e28a39220e0..dbdb5b4a9a1 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -380,7 +380,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); } - /// Compare two `&T` values using `::eq` + /// Compare two values using `::eq`. + /// If the values are already references, just call it directly, otherwise + /// take a reference to the values first and then call it. fn non_scalar_compare( &mut self, block: BasicBlock, @@ -441,12 +443,36 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } - let ty::Ref(_, deref_ty, _) = *ty.kind() else { - bug!("non_scalar_compare called on non-reference type: {}", ty); - }; + match *ty.kind() { + ty::Ref(_, deref_ty, _) => ty = deref_ty, + _ => { + // non_scalar_compare called on non-reference type + let temp = self.temp(ty, source_info.span); + self.cfg.push_assign(block, source_info, temp, Rvalue::Use(expect)); + let ref_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, ty); + let ref_temp = self.temp(ref_ty, source_info.span); + + self.cfg.push_assign( + block, + source_info, + ref_temp, + Rvalue::Ref(self.tcx.lifetimes.re_erased, BorrowKind::Shared, temp), + ); + expect = Operand::Move(ref_temp); + + let ref_temp = self.temp(ref_ty, source_info.span); + self.cfg.push_assign( + block, + source_info, + ref_temp, + Rvalue::Ref(self.tcx.lifetimes.re_erased, BorrowKind::Shared, val), + ); + val = ref_temp; + } + } let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span)); - let method = trait_method(self.tcx, eq_def_id, sym::eq, [deref_ty, deref_ty]); + let method = trait_method(self.tcx, eq_def_id, sym::eq, [ty, ty]); let bool_ty = self.tcx.types.bool; let eq_result = self.temp(bool_ty, source_info.span); diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index c73f8284ca5..9a55da768cb 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -62,21 +62,13 @@ struct ConstToPat<'tcx> { treat_byte_string_as_slice: bool, } -mod fallback_to_const_ref { - #[derive(Debug)] - /// This error type signals that we encountered a non-struct-eq situation behind a reference. - /// We bubble this up in order to get back to the reference destructuring and make that emit - /// a const pattern instead of a deref pattern. This allows us to simply call `PartialEq::eq` - /// on such patterns (since that function takes a reference) and not have to jump through any - /// hoops to get a reference to the value. - pub(super) struct FallbackToConstRef(()); - - pub(super) fn fallback_to_const_ref(c2p: &super::ConstToPat<'_>) -> FallbackToConstRef { - assert!(c2p.behind_reference.get()); - FallbackToConstRef(()) - } -} -use fallback_to_const_ref::{fallback_to_const_ref, FallbackToConstRef}; +/// This error type signals that we encountered a non-struct-eq situation. +/// We bubble this up in order to get back to the reference destructuring and make that emit +/// a const pattern instead of a deref pattern. This allows us to simply call `PartialEq::eq` +/// on such patterns (since that function takes a reference) and not have to jump through any +/// hoops to get a reference to the value. +#[derive(Debug)] +struct FallbackToConstRef; impl<'tcx> ConstToPat<'tcx> { fn new( @@ -236,13 +228,13 @@ impl<'tcx> ConstToPat<'tcx> { let kind = match cv.ty().kind() { ty::Float(_) => { - tcx.emit_spanned_lint( - lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, - id, - span, - FloatPattern, - ); - PatKind::Constant { value: cv } + tcx.emit_spanned_lint( + lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, + id, + span, + FloatPattern, + ); + return Err(FallbackToConstRef); } ty::Adt(adt_def, _) if adt_def.is_union() => { // Matching on union fields is unsafe, we can't hide it in constants @@ -289,7 +281,7 @@ impl<'tcx> ConstToPat<'tcx> { // Since we are behind a reference, we can just bubble the error up so we get a // constant at reference type, making it easy to let the fallback call // `PartialEq::eq` on it. - return Err(fallback_to_const_ref(self)); + return Err(FallbackToConstRef); } ty::Adt(adt_def, _) if !self.type_marked_structural(cv.ty()) => { debug!( @@ -411,7 +403,7 @@ impl<'tcx> ConstToPat<'tcx> { IndirectStructuralMatch { non_sm_ty: *pointee_ty }, ); } - PatKind::Constant { value: cv } + return Err(FallbackToConstRef); } else { if !self.saw_const_match_error.get() { self.saw_const_match_error.set(true); @@ -439,12 +431,9 @@ impl<'tcx> ConstToPat<'tcx> { // we fall back to a const pattern. If we do not do this, we may end up with // a !structural-match constant that is not of reference type, which makes it // very hard to invoke `PartialEq::eq` on it as a fallback. - let val = match self.recur(tcx.deref_mir_constant(self.param_env.and(cv)), false) { - Ok(subpattern) => PatKind::Deref { subpattern }, - Err(_) => PatKind::Constant { value: cv }, - }; + let subpattern = self.recur(tcx.deref_mir_constant(self.param_env.and(cv)), false)?; self.behind_reference.set(old); - val + PatKind::Deref { subpattern } } } }, @@ -452,7 +441,7 @@ impl<'tcx> ConstToPat<'tcx> { PatKind::Constant { value: cv } } ty::RawPtr(pointee) if pointee.ty.is_sized(tcx, param_env) => { - PatKind::Constant { value: cv } + return Err(FallbackToConstRef); } // FIXME: these can have very surprising behaviour where optimization levels or other // compilation choices change the runtime behaviour of the match. @@ -469,7 +458,7 @@ impl<'tcx> ConstToPat<'tcx> { PointerPattern ); } - PatKind::Constant { value: cv } + return Err(FallbackToConstRef); } _ => { self.saw_const_match_error.set(true); diff --git a/tests/ui/pattern/usefulness/consts-opaque.rs b/tests/ui/pattern/usefulness/consts-opaque.rs index ca4fcd85bb6..c10c6205a08 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.rs +++ b/tests/ui/pattern/usefulness/consts-opaque.rs @@ -20,11 +20,12 @@ const BAR: Bar = Bar; #[derive(PartialEq)] enum Baz { Baz1, - Baz2 + Baz2, } impl Eq for Baz {} const BAZ: Baz = Baz::Baz1; +#[rustfmt::skip] fn main() { match FOO { FOO => {} @@ -124,8 +125,16 @@ fn main() { match WRAPQUUX { Wrap(_) => {} - WRAPQUUX => {} // detected unreachable because we do inspect the `Wrap` layer - //~^ ERROR unreachable pattern + WRAPQUUX => {} + } + + match WRAPQUUX { + Wrap(_) => {} + } + + match WRAPQUUX { + //~^ ERROR: non-exhaustive patterns: `Wrap(_)` not covered + WRAPQUUX => {} } #[derive(PartialEq, Eq)] @@ -138,8 +147,7 @@ fn main() { match WHOKNOWSQUUX { WHOKNOWSQUUX => {} WhoKnows::Yay(_) => {} - WHOKNOWSQUUX => {} // detected unreachable because we do inspect the `WhoKnows` layer - //~^ ERROR unreachable pattern + WHOKNOWSQUUX => {} WhoKnows::Nope => {} } } diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr index 3f0b4a9f26a..e01b06ccc82 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.stderr +++ b/tests/ui/pattern/usefulness/consts-opaque.stderr @@ -1,5 +1,5 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:30:9 + --> $DIR/consts-opaque.rs:31:9 | LL | FOO => {} | ^^^ @@ -8,7 +8,7 @@ LL | FOO => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:37:9 + --> $DIR/consts-opaque.rs:38:9 | LL | FOO_REF => {} | ^^^^^^^ @@ -17,7 +17,7 @@ LL | FOO_REF => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details warning: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:45:9 + --> $DIR/consts-opaque.rs:46:9 | LL | FOO_REF_REF => {} | ^^^^^^^^^^^ @@ -29,7 +29,7 @@ LL | FOO_REF_REF => {} = note: `#[warn(indirect_structural_match)]` on by default error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:53:9 + --> $DIR/consts-opaque.rs:54:9 | LL | BAR => {} // should not be emitting unreachable warning | ^^^ @@ -38,7 +38,7 @@ LL | BAR => {} // should not be emitting unreachable warning = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:61:9 + --> $DIR/consts-opaque.rs:62:9 | LL | BAR => {} | ^^^ @@ -47,7 +47,7 @@ LL | BAR => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:70:9 + --> $DIR/consts-opaque.rs:71:9 | LL | BAR => {} | ^^^ @@ -56,7 +56,7 @@ LL | BAR => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:72:9 + --> $DIR/consts-opaque.rs:73:9 | LL | BAR => {} // should not be emitting unreachable warning | ^^^ @@ -65,7 +65,7 @@ LL | BAR => {} // should not be emitting unreachable warning = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:80:9 + --> $DIR/consts-opaque.rs:81:9 | LL | BAZ => {} | ^^^ @@ -74,7 +74,7 @@ LL | BAZ => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:90:9 + --> $DIR/consts-opaque.rs:91:9 | LL | BAZ => {} | ^^^ @@ -83,7 +83,7 @@ LL | BAZ => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/consts-opaque.rs:97:9 + --> $DIR/consts-opaque.rs:98:9 | LL | BAZ => {} | ^^^ @@ -92,7 +92,7 @@ LL | BAZ => {} = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: unreachable pattern - --> $DIR/consts-opaque.rs:32:9 + --> $DIR/consts-opaque.rs:33:9 | LL | FOO => {} | --- matches any value @@ -107,7 +107,7 @@ LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/consts-opaque.rs:39:9 + --> $DIR/consts-opaque.rs:40:9 | LL | FOO_REF => {} | ------- matches any value @@ -116,7 +116,7 @@ LL | Foo(_) => {} // should not be emitting unreachable warning | ^^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:53:9 + --> $DIR/consts-opaque.rs:54:9 | LL | Bar => {} | --- matches any value @@ -124,7 +124,7 @@ LL | BAR => {} // should not be emitting unreachable warning | ^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:56:9 + --> $DIR/consts-opaque.rs:57:9 | LL | Bar => {} | --- matches any value @@ -133,7 +133,7 @@ LL | _ => {} | ^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:63:9 + --> $DIR/consts-opaque.rs:64:9 | LL | BAR => {} | --- matches any value @@ -142,7 +142,7 @@ LL | Bar => {} // should not be emitting unreachable warning | ^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:65:9 + --> $DIR/consts-opaque.rs:66:9 | LL | BAR => {} | --- matches any value @@ -151,7 +151,7 @@ LL | _ => {} | ^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:72:9 + --> $DIR/consts-opaque.rs:73:9 | LL | BAR => {} | --- matches any value @@ -160,7 +160,7 @@ LL | BAR => {} // should not be emitting unreachable warning | ^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:75:9 + --> $DIR/consts-opaque.rs:76:9 | LL | BAR => {} | --- matches any value @@ -169,7 +169,7 @@ LL | _ => {} // should not be emitting unreachable warning | ^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:82:9 + --> $DIR/consts-opaque.rs:83:9 | LL | BAZ => {} | --- matches any value @@ -178,7 +178,7 @@ LL | Baz::Baz1 => {} // should not be emitting unreachable warning | ^^^^^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:84:9 + --> $DIR/consts-opaque.rs:85:9 | LL | BAZ => {} | --- matches any value @@ -187,7 +187,7 @@ LL | _ => {} | ^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:92:9 + --> $DIR/consts-opaque.rs:93:9 | LL | BAZ => {} | --- matches any value @@ -196,7 +196,7 @@ LL | _ => {} | ^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:99:9 + --> $DIR/consts-opaque.rs:100:9 | LL | BAZ => {} | --- matches any value @@ -205,7 +205,7 @@ LL | Baz::Baz2 => {} // should not be emitting unreachable warning | ^^^^^^^^^ unreachable pattern error: unreachable pattern - --> $DIR/consts-opaque.rs:101:9 + --> $DIR/consts-opaque.rs:102:9 | LL | BAZ => {} | --- matches any value @@ -213,19 +213,24 @@ LL | BAZ => {} LL | _ => {} // should not be emitting unreachable warning | ^ unreachable pattern -error: unreachable pattern - --> $DIR/consts-opaque.rs:127:9 +error[E0004]: non-exhaustive patterns: `Wrap(_)` not covered + --> $DIR/consts-opaque.rs:135:11 | -LL | Wrap(_) => {} - | ------- matches any value -LL | WRAPQUUX => {} // detected unreachable because we do inspect the `Wrap` layer - | ^^^^^^^^ unreachable pattern - -error: unreachable pattern - --> $DIR/consts-opaque.rs:141:9 +LL | match WRAPQUUX { + | ^^^^^^^^ pattern `Wrap(_)` not covered + | +note: `Wrap usize>` defined here + --> $DIR/consts-opaque.rs:117:12 + | +LL | struct Wrap(T); + | ^^^^ + = note: the matched value is of type `Wrap usize>` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ WRAPQUUX => {}, +LL + Wrap(_) => todo!() | -LL | WHOKNOWSQUUX => {} // detected unreachable because we do inspect the `WhoKnows` layer - | ^^^^^^^^^^^^ -error: aborting due to 24 previous errors; 1 warning emitted +error: aborting due to 23 previous errors; 1 warning emitted +For more information about this error, try `rustc --explain E0004`. From 87f9f99f9cdddda1f24fe9aea7dc1326d55b9c08 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 6 Apr 2023 10:02:33 +0000 Subject: [PATCH 21/52] Update some comments --- .../src/thir/pattern/const_to_pat.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 9a55da768cb..b243f1dc8d0 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -385,11 +385,11 @@ impl<'tcx> ConstToPat<'tcx> { self.behind_reference.set(old); val } - // Backwards compatibility hack: support references to non-structural types. - // We'll lower - // this pattern to a `PartialEq::eq` comparison and `PartialEq::eq` takes a - // reference. This makes the rest of the matching logic simpler as it doesn't have - // to figure out how to get a reference again. + // Backwards compatibility hack: support references to non-structural types, + // but hard error if we aren't behind a double reference. We could just use + // the fallback code path below, but that would allow *more* of this fishy + // code to compile, as then it only goes through the future incompat lint + // instead of a hard error. ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => { if self.behind_reference.get() { if !self.saw_const_match_error.get() @@ -427,10 +427,6 @@ impl<'tcx> ConstToPat<'tcx> { PatKind::Wild } else { let old = self.behind_reference.replace(true); - // In case there are structural-match violations somewhere in this subpattern, - // we fall back to a const pattern. If we do not do this, we may end up with - // a !structural-match constant that is not of reference type, which makes it - // very hard to invoke `PartialEq::eq` on it as a fallback. let subpattern = self.recur(tcx.deref_mir_constant(self.param_env.and(cv)), false)?; self.behind_reference.set(old); PatKind::Deref { subpattern } From 9799fb1ddc1ede61d925f17517455a063f254a33 Mon Sep 17 00:00:00 2001 From: klensy Date: Mon, 15 May 2023 19:19:13 +0300 Subject: [PATCH 22/52] fixup version placeholder for cfi_encoding feature --- compiler/rustc_feature/src/active.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index fe8c630666b..57e55752027 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -338,7 +338,7 @@ declare_features! ( /// Allow conditional compilation depending on rust version (active, cfg_version, "1.45.0", Some(64796), None), /// Allows to use the `#[cfi_encoding = ""]` attribute. - (active, cfi_encoding, "1.69.0", Some(89653), None), + (active, cfi_encoding, "CURRENT_RUSTC_VERSION", Some(89653), None), /// Allows `for<...>` on closures and generators. (active, closure_lifetime_binder, "1.64.0", Some(97362), None), /// Allows `#[track_caller]` on closures and generators. From 29a81f5436e8112d91625e722a0e967492c968c0 Mon Sep 17 00:00:00 2001 From: jyn Date: Mon, 15 May 2023 11:48:15 -0500 Subject: [PATCH 23/52] Add clubby789 to the bootstrap review rotation --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 54c8b2060c5..2e83ef202cf 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -532,6 +532,7 @@ bootstrap = [ "@Mark-Simulacrum", "@albertlarsan68", "@ozkanonur", + "@clubby789", ] infra-ci = [ "@Mark-Simulacrum", From a5763ff8d3e67c156ebe8160de1db26a644d4c5d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 10 May 2023 23:00:47 +0000 Subject: [PATCH 24/52] Recover `impl` correctly --- compiler/rustc_parse/src/parser/generics.rs | 5 +++++ tests/ui/parser/impl-on-unsized-typo.rs | 6 ++++++ tests/ui/parser/impl-on-unsized-typo.stderr | 8 ++++++++ 3 files changed, 19 insertions(+) create mode 100644 tests/ui/parser/impl-on-unsized-typo.rs create mode 100644 tests/ui/parser/impl-on-unsized-typo.stderr diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index e6d0f9fbc76..cd779b0b43e 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -453,6 +453,8 @@ impl<'a> Parser<'a> { // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds // `<` (LIFETIME|IDENT) `=` - generic parameter with a default // `<` const - generic const parameter + // `<` IDENT `?` - RECOVERY for `impl` recovery for types. // The only truly ambiguous case is // `<` IDENT `>` `::` IDENT ... // we disambiguate it in favor of generics (`impl ::absolute::Path { ... }`) @@ -463,6 +465,9 @@ impl<'a> Parser<'a> { || self.look_ahead(start + 1, |t| t.is_lifetime() || t.is_ident()) && self.look_ahead(start + 2, |t| { matches!(t.kind, token::Gt | token::Comma | token::Colon | token::Eq) + // Recovery-only branch -- this could be removed, + // since it only affects diagnostics currently. + || matches!(t.kind, token::Question) }) || self.is_keyword_ahead(start + 1, &[kw::Const])) } diff --git a/tests/ui/parser/impl-on-unsized-typo.rs b/tests/ui/parser/impl-on-unsized-typo.rs new file mode 100644 index 00000000000..e09c0463045 --- /dev/null +++ b/tests/ui/parser/impl-on-unsized-typo.rs @@ -0,0 +1,6 @@ +trait Tr {} + +impl Tr for T {} +//~^ ERROR expected one of `,`, `:`, `=`, or `>`, found `?` + +fn main() {} diff --git a/tests/ui/parser/impl-on-unsized-typo.stderr b/tests/ui/parser/impl-on-unsized-typo.stderr new file mode 100644 index 00000000000..23dcc1efd68 --- /dev/null +++ b/tests/ui/parser/impl-on-unsized-typo.stderr @@ -0,0 +1,8 @@ +error: expected one of `,`, `:`, `=`, or `>`, found `?` + --> $DIR/impl-on-unsized-typo.rs:3:8 + | +LL | impl Tr for T {} + | ^ expected one of `,`, `:`, `=`, or `>` + +error: aborting due to previous error + From 99cae9c4c10969f28363a02f366503f54021f638 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Sun, 14 May 2023 15:36:20 +0000 Subject: [PATCH 25/52] rustdoc-json: Add tests for visibility of impls --- .../impls/impl_item_visibility.rs | 26 +++++++++++++++++ .../impls/impl_item_visibility_show_hidden.rs | 28 +++++++++++++++++++ .../impl_item_visibility_show_private.rs | 27 ++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 tests/rustdoc-json/impls/impl_item_visibility.rs create mode 100644 tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs create mode 100644 tests/rustdoc-json/impls/impl_item_visibility_show_private.rs diff --git a/tests/rustdoc-json/impls/impl_item_visibility.rs b/tests/rustdoc-json/impls/impl_item_visibility.rs new file mode 100644 index 00000000000..efa54d91dca --- /dev/null +++ b/tests/rustdoc-json/impls/impl_item_visibility.rs @@ -0,0 +1,26 @@ +#![feature(no_core)] +#![no_core] + +pub struct Foo; + +/// impl Foo priv +impl Foo { + fn baz() {} +} +// @!has '$.index[*][?(@.docs=="impl Foo priv")]' + + +/// impl Foo pub +impl Foo { + pub fn qux() {} +} +// @is '$.index[*][?(@.docs=="impl Foo pub")].visibility' '"default"' + + +/// impl Foo hidden +impl Foo { + #[doc(hidden)] + pub fn __quazl(){} +} +// FIXME(#111564): Is this the right behaviour? +// @is '$.index[*][?(@.docs=="impl Foo hidden")].visibility' '"default"' diff --git a/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs b/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs new file mode 100644 index 00000000000..3c6fefc4ca2 --- /dev/null +++ b/tests/rustdoc-json/impls/impl_item_visibility_show_hidden.rs @@ -0,0 +1,28 @@ +// compile-flags: --document-hidden-items +#![feature(no_core)] +#![no_core] + +pub struct Foo; + +/// impl Foo priv +impl Foo { + fn baz() {} +} +// FIXME(#111564): Is this the right behaviour? +// @is '$.index[*][?(@.docs=="impl Foo priv")].visibility' '"default"' + + +/// impl Foo pub +impl Foo { + pub fn qux() {} +} +// @is '$.index[*][?(@.docs=="impl Foo pub")].visibility' '"default"' + + +/// impl Foo hidden +impl Foo { + #[doc(hidden)] + pub fn __quazl(){} +} +// FIXME(#111564): Is this the right behaviour? +// @is '$.index[*][?(@.docs=="impl Foo hidden")].visibility' '"default"' diff --git a/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs b/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs new file mode 100644 index 00000000000..b98d1e4167c --- /dev/null +++ b/tests/rustdoc-json/impls/impl_item_visibility_show_private.rs @@ -0,0 +1,27 @@ +// compile-flags: --document-private-items +#![feature(no_core)] +#![no_core] + +pub struct Foo; + +/// impl Foo priv +impl Foo { + fn baz() {} +} +// @is '$.index[*][?(@.docs=="impl Foo priv")].visibility' '"default"' + + +/// impl Foo pub +impl Foo { + pub fn qux() {} +} +// @is '$.index[*][?(@.docs=="impl Foo pub")].visibility' '"default"' + + +/// impl Foo hidden +impl Foo { + #[doc(hidden)] + pub fn __quazl(){} +} +// FIXME(#111564): Is this the right behaviour? +// @is '$.index[*][?(@.docs=="impl Foo hidden")].visibility' '"default"' From 9688a6cebb8478b504172980002ac34c29bd79ef Mon Sep 17 00:00:00 2001 From: Benjamin Atelsek Date: Mon, 15 May 2023 15:13:21 -0400 Subject: [PATCH 26/52] Fixed typo --- library/alloc/src/collections/btree/map.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 2daef82d6f1..1f8a1ecba6e 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -3021,7 +3021,7 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> { }) } - /// Returns a mutable reference to the of the element that the cursor is + /// Returns a mutable reference to the key of the element that the cursor is /// currently pointing to. /// /// This returns `None` if the cursor is currently pointing to the From 65f9603a4e9b75ddeba961de4a66a9f88072eb77 Mon Sep 17 00:00:00 2001 From: Alona Enraght-Moony Date: Mon, 15 May 2023 19:40:06 +0100 Subject: [PATCH 27/52] Add more interesting nonsense to weird-exprs.rs --- tests/ui/weird-exprs.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/ui/weird-exprs.rs b/tests/ui/weird-exprs.rs index d65703ef5ca..c4fa850a4f9 100644 --- a/tests/ui/weird-exprs.rs +++ b/tests/ui/weird-exprs.rs @@ -5,13 +5,16 @@ #![allow(non_camel_case_types)] #![allow(dead_code)] +#![allow(redundant_semicolons)] #![allow(unreachable_code)] #![allow(unused_braces, unused_must_use, unused_parens)] #![allow(uncommon_codepoints, confusable_idents)] +#![allow(unused_imports)] #![allow(unreachable_patterns)] #![recursion_limit = "256"] +extern crate core; use std::cell::Cell; use std::mem::swap; @@ -204,6 +207,30 @@ fn closure_matching() { assert!(matches!(x(..), |_| Some(4))); } +fn semisemisemisemisemi() { + ;;;;;;; ;;;;;;; ;;; ;;; ;; + ;; ;; ;;;; ;;;; ;; + ;;;;;;; ;;;;; ;; ;;;; ;; ;; + ;; ;; ;; ;; ;; ;; + ;;;;;;; ;;;;;;; ;; ;; ;; +} + +fn useful_syntax() { + use {{std::{{collections::{{HashMap}}}}}}; + use ::{{{{core}, {std}}}}; + use {{::{{core as core2}}}}; +} + +fn infcx() { + pub mod cx { + pub mod cx { + pub use super::cx; + pub struct Cx; + } + } + let _cx: cx::cx::Cx = cx::cx::cx::cx::cx::Cx; +} + pub fn main() { strange(); funny(); @@ -227,4 +254,7 @@ pub fn main() { function(); bathroom_stall(); closure_matching(); + semisemisemisemisemi(); + useful_syntax(); + infcx(); } From c11fd9297acb4e391c21ee0a5b89690816a4f791 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Mon, 15 May 2023 13:35:00 -0700 Subject: [PATCH 28/52] Add eholk back to compiler-contributors reviewers @eholk is back from vacation so he can review things again. --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index 54c8b2060c5..cf2d9f3169a 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -512,6 +512,7 @@ compiler-team = [ ] compiler-team-contributors = [ "@compiler-errors", + "@eholk", "@jackh726", "@TaKO8Ki", "@WaffleLapkin", From eeeb70e31efccb9fce62cde81c992a0d02759fe2 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 15 May 2023 14:08:51 -0700 Subject: [PATCH 29/52] Fix release date of 1.58.1 in release notes. --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index e72905c15bd..85266a17550 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1481,7 +1481,7 @@ and related tools. [is_power_of_two_usize]: https://doc.rust-lang.org/stable/core/num/struct.NonZeroUsize.html#method.is_power_of_two [stdarch/1266]: https://github.com/rust-lang/stdarch/pull/1266 -Version 1.58.1 (2022-01-19) +Version 1.58.1 (2022-01-20) =========================== * Fix race condition in `std::fs::remove_dir_all` ([CVE-2022-21658]) From b2b2be1cad5a3009f53f490ae09abf33958e40df Mon Sep 17 00:00:00 2001 From: bohan Date: Tue, 16 May 2023 01:39:35 +0800 Subject: [PATCH 30/52] fix(diagnostic): wrap parens for ref impl trait param --- .../rustc_hir_typeck/src/method/suggest.rs | 77 +++++++++++-------- tests/ui/suggestions/issue-99597.rs | 15 ++++ tests/ui/suggestions/issue-99597.stderr | 15 ++++ 3 files changed, 76 insertions(+), 31 deletions(-) create mode 100644 tests/ui/suggestions/issue-99597.rs create mode 100644 tests/ui/suggestions/issue-99597.stderr diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 486c217707e..550a87e6102 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2633,47 +2633,62 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Nothing, } let ast_generics = hir.get_generics(id.owner.def_id).unwrap(); - let (sp, mut introducer) = if let Some(span) = - ast_generics.bounds_span_for_suggestions(def_id) - { - (span, Introducer::Plus) - } else if let Some(colon_span) = param.colon_span { - (colon_span.shrink_to_hi(), Introducer::Nothing) - } else { - (param.span.shrink_to_hi(), Introducer::Colon) - }; - if matches!( - param.kind, - hir::GenericParamKind::Type { synthetic: true, .. }, - ) { - introducer = Introducer::Plus - } let trait_def_ids: FxHashSet = ast_generics .bounds_for_param(def_id) .flat_map(|bp| bp.bounds.iter()) .filter_map(|bound| bound.trait_ref()?.trait_def_id()) .collect(); - if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) { - err.span_suggestions( - sp, - message(format!( - "restrict type parameter `{}` with", - param.name.ident(), - )), + if candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) { + return; + } + let msg = message(format!( + "restrict type parameter `{}` with", + param.name.ident(), + )); + let bounds_span = ast_generics.bounds_span_for_suggestions(def_id); + if rcvr_ty.is_ref() && param.is_impl_trait() && bounds_span.is_some() { + err.multipart_suggestions( + msg, candidates.iter().map(|t| { - format!( - "{} {}", - match introducer { - Introducer::Plus => " +", - Introducer::Colon => ":", - Introducer::Nothing => "", - }, - self.tcx.def_path_str(t.def_id), - ) + vec![ + (param.span.shrink_to_lo(), "(".to_string()), + ( + bounds_span.unwrap(), + format!(" + {})", self.tcx.def_path_str(t.def_id)), + ), + ] }), Applicability::MaybeIncorrect, ); + return; } + + let (sp, introducer) = if let Some(span) = bounds_span { + (span, Introducer::Plus) + } else if let Some(colon_span) = param.colon_span { + (colon_span.shrink_to_hi(), Introducer::Nothing) + } else if param.is_impl_trait() { + (param.span.shrink_to_hi(), Introducer::Plus) + } else { + (param.span.shrink_to_hi(), Introducer::Colon) + }; + + err.span_suggestions( + sp, + msg, + candidates.iter().map(|t| { + format!( + "{} {}", + match introducer { + Introducer::Plus => " +", + Introducer::Colon => ":", + Introducer::Nothing => "", + }, + self.tcx.def_path_str(t.def_id) + ) + }), + Applicability::MaybeIncorrect, + ); return; } Node::Item(hir::Item { diff --git a/tests/ui/suggestions/issue-99597.rs b/tests/ui/suggestions/issue-99597.rs new file mode 100644 index 00000000000..8ba9e1fdd62 --- /dev/null +++ b/tests/ui/suggestions/issue-99597.rs @@ -0,0 +1,15 @@ +#![allow(dead_code)] + +trait T1 { } + +trait T2 { + fn test(&self) { } +} + +fn go(s: &impl T1) { + //~^ SUGGESTION ( + s.test(); + //~^ ERROR no method named `test` +} + +fn main() { } diff --git a/tests/ui/suggestions/issue-99597.stderr b/tests/ui/suggestions/issue-99597.stderr new file mode 100644 index 00000000000..bdf2a07c143 --- /dev/null +++ b/tests/ui/suggestions/issue-99597.stderr @@ -0,0 +1,15 @@ +error[E0599]: no method named `test` found for reference `&impl T1` in the current scope + --> $DIR/issue-99597.rs:11:7 + | +LL | s.test(); + | ^^^^ method not found in `&impl T1` + | + = help: items from traits can only be used if the type parameter is bounded by the trait +help: the following trait defines an item `test`, perhaps you need to restrict type parameter `impl T1` with it: + | +LL | fn go(s: &(impl T1 + T2)) { + | + +++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. From 228225842b0345b037fa1959b99178f68ea26d6e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 16 May 2023 09:45:56 +0000 Subject: [PATCH 31/52] Document how constants as opaque patterns behave differently. --- .../src/thir/pattern/deconstruct_pat.rs | 8 ++++---- .../src/thir/pattern/usefulness.rs | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 9af13781312..6a77146138b 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -844,8 +844,8 @@ impl<'tcx> Constructor<'tcx> { } /// Faster version of `is_covered_by` when applied to many constructors. `used_ctors` is - /// assumed to be built from `matrix.head_ctors()` with wildcards filtered out, and `self` is - /// assumed to have been split from a wildcard. + /// assumed to be built from `matrix.head_ctors()` with wildcards and opaques filtered out, + /// and `self` is assumed to have been split from a wildcard. fn is_covered_by_any<'p>( &self, pcx: &PatCtxt<'_, 'p, 'tcx>, @@ -894,7 +894,7 @@ impl<'tcx> Constructor<'tcx> { /// in `to_ctors`: in some cases we only return `Missing`. #[derive(Debug)] pub(super) struct SplitWildcard<'tcx> { - /// Constructors seen in the matrix. + /// Constructors (other than wildcards and opaques) seen in the matrix. matrix_ctors: Vec>, /// All the constructors for this type all_ctors: SmallVec<[Constructor<'tcx>; 1]>, @@ -1037,7 +1037,7 @@ impl<'tcx> SplitWildcard<'tcx> { // Since `all_ctors` never contains wildcards, this won't recurse further. self.all_ctors = self.all_ctors.iter().flat_map(|ctor| ctor.split(pcx, ctors.clone())).collect(); - self.matrix_ctors = ctors.filter(|c| !c.is_wildcard()).cloned().collect(); + self.matrix_ctors = ctors.filter(|c| !matches!(c, Wildcard | Opaque)).cloned().collect(); } /// Whether there are any value constructors for this type that are not present in the matrix. diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index f229b10c447..e5b63506906 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -288,6 +288,22 @@ //! //! The details are not necessary to understand this file, so we explain them in //! [`super::deconstruct_pat`]. Splitting is done by the [`Constructor::split`] function. +//! +//! # Constants in patterns +//! +//! There are two kinds of constants in patterns: +//! +//! * literals (`1`, `true`, `"foo"`) +//! * named or inline consts (`FOO`, `const { 5 + 6 }`) +//! +//! The latter are converted into other patterns with literals at the leaves. For example +//! `const_to_pat(const { [1, 2, 3] })` becomes an `Array(vec![Const(1), Const(2), Const(3)])` +//! pattern. This gets problematic when comparing the constant via `==` would behave differently +//! from matching on the constant converted to a pattern. Situations like that can occur, when +//! the user implements `PartialEq` manually, and thus could make `==` behave arbitrarily different. +//! In order to honor the `==` implementation, constants of types that implement `PartialEq` manually +//! stay as a full constant and become an `Opaque` pattern. These `Opaque` patterns do not participate +//! in exhaustiveness, specialization or overlap checking. use self::ArmType::*; use self::Usefulness::*; From 2eef27a6c1808377e84d68c474f8246a2dafda63 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 10 Apr 2023 14:33:15 +0000 Subject: [PATCH 32/52] Merge `MetadataRef` type aliases --- compiler/rustc_data_structures/src/sync.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 8a778866a77..661dd5dacf5 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -92,6 +92,9 @@ mod mode { } pub use mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode}; + +pub type MetadataRef = OwnedSlice; + cfg_if! { if #[cfg(not(parallel_compiler))] { pub unsafe auto trait Send {} @@ -244,8 +247,6 @@ cfg_if! { r } - pub type MetadataRef = OwnedSlice; - pub use std::rc::Rc as Lrc; pub use std::rc::Weak as Weak; pub use std::cell::Ref as ReadGuard; @@ -517,8 +518,6 @@ cfg_if! { } } - pub type MetadataRef = OwnedSlice; - /// This makes locks panic if they are already held. /// It is only useful when you are running in a single thread const ERROR_CHECKING: bool = false; From 086c08d86ac4d63f12961e37ef433a6128ad974b Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 10 Apr 2023 14:33:33 +0000 Subject: [PATCH 33/52] Switch `OwnedSlice` to use `Lrc` & remove `Lrc` from `MetadataBlob` --- .../rustc_data_structures/src/owned_slice.rs | 35 +++++++++++++++++-- .../src/owned_slice/tests.rs | 12 ++++++- compiler/rustc_metadata/src/locator.rs | 2 +- compiler/rustc_metadata/src/rmeta/decoder.rs | 7 ++-- .../src/rmeta/def_path_hash_map.rs | 3 +- compiler/rustc_metadata/src/rmeta/mod.rs | 1 - 6 files changed, 47 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_data_structures/src/owned_slice.rs b/compiler/rustc_data_structures/src/owned_slice.rs index 311a42aa42a..8cf74a98adb 100644 --- a/compiler/rustc_data_structures/src/owned_slice.rs +++ b/compiler/rustc_data_structures/src/owned_slice.rs @@ -1,5 +1,6 @@ use std::{borrow::Borrow, ops::Deref}; +use crate::sync::Lrc; // Use our fake Send/Sync traits when on not parallel compiler, // so that `OwnedSlice` only implements/requires Send/Sync // for parallel compiler builds. @@ -7,7 +8,7 @@ use crate::sync::{Send, Sync}; /// An owned slice. /// -/// This is similar to `Box<[u8]>` but allows slicing and using anything as the +/// This is similar to `Lrc<[u8]>` but allows slicing and using anything as the /// backing buffer. /// /// See [`slice_owned`] for `OwnedSlice` construction and examples. @@ -16,6 +17,7 @@ use crate::sync::{Send, Sync}; /// /// This is essentially a replacement for `owning_ref` which is a lot simpler /// and even sound! šŸŒø +#[derive(Clone)] pub struct OwnedSlice { /// This is conceptually a `&'self.owner [u8]`. bytes: *const [u8], @@ -31,7 +33,7 @@ pub struct OwnedSlice { // \/ // āŠ‚(Ā“ļ½„ā—”ļ½„āŠ‚ )āˆ˜ĖšĖ³Ā° (I am the phantom remnant of #97770) #[expect(dead_code)] - owner: Box, + owner: Lrc, } /// Makes an [`OwnedSlice`] out of an `owner` and a `slicer` function. @@ -83,12 +85,39 @@ where // N.B. the HRTB on the `slicer` is important ā€” without it the caller could provide // a short lived slice, unrelated to the owner. - let owner = Box::new(owner); + let owner = Lrc::new(owner); let bytes = slicer(&*owner)?; Ok(OwnedSlice { bytes, owner }) } +impl OwnedSlice { + /// Slice this slice by `slicer`. + /// + /// # Examples + /// + /// ```rust + /// # use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned}; + /// let vec = vec![1, 2, 3, 4]; + /// + /// // Identical to slicing via `&v[1..3]` but produces an owned slice + /// let slice: OwnedSlice = slice_owned(vec, |v| &v[..]); + /// assert_eq!(&*slice, [1, 2, 3, 4]); + /// + /// let slice = slice.slice(|slice| &slice[1..][..2]); + /// assert_eq!(&*slice, [2, 3]); + /// ``` + /// + pub fn slice(self, slicer: impl FnOnce(&[u8]) -> &[u8]) -> OwnedSlice { + // This is basically identical to `try_slice_owned`, + // `slicer` can only return slices of its argument or some static data, + // both of which are valid while `owner` is alive. + + let bytes = slicer(&self); + OwnedSlice { bytes, ..self } + } +} + impl Deref for OwnedSlice { type Target = [u8]; diff --git a/compiler/rustc_data_structures/src/owned_slice/tests.rs b/compiler/rustc_data_structures/src/owned_slice/tests.rs index e151b8c2de0..1eb5378cd1a 100644 --- a/compiler/rustc_data_structures/src/owned_slice/tests.rs +++ b/compiler/rustc_data_structures/src/owned_slice/tests.rs @@ -26,7 +26,7 @@ fn static_storage() { } #[test] -fn slice_the_slice() { +fn slice_owned_the_slice() { let slice = slice_owned(vec![1, 2, 3, 4, 5, 6], Vec::as_slice); let slice = slice_owned(slice, |s| &s[1..][..4]); let slice = slice_owned(slice, |s| s); @@ -35,6 +35,16 @@ fn slice_the_slice() { assert_eq!(&*slice, &[1, 2, 3, 4, 5, 6][1..][..4][1..]); } +#[test] +fn slice_the_slice() { + let slice = slice_owned(vec![1, 2, 3, 4, 5, 6], Vec::as_slice) + .slice(|s| &s[1..][..4]) + .slice(|s| s) + .slice(|s| &s[1..]); + + assert_eq!(&*slice, &[1, 2, 3, 4, 5, 6][1..][..4][1..]); +} + #[test] fn try_and_fail() { let res = try_slice_owned(vec![0], |v| v.get(12..).ok_or(())); diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index c6af8d63289..a083e9b5858 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -843,7 +843,7 @@ fn get_metadata_section<'p>( slice_owned(mmap, Deref::deref) } }; - let blob = MetadataBlob::new(raw_bytes); + let blob = MetadataBlob(raw_bytes); if blob.is_compatible() { Ok(blob) } else { diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 1c36d5e82da..699e1f49ed6 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -7,6 +7,7 @@ use crate::rmeta::*; use rustc_ast as ast; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::owned_slice::OwnedSlice; use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc, OnceCell}; use rustc_data_structures::unhash::UnhashMap; @@ -50,7 +51,7 @@ mod cstore_impl; /// A `MetadataBlob` internally is just a reference counted pointer to /// the actual data, so cloning it is cheap. #[derive(Clone)] -pub(crate) struct MetadataBlob(Lrc); +pub(crate) struct MetadataBlob(pub(crate) OwnedSlice); impl std::ops::Deref for MetadataBlob { type Target = [u8]; @@ -660,10 +661,6 @@ impl<'a, 'tcx, I: Idx, T> Decodable> for LazyTable implement_ty_decoder!(DecodeContext<'a, 'tcx>); impl MetadataBlob { - pub(crate) fn new(metadata_ref: MetadataRef) -> MetadataBlob { - MetadataBlob(Lrc::new(metadata_ref)) - } - pub(crate) fn is_compatible(&self) -> bool { self.blob().starts_with(METADATA_HEADER) } diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs index 05402a58701..4f280bb9d80 100644 --- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -1,6 +1,5 @@ use crate::rmeta::DecodeContext; use crate::rmeta::EncodeContext; -use rustc_data_structures::owned_slice::slice_owned; use rustc_data_structures::owned_slice::OwnedSlice; use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap}; use rustc_middle::parameterized_over_tcx; @@ -47,7 +46,7 @@ impl<'a, 'tcx> Decodable> for DefPathHashMapRef<'static> fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefPathHashMapRef<'static> { let len = d.read_usize(); let pos = d.position(); - let o = slice_owned(d.blob().clone(), |blob| &blob[pos..pos + len]); + let o = d.blob().clone().0.slice(|blob| &blob[pos..pos + len]); // Although we already have the data we need via the `OwnedSlice`, we still need // to advance the `DecodeContext`'s position so it's in a valid state after diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 1328d700210..b00566081b9 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -7,7 +7,6 @@ use table::TableBuilder; use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::MetadataRef; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, DocLinkResMap}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId}; From e39d61cbf3ae855801f7a2a494ce1033a00610d2 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 10 Apr 2023 15:30:11 +0000 Subject: [PATCH 34/52] Remove `MetadataRef` type alias --- compiler/rustc_codegen_ssa/src/back/metadata.rs | 9 ++++----- compiler/rustc_codegen_ssa/src/traits/backend.rs | 8 +++----- compiler/rustc_data_structures/src/sync.rs | 3 --- compiler/rustc_metadata/src/locator.rs | 3 +-- compiler/rustc_session/src/cstore.rs | 7 ++++--- 5 files changed, 12 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 8968133bac5..8bf84772f08 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -14,8 +14,7 @@ use snap::write::FrameEncoder; use object::elf::NT_GNU_PROPERTY_TYPE_0; use rustc_data_structures::memmap::Mmap; -use rustc_data_structures::owned_slice::try_slice_owned; -use rustc_data_structures::sync::MetadataRef; +use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice}; use rustc_metadata::fs::METADATA_FILENAME; use rustc_metadata::EncodedMetadata; use rustc_session::cstore::MetadataLoader; @@ -39,7 +38,7 @@ pub struct DefaultMetadataLoader; fn load_metadata_with( path: &Path, f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>, -) -> Result { +) -> Result { let file = File::open(path).map_err(|e| format!("failed to open file '{}': {}", path.display(), e))?; @@ -49,7 +48,7 @@ fn load_metadata_with( } impl MetadataLoader for DefaultMetadataLoader { - fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result { + fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result { load_metadata_with(path, |data| { let archive = object::read::archive::ArchiveFile::parse(&*data) .map_err(|e| format!("failed to parse rlib '{}': {}", path.display(), e))?; @@ -69,7 +68,7 @@ impl MetadataLoader for DefaultMetadataLoader { }) } - fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result { + fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result { load_metadata_with(path, |data| search_for_section(path, data, ".rustc")) } } diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 684598eebe6..d0efc171998 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -1,3 +1,5 @@ +use std::any::Any; + use super::write::WriteBackendMethods; use super::CodegenObject; use crate::back::write::TargetMachineFactoryFn; @@ -5,6 +7,7 @@ use crate::{CodegenResults, ModuleCodegen}; use rustc_ast::expand::allocator::AllocatorKind; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::sync::{DynSend, DynSync}; use rustc_errors::ErrorGuaranteed; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; @@ -20,11 +23,6 @@ use rustc_span::symbol::Symbol; use rustc_target::abi::call::FnAbi; use rustc_target::spec::Target; -pub use rustc_data_structures::sync::MetadataRef; - -use rustc_data_structures::sync::{DynSend, DynSync}; -use std::any::Any; - pub trait BackendTypes { type Value: CodegenObject; type Function: CodegenObject; diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 661dd5dacf5..6c3197d8ec2 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -40,7 +40,6 @@ //! [^2] `MTLockRef` is a typedef. pub use crate::marker::*; -use crate::owned_slice::OwnedSlice; use std::collections::HashMap; use std::hash::{BuildHasher, Hash}; use std::ops::{Deref, DerefMut}; @@ -93,8 +92,6 @@ mod mode { pub use mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode}; -pub type MetadataRef = OwnedSlice; - cfg_if! { if #[cfg(not(parallel_compiler))] { pub unsafe auto trait Send {} diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index a083e9b5858..6c4d121fd01 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -220,7 +220,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::owned_slice::slice_owned; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::MetadataRef; use rustc_errors::{DiagnosticArgValue, FatalError, IntoDiagnosticArg}; use rustc_fs_util::try_canonicalize; use rustc_session::config::{self, CrateType}; @@ -782,7 +781,7 @@ fn get_metadata_section<'p>( if !filename.exists() { return Err(MetadataError::NotPresent(filename)); } - let raw_bytes: MetadataRef = match flavor { + let raw_bytes = match flavor { CrateFlavor::Rlib => { loader.get_rlib_metadata(target, filename).map_err(MetadataError::LoadFailure)? } diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 8089d81cc22..dc475e8c6d5 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -6,7 +6,8 @@ use crate::search_paths::PathKind; use crate::utils::NativeLibKind; use crate::Session; use rustc_ast as ast; -use rustc_data_structures::sync::{self, AppendOnlyIndexVec, MetadataRef, RwLock}; +use rustc_data_structures::owned_slice::OwnedSlice; +use rustc_data_structures::sync::{self, AppendOnlyIndexVec, RwLock}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions}; use rustc_span::hygiene::{ExpnHash, ExpnId}; @@ -203,8 +204,8 @@ pub enum ExternCrateSource { /// metadata in library -- this trait just serves to decouple rustc_metadata from /// the archive reader, which depends on LLVM. pub trait MetadataLoader: std::fmt::Debug { - fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result; - fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result; + fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result; + fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result; } pub type MetadataLoaderDyn = dyn MetadataLoader + Send + Sync + sync::DynSend + sync::DynSync; From a6197a5dcad33acd67a8455196b8dbaab525e3f9 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 16 May 2023 12:09:24 +0000 Subject: [PATCH 35/52] Fixup comments --- compiler/rustc_data_structures/src/owned_slice.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_data_structures/src/owned_slice.rs b/compiler/rustc_data_structures/src/owned_slice.rs index 8cf74a98adb..cbb3047d884 100644 --- a/compiler/rustc_data_structures/src/owned_slice.rs +++ b/compiler/rustc_data_structures/src/owned_slice.rs @@ -74,10 +74,10 @@ where O: Send + Sync + 'static, F: FnOnce(&O) -> Result<&[u8], E>, { - // We box the owner of the bytes, so it doesn't move. + // We wrap the owner of the bytes in, so it doesn't move. // // Since the owner does not move and we don't access it in any way - // before drop, there is nothing that can invalidate the bytes pointer. + // before dropping, there is nothing that can invalidate the bytes pointer. // // Thus, "extending" the lifetime of the reference returned from `F` is fine. // We pretend that we pass it a reference that lives as long as the returned slice. @@ -137,11 +137,11 @@ impl Borrow<[u8]> for OwnedSlice { } } -// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Box)`, which is `Send` +// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Arc)`, which is `Send` #[cfg(parallel_compiler)] unsafe impl Send for OwnedSlice {} -// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Box)`, which is `Sync` +// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Arc)`, which is `Sync` #[cfg(parallel_compiler)] unsafe impl Sync for OwnedSlice {} From 88493d26657557b1e328be2057594db79cb2f594 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 16 May 2023 14:35:27 +0200 Subject: [PATCH 36/52] Only keep impl blocks from bodies --- src/librustdoc/visit_ast.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index ff13daa6db4..8f8dc6b7090 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet}; -use rustc_hir::intravisit::{walk_item, Visitor}; +use rustc_hir::intravisit::{walk_body, walk_item, Visitor}; use rustc_hir::{Node, CRATE_HIR_ID}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; @@ -106,6 +106,7 @@ pub(crate) struct RustdocVisitor<'a, 'tcx> { exact_paths: DefIdMap>, modules: Vec>, is_importable_from_parent: bool, + inside_body: bool, } impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { @@ -129,6 +130,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { exact_paths: Default::default(), modules: vec![om], is_importable_from_parent: true, + inside_body: false, } } @@ -368,6 +370,26 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { import_id: Option, ) { debug!("visiting item {:?}", item); + if self.inside_body { + // Only impls can be "seen" outside a body. For example: + // + // ``` + // struct Bar; + // + // fn foo() { + // impl Bar { fn bar() {} } + // } + // Bar::bar(); + // ``` + if let hir::ItemKind::Impl(impl_) = item.kind && + // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick + // them up regardless of where they're located. + impl_.of_trait.is_none() + { + self.add_to_current_mod(item, None, None); + } + return; + } let name = renamed.unwrap_or(item.ident.name); let tcx = self.cx.tcx; @@ -564,4 +586,10 @@ impl<'a, 'tcx> Visitor<'tcx> for RustdocVisitor<'a, 'tcx> { fn visit_lifetime(&mut self, _: &hir::Lifetime) { // Unneeded. } + + fn visit_body(&mut self, b: &'tcx hir::Body<'tcx>) { + let prev = mem::replace(&mut self.inside_body, true); + walk_body(self, b); + self.inside_body = prev; + } } From 0f1d4b5d4d46687130cbd2766ab1d761bdac90c4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 16 May 2023 14:35:46 +0200 Subject: [PATCH 37/52] Add regression test for #111415 --- tests/rustdoc/nested-items-issue-111415.rs | 36 ++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 tests/rustdoc/nested-items-issue-111415.rs diff --git a/tests/rustdoc/nested-items-issue-111415.rs b/tests/rustdoc/nested-items-issue-111415.rs new file mode 100644 index 00000000000..9b7688c332c --- /dev/null +++ b/tests/rustdoc/nested-items-issue-111415.rs @@ -0,0 +1,36 @@ +// Regression test for . +// This test ensures that only impl blocks are documented in bodies. + +#![crate_name = "foo"] + +// @has 'foo/index.html' +// Checking there are only three sections. +// @count - '//*[@id="main-content"]/*[@class="small-section-header"]' 3 +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Structs' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Functions' +// @has - '//*[@id="main-content"]/*[@class="small-section-header"]' 'Traits' +// Checking that there are only three items. +// @count - '//*[@id="main-content"]//*[@class="item-name"]' 3 +// @has - '//*[@id="main-content"]//a[@href="struct.Bar.html"]' 'Bar' +// @has - '//*[@id="main-content"]//a[@href="fn.foo.html"]' 'foo' +// @has - '//*[@id="main-content"]//a[@href="trait.Foo.html"]' 'Foo' + +// Now checking that the `foo` method is visible in `Bar` page. +// @has 'foo/struct.Bar.html' +// @has - '//*[@id="method.foo"]/*[@class="code-header"]' 'pub fn foo()' +// @has - '//*[@id="method.bar"]/*[@class="code-header"]' 'fn bar()' +pub struct Bar; + +pub trait Foo { + fn bar() {} +} + +pub fn foo() { + pub mod inaccessible {} + pub fn inner() {} + pub const BAR: u32 = 0; + impl Bar { + pub fn foo() {} + } + impl Foo for Bar {} +} From 8921391a12be89c22ca8a5724cf5c6e98ef47149 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 12 May 2023 00:34:10 +0000 Subject: [PATCH 38/52] Use error term if missing associated item in new solver --- .../src/solve/project_goals.rs | 16 +++++++++++++++- ...81-1.stderr => issue-103181-1.current.stderr} | 2 +- tests/ui/impl-trait/issue-103181-1.next.stderr | 12 ++++++++++++ tests/ui/impl-trait/issue-103181-1.rs | 2 ++ 4 files changed, 30 insertions(+), 2 deletions(-) rename tests/ui/impl-trait/{issue-103181-1.stderr => issue-103181-1.current.stderr} (91%) create mode 100644 tests/ui/impl-trait/issue-103181-1.next.stderr diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 20ce2d9416e..d3228074421 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -124,10 +124,24 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { }; if !assoc_def.item.defaultness(tcx).has_value() { - tcx.sess.delay_span_bug( + let guar = tcx.sess.delay_span_bug( tcx.def_span(assoc_def.item.def_id), "missing value for assoc item in impl", ); + let error_term = match assoc_def.item.kind { + ty::AssocKind::Const => tcx + .const_error( + tcx.type_of(goal.predicate.def_id()) + .subst(tcx, goal.predicate.projection_ty.substs), + guar, + ) + .into(), + ty::AssocKind::Type => tcx.ty_error(guar).into(), + ty::AssocKind::Fn => unreachable!(), + }; + ecx.eq(goal.param_env, goal.predicate.term, error_term) + .expect("expected goal term to be fully unconstrained"); + return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); } // Getting the right substitutions here is complex, e.g. given: diff --git a/tests/ui/impl-trait/issue-103181-1.stderr b/tests/ui/impl-trait/issue-103181-1.current.stderr similarity index 91% rename from tests/ui/impl-trait/issue-103181-1.stderr rename to tests/ui/impl-trait/issue-103181-1.current.stderr index cd026607d52..e87a9d28ae1 100644 --- a/tests/ui/impl-trait/issue-103181-1.stderr +++ b/tests/ui/impl-trait/issue-103181-1.current.stderr @@ -1,5 +1,5 @@ error[E0046]: not all trait items implemented, missing: `Error` - --> $DIR/issue-103181-1.rs:9:5 + --> $DIR/issue-103181-1.rs:11:5 | LL | type Error; | ---------- `Error` from trait diff --git a/tests/ui/impl-trait/issue-103181-1.next.stderr b/tests/ui/impl-trait/issue-103181-1.next.stderr new file mode 100644 index 00000000000..e87a9d28ae1 --- /dev/null +++ b/tests/ui/impl-trait/issue-103181-1.next.stderr @@ -0,0 +1,12 @@ +error[E0046]: not all trait items implemented, missing: `Error` + --> $DIR/issue-103181-1.rs:11:5 + | +LL | type Error; + | ---------- `Error` from trait +LL | } +LL | impl HttpBody for () { + | ^^^^^^^^^^^^^^^^^^^^ missing `Error` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/tests/ui/impl-trait/issue-103181-1.rs b/tests/ui/impl-trait/issue-103181-1.rs index 197aedf9d98..5154abcd690 100644 --- a/tests/ui/impl-trait/issue-103181-1.rs +++ b/tests/ui/impl-trait/issue-103181-1.rs @@ -1,3 +1,5 @@ +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next // edition:2021 mod hyper { From e16d71b706e54b3f21305b2042635b94a69b879e Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 16 May 2023 04:25:25 +0100 Subject: [PATCH 39/52] format `Const`'s less verbosely --- compiler/rustc_middle/src/ty/consts.rs | 10 ---- compiler/rustc_middle/src/ty/consts/kind.rs | 4 +- compiler/rustc_middle/src/ty/print/pretty.rs | 60 ++++++++++--------- .../rustc_middle/src/ty/structural_impls.rs | 38 ++++++++++++ 4 files changed, 71 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 0a5792a9c47..1a4bd14815f 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -6,7 +6,6 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::LocalDefId; use rustc_macros::HashStable; -use std::fmt; mod int; mod kind; @@ -21,15 +20,6 @@ pub use valtree::*; #[rustc_pass_by_value] pub struct Const<'tcx>(pub(super) Interned<'tcx, ConstData<'tcx>>); -impl<'tcx> fmt::Debug for Const<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - // This reflects what `Const` looked liked before `Interned` was - // introduced. We print it like this to avoid having to update expected - // output in a lot of tests. - write!(f, "Const {{ ty: {:?}, kind: {:?} }}", self.ty(), self.kind()) - } -} - /// Typed constant value. #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, HashStable, TyEncodable, TyDecodable)] pub struct ConstData<'tcx> { diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index a108f6c8947..1dd4f8a2437 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -42,7 +42,7 @@ impl<'tcx> UnevaluatedConst<'tcx> { } /// Represents a constant in Rust. -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] +#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable)] #[derive(Hash, HashStable, TypeFoldable, TypeVisitable)] #[derive(derive_more::From)] pub enum ConstKind<'tcx> { @@ -128,7 +128,7 @@ impl<'tcx> ConstKind<'tcx> { } /// An inference variable for a const, for use in const generics. -#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)] +#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)] pub enum InferConst<'tcx> { /// Infer the value of the const. Var(ty::ConstVid<'tcx>), diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 385156262c7..a8193c3e559 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -703,7 +703,7 @@ pub trait PrettyPrinter<'tcx>: ty::Error(_) => p!("[type error]"), ty::Param(ref param_ty) => p!(print(param_ty)), ty::Bound(debruijn, bound_ty) => match bound_ty.kind { - ty::BoundTyKind::Anon => self.pretty_print_bound_var(debruijn, bound_ty.var)?, + ty::BoundTyKind::Anon => debug_bound_var(&mut self, debruijn, bound_ty.var)?, ty::BoundTyKind::Param(_, s) => match self.should_print_verbose() { true if debruijn == ty::INNERMOST => p!(write("^{}", s)), true => p!(write("^{}_{}", debruijn.index(), s)), @@ -741,7 +741,7 @@ pub trait PrettyPrinter<'tcx>: } ty::Placeholder(placeholder) => match placeholder.bound.kind { ty::BoundTyKind::Anon => { - self.pretty_print_placeholder_var(placeholder.universe, placeholder.bound.var)? + debug_placeholder_var(&mut self, placeholder.universe, placeholder.bound.var)?; } ty::BoundTyKind::Param(_, name) => p!(write("{}", name)), }, @@ -1164,30 +1164,6 @@ pub trait PrettyPrinter<'tcx>: traits.entry(trait_ref).or_default().extend(proj_ty); } - fn pretty_print_bound_var( - &mut self, - debruijn: ty::DebruijnIndex, - var: ty::BoundVar, - ) -> Result<(), Self::Error> { - if debruijn == ty::INNERMOST { - write!(self, "^{}", var.index()) - } else { - write!(self, "^{}_{}", debruijn.index(), var.index()) - } - } - - fn pretty_print_placeholder_var( - &mut self, - ui: ty::UniverseIndex, - var: ty::BoundVar, - ) -> Result<(), Self::Error> { - if ui == ty::UniverseIndex::ROOT { - write!(self, "!{}", var.index()) - } else { - write!(self, "!{}_{}", ui.index(), var.index()) - } - } - fn ty_infer_name(&self, _: ty::TyVid) -> Option { None } @@ -1321,7 +1297,7 @@ pub trait PrettyPrinter<'tcx>: define_scoped_cx!(self); if self.should_print_verbose() { - p!(write("Const({:?}: {:?})", ct.kind(), ct.ty())); + p!(write("{:?}", ct)); return Ok(self); } @@ -1380,9 +1356,11 @@ pub trait PrettyPrinter<'tcx>: } ty::ConstKind::Bound(debruijn, bound_var) => { - self.pretty_print_bound_var(debruijn, bound_var)? + debug_bound_var(&mut self, debruijn, bound_var)? } - ty::ConstKind::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)), + ty::ConstKind::Placeholder(placeholder) => { + debug_placeholder_var(&mut self, placeholder.universe, placeholder.bound)?; + }, // FIXME(generic_const_exprs): // write out some legible representation of an abstract const? ty::ConstKind::Expr(_) => p!("[const expr]"), @@ -3067,3 +3045,27 @@ pub struct OpaqueFnEntry<'tcx> { fn_trait_ref: Option>, return_ty: Option>>, } + +pub fn debug_bound_var( + fmt: &mut T, + debruijn: ty::DebruijnIndex, + var: ty::BoundVar, +) -> Result<(), std::fmt::Error> { + if debruijn == ty::INNERMOST { + write!(fmt, "^{}", var.index()) + } else { + write!(fmt, "^{}_{}", debruijn.index(), var.index()) + } +} + +pub fn debug_placeholder_var( + fmt: &mut T, + universe: ty::UniverseIndex, + bound: ty::BoundVar, +) -> Result<(), std::fmt::Error> { + if universe == ty::UniverseIndex::ROOT { + write!(fmt, "!{}", bound.index()) + } else { + write!(fmt, "!{}_{}", universe.index(), bound.index()) + } +} diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index e73208b877f..16cb6c91046 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -192,6 +192,44 @@ impl<'tcx> fmt::Debug for AliasTy<'tcx> { } } +impl<'tcx> fmt::Debug for ty::InferConst<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + InferConst::Var(var) => write!(f, "{var:?}"), + InferConst::Fresh(var) => write!(f, "Fresh({var:?})"), + } + } +} + +impl<'tcx> fmt::Debug for ty::Const<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // This reflects what `Const` looked liked before `Interned` was + // introduced. We print it like this to avoid having to update expected + // output in a lot of tests. + write!(f, "Const {{ ty: {:?}, kind: {:?} }}", self.ty(), self.kind()) + } +} + +impl<'tcx> fmt::Debug for ty::ConstKind<'tcx> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + use ty::ConstKind::*; + match self { + Param(param) => write!(f, "{param:?}"), + Infer(var) => write!(f, "{var:?}"), + Bound(debruijn, var) => ty::print::debug_bound_var(f, *debruijn, *var), + Placeholder(placeholder) => { + ty::print::debug_placeholder_var(f, placeholder.universe, placeholder.bound) + } + Unevaluated(uv) => { + f.debug_tuple("Unevaluated").field(&uv.substs).field(&uv.def).finish() + } + Value(valtree) => write!(f, "{valtree:?}"), + Error(_) => write!(f, "[const error]"), + Expr(expr) => write!(f, "{expr:?}"), + } + } +} + /////////////////////////////////////////////////////////////////////////// // Atomic structs // From 2a554eb40677a659092c5b95a52821275924c4bf Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 16 May 2023 17:16:01 +0100 Subject: [PATCH 40/52] bless --- tests/mir-opt/issue_99325.main.built.after.mir | 4 ++-- tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir | 2 +- tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/mir-opt/issue_99325.main.built.after.mir b/tests/mir-opt/issue_99325.main.built.after.mir index f0c9ef419bd..0424ce3abeb 100644 --- a/tests/mir-opt/issue_99325.main.built.after.mir +++ b/tests/mir-opt/issue_99325.main.built.after.mir @@ -1,8 +1,8 @@ // MIR for `main` after built | User Type Annotations -| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Value(Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)])) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} -| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated(UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), substs: [] }) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Branch([Leaf(0x41), Leaf(0x41), Leaf(0x41), Leaf(0x41)]) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:10:16: 10:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} +| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserSubsts { substs: [Const { ty: &'static [u8; 4], kind: Unevaluated([], DefId(0:8 ~ issue_99325[22bb]::main::{constant#1})) }], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:11:16: 11:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">} | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/issue_99325.rs:+0:15: +0:15 diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index 71bdfcc5c49..c425f3cd506 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -22,7 +22,7 @@ | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11 - let mut _1: [usize; Const(Value(Leaf(0x00000003)): usize)]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 + let mut _1: [usize; Const { ty: usize, kind: Leaf(0x00000003) }]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 let _3: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:16: +2:17 let mut _4: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 let mut _5: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 diff --git a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 9fa8609b751..22ad24f8d77 100644 --- a/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/tests/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -22,7 +22,7 @@ | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/region_subtyping_basic.rs:+0:11: +0:11 - let mut _1: [usize; Const(Value(Leaf(0x0000000000000003)): usize)]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 + let mut _1: [usize; Const { ty: usize, kind: Leaf(0x0000000000000003) }]; // in scope 0 at $DIR/region_subtyping_basic.rs:+1:9: +1:14 let _3: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:16: +2:17 let mut _4: usize; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 let mut _5: bool; // in scope 0 at $DIR/region_subtyping_basic.rs:+2:14: +2:18 From e7963a65ed4b913274fcd0a0dec0c71c2754a97c Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 4 Feb 2023 19:12:01 -0800 Subject: [PATCH 41/52] Hide repr attribute from doc of types without guaranteed repr --- library/core/src/any.rs | 2 +- library/core/src/ffi/mod.rs | 14 +++++++------- library/core/src/task/wake.rs | 2 +- .../portable-simd/crates/core_simd/src/masks.rs | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/core/src/any.rs b/library/core/src/any.rs index bb93ea509d8..d1c1ae6526b 100644 --- a/library/core/src/any.rs +++ b/library/core/src/any.rs @@ -866,7 +866,7 @@ where /// /// A data provider provides values by calling this type's provide methods. #[unstable(feature = "provide_any", issue = "96024")] -#[repr(transparent)] +#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 pub struct Demand<'a>(dyn Erased<'a> + 'a); impl<'a> Demand<'a> { diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index b85894259f1..b73abbbaca7 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -203,7 +203,7 @@ mod c_long_definition { // be UB. #[doc = include_str!("c_void.md")] #[cfg_attr(not(bootstrap), lang = "c_void")] -#[repr(u8)] +#[cfg_attr(not(doc), repr(u8))] // work around https://github.com/rust-lang/rust/issues/90435 #[stable(feature = "core_c_void", since = "1.30.0")] pub enum c_void { #[unstable( @@ -244,7 +244,7 @@ impl fmt::Debug for c_void { target_os = "uefi", windows, ))] -#[repr(transparent)] +#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 #[unstable( feature = "c_variadic", reason = "the `c_variadic` feature has not been properly tested on \ @@ -296,7 +296,7 @@ impl<'f> fmt::Debug for VaListImpl<'f> { not(target_os = "uefi"), not(windows), ))] -#[repr(C)] +#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 #[derive(Debug)] #[unstable( feature = "c_variadic", @@ -316,7 +316,7 @@ pub struct VaListImpl<'f> { /// PowerPC ABI implementation of a `va_list`. #[cfg(all(target_arch = "powerpc", not(target_os = "uefi"), not(windows)))] -#[repr(C)] +#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 #[derive(Debug)] #[unstable( feature = "c_variadic", @@ -336,7 +336,7 @@ pub struct VaListImpl<'f> { /// s390x ABI implementation of a `va_list`. #[cfg(target_arch = "s390x")] -#[repr(C)] +#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 #[derive(Debug)] #[unstable( feature = "c_variadic", @@ -355,7 +355,7 @@ pub struct VaListImpl<'f> { /// x86_64 ABI implementation of a `va_list`. #[cfg(all(target_arch = "x86_64", not(target_os = "uefi"), not(windows)))] -#[repr(C)] +#[cfg_attr(not(doc), repr(C))] // work around https://github.com/rust-lang/rust/issues/66401 #[derive(Debug)] #[unstable( feature = "c_variadic", @@ -373,7 +373,7 @@ pub struct VaListImpl<'f> { } /// A wrapper for a `va_list` -#[repr(transparent)] +#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 #[derive(Debug)] #[unstable( feature = "c_variadic", diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 808825326ae..7043ab5ff2b 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -232,7 +232,7 @@ impl fmt::Debug for Context<'_> { /// /// [`Future::poll()`]: core::future::Future::poll /// [`Poll::Pending`]: core::task::Poll::Pending -#[repr(transparent)] +#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/66401 #[stable(feature = "futures_api", since = "1.36.0")] pub struct Waker { waker: RawWaker, diff --git a/library/portable-simd/crates/core_simd/src/masks.rs b/library/portable-simd/crates/core_simd/src/masks.rs index e58df80fca8..e0f3c7beef6 100644 --- a/library/portable-simd/crates/core_simd/src/masks.rs +++ b/library/portable-simd/crates/core_simd/src/masks.rs @@ -88,7 +88,7 @@ impl_element! { isize } /// The layout of this type is unspecified, and may change between platforms /// and/or Rust versions, and code should not assume that it is equivalent to /// `[T; LANES]`. -#[repr(transparent)] +#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/90435 pub struct Mask(mask_impl::Mask) where T: MaskElement, From c3efa51947c3b14652d1e85dd3bb406522c8af22 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 16 May 2023 19:23:38 +0200 Subject: [PATCH 42/52] Remove `LangItems::require` It's just a short wrapper used by `tcx.require_lang_item`. Deleting it gives us a negative diff. --- compiler/rustc_codegen_cranelift/src/base.rs | 6 +----- compiler/rustc_hir/src/errors.rs | 10 ---------- compiler/rustc_hir/src/lang_items.rs | 8 -------- compiler/rustc_hir/src/lib.rs | 1 - compiler/rustc_hir_analysis/src/coherence/builtin.rs | 4 +--- compiler/rustc_middle/messages.ftl | 2 ++ compiler/rustc_middle/src/error.rs | 10 +++++++++- compiler/rustc_middle/src/middle/lang_items.rs | 8 ++------ .../src/matches/redundant_pattern_match.rs | 9 +++++---- 9 files changed, 20 insertions(+), 38 deletions(-) delete mode 100644 compiler/rustc_hir/src/errors.rs diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index e9dbea1be67..25fd5ca3ae8 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -966,11 +966,7 @@ fn codegen_panic_inner<'tcx>( args: &[Value], span: Span, ) { - let def_id = fx - .tcx - .lang_items() - .require(lang_item) - .unwrap_or_else(|e| fx.tcx.sess.span_fatal(span, e.to_string())); + let def_id = fx.tcx.require_lang_item(lang_item, Some(span)); let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx); let symbol_name = fx.tcx.symbol_name(instance).name; diff --git a/compiler/rustc_hir/src/errors.rs b/compiler/rustc_hir/src/errors.rs deleted file mode 100644 index e593ed1044a..00000000000 --- a/compiler/rustc_hir/src/errors.rs +++ /dev/null @@ -1,10 +0,0 @@ -use crate::LangItem; - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)] -pub struct LangItemError(pub LangItem); - -impl ToString for LangItemError { - fn to_string(&self) -> String { - format!("requires `{}` lang_item", self.0.name()) - } -} diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 1f08befb180..4b3bc816b95 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -8,7 +8,6 @@ //! * Functions called by the compiler itself. use crate::def_id::DefId; -use crate::errors::LangItemError; use crate::{MethodKind, Target}; use rustc_ast as ast; @@ -42,13 +41,6 @@ impl LanguageItems { self.items[item as usize] = Some(def_id); } - /// Requires that a given `LangItem` was bound and returns the corresponding `DefId`. - /// If it wasn't bound, e.g. due to a missing `#[lang = ""]`, - /// returns an error encapsulating the `LangItem`. - pub fn require(&self, it: LangItem) -> Result { - self.get(it).ok_or_else(|| LangItemError(it)) - } - pub fn iter(&self) -> impl Iterator + '_ { self.items .iter() diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs index 98d967cc0b8..616de57dc63 100644 --- a/compiler/rustc_hir/src/lib.rs +++ b/compiler/rustc_hir/src/lib.rs @@ -30,7 +30,6 @@ pub mod def; pub mod def_path_hash_map; pub mod definitions; pub mod diagnostic_items; -pub mod errors; pub use rustc_span::def_id; mod hir; pub mod hir_id; diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index d05d8508408..a98d8e17153 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -298,9 +298,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span)); - let unsize_trait = tcx.lang_items().require(LangItem::Unsize).unwrap_or_else(|err| { - tcx.sess.fatal(format!("`CoerceUnsized` implementation {}", err.to_string())); - }); + let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span)); let source = tcx.type_of(impl_did).subst_identity(); let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity(); diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl index c6bbf2ef0cd..64d511c261a 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -39,5 +39,7 @@ middle_strict_coherence_needs_negative_coherence = to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled .label = due to this attribute +middle_requires_lang_item = requires `{$name}` lang_item + middle_const_not_used_in_type_alias = const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index dc4aa18640f..046186d274c 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -1,5 +1,5 @@ use rustc_macros::Diagnostic; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use crate::ty::Ty; @@ -73,6 +73,14 @@ pub(crate) struct StrictCoherenceNeedsNegativeCoherence { pub attr_span: Option, } +#[derive(Diagnostic)] +#[diag(middle_requires_lang_item)] +pub(crate) struct RequiresLangItem { + #[primary_span] + pub span: Option, + pub name: Symbol, +} + #[derive(Diagnostic)] #[diag(middle_const_not_used_in_type_alias)] pub(super) struct ConstNotUsedTraitAlias { diff --git a/compiler/rustc_middle/src/middle/lang_items.rs b/compiler/rustc_middle/src/middle/lang_items.rs index 343ea1f00f5..9a633e04ce7 100644 --- a/compiler/rustc_middle/src/middle/lang_items.rs +++ b/compiler/rustc_middle/src/middle/lang_items.rs @@ -18,12 +18,8 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns the `DefId` for a given `LangItem`. /// If not found, fatally aborts compilation. pub fn require_lang_item(self, lang_item: LangItem, span: Option) -> DefId { - self.lang_items().require(lang_item).unwrap_or_else(|err| { - if let Some(span) = span { - self.sess.span_fatal(span, err.to_string()) - } else { - self.sess.fatal(err.to_string()) - } + self.lang_items().get(lang_item).unwrap_or_else(|| { + self.sess.emit_fatal(crate::error::RequiresLangItem { span, name: lang_item.name() }); }) } diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs index af121f317cd..0809837d1fd 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs @@ -289,10 +289,11 @@ fn is_pat_variant(cx: &LateContext<'_>, pat: &Pat<'_>, path: &QPath<'_>, expecte let Some(id) = cx.typeck_results().qpath_res(path, pat.hir_id).opt_def_id() else { return false }; match expected_item { - Item::Lang(expected_lang_item) => { - let expected_id = cx.tcx.lang_items().require(expected_lang_item).unwrap(); - cx.tcx.parent(id) == expected_id - }, + Item::Lang(expected_lang_item) => cx + .tcx + .lang_items() + .get(expected_lang_item) + .map_or(false, |expected_id| cx.tcx.parent(id) == expected_id), Item::Diag(expected_ty, expected_variant) => { let ty = cx.typeck_results().pat_ty(pat); From 0336dd132b50af57389aa222793aff3c38b88daf Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 16 May 2023 19:40:02 +0200 Subject: [PATCH 43/52] Add derive for `core::marker::ConstParamTy` This makes it easier to implement it for a type, just like `Copy`. --- .../src/deriving/bounds.rs | 23 +++++++++++++ compiler/rustc_builtin_macros/src/lib.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + library/core/src/marker.rs | 8 +++++ .../adt_const_params/const_param_ty_good.rs | 10 ++++++ .../const_param_ty_impl_bad_field.rs | 4 +++ .../const_param_ty_impl_bad_field.stderr | 13 +++++++- .../const_param_ty_impl_no_structural_eq.rs | 4 +++ ...onst_param_ty_impl_no_structural_eq.stderr | 12 ++++++- .../const_param_ty_impl_union.rs | 33 +++++++++++++++++++ .../const_param_ty_impl_union.stderr | 8 +++++ 11 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs create mode 100644 tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs index 0481a118906..2c8e6f99c67 100644 --- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs +++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs @@ -27,3 +27,26 @@ pub fn expand_deriving_copy( trait_def.expand(cx, mitem, item, push); } + +pub fn expand_deriving_const_param_ty( + cx: &mut ExtCtxt<'_>, + span: Span, + mitem: &MetaItem, + item: &Annotatable, + push: &mut dyn FnMut(Annotatable), + is_const: bool, +) { + let trait_def = TraitDef { + span, + path: path_std!(marker::ConstParamTy), + skip_path_as_bound: false, + needs_copy_as_bound_if_packed: false, + additional_bounds: Vec::new(), + supports_unions: false, + methods: Vec::new(), + associated_types: Vec::new(), + is_const, + }; + + trait_def.expand(cx, mitem, item, push); +} diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 4e5edb4d6b1..ebf1448f55c 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -115,6 +115,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { register_derive! { Clone: clone::expand_deriving_clone, Copy: bounds::expand_deriving_copy, + ConstParamTy: bounds::expand_deriving_const_param_ty, Debug: debug::expand_deriving_debug, Default: default::expand_deriving_default, Eq: eq::expand_deriving_eq, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 60efcb768cb..b3e54b10900 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -164,6 +164,7 @@ symbols! { Capture, Center, Clone, + ConstParamTy, Context, Continue, Copy, diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 97f9d01e016..ede0e5db50c 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -991,6 +991,14 @@ pub trait PointerLike {} #[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")] pub trait ConstParamTy: StructuralEq {} +/// Derive macro generating an impl of the trait `Copy`. +#[rustc_builtin_macro] +#[unstable(feature = "adt_const_params", issue = "95174")] +#[cfg(not(bootstrap))] +pub macro ConstParamTy($item:item) { + /* compiler built-in */ +} + // FIXME(generic_const_parameter_types): handle `ty::FnDef`/`ty::Closure` // FIXME(generic_const_parameter_types): handle `ty::Tuple` marker_impls! { diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs index a1b711a3024..87ae83dd966 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs @@ -11,6 +11,13 @@ struct S { impl ConstParamTy for S {} +#[derive(PartialEq, Eq, ConstParamTy)] +struct D { + field: u8, + gen: T, +} + + fn check() {} fn main() { @@ -39,5 +46,8 @@ fn main() { check::>(); check::>(); + check::>(); + check::>(); + // FIXME: test tuples } diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs index 07fd243737e..74283a37afc 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.rs @@ -10,4 +10,8 @@ struct CantParam(NotParam); impl std::marker::ConstParamTy for CantParam {} //~^ error: the trait `ConstParamTy` cannot be implemented for this type +#[derive(std::marker::ConstParamTy, Eq, PartialEq)] +//~^ error: the trait `ConstParamTy` cannot be implemented for this type +struct CantParamDerive(NotParam); + fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr index c8e065848b1..52b65d6061a 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_bad_field.stderr @@ -7,6 +7,17 @@ LL | LL | impl std::marker::ConstParamTy for CantParam {} | ^^^^^^^^^ -error: aborting due to previous error +error[E0204]: the trait `ConstParamTy` cannot be implemented for this type + --> $DIR/const_param_ty_impl_bad_field.rs:13:10 + | +LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | struct CantParamDerive(NotParam); + | -------- this field does not implement `ConstParamTy` + | + = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0204`. diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs index 17ef396164e..37986de481f 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs @@ -10,6 +10,10 @@ struct CantParam(ImplementsConstParamTy); impl std::marker::ConstParamTy for CantParam {} //~^ error: the type `CantParam` does not `#[derive(Eq)]` +#[derive(std::marker::ConstParamTy)] +//~^ error: the type `CantParamDerive` does not `#[derive(Eq)]` +struct CantParamDerive(ImplementsConstParamTy); + fn check() {} fn main() { diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr index ca5abf5e254..52701d55914 100644 --- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr @@ -7,6 +7,16 @@ LL | impl std::marker::ConstParamTy for CantParam {} note: required by a bound in `ConstParamTy` --> $SRC_DIR/core/src/marker.rs:LL:COL -error: aborting due to previous error +error[E0277]: the type `CantParamDerive` does not `#[derive(Eq)]` + --> $DIR/const_param_ty_impl_no_structural_eq.rs:13:10 + | +LL | #[derive(std::marker::ConstParamTy)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralEq` is not implemented for `CantParamDerive` + | +note: required by a bound in `ConstParamTy` + --> $SRC_DIR/core/src/marker.rs:LL:COL + = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs new file mode 100644 index 00000000000..d70377a20c1 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs @@ -0,0 +1,33 @@ +#![allow(incomplete_features)] +#![feature(adt_const_params, structural_match)] + +union Union { + a: u8, +} + +impl PartialEq for Union { + fn eq(&self, other: &Union) -> bool { + true + } +} +impl Eq for Union {} +impl std::marker::StructuralEq for Union {} + +impl std::marker::ConstParamTy for Union {} + +#[derive(std::marker::ConstParamTy)] +//~^ ERROR this trait cannot be derived for unions +union UnionDerive { + a: u8, +} + +impl PartialEq for UnionDerive { + fn eq(&self, other: &UnionDerive) -> bool { + true + } +} +impl Eq for UnionDerive {} +impl std::marker::StructuralEq for UnionDerive {} + + +fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr new file mode 100644 index 00000000000..29370304605 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr @@ -0,0 +1,8 @@ +error: this trait cannot be derived for unions + --> $DIR/const_param_ty_impl_union.rs:18:10 + | +LL | #[derive(std::marker::ConstParamTy)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From ffacb8861a860e5797e2835668336e60147ef454 Mon Sep 17 00:00:00 2001 From: JoJoJet <21144246+JoJoJet@users.noreply.github.com> Date: Tue, 16 May 2023 15:36:05 -0400 Subject: [PATCH 44/52] add `UnsafeCell::from_mut` --- compiler/rustc_span/src/symbol.rs | 1 + library/core/src/cell.rs | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9951d8f4fc1..02505457efa 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1583,6 +1583,7 @@ symbols! { unrestricted_attribute_tokens, unsafe_block_in_unsafe_fn, unsafe_cell, + unsafe_cell_from_mut, unsafe_no_drop_flag, unsafe_pin_internals, unsize, diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 2c3c14853a4..744767aae44 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -2030,6 +2030,27 @@ impl UnsafeCell { } impl UnsafeCell { + /// Converts from `&mut T` to `&mut UnsafeCell`. + /// + /// # Examples + /// + /// ``` + /// # #![feature(unsafe_cell_from_mut)] + /// use std::cell::UnsafeCell; + /// + /// let mut val = 42; + /// let uc = UnsafeCell::from_mut(&mut val); + /// + /// *uc.get_mut() -= 1; + /// assert_eq!(*uc.get_mut(), 41); + /// ``` + #[inline(always)] + #[unstable(feature = "unsafe_cell_from_mut", issue = "111645")] + pub const fn from_mut(value: &mut T) -> &mut UnsafeCell { + // SAFETY: `UnsafeCell` has the same memory layout as `T` due to #[repr(transparent)]. + unsafe { &mut *(value as *mut T as *mut UnsafeCell) } + } + /// Gets a mutable pointer to the wrapped value. /// /// This can be cast to a pointer of any kind. From 35cf5726e3a7a16d97243bc6c23ff8173e2119de Mon Sep 17 00:00:00 2001 From: clubby789 Date: Tue, 16 May 2023 21:36:42 +0000 Subject: [PATCH 45/52] Erase regions of type in `offset_of!` --- compiler/rustc_mir_build/src/build/expr/as_rvalue.rs | 7 ++++--- tests/ui/offset-of/offset-of-arg-count.rs | 5 +++++ 2 files changed, 9 insertions(+), 3 deletions(-) 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 c385b00692f..0105a265ffb 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -481,9 +481,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { })))) } - ExprKind::OffsetOf { container, fields } => { - block.and(Rvalue::NullaryOp(NullOp::OffsetOf(fields), container)) - } + ExprKind::OffsetOf { container, fields } => block.and(Rvalue::NullaryOp( + NullOp::OffsetOf(fields), + this.tcx.erase_regions(container), + )), ExprKind::Literal { .. } | ExprKind::NamedConst { .. } diff --git a/tests/ui/offset-of/offset-of-arg-count.rs b/tests/ui/offset-of/offset-of-arg-count.rs index 5e66e33f8a2..92a205f14d9 100644 --- a/tests/ui/offset-of/offset-of-arg-count.rs +++ b/tests/ui/offset-of/offset-of-arg-count.rs @@ -12,6 +12,11 @@ fn main() { offset_of!(S, f.,); //~ ERROR expected identifier offset_of!(S, f..); //~ ERROR no rules expected the token offset_of!(S, f..,); //~ ERROR no rules expected the token + offset_of!(Lt<'static>, bar); // issue #111657 + } struct S { f: u8, } +struct Lt<'a> { + bar: &'a (), +} From d169581ea75ab0b52279dcaebe7cdfd09da4be92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 16 May 2023 01:15:32 +0200 Subject: [PATCH 46/52] Move rustc_middle/src/ty/query.rs to rustc_middle/src/query/plumbing.rs --- compiler/rustc_middle/src/{ty/query.rs => query/plumbing.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename compiler/rustc_middle/src/{ty/query.rs => query/plumbing.rs} (100%) diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/query/plumbing.rs similarity index 100% rename from compiler/rustc_middle/src/ty/query.rs rename to compiler/rustc_middle/src/query/plumbing.rs From 54b582a0e8093844bfd42a5f5761212730e7ce05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Tue, 16 May 2023 01:53:21 +0200 Subject: [PATCH 47/52] Finish move of query.rs --- compiler/rustc_const_eval/src/const_eval/error.rs | 3 ++- .../rustc_const_eval/src/interpret/eval_context.rs | 5 ++--- compiler/rustc_middle/src/lib.rs | 1 - compiler/rustc_middle/src/mir/interpret/error.rs | 3 ++- compiler/rustc_middle/src/mir/interpret/queries.rs | 3 ++- compiler/rustc_middle/src/query/mod.rs | 10 +++++----- compiler/rustc_middle/src/ty/context.rs | 8 +++----- compiler/rustc_middle/src/ty/context/tls.rs | 4 ++-- compiler/rustc_middle/src/ty/layout.rs | 9 +++++---- compiler/rustc_middle/src/ty/mod.rs | 2 -- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 2 +- compiler/rustc_monomorphize/src/lib.rs | 3 +-- compiler/rustc_query_impl/src/lib.rs | 2 +- compiler/rustc_query_impl/src/plumbing.rs | 3 +-- compiler/rustc_query_impl/src/profiling_support.rs | 2 +- 16 files changed, 29 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs index 5037c210e7d..c591ff75ab8 100644 --- a/compiler/rustc_const_eval/src/const_eval/error.rs +++ b/compiler/rustc_const_eval/src/const_eval/error.rs @@ -3,7 +3,8 @@ use std::fmt; use rustc_errors::Diagnostic; use rustc_middle::mir::AssertKind; -use rustc_middle::ty::{layout::LayoutError, query::TyCtxtAt, ConstInt}; +use rustc_middle::query::TyCtxtAt; +use rustc_middle::ty::{layout::LayoutError, ConstInt}; use rustc_span::{Span, Symbol}; use super::InterpCx; diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 2fa63dc8c93..040eba10eb4 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -8,13 +8,12 @@ use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; use rustc_index::IndexVec; use rustc_middle::mir; use rustc_middle::mir::interpret::{ErrorHandled, InterpError, ReportedErrorInfo}; +use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{ self, FnAbiError, FnAbiOfHelpers, FnAbiRequest, LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout, }; -use rustc_middle::ty::{ - self, query::TyCtxtAt, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable, -}; +use rustc_middle::ty::{self, subst::SubstsRef, ParamEnv, Ty, TyCtxt, TypeFoldable}; use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_session::Limit; use rustc_span::Span; diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index dc911c88574..22ee2a8c5e5 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -95,7 +95,6 @@ pub mod middle; pub mod mir; pub mod thir; pub mod traits; -#[macro_use] pub mod ty; pub mod util; mod values; diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index d65ceef2472..055d8e9a352 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -1,7 +1,8 @@ use super::{AllocId, AllocRange, ConstAlloc, Pointer, Scalar}; use crate::mir::interpret::ConstValue; -use crate::ty::{layout, query::TyCtxtAt, tls, Ty, ValTree}; +use crate::query::TyCtxtAt; +use crate::ty::{layout, tls, Ty, ValTree}; use rustc_data_structures::sync::Lock; use rustc_errors::{pluralize, struct_span_err, DiagnosticBuilder, ErrorGuaranteed}; diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index ce11dabc195..f53dc8cb0ec 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -1,9 +1,10 @@ use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId}; use crate::mir; +use crate::query::{TyCtxtAt, TyCtxtEnsure}; use crate::ty::subst::InternalSubsts; use crate::ty::visit::TypeVisitableExt; -use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt}; +use crate::ty::{self, TyCtxt}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_session::lint; diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f564f5e99e8..21c69662b9e 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -25,6 +25,7 @@ use crate::mir::interpret::{ use crate::mir::interpret::{LitToConstError, LitToConstInput}; use crate::mir::mono::CodegenUnit; use crate::query::erase::{erase, restore, Erase}; +use crate::query::plumbing::{query_ensure, query_get_at, DynamicQuery}; use crate::thir; use crate::traits::query::{ CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, @@ -39,10 +40,6 @@ use crate::traits::specialization_graph; use crate::traits::{self, ImplSource}; use crate::ty::fast_reject::SimplifiedType; use crate::ty::layout::ValidityRequirement; -use crate::ty::query::{ - query_ensure, query_get_at, DynamicQuery, IntoQueryParam, TyCtxtAt, TyCtxtEnsure, - TyCtxtEnsureWithValue, -}; use crate::ty::subst::{GenericArg, SubstsRef}; use crate::ty::util::AlwaysRequiresDrop; use crate::ty::GeneratorDiagnosticData; @@ -90,8 +87,11 @@ use std::sync::Arc; pub mod erase; mod keys; -pub mod on_disk_cache; pub use keys::{AsLocalKey, Key, LocalCrate}; +pub mod on_disk_cache; +#[macro_use] +pub mod plumbing; +pub use plumbing::{IntoQueryParam, TyCtxtAt, TyCtxtEnsure, TyCtxtEnsureWithValue}; // Each of these queries corresponds to a function pointer field in the // `Providers` struct for requesting a value of that type, and a method diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 097bfb71a6f..e84d0100a5c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -14,14 +14,14 @@ use crate::middle::resolve_bound_vars; use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstAllocation}; use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted}; +use crate::query::plumbing::QuerySystem; use crate::query::LocalCrate; use crate::query::Providers; +use crate::query::{IntoQueryParam, TyCtxtAt}; use crate::thir::Thir; use crate::traits; use crate::traits::solve; use crate::traits::solve::{ExternalConstraints, ExternalConstraintsData}; -use crate::ty::query::QuerySystem; -use crate::ty::query::{self, TyCtxtAt}; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, Const, ConstData, FloatTy, FloatVar, FloatVid, GenericParamDefKind, ImplPolarity, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, @@ -80,8 +80,6 @@ use std::iter; use std::mem; use std::ops::{Bound, Deref}; -use super::query::IntoQueryParam; - const TINY_CONST_EVAL_LIMIT: Limit = Limit(20); #[allow(rustc::usage_of_ty_tykind)] @@ -512,7 +510,7 @@ pub struct GlobalCtxt<'tcx> { untracked: Untracked, - pub query_system: query::QuerySystem<'tcx>, + pub query_system: QuerySystem<'tcx>, pub(crate) query_kinds: &'tcx [DepKindStruct<'tcx>], // Internal caches for metadata decoding. No need to track deps on this. diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs index bf9806f6406..5c1c419811e 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -1,7 +1,7 @@ use super::{GlobalCtxt, TyCtxt}; use crate::dep_graph::TaskDepsRef; -use crate::ty::query; +use crate::query::plumbing::QueryJobId; use rustc_data_structures::sync::{self, Lock}; use rustc_errors::Diagnostic; #[cfg(not(parallel_compiler))] @@ -22,7 +22,7 @@ pub struct ImplicitCtxt<'a, 'tcx> { /// The current query job, if any. This is updated by `JobOwner::start` in /// `ty::query::plumbing` when executing a query. - pub query: Option, + pub query: Option, /// Where to store diagnostics for the current query job, if any. /// This is updated by `JobOwner::start` in `ty::query::plumbing` when executing a query. diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 47cf48f46cf..ba91e5aea5a 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1,5 +1,6 @@ use crate::fluent_generated as fluent; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; +use crate::query::TyCtxtAt; use crate::ty::normalize_erasing_regions::NormalizationError; use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitableExt}; use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic}; @@ -543,20 +544,20 @@ impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> { } } -impl<'tcx> HasDataLayout for ty::query::TyCtxtAt<'tcx> { +impl<'tcx> HasDataLayout for TyCtxtAt<'tcx> { #[inline] fn data_layout(&self) -> &TargetDataLayout { &self.data_layout } } -impl<'tcx> HasTargetSpec for ty::query::TyCtxtAt<'tcx> { +impl<'tcx> HasTargetSpec for TyCtxtAt<'tcx> { fn target_spec(&self) -> &Target { &self.sess.target } } -impl<'tcx> HasTyCtxt<'tcx> for ty::query::TyCtxtAt<'tcx> { +impl<'tcx> HasTyCtxt<'tcx> for TyCtxtAt<'tcx> { #[inline] fn tcx(&self) -> TyCtxt<'tcx> { **self @@ -683,7 +684,7 @@ impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxt<'tcx>> { } } -impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { +impl<'tcx> LayoutOfHelpers<'tcx> for LayoutCx<'tcx, TyCtxtAt<'tcx>> { type LayoutOfResult = Result, LayoutError<'tcx>>; #[inline] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index df324bcc52c..be0d1e61a46 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -122,8 +122,6 @@ pub mod inhabitedness; pub mod layout; pub mod normalize_erasing_regions; pub mod print; -#[macro_use] -pub mod query; pub mod relate; pub mod subst; pub mod trait_def; diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 385156262c7..048d873fb68 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1,6 +1,6 @@ use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; +use crate::query::IntoQueryParam; use crate::query::Providers; -use crate::ty::query::IntoQueryParam; use crate::ty::{ self, ConstInt, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 55c937b305a..35b154b7b34 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -185,9 +185,9 @@ use rustc_middle::mir::interpret::{ErrorHandled, GlobalAlloc, Scalar}; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; use rustc_middle::mir::visit::Visitor as MirVisitor; use rustc_middle::mir::{self, Local, Location}; +use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::query::TyCtxtAt; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{ self, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 1c18e6b0b02..ecc50c3f664 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -12,10 +12,9 @@ extern crate rustc_middle; use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_fluent_macro::fluent_messages; use rustc_hir::lang_items::LangItem; -use rustc_middle::query::Providers; +use rustc_middle::query::{Providers, TyCtxtAt}; use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; -use rustc_middle::ty::query::TyCtxtAt; use rustc_middle::ty::{self, Ty}; mod collector; diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 3c542821b67..b76734dd072 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -24,12 +24,12 @@ use rustc_middle::dep_graph::DepNodeIndex; use rustc_middle::dep_graph::{self, DepKind, DepKindStruct}; use rustc_middle::query::erase::{erase, restore, Erase}; use rustc_middle::query::on_disk_cache::OnDiskCache; +use rustc_middle::query::plumbing::{DynamicQuery, QuerySystem, QuerySystemFns}; use rustc_middle::query::AsLocalKey; use rustc_middle::query::{ query_keys, query_provided, query_provided_to_value, query_storage, query_values, DynamicQueries, ExternProviders, Providers, QueryCaches, QueryEngine, QueryStates, }; -use rustc_middle::ty::query::{DynamicQuery, QuerySystem, QuerySystemFns}; use rustc_middle::ty::TyCtxt; use rustc_query_system::dep_graph::SerializedDepNodeIndex; use rustc_query_system::ich::StableHashingContext; diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index 5acfeb47a12..79d8abc4b69 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -716,8 +716,7 @@ macro_rules! define_queries { mod query_structs { use super::*; - use rustc_middle::ty::query::QueryStruct; - use rustc_middle::ty::query::QueryKeyStringCache; + use rustc_middle::query::plumbing::{QueryKeyStringCache, QueryStruct}; use rustc_middle::dep_graph::DepKind; use crate::QueryConfigRestored; diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs index 7d9306f8087..e042ee62dfe 100644 --- a/compiler/rustc_query_impl/src/profiling_support.rs +++ b/compiler/rustc_query_impl/src/profiling_support.rs @@ -2,7 +2,7 @@ use measureme::{StringComponent, StringId}; use rustc_data_structures::profiling::SelfProfiler; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE}; use rustc_hir::definitions::DefPathData; -use rustc_middle::ty::query::QueryKeyStringCache; +use rustc_middle::query::plumbing::QueryKeyStringCache; use rustc_middle::ty::TyCtxt; use rustc_query_system::query::QueryCache; use std::fmt::Debug; From 41a0286afce74a2013fd8eb888087f1aba80062a Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Wed, 17 May 2023 01:32:31 +0100 Subject: [PATCH 48/52] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 13413c64ff8..09276c703a4 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 13413c64ff88dd6c2824e9eb9374fc5f10895d28 +Subproject commit 09276c703a473ab33daaeb94917232e80eefd628 From c544fc3584cc76824b9adfb5db490db581ddbbea Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 17 May 2023 10:35:12 +0200 Subject: [PATCH 49/52] Update to LLVM 16.0.4 --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index ea6fa9c2d43..533d3f338b8 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit ea6fa9c2d43aaf0f11559719eda9b54d356d5416 +Subproject commit 533d3f338b804d54e5d0ac4fba6276af23002d9c From db645124221a1e2d3e70b14fbedef019e036c066 Mon Sep 17 00:00:00 2001 From: mu001999 Date: Wed, 17 May 2023 16:59:39 +0800 Subject: [PATCH 50/52] Emits E0599 when meeting MyTrait::missing_method --- compiler/rustc_errors/src/lib.rs | 1 + .../rustc_hir_analysis/src/astconv/mod.rs | 7 +- compiler/rustc_hir_typeck/messages.ftl | 11 +++ compiler/rustc_hir_typeck/src/errors.rs | 24 ++++++ compiler/rustc_hir_typeck/src/expr.rs | 1 + .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 26 +++++- .../rustc_hir_typeck/src/method/suggest.rs | 85 ++++++++++++------- tests/ui/resolve/issue-111312.rs | 11 +++ tests/ui/resolve/issue-111312.stderr | 15 ++++ tests/ui/traits/issue-106072.rs | 1 - tests/ui/traits/issue-106072.stderr | 12 +-- 11 files changed, 147 insertions(+), 47 deletions(-) create mode 100644 tests/ui/resolve/issue-111312.rs create mode 100644 tests/ui/resolve/issue-111312.stderr diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 22c41f7b93f..0f360473619 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -478,6 +478,7 @@ pub enum StashKey { /// FRU syntax MaybeFruTypo, CallAssocMethod, + TraitMissingMethod, } fn default_track_diagnostic(d: &mut Diagnostic, f: &mut dyn FnMut(&mut Diagnostic)) { diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 6ac1df6a079..deba12cb59f 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -19,7 +19,7 @@ use rustc_ast::TraitObjectSyntax; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{ struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, FatalError, - MultiSpan, + MultiSpan, StashKey, }; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; @@ -38,7 +38,6 @@ use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt} use rustc_middle::ty::{DynKind, ToPredicate}; use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS}; use rustc_span::edit_distance::find_best_match_for_name; -use rustc_span::edition::Edition; use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::{sym, Span, DUMMY_SP}; use rustc_target::spec::abi; @@ -3718,7 +3717,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { )); } - if self_ty.span.edition() >= Edition::Edition2021 { + if self_ty.span.edition().rust_2021() { let msg = "trait objects must include the `dyn` keyword"; let label = "add `dyn` keyword before this trait"; let mut diag = @@ -3732,7 +3731,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } // check if the impl trait that we are considering is a impl of a local trait self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag); - diag.emit(); + diag.stash(self_ty.span, StashKey::TraitMissingMethod); } else { let msg = "trait objects without an explicit `dyn` are deprecated"; tcx.struct_span_lint_hir( diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index aa664031a87..4a669e3f8b8 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -79,3 +79,14 @@ hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but hir_typeck_suggest_boxing_note = for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html hir_typeck_suggest_boxing_when_appropriate = store this in the heap by calling `Box::new` + +hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method -> + [true] {""} + *[other] {" "}in the current scope +} + +hir_typeck_candidate_trait_note = `{$trait_name}` defines an item `{$item_name}`{$action_or_ty -> + [NONE] {""} + [implement] , perhaps you need to implement it + *[other] , perhaps you need to restrict type parameter `{$action_or_ty}` with it +} diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index ce30bbeca0b..102a313067f 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -1,4 +1,6 @@ //! Errors emitted by `rustc_hir_typeck`. +use std::borrow::Cow; + use crate::fluent_generated as fluent; use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage}; use rustc_macros::{Diagnostic, Subdiagnostic}; @@ -295,3 +297,25 @@ pub enum SuggestBoxing { end: Span, }, } + +#[derive(Diagnostic)] +#[diag(hir_typeck_no_associated_item, code = "E0599")] +pub struct NoAssociatedItem { + #[primary_span] + pub span: Span, + pub item_kind: &'static str, + pub item_name: Ident, + pub ty_prefix: Cow<'static, str>, + pub ty_str: String, + pub trait_missing_method: bool, +} + +#[derive(Subdiagnostic)] +#[note(hir_typeck_candidate_trait_note)] +pub struct CandidateTraitNote { + #[primary_span] + pub span: Span, + pub trait_name: String, + pub item_name: Ident, + pub action_or_ty: String, +} diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index bba049c3819..8ea159bba74 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1245,6 +1245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error, Some((rcvr, args)), expected, + false, ) { err.emit(); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 9e78e6acba5..039316c74dd 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -4,7 +4,7 @@ use crate::rvalue_scopes; use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy, RawTy}; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; @@ -853,6 +853,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let item_name = item_segment.ident; let result = self .resolve_fully_qualified_call(span, item_name, ty.normalized, qself.span, hir_id) + .and_then(|r| { + // lint bare trait if the method is found in the trait + if span.edition().rust_2021() && let Some(mut diag) = self.tcx.sess.diagnostic().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) { + diag.emit(); + } + Ok(r) + }) .or_else(|error| { let guar = self .tcx @@ -863,17 +870,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => Err(guar), }; + let trait_missing_method = + matches!(error, method::MethodError::NoMatch(_)) && ty.normalized.is_trait(); // If we have a path like `MyTrait::missing_method`, then don't register // a WF obligation for `dyn MyTrait` when method lookup fails. Otherwise, // register a WF obligation so that we can detect any additional // errors in the self type. - if !(matches!(error, method::MethodError::NoMatch(_)) && ty.normalized.is_trait()) { + if !trait_missing_method { self.register_wf_obligation( ty.raw.into(), qself.span, traits::WellFormed(None), ); } + + // emit or cancel the diagnostic for bare traits + if span.edition().rust_2021() && let Some(mut diag) = self.tcx.sess.diagnostic().steal_diagnostic(qself.span, StashKey::TraitMissingMethod) { + if trait_missing_method { + // cancel the diag for bare traits when meeting `MyTrait::missing_method` + diag.cancel(); + } else { + diag.emit(); + } + } + if item_name.name != kw::Empty { if let Some(mut e) = self.report_method_error( span, @@ -883,10 +903,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error, None, Expectation::NoExpectation, + trait_missing_method && span.edition().rust_2021(), // emits missing method for trait only after edition 2021 ) { e.emit(); } } + result }); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 486c217707e..87a36ce4ff9 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2,6 +2,8 @@ //! found or is otherwise invalid. use crate::errors; +use crate::errors::CandidateTraitNote; +use crate::errors::NoAssociatedItem; use crate::Expectation; use crate::FnCtxt; use rustc_ast::ast::Mutability; @@ -38,6 +40,7 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _ use rustc_trait_selection::traits::{ FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, }; +use std::borrow::Cow; use super::probe::{AutorefOrPtrAdjustment, IsSuggestion, Mode, ProbeScope}; use super::{CandidateSource, MethodError, NoMatchData}; @@ -112,6 +115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error: MethodError<'tcx>, args: Option<(&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>])>, expected: Expectation<'tcx>, + trait_missing_method: bool, ) -> Option> { // Avoid suggestions when we don't know what's going on. if rcvr_ty.references_error() { @@ -136,6 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sugg_span, &mut no_match_data, expected, + trait_missing_method, ); } @@ -278,6 +283,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sugg_span: Span, no_match_data: &mut NoMatchData<'tcx>, expected: Expectation<'tcx>, + trait_missing_method: bool, ) -> Option> { let mode = no_match_data.mode; let tcx = self.tcx; @@ -323,7 +329,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span = item_name.span; // Don't show generic arguments when the method can't be found in any implementation (#81576). - let mut ty_str_reported = ty_str.clone(); + let mut ty_str_reported = if trait_missing_method { + ty_str.strip_prefix("dyn ").expect("Failed to remove the prefix dyn").to_owned() + } else { + ty_str.clone() + }; + if let ty::Adt(_, generics) = rcvr_ty.kind() { if generics.len() > 0 { let mut autoderef = self.autoderef(span, rcvr_ty); @@ -355,25 +366,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { self.suggest_missing_writer(rcvr_ty, args) } else { - struct_span_err!( - tcx.sess, + tcx.sess.create_err(NoAssociatedItem { span, - E0599, - "no {} named `{}` found for {} `{}` in the current scope", item_kind, item_name, - rcvr_ty.prefix_string(self.tcx), - ty_str_reported, - ) + ty_prefix: if trait_missing_method { + // FIXME(mu001999) E0599 maybe not suitable here because it is for types + Cow::from("trait") + } else { + rcvr_ty.prefix_string(self.tcx) + }, + ty_str: ty_str_reported, + trait_missing_method, + }) }; if tcx.sess.source_map().is_multiline(sugg_span) { err.span_label(sugg_span.with_hi(span.lo()), ""); } - let ty_str = if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 { + let mut ty_str = if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 { short_ty_str } else { ty_str }; + if trait_missing_method { + ty_str = + ty_str.strip_prefix("dyn ").expect("Failed to remove the prefix dyn").to_owned(); + } + if let Some(file) = ty_file { err.note(format!("the full type name has been written to '{}'", file.display(),)); } @@ -1067,6 +1086,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &static_candidates, unsatisfied_bounds, expected.only_has_type(self), + trait_missing_method, ); } @@ -2375,6 +2395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { static_candidates: &[CandidateSource], unsatisfied_bounds: bool, return_type: Option>, + trait_missing_method: bool, ) { let mut alt_rcvr_sugg = false; if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) { @@ -2598,11 +2619,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, _ => None, }; - err.help(if param_type.is_some() { - "items from traits can only be used if the type parameter is bounded by the trait" - } else { - "items from traits can only be used if the trait is implemented and in scope" - }); + if !trait_missing_method { + err.help(if param_type.is_some() { + "items from traits can only be used if the type parameter is bounded by the trait" + } else { + "items from traits can only be used if the trait is implemented and in scope" + }); + } + let candidates_len = candidates.len(); let message = |action| { format!( @@ -2736,27 +2760,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (candidates, Vec::new()) }; - let action = if let Some(param) = param_type { - format!("restrict type parameter `{}` with", param) - } else { - // FIXME: it might only need to be imported into scope, not implemented. - "implement".to_string() - }; match &potential_candidates[..] { [] => {} [trait_info] if trait_info.def_id.is_local() => { - err.span_note( - self.tcx.def_span(trait_info.def_id), - format!( - "`{}` defines an item `{}`, perhaps you need to {} it", - self.tcx.def_path_str(trait_info.def_id), - item_name, - action - ), - ); + err.subdiagnostic(CandidateTraitNote { + span: self.tcx.def_span(trait_info.def_id), + trait_name: self.tcx.def_path_str(trait_info.def_id), + item_name, + action_or_ty: if trait_missing_method { + "NONE".to_string() + } else { + param_type.map_or_else( + || "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented. + ToString::to_string, + ) + }, + }); } trait_infos => { - let mut msg = message(action); + let mut msg = message(param_type.map_or_else( + || "implement".to_string(), // FIXME: it might only need to be imported into scope, not implemented. + |param| format!("restrict type parameter `{}` with", param), + )); for (i, trait_info) in trait_infos.iter().enumerate() { msg.push_str(&format!( "\ncandidate #{}: `{}`", diff --git a/tests/ui/resolve/issue-111312.rs b/tests/ui/resolve/issue-111312.rs new file mode 100644 index 00000000000..acea37b358b --- /dev/null +++ b/tests/ui/resolve/issue-111312.rs @@ -0,0 +1,11 @@ +// edition: 2021 + +trait Has { + fn has() {} +} + +trait HasNot {} + +fn main() { + HasNot::has(); //~ ERROR +} diff --git a/tests/ui/resolve/issue-111312.stderr b/tests/ui/resolve/issue-111312.stderr new file mode 100644 index 00000000000..4c864029c98 --- /dev/null +++ b/tests/ui/resolve/issue-111312.stderr @@ -0,0 +1,15 @@ +error[E0599]: no function or associated item named `has` found for trait `HasNot` + --> $DIR/issue-111312.rs:10:13 + | +LL | HasNot::has(); + | ^^^ function or associated item not found in `HasNot` + | +note: `Has` defines an item `has` + --> $DIR/issue-111312.rs:3:1 + | +LL | trait Has { + | ^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/traits/issue-106072.rs b/tests/ui/traits/issue-106072.rs index 7064a39d21e..b174669545a 100644 --- a/tests/ui/traits/issue-106072.rs +++ b/tests/ui/traits/issue-106072.rs @@ -1,5 +1,4 @@ #[derive(Clone)] //~ trait objects must include the `dyn` keyword - //~| trait objects must include the `dyn` keyword struct Foo; trait Foo {} //~ the name `Foo` is defined multiple times fn main() {} diff --git a/tests/ui/traits/issue-106072.stderr b/tests/ui/traits/issue-106072.stderr index f9b7b814663..1037603ceb7 100644 --- a/tests/ui/traits/issue-106072.stderr +++ b/tests/ui/traits/issue-106072.stderr @@ -1,5 +1,5 @@ error[E0428]: the name `Foo` is defined multiple times - --> $DIR/issue-106072.rs:4:1 + --> $DIR/issue-106072.rs:3:1 | LL | struct Foo; | ----------- previous definition of the type `Foo` here @@ -16,15 +16,7 @@ LL | #[derive(Clone)] | = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0782]: trait objects must include the `dyn` keyword - --> $DIR/issue-106072.rs:1:10 - | -LL | #[derive(Clone)] - | ^^^^^ - | - = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0428, E0782. For more information about an error, try `rustc --explain E0428`. From 54f882e47850f25b3d2e1a0a7371f3a6243df27a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 17 May 2023 11:43:13 +0200 Subject: [PATCH 51/52] Add missing backslash in HTML string --- src/librustdoc/html/render/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index d6773169639..0a2f5f6653c 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1751,7 +1751,7 @@ fn render_impl( if trait_.is_none() && i.inner_impl().items.is_empty() { w.write_str( "
\ -
This impl block contains no items.
+
This impl block contains no items.
\
", ); } From f16acbeef63cee81026013f6f8ffd538a6e04e66 Mon Sep 17 00:00:00 2001 From: Jules Bertholet Date: Thu, 18 May 2023 01:30:12 -0400 Subject: [PATCH 52/52] Document `Pin` memory layout --- library/core/src/pin.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index c4b89a63019..6b319b4355c 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -393,6 +393,8 @@ use crate::ops::{CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Receiver}; /// value in place, preventing the value referenced by that pointer from being moved /// unless it implements [`Unpin`]. /// +/// `Pin

` is guaranteed to have the same memory layout and ABI as `P`. +/// /// *See the [`pin` module] documentation for an explanation of pinning.* /// /// [`pin` module]: self