From 2e98368c2f1a4cbefa3c8f43f550a7fc1831636e Mon Sep 17 00:00:00 2001 From: ozkanonur Date: Fri, 14 Apr 2023 15:03:49 +0300 Subject: [PATCH 01/42] make sysroot finding compatible with multiarch systems Signed-off-by: ozkanonur --- compiler/rustc_session/src/filesearch.rs | 35 ++++++++++++------------ 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 40879db49def9..7fdbd48d56334 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -227,28 +227,29 @@ pub fn get_or_default_sysroot() -> Result { ))?; // if `dir` points target's dir, move up to the sysroot - if dir.ends_with(crate::config::host_triple()) { + let mut sysroot_dir = if dir.ends_with(crate::config::host_triple()) { dir.parent() // chop off `$target` .and_then(|p| p.parent()) // chop off `rustlib` - .and_then(|p| { - // chop off `lib` (this could be also $arch dir if the host sysroot uses a - // multi-arch layout like Debian or Ubuntu) - match p.parent() { - Some(p) => match p.file_name() { - Some(f) if f == "lib" => p.parent(), // first chop went for $arch, so chop again for `lib` - _ => Some(p), - }, - None => None, - } - }) + .and_then(|p| p.parent()) // chop off `lib` .map(|s| s.to_owned()) - .ok_or(format!( - "Could not move 3 levels upper using `parent()` on {}", - dir.display() - )) + .ok_or_else(|| { + format!("Could not move 3 levels upper using `parent()` on {}", dir.display()) + })? } else { - Ok(dir.to_owned()) + dir.to_owned() + }; + + // On multiarch linux systems, there will be multiarch directory named + // with the architecture(e.g `x86_64-linux-gnu`) under the `lib` directory. + // Which cause us to mistakenly end up in the lib directory instead of the sysroot directory. + if sysroot_dir.ends_with("lib") { + sysroot_dir = + sysroot_dir.parent().map(|real_sysroot| real_sysroot.to_owned()).ok_or_else( + || format!("Could not move to parent path of {}", sysroot_dir.display()), + )? } + + Ok(sysroot_dir) } // Use env::args().next() to get the path of the executable without From c9a6e41026d7aa27d897fb83e995447719753076 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 22 Mar 2023 21:56:09 +0000 Subject: [PATCH 02/42] Report allocation errors as panics --- library/alloc/Cargo.toml | 3 ++ library/alloc/src/alloc.rs | 84 ++++++++++++++++++++++++++++++++---- library/alloc/src/lib.rs | 1 + library/std/Cargo.toml | 2 +- library/std/src/lib.rs | 1 + library/std/src/panicking.rs | 43 ++++++++++-------- 6 files changed, 107 insertions(+), 27 deletions(-) diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index 95c07abf73106..8975ba3f06bbf 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -35,3 +35,6 @@ compiler-builtins-mem = ['compiler_builtins/mem'] compiler-builtins-c = ["compiler_builtins/c"] compiler-builtins-no-asm = ["compiler_builtins/no-asm"] compiler-builtins-mangled-names = ["compiler_builtins/mangled-names"] + +# Make panics and failed asserts immediately abort without formatting any message +panic_immediate_abort = ["core/panic_immediate_abort"] diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 6f2ba957bcda0..08c65a96bc744 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -14,6 +14,11 @@ use core::ptr::{self, NonNull}; #[doc(inline)] pub use core::alloc::*; +#[cfg(not(no_global_oom_handling))] +use core::any::Any; +#[cfg(not(no_global_oom_handling))] +use core::panic::BoxMeUp; + #[cfg(test)] mod tests; @@ -343,14 +348,77 @@ pub(crate) unsafe fn box_free(ptr: Unique, alloc: A) } } -// # Allocation error handler +/// Payload passed to the panic handler when `handle_alloc_error` is called. +#[unstable(feature = "panic_oom_payload", issue = "none")] +#[derive(Debug)] +pub struct AllocErrorPanicPayload { + layout: Layout, +} + +impl AllocErrorPanicPayload { + /// Internal function for the standard library to clone a payload. + #[unstable(feature = "std_internals", issue = "none")] + #[doc(hidden)] + pub fn internal_clone(&self) -> Self { + AllocErrorPanicPayload { layout: self.layout } + } + /// Returns the [`Layout`] of the allocation attempt that caused the error. + #[unstable(feature = "panic_oom_payload", issue = "none")] + pub fn layout(&self) -> Layout { + self.layout + } +} + +#[unstable(feature = "std_internals", issue = "none")] #[cfg(not(no_global_oom_handling))] -extern "Rust" { - // This is the magic symbol to call the global alloc error handler. rustc generates - // it to call `__rg_oom` if there is a `#[alloc_error_handler]`, or to call the - // default implementations below (`__rdl_oom`) otherwise. - fn __rust_alloc_error_handler(size: usize, align: usize) -> !; +unsafe impl BoxMeUp for AllocErrorPanicPayload { + fn take_box(&mut self) -> *mut (dyn Any + Send) { + use crate::boxed::Box; + Box::into_raw(Box::new(self.internal_clone())) + } + + fn get(&mut self) -> &(dyn Any + Send) { + self + } +} + +// # Allocation error handler + +#[cfg(all(not(no_global_oom_handling), not(test)))] +fn rust_oom(layout: Layout) -> ! { + if cfg!(feature = "panic_immediate_abort") { + core::intrinsics::abort() + } + + extern "Rust" { + // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call + // that gets resolved to the `#[panic_handler]` function. + #[lang = "panic_impl"] + fn panic_impl(pi: &core::panic::PanicInfo<'_>) -> !; + + // This symbol is emitted by rustc next to __rust_alloc_error_handler. + // Its value depends on the -Zoom={panic,abort} compiler option. + static __rust_alloc_error_handler_should_panic: u8; + } + + // Hack to work around issues with the lifetime of Arguments. + match format_args!("memory allocation of {} bytes failed", layout.size()) { + fmt => { + // Create a PanicInfo with a custom payload for the panic handler. + let can_unwind = unsafe { __rust_alloc_error_handler_should_panic != 0 }; + let mut pi = core::panic::PanicInfo::internal_constructor( + Some(&fmt), + core::panic::Location::caller(), + can_unwind, + ); + let payload = AllocErrorPanicPayload { layout }; + pi.set_payload(&payload); + + // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. + unsafe { panic_impl(&pi) } + } + } } /// Abort on memory allocation error or failure. @@ -375,9 +443,7 @@ pub const fn handle_alloc_error(layout: Layout) -> ! { } fn rt_error(layout: Layout) -> ! { - unsafe { - __rust_alloc_error_handler(layout.size(), layout.align()); - } + rust_oom(layout); } unsafe { core::intrinsics::const_eval_select((layout,), ct_error, rt_error) } diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index aa240c37e8442..146e366013f30 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -136,6 +136,7 @@ #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array)] #![feature(maybe_uninit_uninit_array_transpose)] +#![feature(panic_internals)] #![feature(pattern)] #![feature(pointer_byte_offsets)] #![feature(provide_any)] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 96c75f97f6e2b..cbd259e677309 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -67,7 +67,7 @@ llvm-libunwind = ["unwind/llvm-libunwind"] system-llvm-libunwind = ["unwind/system-llvm-libunwind"] # Make panics and failed asserts immediately abort without formatting any message -panic_immediate_abort = ["core/panic_immediate_abort"] +panic_immediate_abort = ["alloc/panic_immediate_abort"] # Enable std_detect default features for stdarch/crates/std_detect: # https://github.com/rust-lang/stdarch/blob/master/crates/std_detect/Cargo.toml diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 98fcc76aa98f6..109d6331ade93 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -319,6 +319,7 @@ #![feature(get_mut_unchecked)] #![feature(map_try_insert)] #![feature(new_uninit)] +#![feature(panic_oom_payload)] #![feature(slice_concat_trait)] #![feature(thin_box)] #![feature(try_reserve_kind)] diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index a46a29cbad608..ca4cf68ad54e2 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -245,19 +245,24 @@ fn default_hook(info: &PanicInfo<'_>) { // The current implementation always returns `Some`. let location = info.location().unwrap(); - - let msg = match info.payload().downcast_ref::<&'static str>() { - Some(s) => *s, - None => match info.payload().downcast_ref::() { - Some(s) => &s[..], - None => "Box", - }, - }; let thread = thread_info::current_thread(); let name = thread.as_ref().and_then(|t| t.name()).unwrap_or(""); let write = |err: &mut dyn crate::io::Write| { - let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}"); + // Use the panic message directly if available, otherwise take it from + // the payload. + if let Some(msg) = info.message() { + let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}"); + } else { + let msg = if let Some(s) = info.payload().downcast_ref::<&'static str>() { + *s + } else if let Some(s) = info.payload().downcast_ref::() { + &s[..] + } else { + "Box" + }; + let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}"); + } static FIRST_PANIC: AtomicBool = AtomicBool::new(true); @@ -524,6 +529,8 @@ pub fn panicking() -> bool { #[cfg(not(test))] #[panic_handler] pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { + use alloc::alloc::AllocErrorPanicPayload; + struct PanicPayload<'a> { inner: &'a fmt::Arguments<'a>, string: Option, @@ -550,8 +557,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { unsafe impl<'a> BoxMeUp for PanicPayload<'a> { fn take_box(&mut self) -> *mut (dyn Any + Send) { // We do two allocations here, unfortunately. But (a) they're required with the current - // scheme, and (b) we don't handle panic + OOM properly anyway (see comment in - // begin_panic below). + // scheme, and (b) OOM uses its own separate payload type which doesn't allocate. let contents = mem::take(self.fill()); Box::into_raw(Box::new(contents)) } @@ -576,7 +582,14 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! { let loc = info.location().unwrap(); // The current implementation always returns Some let msg = info.message().unwrap(); // The current implementation always returns Some crate::sys_common::backtrace::__rust_end_short_backtrace(move || { - if let Some(msg) = msg.as_str() { + if let Some(payload) = info.payload().downcast_ref::() { + rust_panic_with_hook( + &mut payload.internal_clone(), + info.message(), + loc, + info.can_unwind(), + ); + } else if let Some(msg) = msg.as_str() { rust_panic_with_hook(&mut StrPanicPayload(msg), info.message(), loc, info.can_unwind()); } else { rust_panic_with_hook( @@ -623,11 +636,7 @@ pub const fn begin_panic(msg: M) -> ! { unsafe impl BoxMeUp for PanicPayload { fn take_box(&mut self) -> *mut (dyn Any + Send) { - // Note that this should be the only allocation performed in this code path. Currently - // this means that panic!() on OOM will invoke this code path, but then again we're not - // really ready for panic on OOM anyway. If we do start doing this, then we should - // propagate this allocation to be performed in the parent of this thread instead of the - // thread that's panicking. + // Note that this should be the only allocation performed in this code path. let data = match self.inner.take() { Some(a) => Box::new(a) as Box, None => process::abort(), From abc0660118cc95f47445fd33502a11dd448f5968 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 22 Mar 2023 23:43:20 +0000 Subject: [PATCH 03/42] Remove #[alloc_error_handler] from the compiler and library --- compiler/rustc_builtin_macros/messages.ftl | 2 - .../src/alloc_error_handler.rs | 97 ------------------- compiler/rustc_builtin_macros/src/errors.rs | 7 -- compiler/rustc_builtin_macros/src/lib.rs | 2 - .../example/alloc_example.rs | 7 +- .../rustc_codegen_cranelift/src/allocator.rs | 23 +---- .../example/alloc_example.rs | 7 +- compiler/rustc_codegen_gcc/src/allocator.rs | 34 +------ compiler/rustc_codegen_gcc/src/lib.rs | 4 +- compiler/rustc_codegen_llvm/src/allocator.rs | 48 --------- compiler/rustc_codegen_llvm/src/lib.rs | 3 +- .../src/back/symbol_export.rs | 2 +- compiler/rustc_codegen_ssa/src/base.rs | 13 +-- .../rustc_codegen_ssa/src/traits/backend.rs | 1 - compiler/rustc_feature/src/active.rs | 2 - compiler/rustc_feature/src/removed.rs | 2 + compiler/rustc_metadata/messages.ftl | 10 -- compiler/rustc_metadata/src/creader.rs | 68 ------------- compiler/rustc_metadata/src/errors.rs | 17 ---- compiler/rustc_metadata/src/rmeta/decoder.rs | 4 - .../src/rmeta/decoder/cstore_impl.rs | 3 - compiler/rustc_metadata/src/rmeta/encoder.rs | 1 - compiler/rustc_metadata/src/rmeta/mod.rs | 1 - compiler/rustc_middle/src/query/mod.rs | 11 --- library/alloc/src/alloc.rs | 10 +- library/core/src/macros/mod.rs | 10 -- library/core/src/prelude/v1.rs | 4 +- library/std/src/alloc.rs | 73 +------------- library/std/src/lib.rs | 1 - library/std/src/prelude/v1.rs | 4 +- .../crates/hir-def/src/builtin_attr.rs | 4 - tests/run-make/issue-51671/Makefile | 1 - tests/run-make/issue-51671/app.rs | 7 +- tests/run-make/issue-69368/Makefile | 19 ---- tests/run-make/issue-69368/a.rs | 26 ----- tests/run-make/issue-69368/b.rs | 8 -- tests/run-make/issue-69368/c.rs | 34 ------- .../run-make/wasm-symbols-not-exported/bar.rs | 7 +- .../alloc-error-handler-bad-signature-1.rs | 18 ---- ...alloc-error-handler-bad-signature-1.stderr | 44 --------- .../alloc-error-handler-bad-signature-2.rs | 17 ---- ...alloc-error-handler-bad-signature-2.stderr | 50 ---------- .../alloc-error-handler-bad-signature-3.rs | 15 --- ...alloc-error-handler-bad-signature-3.stderr | 21 ---- .../alloc-error/default-alloc-error-hook.rs | 4 +- .../no_std-alloc-error-handler-custom.rs | 84 ---------------- .../feature-gate-alloc-error-handler.rs | 16 --- .../feature-gate-alloc-error-handler.stderr | 12 --- tests/ui/missing/missing-allocator.rs | 6 -- 49 files changed, 22 insertions(+), 842 deletions(-) delete mode 100644 compiler/rustc_builtin_macros/src/alloc_error_handler.rs delete mode 100644 tests/run-make/issue-69368/Makefile delete mode 100644 tests/run-make/issue-69368/a.rs delete mode 100644 tests/run-make/issue-69368/b.rs delete mode 100644 tests/run-make/issue-69368/c.rs delete mode 100644 tests/ui/alloc-error/alloc-error-handler-bad-signature-1.rs delete mode 100644 tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr delete mode 100644 tests/ui/alloc-error/alloc-error-handler-bad-signature-2.rs delete mode 100644 tests/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr delete mode 100644 tests/ui/alloc-error/alloc-error-handler-bad-signature-3.rs delete mode 100644 tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr delete mode 100644 tests/ui/allocator/no_std-alloc-error-handler-custom.rs delete mode 100644 tests/ui/feature-gates/feature-gate-alloc-error-handler.rs delete mode 100644 tests/ui/feature-gates/feature-gate-alloc-error-handler.stderr diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 83dc1ac50e55d..43187c327092a 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -4,8 +4,6 @@ builtin_macros_requires_cfg_pattern = builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern -builtin_macros_alloc_error_must_be_fn = alloc_error_handler must be a function - builtin_macros_assert_requires_boolean = macro requires a boolean expression as an argument .label = boolean expression required diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs deleted file mode 100644 index 82bae9157e79d..0000000000000 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ /dev/null @@ -1,97 +0,0 @@ -use crate::errors; -use crate::util::check_builtin_macro_attribute; - -use rustc_ast::ptr::P; -use rustc_ast::{self as ast, FnHeader, FnSig, Generics, StmtKind}; -use rustc_ast::{Fn, ItemKind, Stmt, TyKind, Unsafe}; -use rustc_expand::base::{Annotatable, ExtCtxt}; -use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::Span; -use thin_vec::{thin_vec, ThinVec}; - -pub fn expand( - ecx: &mut ExtCtxt<'_>, - _span: Span, - meta_item: &ast::MetaItem, - item: Annotatable, -) -> Vec { - check_builtin_macro_attribute(ecx, meta_item, sym::alloc_error_handler); - - let orig_item = item.clone(); - - // Allow using `#[alloc_error_handler]` on an item statement - // FIXME - if we get deref patterns, use them to reduce duplication here - let (item, is_stmt, sig_span) = - if let Annotatable::Item(item) = &item - && let ItemKind::Fn(fn_kind) = &item.kind - { - (item, false, ecx.with_def_site_ctxt(fn_kind.sig.span)) - } else if let Annotatable::Stmt(stmt) = &item - && let StmtKind::Item(item) = &stmt.kind - && let ItemKind::Fn(fn_kind) = &item.kind - { - (item, true, ecx.with_def_site_ctxt(fn_kind.sig.span)) - } else { - ecx.sess.parse_sess.span_diagnostic.emit_err(errors::AllocErrorMustBeFn {span: item.span() }); - return vec![orig_item]; - }; - - // Generate a bunch of new items using the AllocFnFactory - let span = ecx.with_def_site_ctxt(item.span); - - // Generate item statements for the allocator methods. - let stmts = thin_vec![generate_handler(ecx, item.ident, span, sig_span)]; - - // Generate anonymous constant serving as container for the allocator methods. - let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new())); - let const_body = ecx.expr_block(ecx.block(span, stmts)); - let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body); - let const_item = if is_stmt { - Annotatable::Stmt(P(ecx.stmt_item(span, const_item))) - } else { - Annotatable::Item(const_item) - }; - - // Return the original item and the new methods. - vec![orig_item, const_item] -} - -// #[rustc_std_internal_symbol] -// unsafe fn __rg_oom(size: usize, align: usize) -> ! { -// handler(core::alloc::Layout::from_size_align_unchecked(size, align)) -// } -fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span) -> Stmt { - let usize = cx.path_ident(span, Ident::new(sym::usize, span)); - let ty_usize = cx.ty_path(usize); - let size = Ident::from_str_and_span("size", span); - let align = Ident::from_str_and_span("align", span); - - let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]); - let layout_new = cx.expr_path(cx.path(span, layout_new)); - let layout = cx.expr_call( - span, - layout_new, - thin_vec![cx.expr_ident(span, size), cx.expr_ident(span, align)], - ); - - let call = cx.expr_call_ident(sig_span, handler, thin_vec![layout]); - - let never = ast::FnRetTy::Ty(cx.ty(span, TyKind::Never)); - let params = thin_vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)]; - let decl = cx.fn_decl(params, never); - let header = FnHeader { unsafety: Unsafe::Yes(span), ..FnHeader::default() }; - let sig = FnSig { decl, header, span: span }; - - let body = Some(cx.block_expr(call)); - let kind = ItemKind::Fn(Box::new(Fn { - defaultness: ast::Defaultness::Final, - sig, - generics: Generics::default(), - body, - })); - - let attrs = thin_vec![cx.attr_word(sym::rustc_std_internal_symbol, span)]; - - let item = cx.item(span, Ident::from_str_and_span("__rg_oom", span), attrs, kind); - cx.stmt_item(sig_span, item) -} diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs index 630f9b87bc3ea..bf0ac3f0ee3f7 100644 --- a/compiler/rustc_builtin_macros/src/errors.rs +++ b/compiler/rustc_builtin_macros/src/errors.rs @@ -19,13 +19,6 @@ pub(crate) struct OneCfgPattern { pub(crate) span: Span, } -#[derive(Diagnostic)] -#[diag(builtin_macros_alloc_error_must_be_fn)] -pub(crate) struct AllocErrorMustBeFn { - #[primary_span] - pub(crate) span: Span, -} - #[derive(Diagnostic)] #[diag(builtin_macros_assert_requires_boolean)] pub(crate) struct AssertRequiresBoolean { diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 37fbd03a6a216..e326c37635a94 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -27,7 +27,6 @@ use rustc_expand::proc_macro::BangProcMacro; use rustc_macros::fluent_messages; use rustc_span::symbol::sym; -mod alloc_error_handler; mod assert; mod cfg; mod cfg_accessible; @@ -102,7 +101,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { } register_attr! { - alloc_error_handler: alloc_error_handler::expand, bench: test::expand_bench, cfg_accessible: cfg_accessible::Expander, cfg_eval: cfg_eval::expand, diff --git a/compiler/rustc_codegen_cranelift/example/alloc_example.rs b/compiler/rustc_codegen_cranelift/example/alloc_example.rs index 4ede2fe4efe82..e39c3272958be 100644 --- a/compiler/rustc_codegen_cranelift/example/alloc_example.rs +++ b/compiler/rustc_codegen_cranelift/example/alloc_example.rs @@ -1,4 +1,4 @@ -#![feature(start, core_intrinsics, alloc_error_handler)] +#![feature(start, core_intrinsics)] #![no_std] extern crate alloc; @@ -22,11 +22,6 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! { core::intrinsics::abort(); } -#[alloc_error_handler] -fn alloc_error_handler(_: alloc::alloc::Layout) -> ! { - core::intrinsics::abort(); -} - #[start] fn main(_argc: isize, _argv: *const *const u8) -> isize { let world: Box<&str> = Box::new("Hello World!\0"); diff --git a/compiler/rustc_codegen_cranelift/src/allocator.rs b/compiler/rustc_codegen_cranelift/src/allocator.rs index 2c246ceb37d54..9fb8079a21fc2 100644 --- a/compiler/rustc_codegen_cranelift/src/allocator.rs +++ b/compiler/rustc_codegen_cranelift/src/allocator.rs @@ -6,7 +6,6 @@ use crate::prelude::*; use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS}; use rustc_codegen_ssa::base::allocator_kind_for_codegen; use rustc_session::config::OomStrategy; -use rustc_span::symbol::sym; /// Returns whether an allocator shim was created pub(crate) fn codegen( @@ -15,13 +14,7 @@ pub(crate) fn codegen( unwind_context: &mut UnwindContext, ) -> bool { let Some(kind) = allocator_kind_for_codegen(tcx) else { return false }; - codegen_inner( - module, - unwind_context, - kind, - tcx.alloc_error_handler_kind(()).unwrap(), - tcx.sess.opts.unstable_opts.oom, - ); + codegen_inner(module, unwind_context, kind, tcx.sess.opts.unstable_opts.oom); true } @@ -29,7 +22,6 @@ fn codegen_inner( module: &mut impl Module, unwind_context: &mut UnwindContext, kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, oom_strategy: OomStrategy, ) { let usize_ty = module.target_config().pointer_type(); @@ -71,19 +63,6 @@ fn codegen_inner( ); } - let sig = Signature { - call_conv: module.target_config().default_call_conv, - params: vec![AbiParam::new(usize_ty), AbiParam::new(usize_ty)], - returns: vec![], - }; - crate::common::create_wrapper_function( - module, - unwind_context, - sig, - "__rust_alloc_error_handler", - &alloc_error_handler_kind.fn_name(sym::oom), - ); - let data_id = module.declare_data(OomStrategy::SYMBOL, Linkage::Export, false, false).unwrap(); let mut data_ctx = DataContext::new(); data_ctx.set_align(1); diff --git a/compiler/rustc_codegen_gcc/example/alloc_example.rs b/compiler/rustc_codegen_gcc/example/alloc_example.rs index 754e7931412da..faff1dca23f3f 100644 --- a/compiler/rustc_codegen_gcc/example/alloc_example.rs +++ b/compiler/rustc_codegen_gcc/example/alloc_example.rs @@ -1,4 +1,4 @@ -#![feature(start, core_intrinsics, alloc_error_handler, lang_items)] +#![feature(start, core_intrinsics, lang_items)] #![no_std] extern crate alloc; @@ -21,11 +21,6 @@ fn panic_handler(_: &core::panic::PanicInfo) -> ! { core::intrinsics::abort(); } -#[alloc_error_handler] -fn alloc_error_handler(_: alloc::alloc::Layout) -> ! { - core::intrinsics::abort(); -} - #[lang = "eh_personality"] fn eh_personality() -> ! { loop {} diff --git a/compiler/rustc_codegen_gcc/src/allocator.rs b/compiler/rustc_codegen_gcc/src/allocator.rs index 4bad33ee879ee..e90db44ece1fc 100644 --- a/compiler/rustc_codegen_gcc/src/allocator.rs +++ b/compiler/rustc_codegen_gcc/src/allocator.rs @@ -5,11 +5,10 @@ use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS use rustc_middle::bug; use rustc_middle::ty::TyCtxt; use rustc_session::config::OomStrategy; -use rustc_span::symbol::sym; use crate::GccContext; -pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) { +pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_name: &str, kind: AllocatorKind) { let context = &mods.context; let usize = match tcx.sess.target.pointer_width { @@ -87,37 +86,6 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt<'_>, mods: &mut GccContext, _module_nam // as described in https://github.com/rust-lang/rust/commit/77a96ed5646f7c3ee8897693decc4626fe380643 } - let types = [usize, usize]; - let name = "__rust_alloc_error_handler".to_string(); - let args: Vec<_> = types.iter().enumerate() - .map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index))) - .collect(); - let func = context.new_function(None, FunctionType::Exported, void, &args, name, false); - - if tcx.sess.target.default_hidden_visibility { - #[cfg(feature="master")] - func.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); - } - - let callee = alloc_error_handler_kind.fn_name(sym::oom); - let args: Vec<_> = types.iter().enumerate() - .map(|(index, typ)| context.new_parameter(None, *typ, &format!("param{}", index))) - .collect(); - let callee = context.new_function(None, FunctionType::Extern, void, &args, callee, false); - #[cfg(feature="master")] - callee.add_attribute(FnAttribute::Visibility(gccjit::Visibility::Hidden)); - - let block = func.new_block("entry"); - - let args = args - .iter() - .enumerate() - .map(|(i, _)| func.get_param(i as i32).to_rvalue()) - .collect::>(); - let _ret = context.new_call(None, callee, &args); - //llvm::LLVMSetTailCall(ret, True); - block.end_with_void_return(None); - let name = OomStrategy::SYMBOL.to_string(); let global = context.new_global(None, GlobalKind::Exported, i8, name); let value = tcx.sess.opts.unstable_opts.oom.should_panic(); diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 0b661505acc00..be710fefe49cc 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -162,11 +162,11 @@ impl CodegenBackend for GccCodegenBackend { } impl ExtraBackendMethods for GccCodegenBackend { - fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) -> Self::Module { + fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind) -> Self::Module { let mut mods = GccContext { context: Context::default(), }; - unsafe { allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); } + unsafe { allocator::codegen(tcx, &mut mods, module_name, kind); } mods } diff --git a/compiler/rustc_codegen_llvm/src/allocator.rs b/compiler/rustc_codegen_llvm/src/allocator.rs index 668d929270530..fc9251dda8200 100644 --- a/compiler/rustc_codegen_llvm/src/allocator.rs +++ b/compiler/rustc_codegen_llvm/src/allocator.rs @@ -4,7 +4,6 @@ use rustc_ast::expand::allocator::{AllocatorKind, AllocatorTy, ALLOCATOR_METHODS use rustc_middle::bug; use rustc_middle::ty::TyCtxt; use rustc_session::config::{DebugInfo, OomStrategy}; -use rustc_span::symbol::sym; use crate::debuginfo; use crate::llvm::{self, False, True}; @@ -15,7 +14,6 @@ pub(crate) unsafe fn codegen( module_llvm: &mut ModuleLlvm, module_name: &str, kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, ) { let llcx = &*module_llvm.llcx; let llmod = module_llvm.llmod(); @@ -100,52 +98,6 @@ pub(crate) unsafe fn codegen( llvm::LLVMDisposeBuilder(llbuilder); } - // rust alloc error handler - let args = [usize, usize]; // size, align - - let ty = llvm::LLVMFunctionType(void, args.as_ptr(), args.len() as c_uint, False); - let name = "__rust_alloc_error_handler"; - let llfn = llvm::LLVMRustGetOrInsertFunction(llmod, name.as_ptr().cast(), name.len(), ty); - // -> ! DIFlagNoReturn - let no_return = llvm::AttributeKind::NoReturn.create_attr(llcx); - attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[no_return]); - - if tcx.sess.target.default_hidden_visibility { - llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden); - } - if tcx.sess.must_emit_unwind_tables() { - let uwtable = attributes::uwtable_attr(llcx); - attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[uwtable]); - } - - let callee = alloc_error_handler_kind.fn_name(sym::oom); - let callee = llvm::LLVMRustGetOrInsertFunction(llmod, callee.as_ptr().cast(), callee.len(), ty); - // -> ! DIFlagNoReturn - attributes::apply_to_llfn(callee, llvm::AttributePlace::Function, &[no_return]); - llvm::LLVMRustSetVisibility(callee, llvm::Visibility::Hidden); - - let llbb = llvm::LLVMAppendBasicBlockInContext(llcx, llfn, "entry\0".as_ptr().cast()); - - let llbuilder = llvm::LLVMCreateBuilderInContext(llcx); - llvm::LLVMPositionBuilderAtEnd(llbuilder, llbb); - let args = args - .iter() - .enumerate() - .map(|(i, _)| llvm::LLVMGetParam(llfn, i as c_uint)) - .collect::>(); - let ret = llvm::LLVMRustBuildCall( - llbuilder, - ty, - callee, - args.as_ptr(), - args.len() as c_uint, - [].as_ptr(), - 0 as c_uint, - ); - llvm::LLVMSetTailCall(ret, True); - llvm::LLVMBuildRetVoid(llbuilder); - llvm::LLVMDisposeBuilder(llbuilder); - // __rust_alloc_error_handler_should_panic let name = OomStrategy::SYMBOL; let ll_g = llvm::LLVMRustGetOrInsertGlobal(llmod, name.as_ptr().cast(), name.len(), i8); diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 3f77ea77effe3..33d66bcd23784 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -115,11 +115,10 @@ impl ExtraBackendMethods for LlvmCodegenBackend { tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, ) -> ModuleLlvm { let mut module_llvm = ModuleLlvm::new_metadata(tcx, module_name); unsafe { - allocator::codegen(tcx, &mut module_llvm, module_name, kind, alloc_error_handler_kind); + allocator::codegen(tcx, &mut module_llvm, module_name, kind); } module_llvm } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index d0fd3cd766674..dbf30e42ae44b 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -219,7 +219,7 @@ fn exported_symbols_provider_local( for symbol_name in ALLOCATOR_METHODS .iter() .map(|method| format!("__rust_{}", method.name)) - .chain(["__rust_alloc_error_handler".to_string(), OomStrategy::SYMBOL.to_string()]) + .chain([OomStrategy::SYMBOL.to_string()]) { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name)); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index c5ca7936a2b45..3e9d29df02cdf 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -635,16 +635,9 @@ pub fn codegen_crate( if let Some(kind) = allocator_kind_for_codegen(tcx) { let llmod_id = cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string(); - let module_llvm = tcx.sess.time("write_allocator_module", || { - backend.codegen_allocator( - tcx, - &llmod_id, - kind, - // If allocator_kind is Some then alloc_error_handler_kind must - // also be Some. - tcx.alloc_error_handler_kind(()).unwrap(), - ) - }); + let module_llvm = tcx + .sess + .time("write_allocator_module", || backend.codegen_allocator(tcx, &llmod_id, kind)); ongoing_codegen.submit_pre_codegened_module_to_llvm( tcx, diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 64bebe50ddbf2..2e88b7ce21901 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -123,7 +123,6 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, - alloc_error_handler_kind: AllocatorKind, ) -> Self::Module; /// This generates the codegen unit and returns it along with /// a `u64` giving an estimate of the unit's processing cost. diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 48f5bd1cb5048..594e6cca912e7 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -291,8 +291,6 @@ declare_features! ( (active, abi_x86_interrupt, "1.17.0", Some(40180), None), /// Allows additional const parameter types, such as `&'static str` or user defined types (incomplete, adt_const_params, "1.56.0", Some(95174), None), - /// Allows defining an `#[alloc_error_handler]`. - (active, alloc_error_handler, "1.29.0", Some(51540), None), /// Allows trait methods with arbitrary self types. (active, arbitrary_self_types, "1.23.0", Some(44874), None), /// Allows using `const` operands in inline assembly. diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index 48d9fbfa6d261..568c289e2f714 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -47,6 +47,8 @@ declare_features! ( (removed, advanced_slice_patterns, "1.0.0", Some(62254), None, Some("merged into `#![feature(slice_patterns)]`")), + /// Allows defining an `#[alloc_error_handler]`. + (removed, alloc_error_handler, "CURRENT_RUSTC_VERSION", Some(51540), None, Some("now handled by panic handler")), (removed, allocator, "1.0.0", None, None, None), /// Allows a test to fail without failing the whole suite. (removed, allow_fail, "1.19.0", Some(46488), None, Some("removed due to no clear use cases")), diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index 79b8b41725704..f0158aeae851d 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -155,19 +155,9 @@ metadata_no_multiple_global_alloc = metadata_prev_global_alloc = previous global allocator defined here -metadata_no_multiple_alloc_error_handler = - cannot define multiple allocation error handlers - .label = cannot define a new allocation error handler - -metadata_prev_alloc_error_handler = - previous allocation error handler defined here - metadata_conflicting_global_alloc = the `#[global_allocator]` in {$other_crate_name} conflicts with global allocator in: {$crate_name} -metadata_conflicting_alloc_error_handler = - the `#[alloc_error_handler]` in {$other_crate_name} conflicts with allocation error handler in: {$crate_name} - metadata_global_alloc_required = no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index 23aceca06223a..89751b0b72111 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -38,13 +38,8 @@ pub struct CStore { /// This crate needs an allocator and either provides it itself, or finds it in a dependency. /// If the above is true, then this field denotes the kind of the found allocator. allocator_kind: Option, - /// This crate needs an allocation error handler and either provides it itself, or finds it in a dependency. - /// If the above is true, then this field denotes the kind of the found allocator. - alloc_error_handler_kind: Option, /// This crate has a `#[global_allocator]` item. has_global_allocator: bool, - /// This crate has a `#[alloc_error_handler]` item. - has_alloc_error_handler: bool, /// The interned [StableCrateId]s. pub(crate) stable_crate_ids: StableCrateIdMap, @@ -221,18 +216,10 @@ impl CStore { self.allocator_kind } - pub(crate) fn alloc_error_handler_kind(&self) -> Option { - self.alloc_error_handler_kind - } - pub(crate) fn has_global_allocator(&self) -> bool { self.has_global_allocator } - pub(crate) fn has_alloc_error_handler(&self) -> bool { - self.has_alloc_error_handler - } - pub fn report_unused_deps(&self, tcx: TyCtxt<'_>) { let json_unused_externs = tcx.sess.opts.json_unused_externs; @@ -268,9 +255,7 @@ impl CStore { metas: IndexVec::from_iter(iter::once(None)), injected_panic_runtime: None, allocator_kind: None, - alloc_error_handler_kind: None, has_global_allocator: false, - has_alloc_error_handler: false, stable_crate_ids, unused_externs: Vec::new(), } @@ -776,14 +761,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } spans => !spans.is_empty(), }; - self.cstore.has_alloc_error_handler = match &*alloc_error_handler_spans(krate) { - [span1, span2, ..] => { - self.sess - .emit_err(errors::NoMultipleAllocErrorHandler { span2: *span2, span1: *span1 }); - true - } - spans => !spans.is_empty(), - }; // Check to see if we actually need an allocator. This desire comes // about through the `#![needs_allocator]` attribute and is typically @@ -824,21 +801,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } } } - let mut alloc_error_handler = - self.cstore.has_alloc_error_handler.then(|| Symbol::intern("this crate")); - for (_, data) in self.cstore.iter_crate_data() { - if data.has_alloc_error_handler() { - match alloc_error_handler { - Some(other_crate) => { - self.sess.emit_err(errors::ConflictingAllocErrorHandler { - crate_name: data.name(), - other_crate_name: other_crate, - }); - } - None => alloc_error_handler = Some(data.name()), - } - } - } if global_allocator.is_some() { self.cstore.allocator_kind = Some(AllocatorKind::Global); @@ -854,14 +816,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { } self.cstore.allocator_kind = Some(AllocatorKind::Default); } - - if alloc_error_handler.is_some() { - self.cstore.alloc_error_handler_kind = Some(AllocatorKind::Global); - } else { - // The alloc crate provides a default allocation error handler if - // one isn't specified. - self.cstore.alloc_error_handler_kind = Some(AllocatorKind::Default); - } } fn inject_dependency_if( @@ -1037,28 +991,6 @@ fn global_allocator_spans(krate: &ast::Crate) -> Vec { f.spans } -fn alloc_error_handler_spans(krate: &ast::Crate) -> Vec { - struct Finder { - name: Symbol, - spans: Vec, - } - impl<'ast> visit::Visitor<'ast> for Finder { - fn visit_item(&mut self, item: &'ast ast::Item) { - if item.ident.name == self.name - && attr::contains_name(&item.attrs, sym::rustc_std_internal_symbol) - { - self.spans.push(item.span); - } - visit::walk_item(self, item) - } - } - - let name = Symbol::intern(&AllocatorKind::Global.fn_name(sym::oom)); - let mut f = Finder { name, spans: Vec::new() }; - visit::walk_crate(&mut f, krate); - f.spans -} - // On Windows the compiler would sometimes intermittently fail to open the // proc-macro DLL with `Error::LoadLibraryExW`. It is suspected that something in the // system still holds a lock on the file, so we retry a few times before calling it diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index 51b41b5f6a214..7ecb551a3e596 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -352,16 +352,6 @@ pub struct NoMultipleGlobalAlloc { pub span1: Span, } -#[derive(Diagnostic)] -#[diag(metadata_no_multiple_alloc_error_handler)] -pub struct NoMultipleAllocErrorHandler { - #[primary_span] - #[label] - pub span2: Span, - #[label(metadata_prev_alloc_error_handler)] - pub span1: Span, -} - #[derive(Diagnostic)] #[diag(metadata_conflicting_global_alloc)] pub struct ConflictingGlobalAlloc { @@ -369,13 +359,6 @@ pub struct ConflictingGlobalAlloc { pub other_crate_name: Symbol, } -#[derive(Diagnostic)] -#[diag(metadata_conflicting_alloc_error_handler)] -pub struct ConflictingAllocErrorHandler { - pub crate_name: Symbol, - pub other_crate_name: Symbol, -} - #[derive(Diagnostic)] #[diag(metadata_global_alloc_required)] pub struct GlobalAllocRequired; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 2930ce75028b7..f7c9379e10989 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1692,10 +1692,6 @@ impl CrateMetadata { self.root.has_global_allocator } - pub(crate) fn has_alloc_error_handler(&self) -> bool { - self.root.has_alloc_error_handler - } - pub(crate) fn has_default_lib_allocator(&self) -> bool { self.root.has_default_lib_allocator } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 31798afb852c5..6212597e1ac8d 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -290,7 +290,6 @@ provide! { tcx, def_id, other, cdata, is_panic_runtime => { cdata.root.panic_runtime } is_compiler_builtins => { cdata.root.compiler_builtins } has_global_allocator => { cdata.root.has_global_allocator } - has_alloc_error_handler => { cdata.root.has_alloc_error_handler } has_panic_handler => { cdata.root.has_panic_handler } is_profiler_runtime => { cdata.root.profiler_runtime } required_panic_strategy => { cdata.root.required_panic_strategy } @@ -379,7 +378,6 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { // resolve! Does this work? Unsure! That's what the issue is about *providers = Providers { allocator_kind: |tcx, ()| CStore::from_tcx(tcx).allocator_kind(), - alloc_error_handler_kind: |tcx, ()| CStore::from_tcx(tcx).alloc_error_handler_kind(), is_private_dep: |_tcx, LocalCrate| false, native_library: |tcx, id| { tcx.native_libraries(id.krate) @@ -496,7 +494,6 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { dependency_formats: |tcx, ()| Lrc::new(crate::dependency_format::calculate(tcx)), has_global_allocator: |tcx, LocalCrate| CStore::from_tcx(tcx).has_global_allocator(), - has_alloc_error_handler: |tcx, LocalCrate| CStore::from_tcx(tcx).has_alloc_error_handler(), postorder_cnums: |tcx, ()| { tcx.arena .alloc_slice(&CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE)) diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 657b903e0a8af..f9e42fdecdc40 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -676,7 +676,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop, edition: tcx.sess.edition(), has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE), - has_alloc_error_handler: tcx.has_alloc_error_handler(LOCAL_CRATE), has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE), has_default_lib_allocator: attr::contains_name(&attrs, sym::default_lib_allocator), proc_macro_data, diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index dc77a079b075d..68dc22e31e960 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -225,7 +225,6 @@ pub(crate) struct CrateRoot { panic_in_drop_strategy: PanicStrategy, edition: Edition, has_global_allocator: bool, - has_alloc_error_handler: bool, has_panic_handler: bool, has_default_lib_allocator: bool, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 7a5a1603585b1..0cecf8db1af67 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1460,13 +1460,6 @@ rustc_queries! { desc { "checking if the crate has_global_allocator" } separate_provide_extern } - query has_alloc_error_handler(_: CrateNum) -> bool { - // This query depends on untracked global state in CStore - eval_always - fatal_cycle - desc { "checking if the crate has_alloc_error_handler" } - separate_provide_extern - } query has_panic_handler(_: CrateNum) -> bool { fatal_cycle desc { "checking if the crate has_panic_handler" } @@ -1839,10 +1832,6 @@ rustc_queries! { eval_always desc { "getting the allocator kind for the current crate" } } - query alloc_error_handler_kind(_: ()) -> Option { - eval_always - desc { "alloc error handler kind for the current crate" } - } query upvars_mentioned(def_id: DefId) -> Option<&'tcx FxIndexMap> { desc { |tcx| "collecting upvars mentioned in `{}`", tcx.def_path_str(def_id) } diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 08c65a96bc744..97bedc604da82 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -397,7 +397,7 @@ fn rust_oom(layout: Layout) -> ! { #[lang = "panic_impl"] fn panic_impl(pi: &core::panic::PanicInfo<'_>) -> !; - // This symbol is emitted by rustc next to __rust_alloc_error_handler. + // This symbol is emitted by rustc . // Its value depends on the -Zoom={panic,abort} compiler option. static __rust_alloc_error_handler_should_panic: u8; } @@ -426,13 +426,6 @@ fn rust_oom(layout: Layout) -> ! { /// Callers of memory allocation APIs wishing to abort computation /// in response to an allocation error are encouraged to call this function, /// rather than directly invoking `panic!` or similar. -/// -/// The default behavior of this function is to print a message to standard error -/// and abort the process. -/// It can be replaced with [`set_alloc_error_hook`] and [`take_alloc_error_hook`]. -/// -/// [`set_alloc_error_hook`]: ../../std/alloc/fn.set_alloc_error_hook.html -/// [`take_alloc_error_hook`]: ../../std/alloc/fn.take_alloc_error_hook.html #[stable(feature = "global_alloc", since = "1.28.0")] #[rustc_const_unstable(feature = "const_alloc_error", issue = "92523")] #[cfg(all(not(no_global_oom_handling), not(test)))] @@ -453,6 +446,7 @@ pub const fn handle_alloc_error(layout: Layout) -> ! { #[cfg(all(not(no_global_oom_handling), test))] pub use std::alloc::handle_alloc_error; +#[cfg(bootstrap)] #[cfg(all(not(no_global_oom_handling), not(test)))] #[doc(hidden)] #[allow(unused_attributes)] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 7c93c93b4a019..cc3179ee7801b 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1531,16 +1531,6 @@ pub(crate) mod builtin { /* compiler built-in */ } - /// Attribute macro applied to a function to register it as a handler for allocation failure. - /// - /// See also [`std::alloc::handle_alloc_error`](../../../std/alloc/fn.handle_alloc_error.html). - #[unstable(feature = "alloc_error_handler", issue = "51540")] - #[allow_internal_unstable(rustc_attrs)] - #[rustc_builtin_macro] - pub macro alloc_error_handler($item:item) { - /* compiler built-in */ - } - /// Keeps the item it's applied to if the passed path is accessible, and removes it otherwise. #[unstable( feature = "cfg_accessible", diff --git a/library/core/src/prelude/v1.rs b/library/core/src/prelude/v1.rs index 10525a16f3a66..9c4c0f6ab7aa5 100644 --- a/library/core/src/prelude/v1.rs +++ b/library/core/src/prelude/v1.rs @@ -76,9 +76,7 @@ pub use crate::macros::builtin::{RustcDecodable, RustcEncodable}; // Do not `doc(no_inline)` so that they become doc items on their own // (no public module for them to be re-exported from). #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] -pub use crate::macros::builtin::{ - alloc_error_handler, bench, derive, global_allocator, test, test_case, -}; +pub use crate::macros::builtin::{bench, derive, global_allocator, test, test_case}; #[unstable(feature = "derive_const", issue = "none")] pub use crate::macros::builtin::derive_const; diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index c5a5991cc81c4..448a8edc29177 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -57,9 +57,8 @@ #![stable(feature = "alloc_module", since = "1.28.0")] use core::intrinsics; +use core::ptr; use core::ptr::NonNull; -use core::sync::atomic::{AtomicPtr, Ordering}; -use core::{mem, ptr}; #[stable(feature = "alloc_module", since = "1.28.0")] #[doc(inline)] @@ -286,76 +285,6 @@ unsafe impl Allocator for System { } } -static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); - -/// Registers a custom allocation error hook, replacing any that was previously registered. -/// -/// The allocation error hook is invoked when an infallible memory allocation fails, before -/// the runtime aborts. The default hook prints a message to standard error, -/// but this behavior can be customized with the [`set_alloc_error_hook`] and -/// [`take_alloc_error_hook`] functions. -/// -/// The hook is provided with a `Layout` struct which contains information -/// about the allocation that failed. -/// -/// The allocation error hook is a global resource. -/// -/// # Examples -/// -/// ``` -/// #![feature(alloc_error_hook)] -/// -/// use std::alloc::{Layout, set_alloc_error_hook}; -/// -/// fn custom_alloc_error_hook(layout: Layout) { -/// panic!("memory allocation of {} bytes failed", layout.size()); -/// } -/// -/// set_alloc_error_hook(custom_alloc_error_hook); -/// ``` -#[unstable(feature = "alloc_error_hook", issue = "51245")] -pub fn set_alloc_error_hook(hook: fn(Layout)) { - HOOK.store(hook as *mut (), Ordering::SeqCst); -} - -/// Unregisters the current allocation error hook, returning it. -/// -/// *See also the function [`set_alloc_error_hook`].* -/// -/// If no custom hook is registered, the default hook will be returned. -#[unstable(feature = "alloc_error_hook", issue = "51245")] -pub fn take_alloc_error_hook() -> fn(Layout) { - let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst); - if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } } -} - -fn default_alloc_error_hook(layout: Layout) { - extern "Rust" { - // This symbol is emitted by rustc next to __rust_alloc_error_handler. - // Its value depends on the -Zoom={panic,abort} compiler option. - static __rust_alloc_error_handler_should_panic: u8; - } - - #[allow(unused_unsafe)] - if unsafe { __rust_alloc_error_handler_should_panic != 0 } { - panic!("memory allocation of {} bytes failed", layout.size()); - } else { - rtprintpanic!("memory allocation of {} bytes failed\n", layout.size()); - } -} - -#[cfg(not(test))] -#[doc(hidden)] -#[alloc_error_handler] -#[unstable(feature = "alloc_internals", issue = "none")] -pub fn rust_oom(layout: Layout) -> ! { - let hook = HOOK.load(Ordering::SeqCst); - let hook: fn(Layout) = - if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } }; - hook(layout); - crate::process::abort() -} - #[cfg(not(test))] #[doc(hidden)] #[allow(unused_attributes)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 109d6331ade93..900df71919b95 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -236,7 +236,6 @@ // // Language features: // tidy-alphabetical-start -#![feature(alloc_error_handler)] #![feature(allocator_internals)] #![feature(allow_internal_unsafe)] #![feature(allow_internal_unstable)] diff --git a/library/std/src/prelude/v1.rs b/library/std/src/prelude/v1.rs index 2aefd7c513dc8..4f325a70b1891 100644 --- a/library/std/src/prelude/v1.rs +++ b/library/std/src/prelude/v1.rs @@ -60,9 +60,7 @@ pub use core::prelude::v1::{RustcDecodable, RustcEncodable}; // Do not `doc(no_inline)` so that they become doc items on their own // (no public module for them to be re-exported from). #[stable(feature = "builtin_macro_prelude", since = "1.38.0")] -pub use core::prelude::v1::{ - alloc_error_handler, bench, derive, global_allocator, test, test_case, -}; +pub use core::prelude::v1::{bench, derive, global_allocator, test, test_case}; #[unstable(feature = "derive_const", issue = "none")] pub use core::prelude::v1::derive_const; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs index f7c1e683d0d20..e3e5fac98c0e5 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_attr.rs @@ -381,10 +381,6 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!(rustc_allocator, Normal, template!(Word), WarnFollowing, IMPL_DETAIL), rustc_attr!(rustc_nounwind, Normal, template!(Word), WarnFollowing, IMPL_DETAIL), - gated!( - alloc_error_handler, Normal, template!(Word), WarnFollowing, - experimental!(alloc_error_handler) - ), gated!( default_lib_allocator, Normal, template!(Word), WarnFollowing, allocator_internals, experimental!(default_lib_allocator), diff --git a/tests/run-make/issue-51671/Makefile b/tests/run-make/issue-51671/Makefile index c93645369928c..00cf913466238 100644 --- a/tests/run-make/issue-51671/Makefile +++ b/tests/run-make/issue-51671/Makefile @@ -6,4 +6,3 @@ all: $(RUSTC) --emit=obj app.rs nm $(TMPDIR)/app.o | $(CGREP) rust_begin_unwind nm $(TMPDIR)/app.o | $(CGREP) rust_eh_personality - nm $(TMPDIR)/app.o | $(CGREP) __rg_oom diff --git a/tests/run-make/issue-51671/app.rs b/tests/run-make/issue-51671/app.rs index e9dc1e9744fb1..a9d3457bf90e6 100644 --- a/tests/run-make/issue-51671/app.rs +++ b/tests/run-make/issue-51671/app.rs @@ -1,5 +1,5 @@ #![crate_type = "bin"] -#![feature(lang_items, alloc_error_handler)] +#![feature(lang_items)] #![no_main] #![no_std] @@ -13,8 +13,3 @@ fn panic(_: &PanicInfo) -> ! { #[lang = "eh_personality"] fn eh() {} - -#[alloc_error_handler] -fn oom(_: Layout) -> ! { - loop {} -} diff --git a/tests/run-make/issue-69368/Makefile b/tests/run-make/issue-69368/Makefile deleted file mode 100644 index b1229d1b07fc7..0000000000000 --- a/tests/run-make/issue-69368/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# Test that previously triggered a linker failure with root cause -# similar to one found in the issue #69368. -# -# The crate that provides oom lang item is missing some other lang -# items. Necessary to prevent the use of start-group / end-group. -# -# The weak lang items are defined in a separate compilation units, -# so that linker could omit them if not used. -# -# The crates that need those weak lang items are dependencies of -# crates that provide them. - -all: - $(RUSTC) a.rs - $(RUSTC) b.rs - $(RUSTC) c.rs diff --git a/tests/run-make/issue-69368/a.rs b/tests/run-make/issue-69368/a.rs deleted file mode 100644 index a54f429550e74..0000000000000 --- a/tests/run-make/issue-69368/a.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![crate_type = "rlib"] -#![feature(lang_items)] -#![feature(panic_unwind)] -#![no_std] - -extern crate panic_unwind; - -#[panic_handler] -pub fn panic_handler(_: &core::panic::PanicInfo) -> ! { - loop {} -} - -#[no_mangle] -extern "C" fn __rust_drop_panic() -> ! { - loop {} -} - -#[no_mangle] -extern "C" fn __rust_foreign_exception() -> ! { - loop {} -} - -#[lang = "eh_personality"] -fn eh_personality() { - loop {} -} diff --git a/tests/run-make/issue-69368/b.rs b/tests/run-make/issue-69368/b.rs deleted file mode 100644 index 4d6af0266563b..0000000000000 --- a/tests/run-make/issue-69368/b.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![crate_type = "rlib"] -#![feature(alloc_error_handler)] -#![no_std] - -#[alloc_error_handler] -pub fn error_handler(_: core::alloc::Layout) -> ! { - panic!(); -} diff --git a/tests/run-make/issue-69368/c.rs b/tests/run-make/issue-69368/c.rs deleted file mode 100644 index 729c4249a053a..0000000000000 --- a/tests/run-make/issue-69368/c.rs +++ /dev/null @@ -1,34 +0,0 @@ -#![crate_type = "bin"] -#![feature(start)] -#![no_std] - -extern crate alloc; -extern crate a; -extern crate b; - -use alloc::vec::Vec; -use core::alloc::*; - -struct Allocator; - -unsafe impl GlobalAlloc for Allocator { - unsafe fn alloc(&self, _: Layout) -> *mut u8 { - loop {} - } - - unsafe fn dealloc(&self, _: *mut u8, _: Layout) { - loop {} - } -} - -#[global_allocator] -static ALLOCATOR: Allocator = Allocator; - -#[start] -fn main(argc: isize, _argv: *const *const u8) -> isize { - let mut v = Vec::new(); - for i in 0..argc { - v.push(i); - } - v.iter().sum() -} diff --git a/tests/run-make/wasm-symbols-not-exported/bar.rs b/tests/run-make/wasm-symbols-not-exported/bar.rs index 6ffbd3ec6900d..eb768446b4b92 100644 --- a/tests/run-make/wasm-symbols-not-exported/bar.rs +++ b/tests/run-make/wasm-symbols-not-exported/bar.rs @@ -1,4 +1,4 @@ -#![feature(panic_handler, alloc_error_handler)] +#![feature(panic_handler)] #![crate_type = "cdylib"] #![no_std] @@ -24,11 +24,6 @@ pub extern fn foo(a: u32) -> u32 { a * 2 } -#[alloc_error_handler] -fn a(_: core::alloc::Layout) -> ! { - loop {} -} - #[panic_handler] fn b(_: &core::panic::PanicInfo) -> ! { loop {} diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.rs b/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.rs deleted file mode 100644 index cd06423e3a557..0000000000000 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.rs +++ /dev/null @@ -1,18 +0,0 @@ -// compile-flags:-C panic=abort - -#![feature(alloc_error_handler)] -#![no_std] -#![no_main] - -use core::alloc::Layout; - -#[alloc_error_handler] -fn oom( - info: &Layout, //~^ ERROR mismatched types -) -> () //~^^ ERROR mismatched types -{ - loop {} -} - -#[panic_handler] -fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr deleted file mode 100644 index de92841d7f18e..0000000000000 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-1.stderr +++ /dev/null @@ -1,44 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/alloc-error-handler-bad-signature-1.rs:10:1 - | -LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion -LL | // fn oom( -LL | || info: &Layout, -LL | || ) -> () - | ||_______- arguments to this function are incorrect -LL | | { -LL | | loop {} -LL | | } - | |__^ expected `&Layout`, found `Layout` - | -note: function defined here - --> $DIR/alloc-error-handler-bad-signature-1.rs:10:4 - | -LL | fn oom( - | ^^^ -LL | info: &Layout, - | ------------- - = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0308]: mismatched types - --> $DIR/alloc-error-handler-bad-signature-1.rs:10:1 - | -LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion -LL | // fn oom( -LL | || info: &Layout, -LL | || ) -> () - | ||_______^ expected `!`, found `()` -LL | | { -LL | | loop {} -LL | | } - | |__- expected `!` because of return type - | - = note: expected type `!` - found unit type `()` - = note: this error originates in the attribute macro `alloc_error_handler` (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 E0308`. diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.rs b/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.rs deleted file mode 100644 index 4f76257fc7267..0000000000000 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.rs +++ /dev/null @@ -1,17 +0,0 @@ -// compile-flags:-C panic=abort - -#![feature(alloc_error_handler)] -#![no_std] -#![no_main] - -struct Layout; - -#[alloc_error_handler] -fn oom( - info: Layout, //~^ ERROR mismatched types -) { //~^^ ERROR mismatched types - loop {} -} - -#[panic_handler] -fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr deleted file mode 100644 index 7a495380f2ba1..0000000000000 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-2.stderr +++ /dev/null @@ -1,50 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/alloc-error-handler-bad-signature-2.rs:10:1 - | -LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion -LL | // fn oom( -LL | || info: Layout, -LL | || ) { - | ||_- arguments to this function are incorrect -LL | | loop {} -LL | | } - | |__^ expected `Layout`, found `core::alloc::Layout` - | - = note: `core::alloc::Layout` and `Layout` have similar names, but are actually distinct types -note: `core::alloc::Layout` is defined in crate `core` - --> $SRC_DIR/core/src/alloc/layout.rs:LL:COL -note: `Layout` is defined in the current crate - --> $DIR/alloc-error-handler-bad-signature-2.rs:7:1 - | -LL | struct Layout; - | ^^^^^^^^^^^^^ -note: function defined here - --> $DIR/alloc-error-handler-bad-signature-2.rs:10:4 - | -LL | fn oom( - | ^^^ -LL | info: Layout, - | ------------ - = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info) - -error[E0308]: mismatched types - --> $DIR/alloc-error-handler-bad-signature-2.rs:10:1 - | -LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion -LL | // fn oom( -LL | || info: Layout, -LL | || ) { - | ||_^ expected `!`, found `()` -LL | | loop {} -LL | | } - | |__- expected `!` because of return type - | - = note: expected type `!` - found unit type `()` - = note: this error originates in the attribute macro `alloc_error_handler` (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 E0308`. diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.rs b/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.rs deleted file mode 100644 index ea9ad39a70d81..0000000000000 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.rs +++ /dev/null @@ -1,15 +0,0 @@ -// compile-flags:-C panic=abort - -#![feature(alloc_error_handler)] -#![no_std] -#![no_main] - -struct Layout; - -#[alloc_error_handler] -fn oom() -> ! { //~ ERROR function takes 0 arguments but 1 argument was supplied - loop {} -} - -#[panic_handler] -fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr deleted file mode 100644 index eb739b149a103..0000000000000 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr +++ /dev/null @@ -1,21 +0,0 @@ -error[E0061]: this function takes 0 arguments but 1 argument was supplied - --> $DIR/alloc-error-handler-bad-signature-3.rs:10:1 - | -LL | #[alloc_error_handler] - | ---------------------- in this procedural macro expansion -LL | fn oom() -> ! { - | _-^^^^^^^^^^^^ -LL | | loop {} -LL | | } - | |_- unexpected argument of type `core::alloc::Layout` - | -note: function defined here - --> $DIR/alloc-error-handler-bad-signature-3.rs:10:4 - | -LL | fn oom() -> ! { - | ^^^ - = note: this error originates in the attribute macro `alloc_error_handler` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/alloc-error/default-alloc-error-hook.rs b/tests/ui/alloc-error/default-alloc-error-hook.rs index 8be09500f4e4e..919d4b714a1ae 100644 --- a/tests/ui/alloc-error/default-alloc-error-hook.rs +++ b/tests/ui/alloc-error/default-alloc-error-hook.rs @@ -2,7 +2,7 @@ // ignore-emscripten no processes // ignore-sgx no processes -use std::alloc::{Layout, handle_alloc_error}; +use std::alloc::{handle_alloc_error, Layout}; use std::env; use std::process::Command; use std::str; @@ -24,5 +24,5 @@ fn main() { .strip_suffix("qemu: uncaught target signal 6 (Aborted) - core dumped\n") .unwrap_or(stderr); - assert_eq!(stderr, "memory allocation of 42 bytes failed\n"); + assert!(stderr.contains("memory allocation of 42 bytes failed")); } diff --git a/tests/ui/allocator/no_std-alloc-error-handler-custom.rs b/tests/ui/allocator/no_std-alloc-error-handler-custom.rs deleted file mode 100644 index 2892624339093..0000000000000 --- a/tests/ui/allocator/no_std-alloc-error-handler-custom.rs +++ /dev/null @@ -1,84 +0,0 @@ -// run-pass -// ignore-android no libc -// ignore-emscripten no libc -// ignore-sgx no libc -// ignore-wasm32 no libc -// only-linux -// compile-flags:-C panic=abort -// aux-build:helper.rs - -#![feature(rustc_private, lang_items)] -#![feature(alloc_error_handler)] -#![no_std] -#![no_main] - -extern crate alloc; -extern crate libc; - -// ARM targets need these symbols -#[no_mangle] -pub fn __aeabi_unwind_cpp_pr0() {} - -#[no_mangle] -pub fn __aeabi_unwind_cpp_pr1() {} - -use alloc::boxed::Box; -use alloc::string::ToString; -use core::alloc::{GlobalAlloc, Layout}; -use core::ptr::null_mut; - -extern crate helper; - -struct MyAllocator; - -#[alloc_error_handler] -fn my_oom(layout: Layout) -> ! { - use alloc::fmt::write; - unsafe { - let size = layout.size(); - let mut s = alloc::string::String::new(); - write(&mut s, format_args!("My OOM: failed to allocate {} bytes!\n", size)).unwrap(); - libc::write(libc::STDERR_FILENO, s.as_ptr() as *const _, s.len()); - libc::exit(0) - } -} - -unsafe impl GlobalAlloc for MyAllocator { - unsafe fn alloc(&self, layout: Layout) -> *mut u8 { - if layout.size() < 4096 { libc::malloc(layout.size()) as _ } else { null_mut() } - } - unsafe fn dealloc(&self, _ptr: *mut u8, _layout: Layout) {} -} - -#[global_allocator] -static A: MyAllocator = MyAllocator; - -#[panic_handler] -fn panic(panic_info: &core::panic::PanicInfo) -> ! { - unsafe { - let s = panic_info.to_string(); - const PSTR: &str = "panic occurred: "; - const CR: &str = "\n"; - libc::write(libc::STDERR_FILENO, PSTR.as_ptr() as *const _, PSTR.len()); - libc::write(libc::STDERR_FILENO, s.as_ptr() as *const _, s.len()); - libc::write(libc::STDERR_FILENO, CR.as_ptr() as *const _, CR.len()); - libc::exit(1) - } -} - -// Because we are compiling this code with `-C panic=abort`, this wouldn't normally be needed. -// However, `core` and `alloc` are both compiled with `-C panic=unwind`, which means that functions -// in these libraries will refer to `rust_eh_personality` if LLVM can not *prove* the contents won't -// unwind. So, for this test case we will define the symbol. -#[lang = "eh_personality"] -extern "C" fn rust_eh_personality() {} - -#[derive(Default, Debug)] -struct Page(#[allow(unused_tuple_struct_fields)] [[u64; 32]; 16]); - -#[no_mangle] -fn main(_argc: i32, _argv: *const *const u8) -> isize { - let zero = Box::::new(Default::default()); - helper::work_with(&zero); - 1 -} diff --git a/tests/ui/feature-gates/feature-gate-alloc-error-handler.rs b/tests/ui/feature-gates/feature-gate-alloc-error-handler.rs deleted file mode 100644 index 78d189d20b64d..0000000000000 --- a/tests/ui/feature-gates/feature-gate-alloc-error-handler.rs +++ /dev/null @@ -1,16 +0,0 @@ -// compile-flags:-C panic=abort - -#![no_std] -#![no_main] - -use core::alloc::Layout; - -#[alloc_error_handler] //~ ERROR use of unstable library feature 'alloc_error_handler' -fn oom(info: Layout) -> ! { - loop {} -} - -#[panic_handler] -fn panic(_: &core::panic::PanicInfo) -> ! { - loop {} -} diff --git a/tests/ui/feature-gates/feature-gate-alloc-error-handler.stderr b/tests/ui/feature-gates/feature-gate-alloc-error-handler.stderr deleted file mode 100644 index f414eb463dfbc..0000000000000 --- a/tests/ui/feature-gates/feature-gate-alloc-error-handler.stderr +++ /dev/null @@ -1,12 +0,0 @@ -error[E0658]: use of unstable library feature 'alloc_error_handler' - --> $DIR/feature-gate-alloc-error-handler.rs:8:3 - | -LL | #[alloc_error_handler] - | ^^^^^^^^^^^^^^^^^^^ - | - = note: see issue #51540 for more information - = help: add `#![feature(alloc_error_handler)]` to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/missing/missing-allocator.rs b/tests/ui/missing/missing-allocator.rs index 2dc509f2c632d..e06e603e3bf94 100644 --- a/tests/ui/missing/missing-allocator.rs +++ b/tests/ui/missing/missing-allocator.rs @@ -3,16 +3,10 @@ #![no_std] #![crate_type = "staticlib"] -#![feature(alloc_error_handler)] #[panic_handler] fn panic(_: &core::panic::PanicInfo) -> ! { loop {} } -#[alloc_error_handler] -fn oom(_: core::alloc::Layout) -> ! { - loop {} -} - extern crate alloc; From 4b981c26487ebe56de6b3000fcd98713804beefc Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 23 Mar 2023 23:39:41 +0000 Subject: [PATCH 04/42] Rename -Zoom=panic to -Zoom=unwind --- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/src/config.rs | 6 +++--- compiler/rustc_session/src/options.rs | 2 +- library/alloc/src/alloc.rs | 4 ++-- tests/ui/oom_unwind.rs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 10dfd32d418a2..101967503c1e2 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -776,7 +776,7 @@ fn test_unstable_options_tracking_hash() { tracked!(no_link, true); tracked!(no_profiler_runtime, true); tracked!(no_unique_section_names, true); - tracked!(oom, OomStrategy::Panic); + tracked!(oom, OomStrategy::Unwind); tracked!(osx_rpath_install_name, true); tracked!(packed_bundled_libs, true); tracked!(panic_abort_tests, true); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 79eb31bb1050e..419b6afe7c68a 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -3048,9 +3048,9 @@ pub(crate) mod dep_tracking { #[derive(Clone, Copy, PartialEq, Hash, Debug, Encodable, Decodable, HashStable_Generic)] pub enum OomStrategy { /// Generate a panic that can be caught by `catch_unwind`. - Panic, + Unwind, - /// Abort the process immediately. + /// Calls the panic hook as normal but aborts instead of unwinding. Abort, } @@ -3059,7 +3059,7 @@ impl OomStrategy { pub fn should_panic(self) -> u8 { match self { - OomStrategy::Panic => 1, + OomStrategy::Unwind => 1, OomStrategy::Abort => 0, } } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 631dd0a2146e8..46c992dfefd5f 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -662,7 +662,7 @@ mod parse { pub(crate) fn parse_oom_strategy(slot: &mut OomStrategy, v: Option<&str>) -> bool { match v { - Some("panic") => *slot = OomStrategy::Panic, + Some("unwind") => *slot = OomStrategy::Unwind, Some("abort") => *slot = OomStrategy::Abort, _ => return false, } diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 97bedc604da82..0db23e55a8653 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -398,7 +398,7 @@ fn rust_oom(layout: Layout) -> ! { fn panic_impl(pi: &core::panic::PanicInfo<'_>) -> !; // This symbol is emitted by rustc . - // Its value depends on the -Zoom={panic,abort} compiler option. + // Its value depends on the -Zoom={unwind,abort} compiler option. static __rust_alloc_error_handler_should_panic: u8; } @@ -458,7 +458,7 @@ pub mod __alloc_error_handler { pub unsafe fn __rdl_oom(size: usize, _align: usize) -> ! { extern "Rust" { // This symbol is emitted by rustc next to __rust_alloc_error_handler. - // Its value depends on the -Zoom={panic,abort} compiler option. + // Its value depends on the -Zoom={unwind,abort} compiler option. static __rust_alloc_error_handler_should_panic: u8; } diff --git a/tests/ui/oom_unwind.rs b/tests/ui/oom_unwind.rs index 21a8fb2b22bee..704d6f8b810a9 100644 --- a/tests/ui/oom_unwind.rs +++ b/tests/ui/oom_unwind.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z oom=panic +// compile-flags: -Z oom=unwind // run-pass // no-prefer-dynamic // needs-unwind From f7581d8d219613d6aa2a017d31d230587a6076f6 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Wed, 12 Apr 2023 21:45:21 +0100 Subject: [PATCH 05/42] Suggest using integration tests for proc-macros --- compiler/rustc_resolve/messages.ftl | 3 +++ compiler/rustc_resolve/src/errors.rs | 9 +++++++++ compiler/rustc_resolve/src/macros.rs | 10 +++++----- tests/ui/proc-macro/test-same-crate.rs | 16 ++++++++++++++++ tests/ui/proc-macro/test-same-crate.stderr | 10 ++++++++++ 5 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 tests/ui/proc-macro/test-same-crate.rs create mode 100644 tests/ui/proc-macro/test-same-crate.stderr diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 2628f247c5411..950caaa5ebe2d 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -223,3 +223,6 @@ resolve_remove_surrounding_derive = resolve_add_as_non_derive = add as non-Derive macro `#[{$macro_path}]` + +resolve_proc_macro_same_crate = can't use a procedural macro from the same crate that defines it + .help = you can define integration tests in a directory named `tests` diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index afa796cb6453b..a0b403828edc1 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -508,3 +508,12 @@ pub(crate) struct RemoveSurroundingDerive { pub(crate) struct AddAsNonDerive<'a> { pub(crate) macro_path: &'a str, } + +#[derive(Diagnostic)] +#[diag(resolve_proc_macro_same_crate)] +pub(crate) struct ProcMacroSameCrate { + #[primary_span] + pub(crate) span: Span, + #[help] + pub(crate) is_test: bool, +} diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 22b014c0651c2..2211fb56ccda1 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -1,7 +1,7 @@ //! A bunch of methods and structures more or less related to resolving macros and //! interface provided by `Resolver` to macro expander. -use crate::errors::{AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive}; +use crate::errors::{self, AddAsNonDerive, MacroExpectedFound, RemoveSurroundingDerive}; use crate::Namespace::*; use crate::{BuiltinMacroState, Determinacy}; use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet}; @@ -513,10 +513,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(def_id) = def_id.as_local() { self.unused_macros.remove(&def_id); if self.proc_macro_stubs.contains(&def_id) { - self.tcx.sess.span_err( - path.span, - "can't use a procedural macro from the same crate that defines it", - ); + self.tcx.sess.emit_err(errors::ProcMacroSameCrate { + span: path.span, + is_test: self.tcx.sess.is_test_crate(), + }); } } } diff --git a/tests/ui/proc-macro/test-same-crate.rs b/tests/ui/proc-macro/test-same-crate.rs new file mode 100644 index 0000000000000..c13f384fa3ae1 --- /dev/null +++ b/tests/ui/proc-macro/test-same-crate.rs @@ -0,0 +1,16 @@ +// compile-flags: --test +#![crate_type = "proc-macro"] + +extern crate proc_macro; +use proc_macro::TokenStream; + +#[proc_macro] +pub fn mac(input: TokenStream) -> TokenStream { loop {} } + +#[cfg(test)] +mod test { + #[test] + fn t() { crate::mac!(A) } + //~^ ERROR can't use a procedural macro from the same crate that defines it + //~| HELP you can define integration tests in a directory named `tests` +} diff --git a/tests/ui/proc-macro/test-same-crate.stderr b/tests/ui/proc-macro/test-same-crate.stderr new file mode 100644 index 0000000000000..5d12e149c3c4c --- /dev/null +++ b/tests/ui/proc-macro/test-same-crate.stderr @@ -0,0 +1,10 @@ +error: can't use a procedural macro from the same crate that defines it + --> $DIR/test-same-crate.rs:13:14 + | +LL | fn t() { crate::mac!(A) } + | ^^^^^^^^^^ + | + = help: you can define integration tests in a directory named `tests` + +error: aborting due to previous error + From 99962a841831469fbb7a06ccc5a9c9766d052234 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 18 Apr 2023 17:54:34 +0000 Subject: [PATCH 06/42] Refactor `SyntaxContext::ctxt` logic. --- compiler/rustc_span/src/span_encoding.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_span/src/span_encoding.rs b/compiler/rustc_span/src/span_encoding.rs index c600298c51a08..1eea0f63ca0cc 100644 --- a/compiler/rustc_span/src/span_encoding.rs +++ b/compiler/rustc_span/src/span_encoding.rs @@ -181,19 +181,23 @@ impl Span { #[inline] pub fn ctxt(self) -> SyntaxContext { let ctxt_or_tag = self.ctxt_or_tag as u32; - if ctxt_or_tag <= MAX_CTXT { - if self.len_or_tag == LEN_TAG || self.len_or_tag & PARENT_MASK == 0 { - // Inline format or interned format with inline ctxt. - SyntaxContext::from_u32(ctxt_or_tag) + // Check for interned format. + if self.len_or_tag == LEN_TAG { + if ctxt_or_tag == CTXT_TAG { + // Fully interned format. + let index = self.base_or_index; + with_span_interner(|interner| interner.spans[index as usize].ctxt) } else { - // Inline format or interned format with inline parent. - // We know that the SyntaxContext is root. - SyntaxContext::root() + // Interned format with inline ctxt. + SyntaxContext::from_u32(ctxt_or_tag) } + } else if self.len_or_tag & PARENT_MASK == 0 { + // Inline format with inline ctxt. + SyntaxContext::from_u32(ctxt_or_tag) } else { - // Interned format. - let index = self.base_or_index; - with_span_interner(|interner| interner.spans[index as usize].ctxt) + // Inline format with inline parent. + // We know that the SyntaxContext is root. + SyntaxContext::root() } } } From 14678778dc50ce5886856826f8cd35dc080ead7e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Apr 2023 01:41:01 +0000 Subject: [PATCH 07/42] Remove find_map_relevant_impl --- compiler/rustc_middle/src/ty/trait_def.rs | 62 +++----- compiler/rustc_middle/src/ty/util.rs | 37 +++-- .../src/solve/trait_goals.rs | 10 +- .../src/traits/error_reporting/mod.rs | 145 ++++++++++-------- .../src/traits/select/candidate_assembly.rs | 22 ++- .../passes/collect_intra_doc_links.rs | 20 +-- 6 files changed, 154 insertions(+), 142 deletions(-) diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 6747da7abd3af..e61037e5ea86f 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -139,40 +139,6 @@ impl<'tcx> TyCtxt<'tcx> { treat_projections: TreatProjections, mut f: impl FnMut(DefId), ) { - let _: Option<()> = - self.find_map_relevant_impl(trait_def_id, self_ty, treat_projections, |did| { - f(did); - None - }); - } - - /// `trait_def_id` MUST BE the `DefId` of a trait. - pub fn non_blanket_impls_for_ty( - self, - trait_def_id: DefId, - self_ty: Ty<'tcx>, - ) -> impl Iterator + 'tcx { - let impls = self.trait_impls_of(trait_def_id); - if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsCandidateKey) { - if let Some(impls) = impls.non_blanket_impls.get(&simp) { - return impls.iter().copied(); - } - } - - [].iter().copied() - } - - /// Applies function to every impl that could possibly match the self type `self_ty` and returns - /// the first non-none value. - /// - /// `trait_def_id` MUST BE the `DefId` of a trait. - pub fn find_map_relevant_impl( - self, - trait_def_id: DefId, - self_ty: Ty<'tcx>, - treat_projections: TreatProjections, - mut f: impl FnMut(DefId) -> Option, - ) -> Option { // FIXME: This depends on the set of all impls for the trait. That is // unfortunate wrt. incremental compilation. // @@ -181,9 +147,7 @@ impl<'tcx> TyCtxt<'tcx> { let impls = self.trait_impls_of(trait_def_id); for &impl_def_id in impls.blanket_impls.iter() { - if let result @ Some(_) = f(impl_def_id) { - return result; - } + f(impl_def_id); } // Note that we're using `TreatParams::ForLookup` to query `non_blanket_impls` while using @@ -199,20 +163,30 @@ impl<'tcx> TyCtxt<'tcx> { if let Some(simp) = fast_reject::simplify_type(self, self_ty, treat_params) { if let Some(impls) = impls.non_blanket_impls.get(&simp) { for &impl_def_id in impls { - if let result @ Some(_) = f(impl_def_id) { - return result; - } + f(impl_def_id); } } } else { for &impl_def_id in impls.non_blanket_impls.values().flatten() { - if let result @ Some(_) = f(impl_def_id) { - return result; - } + f(impl_def_id); } } + } - None + /// `trait_def_id` MUST BE the `DefId` of a trait. + pub fn non_blanket_impls_for_ty( + self, + trait_def_id: DefId, + self_ty: Ty<'tcx>, + ) -> impl Iterator + 'tcx { + let impls = self.trait_impls_of(trait_def_id); + if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsCandidateKey) { + if let Some(impls) = impls.non_blanket_impls.get(&simp) { + return impls.iter().copied(); + } + } + + [].iter().copied() } /// Returns an iterator containing all impls for `trait_def_id`. diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index c8a78ec03d947..f076ea7830bc3 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -2,7 +2,6 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir; -use crate::ty::fast_reject::TreatProjections; use crate::ty::layout::IntegerExt; use crate::ty::{ self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, @@ -359,21 +358,29 @@ impl<'tcx> TyCtxt<'tcx> { self.ensure().coherent_trait(drop_trait); let ty = self.type_of(adt_did).subst_identity(); - let (did, constness) = self.find_map_relevant_impl( - drop_trait, - ty, - // FIXME: This could also be some other mode, like "unexpected" - TreatProjections::ForLookup, - |impl_did| { - if let Some(item_id) = self.associated_item_def_ids(impl_did).first() { - if validate(self, impl_did).is_ok() { - return Some((*item_id, self.constness(impl_did))); - } - } - None - }, - )?; + let mut dtor_candidate = None; + self.for_each_relevant_impl(drop_trait, ty, |impl_did| { + let Some(item_id) = self.associated_item_def_ids(impl_did).first() else { + self.sess.delay_span_bug(self.def_span(impl_did), "Drop impl without drop function"); + return; + }; + + if validate(self, impl_did).is_err() { + // Already `ErrorGuaranteed`, no need to delay a span bug here. + return; + } + + if let Some((old_item_id, _)) = dtor_candidate { + self.sess + .struct_span_err(self.def_span(item_id), "multiple drop impls found") + .span_note(self.def_span(old_item_id), "other impl here") + .delay_as_bug(); + } + + dtor_candidate = Some((*item_id, self.constness(impl_did))); + }); + let (did, constness) = dtor_candidate?; Some(ty::Destructor { did, constness }) } diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index abd11a15ac23a..acfc8e98fcb89 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -645,12 +645,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // FIXME: Handling opaques here is kinda sus. Especially because we // simplify them to PlaceholderSimplifiedType. | ty::Alias(ty::Opaque, _) => { - if let Some(def_id) = self.tcx().find_map_relevant_impl( + let mut disqualifying_impl = None; + self.tcx().for_each_relevant_impl_treating_projections( goal.predicate.def_id(), goal.predicate.self_ty(), TreatProjections::NextSolverLookup, - Some, - ) { + |impl_def_id| { + disqualifying_impl = Some(impl_def_id); + }, + ); + if let Some(def_id) = disqualifying_impl { debug!(?def_id, ?goal, "disqualified auto-trait implementation"); // No need to actually consider the candidate here, // since we do that in `consider_impl_candidate`. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 0352f0f380db1..660f78509d3ef 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -32,7 +32,6 @@ use rustc_infer::infer::{InferOk, TypeTrace}; use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::fast_reject::TreatProjections; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print}; use rustc_middle::ty::{ @@ -1836,57 +1835,61 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { }); let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}"); - let secondary_span = match predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => self - .tcx - .opt_associated_item(proj.projection_ty.def_id) - .and_then(|trait_assoc_item| { - self.tcx - .trait_of_item(proj.projection_ty.def_id) - .map(|id| (trait_assoc_item, id)) - }) - .and_then(|(trait_assoc_item, id)| { - let trait_assoc_ident = trait_assoc_item.ident(self.tcx); - self.tcx.find_map_relevant_impl( - id, - proj.projection_ty.self_ty(), - TreatProjections::ForLookup, - |did| { - self.tcx - .associated_items(did) - .in_definition_order() - .find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident) - }, - ) - }) - .and_then(|item| match self.tcx.hir().get_if_local(item.def_id) { - Some( - hir::Node::TraitItem(hir::TraitItem { - kind: hir::TraitItemKind::Type(_, Some(ty)), - .. - }) - | hir::Node::ImplItem(hir::ImplItem { - kind: hir::ImplItemKind::Type(ty), - .. - }), - ) => Some(( - ty.span, - with_forced_trimmed_paths!(format!( - "type mismatch resolving `{}`", - self.resolve_vars_if_possible(predicate) - .print(FmtPrinter::new_with_limit( - self.tcx, - Namespace::TypeNS, - rustc_session::Limit(5), - )) - .unwrap() - .into_buffer() - )), + let secondary_span = (|| { + let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = + predicate.kind().skip_binder() + else { + return None; + }; + + let trait_assoc_item = self.tcx.opt_associated_item(proj.projection_ty.def_id)?; + let trait_assoc_ident = trait_assoc_item.ident(self.tcx); + + let mut associated_items = vec![]; + self.tcx.for_each_relevant_impl( + self.tcx.trait_of_item(proj.projection_ty.def_id)?, + proj.projection_ty.self_ty(), + |impl_def_id| { + associated_items.extend( + self.tcx + .associated_items(impl_def_id) + .in_definition_order() + .find(|assoc| assoc.ident(self.tcx) == trait_assoc_ident), + ); + }, + ); + + let [associated_item]: &[ty::AssocItem] = &associated_items[..] else { + return None; + }; + match self.tcx.hir().get_if_local(associated_item.def_id) { + Some( + hir::Node::TraitItem(hir::TraitItem { + kind: hir::TraitItemKind::Type(_, Some(ty)), + .. + }) + | hir::Node::ImplItem(hir::ImplItem { + kind: hir::ImplItemKind::Type(ty), + .. + }), + ) => Some(( + ty.span, + with_forced_trimmed_paths!(format!( + "type mismatch resolving `{}`", + self.resolve_vars_if_possible(predicate) + .print(FmtPrinter::new_with_limit( + self.tcx, + Namespace::TypeNS, + rustc_session::Limit(5), + )) + .unwrap() + .into_buffer() )), - _ => None, - }), - _ => None, - }; + )), + _ => None, + } + })(); + self.note_type_err( &mut diag, &obligation.cause, @@ -2228,14 +2231,18 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err: &mut Diagnostic, trait_ref: &ty::PolyTraitRef<'tcx>, ) -> bool { - let get_trait_impl = |trait_def_id| { - self.tcx.find_map_relevant_impl( + let get_trait_impls = |trait_def_id| { + let mut trait_impls = vec![]; + self.tcx.for_each_relevant_impl( trait_def_id, trait_ref.skip_binder().self_ty(), - TreatProjections::ForLookup, - Some, - ) + |impl_def_id| { + trait_impls.push(impl_def_id); + }, + ); + trait_impls }; + let required_trait_path = self.tcx.def_path_str(trait_ref.def_id()); let traits_with_same_path: std::collections::BTreeSet<_> = self .tcx @@ -2245,17 +2252,23 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { .collect(); let mut suggested = false; for trait_with_same_path in traits_with_same_path { - if let Some(impl_def_id) = get_trait_impl(trait_with_same_path) { - let impl_span = self.tcx.def_span(impl_def_id); - err.span_help(impl_span, "trait impl with same name found"); - let trait_crate = self.tcx.crate_name(trait_with_same_path.krate); - let crate_msg = format!( - "perhaps two different versions of crate `{}` are being used?", - trait_crate - ); - err.note(&crate_msg); - suggested = true; + let trait_impls = get_trait_impls(trait_with_same_path); + if trait_impls.is_empty() { + continue; } + let impl_spans: Vec<_> = + trait_impls.iter().map(|impl_def_id| self.tcx.def_span(*impl_def_id)).collect(); + err.span_help( + impl_spans, + format!("trait impl{} with same name found", pluralize!(trait_impls.len())), + ); + let trait_crate = self.tcx.crate_name(trait_with_same_path.krate); + let crate_msg = format!( + "perhaps two different versions of crate `{}` are being used?", + trait_crate + ); + err.note(&crate_msg); + suggested = true; } suggested } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 1f5bbc178f7d7..403593a47c100 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -11,7 +11,7 @@ use hir::LangItem; use rustc_hir as hir; use rustc_infer::traits::ObligationCause; use rustc_infer::traits::{Obligation, SelectionError, TraitObligation}; -use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, TreatProjections}; +use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use crate::traits; @@ -875,12 +875,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::Adt(..) => { - // Find a custom `impl Drop` impl, if it exists - let relevant_impl = self.tcx().find_map_relevant_impl( + let mut relevant_impl = None; + self.tcx().for_each_relevant_impl( self.tcx().require_lang_item(LangItem::Drop, None), obligation.predicate.skip_binder().trait_ref.self_ty(), - TreatProjections::ForLookup, - Some, + |impl_def_id| { + if let Some(old_impl_def_id) = relevant_impl { + self.tcx() + .sess + .struct_span_err( + self.tcx().def_span(impl_def_id), + "multiple drop impls found", + ) + .span_note(self.tcx().def_span(old_impl_def_id), "other impl here") + .delay_as_bug(); + } + + relevant_impl = Some(impl_def_id); + }, ); if let Some(impl_def_id) = relevant_impl { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 33e80df9ed77b..f2486abaaa77e 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -13,7 +13,7 @@ use rustc_hir::def::Namespace::*; use rustc_hir::def::{DefKind, Namespace, PerNS}; use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::Mutability; -use rustc_middle::ty::{fast_reject::TreatProjections, Ty, TyCtxt}; +use rustc_middle::ty::{Ty, TyCtxt}; use rustc_middle::{bug, ty}; use rustc_resolve::rustdoc::{has_primitive_or_keyword_docs, prepare_to_doc_link_resolution}; use rustc_resolve::rustdoc::{strip_generics_from_path, MalformedGenerics}; @@ -772,11 +772,10 @@ fn trait_impls_for<'a>( module: DefId, ) -> FxHashSet<(DefId, DefId)> { let tcx = cx.tcx; - let iter = tcx.doc_link_traits_in_scope(module).iter().flat_map(|&trait_| { - trace!("considering explicit impl for trait {:?}", trait_); + let mut impls = FxHashSet::default(); - // Look at each trait implementation to see if it's an impl for `did` - tcx.find_map_relevant_impl(trait_, ty, TreatProjections::ForLookup, |impl_| { + for &trait_ in tcx.doc_link_traits_in_scope(module) { + tcx.for_each_relevant_impl(trait_, ty, |impl_| { let trait_ref = tcx.impl_trait_ref(impl_).expect("this is not an inherent impl"); // Check if these are the same type. let impl_type = trait_ref.skip_binder().self_ty(); @@ -800,10 +799,13 @@ fn trait_impls_for<'a>( _ => false, }; - if saw_impl { Some((impl_, trait_)) } else { None } - }) - }); - iter.collect() + if saw_impl { + impls.insert((impl_, trait_)); + } + }); + } + + impls } /// Check for resolve collisions between a trait and its derive. From 8a7a020a2a11dabf566552c78faf8174e34fc1ec Mon Sep 17 00:00:00 2001 From: John Bobbo Date: Wed, 19 Apr 2023 17:18:51 -0700 Subject: [PATCH 08/42] Remove a few uses of dynamic dispatch during monomorphization/partitioning with the use of an enum. --- .../src/partitioning/default.rs | 13 ++- .../src/partitioning/mod.rs | 98 ++++++++++++++++--- 2 files changed, 91 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 49126045d0cfe..4f2c2ea425f39 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -16,17 +16,20 @@ use super::PartitioningCx; use crate::collector::InliningMap; use crate::partitioning::merging; use crate::partitioning::{ - MonoItemPlacement, Partitioner, PostInliningPartitioning, PreInliningPartitioning, + MonoItemPlacement, Partition, PostInliningPartitioning, PreInliningPartitioning, }; pub struct DefaultPartitioning; -impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { - fn place_root_mono_items( +impl<'tcx> Partition<'tcx> for DefaultPartitioning { + fn place_root_mono_items( &mut self, cx: &PartitioningCx<'_, 'tcx>, - mono_items: &mut dyn Iterator>, - ) -> PreInliningPartitioning<'tcx> { + mono_items: &mut I, + ) -> PreInliningPartitioning<'tcx> + where + I: Iterator>, + { let mut roots = FxHashSet::default(); let mut codegen_units = FxHashMap::default(); let is_incremental_build = cx.tcx.sess.opts.incremental.is_some(); diff --git a/compiler/rustc_monomorphize/src/partitioning/mod.rs b/compiler/rustc_monomorphize/src/partitioning/mod.rs index 18aa0742c099a..993e35c7fd251 100644 --- a/compiler/rustc_monomorphize/src/partitioning/mod.rs +++ b/compiler/rustc_monomorphize/src/partitioning/mod.rs @@ -118,18 +118,81 @@ use crate::errors::{ CouldntDumpMonoStats, SymbolAlreadyDefined, UnknownCguCollectionMode, UnknownPartitionStrategy, }; +enum Partitioner { + Default(default::DefaultPartitioning), + // Other partitioning strategies can go here. + Unknown, +} + +impl<'tcx> Partition<'tcx> for Partitioner { + fn place_root_mono_items( + &mut self, + cx: &PartitioningCx<'_, 'tcx>, + mono_items: &mut I, + ) -> PreInliningPartitioning<'tcx> + where + I: Iterator>, + { + match self { + Partitioner::Default(partitioner) => partitioner.place_root_mono_items(cx, mono_items), + Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy), + } + } + + fn merge_codegen_units( + &mut self, + cx: &PartitioningCx<'_, 'tcx>, + initial_partitioning: &mut PreInliningPartitioning<'tcx>, + ) { + match self { + Partitioner::Default(partitioner) => { + partitioner.merge_codegen_units(cx, initial_partitioning) + } + Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy), + } + } + + fn place_inlined_mono_items( + &mut self, + cx: &PartitioningCx<'_, 'tcx>, + initial_partitioning: PreInliningPartitioning<'tcx>, + ) -> PostInliningPartitioning<'tcx> { + match self { + Partitioner::Default(partitioner) => { + partitioner.place_inlined_mono_items(cx, initial_partitioning) + } + Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy), + } + } + + fn internalize_symbols( + &mut self, + cx: &PartitioningCx<'_, 'tcx>, + post_inlining_partitioning: &mut PostInliningPartitioning<'tcx>, + ) { + match self { + Partitioner::Default(partitioner) => { + partitioner.internalize_symbols(cx, post_inlining_partitioning) + } + Partitioner::Unknown => cx.tcx.sess.emit_fatal(UnknownPartitionStrategy), + } + } +} + pub struct PartitioningCx<'a, 'tcx> { tcx: TyCtxt<'tcx>, target_cgu_count: usize, inlining_map: &'a InliningMap<'tcx>, } -trait Partitioner<'tcx> { - fn place_root_mono_items( +trait Partition<'tcx> { + fn place_root_mono_items( &mut self, cx: &PartitioningCx<'_, 'tcx>, - mono_items: &mut dyn Iterator>, - ) -> PreInliningPartitioning<'tcx>; + mono_items: &mut I, + ) -> PreInliningPartitioning<'tcx> + where + I: Iterator>; fn merge_codegen_units( &mut self, @@ -150,26 +213,27 @@ trait Partitioner<'tcx> { ); } -fn get_partitioner<'tcx>(tcx: TyCtxt<'tcx>) -> Box> { +fn get_partitioner(tcx: TyCtxt<'_>) -> Partitioner { let strategy = match &tcx.sess.opts.unstable_opts.cgu_partitioning_strategy { None => "default", Some(s) => &s[..], }; match strategy { - "default" => Box::new(default::DefaultPartitioning), - _ => { - tcx.sess.emit_fatal(UnknownPartitionStrategy); - } + "default" => Partitioner::Default(default::DefaultPartitioning), + _ => Partitioner::Unknown, } } -pub fn partition<'tcx>( +pub fn partition<'tcx, I>( tcx: TyCtxt<'tcx>, - mono_items: &mut dyn Iterator>, + mono_items: &mut I, max_cgu_count: usize, inlining_map: &InliningMap<'tcx>, -) -> Vec> { +) -> Vec> +where + I: Iterator>, +{ let _prof_timer = tcx.prof.generic_activity("cgu_partitioning"); let mut partitioner = get_partitioner(tcx); @@ -182,7 +246,9 @@ pub fn partition<'tcx>( partitioner.place_root_mono_items(cx, mono_items) }; - initial_partitioning.codegen_units.iter_mut().for_each(|cgu| cgu.create_size_estimate(tcx)); + for cgu in &mut initial_partitioning.codegen_units { + cgu.create_size_estimate(tcx); + } debug_dump(tcx, "INITIAL PARTITIONING:", initial_partitioning.codegen_units.iter()); @@ -202,7 +268,9 @@ pub fn partition<'tcx>( partitioner.place_inlined_mono_items(cx, initial_partitioning) }; - post_inlining.codegen_units.iter_mut().for_each(|cgu| cgu.create_size_estimate(tcx)); + for cgu in &mut post_inlining.codegen_units { + cgu.create_size_estimate(tcx); + } debug_dump(tcx, "POST INLINING:", post_inlining.codegen_units.iter()); @@ -380,7 +448,7 @@ fn collect_and_partition_mono_items(tcx: TyCtxt<'_>, (): ()) -> (&DefIdSet, &[Co || { let mut codegen_units = partition( tcx, - &mut items.iter().cloned(), + &mut items.iter().copied(), tcx.sess.codegen_units(), &inlining_map, ); From 1a446947133c6dc39db8c9dd65a6aebd217e067d Mon Sep 17 00:00:00 2001 From: Qiu Chaofan Date: Wed, 19 Apr 2023 12:54:03 +0800 Subject: [PATCH 09/42] Remove deprecated LLVM any_isa --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index c9acbab253e10..abbe8e597709a 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -523,14 +523,14 @@ extern "C" typedef void (*LLVMRustSelfProfileBeforePassCallback)(void*, // LlvmS extern "C" typedef void (*LLVMRustSelfProfileAfterPassCallback)(void*); // LlvmSelfProfiler std::string LLVMRustwrappedIrGetName(const llvm::Any &WrappedIr) { - if (any_isa(WrappedIr)) - return any_cast(WrappedIr)->getName().str(); - if (any_isa(WrappedIr)) - return any_cast(WrappedIr)->getName().str(); - if (any_isa(WrappedIr)) - return any_cast(WrappedIr)->getName().str(); - if (any_isa(WrappedIr)) - return any_cast(WrappedIr)->getName(); + if (const auto *Cast = any_cast(&WrappedIr)) + return (*Cast)->getName().str(); + if (const auto *Cast = any_cast(&WrappedIr)) + return (*Cast)->getName().str(); + if (const auto *Cast = any_cast(&WrappedIr)) + return (*Cast)->getName().str(); + if (const auto *Cast = any_cast(&WrappedIr)) + return (*Cast)->getName(); return ""; } From 964600b38ed0aeec8d3869aa38d31b3e1553066a Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 17 Apr 2023 16:38:30 +0000 Subject: [PATCH 10/42] Clone region var origins instead of taking in borrowck --- .../src/diagnostics/conflict_errors.rs | 20 +++++--------- .../rustc_borrowck/src/diagnostics/mod.rs | 27 ++++++++----------- compiler/rustc_borrowck/src/nll.rs | 2 +- compiler/rustc_infer/src/infer/mod.rs | 4 +-- tests/ui/traits/new-solver/borrowck-error.rs | 11 ++++++++ .../traits/new-solver/borrowck-error.stderr | 12 +++++++++ 6 files changed, 43 insertions(+), 33 deletions(-) create mode 100644 tests/ui/traits/new-solver/borrowck-error.rs create mode 100644 tests/ui/traits/new-solver/borrowck-error.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 49e74a1b000d4..e20fd49715ee1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -10,7 +10,6 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem}; -use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::ObligationCause; use rustc_middle::hir::nested_filter::OnlyBodies; use rustc_middle::mir::tcx::PlaceTy; @@ -643,11 +642,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let Some(default_trait) = tcx.get_diagnostic_item(sym::Default) else { return false; }; - // Regions are already solved, so we must use a fresh InferCtxt, - // but the type has region variables, so erase those. - tcx.infer_ctxt() - .build() - .type_implements_trait(default_trait, [tcx.erase_regions(ty)], param_env) + self.infcx + .type_implements_trait(default_trait, [ty], param_env) .must_apply_modulo_regions() }; @@ -740,13 +736,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn suggest_cloning(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) { let tcx = self.infcx.tcx; // Try to find predicates on *generic params* that would allow copying `ty` - let infcx = tcx.infer_ctxt().build(); - if let Some(clone_trait_def) = tcx.lang_items().clone_trait() - && infcx + && self.infcx .type_implements_trait( clone_trait_def, - [tcx.erase_regions(ty)], + [ty], self.param_env, ) .must_apply_modulo_regions() @@ -770,12 +764,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { .and_then(|def_id| tcx.hir().get_generics(def_id)) else { return; }; // Try to find predicates on *generic params* that would allow copying `ty` - let infcx = tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); + let ocx = ObligationCtxt::new(&self.infcx); let copy_did = tcx.require_lang_item(LangItem::Copy, Some(span)); let cause = ObligationCause::misc(span, self.mir_def_id()); - ocx.register_bound(cause, self.param_env, infcx.tcx.erase_regions(ty), copy_did); + ocx.register_bound(cause, self.param_env, ty, copy_did); let errors = ocx.select_all_or_error(); // Only emit suggestion if all required predicates are on generic @@ -2220,7 +2213,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let tcx = self.infcx.tcx; let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; - let return_ty = tcx.erase_regions(return_ty); // to avoid panics if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 4a85df9f8c09e..299d04c4fb6e3 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -10,7 +10,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::GeneratorKind; use rustc_index::vec::IndexSlice; -use rustc_infer::infer::{LateBoundRegionConversionTime, TyCtxtInferExt}; +use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ AggregateKind, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location, Operand, Place, @@ -1042,15 +1042,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring { let ty = moved_place.ty(self.body, tcx).ty; let suggest = match tcx.get_diagnostic_item(sym::IntoIterator) { - Some(def_id) => { - let infcx = self.infcx.tcx.infer_ctxt().build(); - type_known_to_meet_bound_modulo_regions( - &infcx, - self.param_env, - tcx.mk_imm_ref(tcx.lifetimes.re_erased, tcx.erase_regions(ty)), - def_id, - ) - } + Some(def_id) => type_known_to_meet_bound_modulo_regions( + &self.infcx, + self.param_env, + tcx.mk_imm_ref(tcx.lifetimes.re_erased, ty), + def_id, + ), _ => false, }; if suggest { @@ -1094,20 +1091,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { is_partial, is_loop_message, }); - let infcx = tcx.infer_ctxt().build(); // Erase and shadow everything that could be passed to the new infcx. - let ty = tcx.erase_regions(moved_place.ty(self.body, tcx).ty); - let method_substs = tcx.erase_regions(method_substs); + let ty = moved_place.ty(self.body, tcx).ty; if let ty::Adt(def, substs) = ty.kind() && Some(def.did()) == tcx.lang_items().pin_type() && let ty::Ref(_, _, hir::Mutability::Mut) = substs.type_at(0).kind() - && let self_ty = infcx.instantiate_binder_with_fresh_vars( + && let self_ty = self.infcx.instantiate_binder_with_fresh_vars( fn_call_span, LateBoundRegionConversionTime::FnCall, tcx.fn_sig(method_did).subst(tcx, method_substs).input(0), ) - && infcx.can_eq(self.param_env, ty, self_ty) + && self.infcx.can_eq(self.param_env, ty, self_ty) { err.eager_subdiagnostic( &self.infcx.tcx.sess.parse_sess.span_diagnostic, @@ -1123,7 +1118,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.param_env, ty::Binder::dummy(trait_ref), ) - && infcx.predicate_must_hold_modulo_regions(&o) + && self.infcx.predicate_must_hold_modulo_regions(&o) { err.span_suggestion_verbose( fn_call_span.shrink_to_lo(), diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 73b8765e57d1a..a5cd7f5815bdf 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -235,7 +235,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( // Create the region inference context, taking ownership of the // region inference data that was contained in `infcx`, and the // base constraints generated by the type-check. - let var_origins = infcx.take_region_var_origins(); + let var_origins = infcx.get_region_var_origins(); let MirTypeckRegionConstraints { placeholder_indices, placeholder_index_to_region: _, diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index f263a0773e4e1..fa19a8bc09c90 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1228,11 +1228,11 @@ impl<'tcx> InferCtxt<'tcx> { /// hence that `resolve_regions_and_report_errors` can never be /// called. This is used only during NLL processing to "hand off" ownership /// of the set of region variables into the NLL region context. - pub fn take_region_var_origins(&self) -> VarInfos { + pub fn get_region_var_origins(&self) -> VarInfos { let mut inner = self.inner.borrow_mut(); let (var_infos, data) = inner .region_constraint_storage - .take() + .clone() .expect("regions already resolved") .with_log(&mut inner.undo_log) .into_infos_and_data(); diff --git a/tests/ui/traits/new-solver/borrowck-error.rs b/tests/ui/traits/new-solver/borrowck-error.rs new file mode 100644 index 0000000000000..4787a2c7e1192 --- /dev/null +++ b/tests/ui/traits/new-solver/borrowck-error.rs @@ -0,0 +1,11 @@ +// compile-flags: -Ztrait-solver=next + +use std::collections::HashMap; + +fn foo() -> &'static HashMap +{ + &HashMap::new() + //~^ ERROR cannot return reference to temporary value +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/borrowck-error.stderr b/tests/ui/traits/new-solver/borrowck-error.stderr new file mode 100644 index 0000000000000..a7d8201747a12 --- /dev/null +++ b/tests/ui/traits/new-solver/borrowck-error.stderr @@ -0,0 +1,12 @@ +error[E0515]: cannot return reference to temporary value + --> $DIR/borrowck-error.rs:7:5 + | +LL | &HashMap::new() + | ^-------------- + | || + | |temporary value created here + | returns a reference to data owned by the current function + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0515`. From 4da05e0b88d8b51fc6912da2d0b93edb2780e76b Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Fri, 21 Apr 2023 09:29:55 -0700 Subject: [PATCH 11/42] Adjust expected result for coverage test --- .../coverage-reports/expected_show_coverage.issue-84561.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/run-make/coverage-reports/expected_show_coverage.issue-84561.txt b/tests/run-make/coverage-reports/expected_show_coverage.issue-84561.txt index 4a60432c14c18..9c3192c008c3d 100644 --- a/tests/run-make/coverage-reports/expected_show_coverage.issue-84561.txt +++ b/tests/run-make/coverage-reports/expected_show_coverage.issue-84561.txt @@ -136,10 +136,10 @@ 134| | 135| |impl std::fmt::Debug for Foo { 136| | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - 137| 7| write!(f, "try and succeed")?; + 137| 9| write!(f, "try and succeed")?; ^0 - 138| 7| Ok(()) - 139| 7| } + 138| 9| Ok(()) + 139| 9| } 140| |} 141| | 142| |static mut DEBUG_LEVEL_ENABLED: bool = false; From f74fe8bf4ca773e416d4da3a3bf37045b06ea3de Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Fri, 21 Apr 2023 20:53:21 +0100 Subject: [PATCH 12/42] Limit read size in `File::read_to_end` loop This works around performance issues on Windows by limiting reads the size of reads when the expected size is known. --- library/std/src/fs.rs | 40 ++++++++++++++++++++----------------- library/std/src/io/mod.rs | 24 +++++++++++++++++----- library/std/src/io/tests.rs | 2 +- library/std/src/lib.rs | 1 + 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index c550378e7d6b7..55580b23a6249 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -249,9 +249,9 @@ pub struct DirBuilder { pub fn read>(path: P) -> io::Result> { fn inner(path: &Path) -> io::Result> { let mut file = File::open(path)?; - let size = file.metadata().map(|m| m.len()).unwrap_or(0); - let mut bytes = Vec::with_capacity(size as usize); - io::default_read_to_end(&mut file, &mut bytes)?; + let size = file.metadata().map(|m| m.len() as usize).ok(); + let mut bytes = Vec::with_capacity(size.unwrap_or(0)); + io::default_read_to_end(&mut file, &mut bytes, size)?; Ok(bytes) } inner(path.as_ref()) @@ -289,9 +289,9 @@ pub fn read>(path: P) -> io::Result> { pub fn read_to_string>(path: P) -> io::Result { fn inner(path: &Path) -> io::Result { let mut file = File::open(path)?; - let size = file.metadata().map(|m| m.len()).unwrap_or(0); - let mut string = String::with_capacity(size as usize); - io::default_read_to_string(&mut file, &mut string)?; + let size = file.metadata().map(|m| m.len() as usize).ok(); + let mut string = String::with_capacity(size.unwrap_or(0)); + io::default_read_to_string(&mut file, &mut string, size)?; Ok(string) } inner(path.as_ref()) @@ -732,12 +732,12 @@ impl fmt::Debug for File { } /// Indicates how much extra capacity is needed to read the rest of the file. -fn buffer_capacity_required(mut file: &File) -> usize { - let size = file.metadata().map(|m| m.len()).unwrap_or(0); - let pos = file.stream_position().unwrap_or(0); +fn buffer_capacity_required(mut file: &File) -> Option { + let size = file.metadata().map(|m| m.len()).ok()?; + let pos = file.stream_position().ok()?; // Don't worry about `usize` overflow because reading will fail regardless // in that case. - size.saturating_sub(pos) as usize + Some(size.saturating_sub(pos) as usize) } #[stable(feature = "rust1", since = "1.0.0")] @@ -761,14 +761,16 @@ impl Read for File { // Reserves space in the buffer based on the file size when available. fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { - buf.reserve(buffer_capacity_required(self)); - io::default_read_to_end(self, buf) + let size = buffer_capacity_required(self); + buf.reserve(size.unwrap_or(0)); + io::default_read_to_end(self, buf, size) } // Reserves space in the buffer based on the file size when available. fn read_to_string(&mut self, buf: &mut String) -> io::Result { - buf.reserve(buffer_capacity_required(self)); - io::default_read_to_string(self, buf) + let size = buffer_capacity_required(self); + buf.reserve(size.unwrap_or(0)); + io::default_read_to_string(self, buf, size) } } #[stable(feature = "rust1", since = "1.0.0")] @@ -817,14 +819,16 @@ impl Read for &File { // Reserves space in the buffer based on the file size when available. fn read_to_end(&mut self, buf: &mut Vec) -> io::Result { - buf.reserve(buffer_capacity_required(self)); - io::default_read_to_end(self, buf) + let size = buffer_capacity_required(self); + buf.reserve(size.unwrap_or(0)); + io::default_read_to_end(self, buf, size) } // Reserves space in the buffer based on the file size when available. fn read_to_string(&mut self, buf: &mut String) -> io::Result { - buf.reserve(buffer_capacity_required(self)); - io::default_read_to_string(self, buf) + let size = buffer_capacity_required(self); + buf.reserve(size.unwrap_or(0)); + io::default_read_to_string(self, buf, size) } } #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 020c723925aeb..b3b5803bf59c3 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -357,9 +357,17 @@ where // of data to return. Simply tacking on an extra DEFAULT_BUF_SIZE space every // time is 4,500 times (!) slower than a default reservation size of 32 if the // reader has a very small amount of data to return. -pub(crate) fn default_read_to_end(r: &mut R, buf: &mut Vec) -> Result { +pub(crate) fn default_read_to_end( + r: &mut R, + buf: &mut Vec, + size_hint: Option, +) -> Result { let start_len = buf.len(); let start_cap = buf.capacity(); + // Optionally limit the maximum bytes read on each iteration. + // This adds an arbitrary fiddle factor to allow for more data than we expect. + let max_read_size = + size_hint.and_then(|s| s.checked_add(1024)?.checked_next_multiple_of(DEFAULT_BUF_SIZE)); let mut initialized = 0; // Extra initialized bytes from previous loop iteration loop { @@ -367,7 +375,12 @@ pub(crate) fn default_read_to_end(r: &mut R, buf: &mut Vec buf.reserve(32); // buf is full, need more space } - let mut read_buf: BorrowedBuf<'_> = buf.spare_capacity_mut().into(); + let mut spare = buf.spare_capacity_mut(); + if let Some(size) = max_read_size { + let len = cmp::min(spare.len(), size); + spare = &mut spare[..len] + } + let mut read_buf: BorrowedBuf<'_> = spare.into(); // SAFETY: These bytes were initialized but not filled in the previous loop unsafe { @@ -419,6 +432,7 @@ pub(crate) fn default_read_to_end(r: &mut R, buf: &mut Vec pub(crate) fn default_read_to_string( r: &mut R, buf: &mut String, + size_hint: Option, ) -> Result { // Note that we do *not* call `r.read_to_end()` here. We are passing // `&mut Vec` (the raw contents of `buf`) into the `read_to_end` @@ -429,7 +443,7 @@ pub(crate) fn default_read_to_string( // To prevent extraneously checking the UTF-8-ness of the entire buffer // we pass it to our hardcoded `default_read_to_end` implementation which // we know is guaranteed to only read data into the end of the buffer. - unsafe { append_to_string(buf, |b| default_read_to_end(r, b)) } + unsafe { append_to_string(buf, |b| default_read_to_end(r, b, size_hint)) } } pub(crate) fn default_read_vectored(read: F, bufs: &mut [IoSliceMut<'_>]) -> Result @@ -709,7 +723,7 @@ pub trait Read { /// [`std::fs::read`]: crate::fs::read #[stable(feature = "rust1", since = "1.0.0")] fn read_to_end(&mut self, buf: &mut Vec) -> Result { - default_read_to_end(self, buf) + default_read_to_end(self, buf, None) } /// Read all bytes until EOF in this source, appending them to `buf`. @@ -752,7 +766,7 @@ pub trait Read { /// [`std::fs::read_to_string`]: crate::fs::read_to_string #[stable(feature = "rust1", since = "1.0.0")] fn read_to_string(&mut self, buf: &mut String) -> Result { - default_read_to_string(self, buf) + default_read_to_string(self, buf, None) } /// Read the exact number of bytes required to fill `buf`. diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs index f4a886d889a99..6d30f5e6c6c8d 100644 --- a/library/std/src/io/tests.rs +++ b/library/std/src/io/tests.rs @@ -314,7 +314,7 @@ fn bench_read_to_end(b: &mut test::Bencher) { b.iter(|| { let mut lr = repeat(1).take(10000000); let mut vec = Vec::with_capacity(1024); - super::default_read_to_end(&mut lr, &mut vec) + super::default_read_to_end(&mut lr, &mut vec, None) }); } diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 98fcc76aa98f6..318a46d1b637e 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -289,6 +289,7 @@ #![feature(float_next_up_down)] #![feature(hasher_prefixfree_extras)] #![feature(hashmap_internals)] +#![feature(int_roundings)] #![feature(ip)] #![feature(ip_in_core)] #![feature(maybe_uninit_slice)] From ddfa2463e205a1bcae51aeb2698f09b4b8288e3d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 24 Nov 2022 19:09:27 +0000 Subject: [PATCH 13/42] Evaluate place expression in `PlaceMention`. --- compiler/rustc_borrowck/src/def_use.rs | 8 +- compiler/rustc_borrowck/src/invalidation.rs | 2 +- compiler/rustc_borrowck/src/lib.rs | 2 +- .../rustc_const_eval/src/interpret/step.rs | 10 ++- compiler/rustc_middle/src/mir/syntax.rs | 3 +- .../clippy/tests/ui/option_if_let_else.fixed | 4 +- .../clippy/tests/ui/option_if_let_else.rs | 4 +- .../clippy/tests/ui/option_if_let_else.stderr | 8 +- .../dangling_pointer_deref_underscore.rs | 11 +++ .../dangling_pointer_deref_underscore.stderr | 15 ++++ tests/ui/borrowck/let_underscore_temporary.rs | 30 ++++++- .../borrowck/let_underscore_temporary.stderr | 79 +++++++++++++++++++ .../span/send-is-not-static-std-sync-2.stderr | 2 - 13 files changed, 159 insertions(+), 19 deletions(-) create mode 100644 src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs create mode 100644 src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr create mode 100644 tests/ui/borrowck/let_underscore_temporary.stderr diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs index 9e9f0b4b4ad0a..6259722b6940f 100644 --- a/compiler/rustc_borrowck/src/def_use.rs +++ b/compiler/rustc_borrowck/src/def_use.rs @@ -52,12 +52,16 @@ pub fn categorize(context: PlaceContext) -> Option { PlaceContext::NonMutatingUse(NonMutatingUseContext::ShallowBorrow) | PlaceContext::NonMutatingUse(NonMutatingUseContext::UniqueBorrow) | + // `PlaceMention` and `AscribeUserType` both evaluate the place, which must not + // contain dangling references. + PlaceContext::NonUse(NonUseContext::PlaceMention) | + PlaceContext::NonUse(NonUseContext::AscribeUserTy) | + PlaceContext::MutatingUse(MutatingUseContext::AddressOf) | PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf) | PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect) | PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) | PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) | - PlaceContext::NonUse(NonUseContext::AscribeUserTy) | PlaceContext::MutatingUse(MutatingUseContext::Retag) => Some(DefUse::Use), @@ -72,8 +76,6 @@ pub fn categorize(context: PlaceContext) -> Option { PlaceContext::MutatingUse(MutatingUseContext::Drop) => Some(DefUse::Drop), - // This statement exists to help unsafeck. It does not require the place to be live. - PlaceContext::NonUse(NonUseContext::PlaceMention) => None, // Debug info is neither def nor use. PlaceContext::NonUse(NonUseContext::VarDebugInfo) => None, diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index 498d254da6536..06986f848bfeb 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -79,7 +79,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> { } // Only relevant for mir typeck StatementKind::AscribeUserType(..) - // Only relevant for unsafeck + // Only relevant for liveness and unsafeck | StatementKind::PlaceMention(..) // Doesn't have any language semantics | StatementKind::Coverage(..) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 6a5a7e08d3836..5bf3e7632ac21 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -665,7 +665,7 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx } // Only relevant for mir typeck StatementKind::AscribeUserType(..) - // Only relevant for unsafeck + // Only relevant for liveness and unsafeck | StatementKind::PlaceMention(..) // Doesn't have any language semantics | StatementKind::Coverage(..) diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 9a366364e769e..f9c15c505137f 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -113,8 +113,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Intrinsic(box intrinsic) => self.emulate_nondiverging_intrinsic(intrinsic)?, - // Statements we do not track. - PlaceMention(..) | AscribeUserType(..) => {} + // Evaluate the place expression, without reading from it. + PlaceMention(box place) => { + let _ = self.eval_place(*place)?; + } + + // This exists purely to guide borrowck lifetime inference, and does not have + // an operational effect. + AscribeUserType(..) => {} // Currently, Miri discards Coverage statements. Coverage statements are only injected // via an optional compile time MIR pass and have no side effects. Since Coverage diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index c38a347809f4f..303c120f795cf 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -331,7 +331,8 @@ pub enum StatementKind<'tcx> { /// This is especially useful for `let _ = PLACE;` bindings that desugar to a single /// `PlaceMention(PLACE)`. /// - /// When executed at runtime this is a nop. + /// When executed at runtime, this computes the given place, but then discards + /// it without doing a load. It is UB if the place is not pointing to live memory. /// /// Disallowed after drop elaboration. PlaceMention(Box>), diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed index 0456005dce496..35ce89c798649 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.fixed +++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed @@ -25,7 +25,7 @@ fn else_if_option(string: Option<&str>) -> Option<(bool, &str)> { fn unop_bad(string: &Option<&str>, mut num: Option) { let _ = string.map_or(0, |s| s.len()); let _ = num.as_ref().map_or(&0, |s| s); - let _ = num.as_mut().map_or(&mut 0, |s| { + let _ = num.as_mut().map_or(&0, |s| { *s += 1; s }); @@ -34,7 +34,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { s += 1; s }); - let _ = num.as_mut().map_or(&mut 0, |s| { + let _ = num.as_mut().map_or(&0, |s| { *s += 1; s }); diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs index 23b148752cbfa..c8683e5aae2d0 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.rs +++ b/src/tools/clippy/tests/ui/option_if_let_else.rs @@ -33,7 +33,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { *s += 1; s } else { - &mut 0 + &0 }; let _ = if let Some(ref s) = num { s } else { &0 }; let _ = if let Some(mut s) = num { @@ -46,7 +46,7 @@ fn unop_bad(string: &Option<&str>, mut num: Option) { *s += 1; s } else { - &mut 0 + &0 }; } diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr index a5dbf6e1f2218..f5e4affb67229 100644 --- a/src/tools/clippy/tests/ui/option_if_let_else.stderr +++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr @@ -30,13 +30,13 @@ LL | let _ = if let Some(s) = &mut num { LL | | *s += 1; LL | | s LL | | } else { -LL | | &mut 0 +LL | | &0 LL | | }; | |_____^ | help: try | -LL ~ let _ = num.as_mut().map_or(&mut 0, |s| { +LL ~ let _ = num.as_mut().map_or(&0, |s| { LL + *s += 1; LL + s LL ~ }); @@ -76,13 +76,13 @@ LL | let _ = if let Some(ref mut s) = num { LL | | *s += 1; LL | | s LL | | } else { -LL | | &mut 0 +LL | | &0 LL | | }; | |_____^ | help: try | -LL ~ let _ = num.as_mut().map_or(&mut 0, |s| { +LL ~ let _ = num.as_mut().map_or(&0, |s| { LL + *s += 1; LL + s LL ~ }); diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs new file mode 100644 index 0000000000000..3b2aba67a686c --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs @@ -0,0 +1,11 @@ +// Make sure we find these even with many checks disabled. +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation + +fn main() { + let p = { + let b = Box::new(42); + &*b as *const i32 + }; + let _ = unsafe { *p }; //~ ERROR: dereferenced after this allocation got freed + panic!("this should never print"); +} diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr new file mode 100644 index 0000000000000..e047c3287b558 --- /dev/null +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed + --> $DIR/dangling_pointer_deref_underscore.rs:LL:CC + | +LL | let _ = unsafe { *p }; + | ^^ pointer to ALLOC was dereferenced after this allocation got freed + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/dangling_pointer_deref_underscore.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/tests/ui/borrowck/let_underscore_temporary.rs b/tests/ui/borrowck/let_underscore_temporary.rs index 37b5c5d9d7ac5..835cd20798f06 100644 --- a/tests/ui/borrowck/let_underscore_temporary.rs +++ b/tests/ui/borrowck/let_underscore_temporary.rs @@ -1,4 +1,4 @@ -// check-pass +// check-fail fn let_underscore(string: &Option<&str>, mut num: Option) { let _ = if let Some(s) = *string { s.len() } else { 0 }; @@ -8,6 +8,7 @@ fn let_underscore(string: &Option<&str>, mut num: Option) { s } else { &mut 0 + //~^ ERROR temporary value dropped while borrowed }; let _ = if let Some(ref s) = num { s } else { &0 }; let _ = if let Some(mut s) = num { @@ -21,6 +22,33 @@ fn let_underscore(string: &Option<&str>, mut num: Option) { s } else { &mut 0 + //~^ ERROR temporary value dropped while borrowed + }; +} + +fn let_ascribe(string: &Option<&str>, mut num: Option) { + let _: _ = if let Some(s) = *string { s.len() } else { 0 }; + let _: _ = if let Some(s) = &num { s } else { &0 }; + let _: _ = if let Some(s) = &mut num { + *s += 1; + s + } else { + &mut 0 + //~^ ERROR temporary value dropped while borrowed + }; + let _: _ = if let Some(ref s) = num { s } else { &0 }; + let _: _ = if let Some(mut s) = num { + s += 1; + s + } else { + 0 + }; + let _: _ = if let Some(ref mut s) = num { + *s += 1; + s + } else { + &mut 0 + //~^ ERROR temporary value dropped while borrowed }; } diff --git a/tests/ui/borrowck/let_underscore_temporary.stderr b/tests/ui/borrowck/let_underscore_temporary.stderr new file mode 100644 index 0000000000000..74f3598c4d001 --- /dev/null +++ b/tests/ui/borrowck/let_underscore_temporary.stderr @@ -0,0 +1,79 @@ +error[E0716]: temporary value dropped while borrowed + --> $DIR/let_underscore_temporary.rs:10:14 + | +LL | let _ = if let Some(s) = &mut num { + | _____________- +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 + | | ^ creates a temporary value which is freed while still in use +LL | | +LL | | }; + | | - + | | | + | |_____temporary value is freed at the end of this statement + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/let_underscore_temporary.rs:24:14 + | +LL | let _ = if let Some(ref mut s) = num { + | _____________- +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 + | | ^ creates a temporary value which is freed while still in use +LL | | +LL | | }; + | | - + | | | + | |_____temporary value is freed at the end of this statement + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/let_underscore_temporary.rs:36:14 + | +LL | let _: _ = if let Some(s) = &mut num { + | ________________- +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 + | | ^ creates a temporary value which is freed while still in use +LL | | +LL | | }; + | | - + | | | + | |_____temporary value is freed at the end of this statement + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error[E0716]: temporary value dropped while borrowed + --> $DIR/let_underscore_temporary.rs:50:14 + | +LL | let _: _ = if let Some(ref mut s) = num { + | ________________- +LL | | *s += 1; +LL | | s +LL | | } else { +LL | | &mut 0 + | | ^ creates a temporary value which is freed while still in use +LL | | +LL | | }; + | | - + | | | + | |_____temporary value is freed at the end of this statement + | borrow later used here + | + = note: consider using a `let` binding to create a longer lived value + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0716`. diff --git a/tests/ui/span/send-is-not-static-std-sync-2.stderr b/tests/ui/span/send-is-not-static-std-sync-2.stderr index b0267fa6f43b0..c825cc8d66865 100644 --- a/tests/ui/span/send-is-not-static-std-sync-2.stderr +++ b/tests/ui/span/send-is-not-static-std-sync-2.stderr @@ -25,8 +25,6 @@ LL | }; error[E0597]: `x` does not live long enough --> $DIR/send-is-not-static-std-sync-2.rs:31:25 | -LL | let (_tx, rx) = { - | --- borrow later used here LL | let x = 1; | - binding `x` declared here LL | let (tx, rx) = mpsc::channel(); From 2870d269f5eb26e77ccf7718080afc62edaca8da Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 18 Mar 2023 16:11:48 +0000 Subject: [PATCH 14/42] Actually keep `PlaceMention` if requested. --- .../src/transform/validate.rs | 9 +------- compiler/rustc_interface/src/tests.rs | 1 + compiler/rustc_middle/src/mir/syntax.rs | 2 -- .../src/cleanup_post_borrowck.rs | 1 - .../src/dead_store_elimination.rs | 5 ++-- compiler/rustc_mir_transform/src/dest_prop.rs | 7 +++--- compiler/rustc_mir_transform/src/lib.rs | 8 +++++-- .../src/remove_place_mention.rs | 23 +++++++++++++++++++ compiler/rustc_session/src/options.rs | 3 +++ src/tools/miri/src/lib.rs | 1 + .../dangling_pointer_deref_underscore.rs | 4 +++- .../dangling_pointer_deref_underscore.stderr | 4 ++-- 12 files changed, 45 insertions(+), 23 deletions(-) create mode 100644 compiler/rustc_mir_transform/src/remove_place_mention.rs diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 8aee019e99494..6ce10672a6145 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -757,14 +757,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } } - StatementKind::PlaceMention(..) => { - if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { - self.fail( - location, - "`PlaceMention` should have been removed after drop lowering phase", - ); - } - } StatementKind::AscribeUserType(..) => { if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { self.fail( @@ -874,6 +866,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { StatementKind::StorageDead(_) | StatementKind::Coverage(_) | StatementKind::ConstEvalCounter + | StatementKind::PlaceMention(..) | StatementKind::Nop => {} } diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index f5d44d239e034..7b0b5102c2db6 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -768,6 +768,7 @@ fn test_unstable_options_tracking_hash() { tracked!(merge_functions, Some(MergeFunctions::Disabled)); tracked!(mir_emit_retag, true); tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]); + tracked!(mir_keep_place_mention, true); tracked!(mir_opt_level, Some(4)); tracked!(move_size_limit, Some(4096)); tracked!(mutable_noalias, false); diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 303c120f795cf..306cb4fa5ed0d 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -333,8 +333,6 @@ pub enum StatementKind<'tcx> { /// /// When executed at runtime, this computes the given place, but then discards /// it without doing a load. It is UB if the place is not pointing to live memory. - /// - /// Disallowed after drop elaboration. PlaceMention(Box>), /// Encodes a user's type ascription. These need to be preserved diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index 0923824db4888..d435d3ee69b76 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -24,7 +24,6 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck { for statement in basic_block.statements.iter_mut() { match statement.kind { StatementKind::AscribeUserType(..) - | StatementKind::PlaceMention(..) | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _))) | StatementKind::FakeRead(..) => statement.make_nop(), _ => (), diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index 18c407b42d373..7bc5183a00a82 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -54,11 +54,10 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS | StatementKind::Coverage(_) | StatementKind::Intrinsic(_) | StatementKind::ConstEvalCounter + | StatementKind::PlaceMention(_) | StatementKind::Nop => (), - StatementKind::FakeRead(_) - | StatementKind::PlaceMention(_) - | StatementKind::AscribeUserType(_, _) => { + StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => { bug!("{:?} not found in this MIR phase!", &statement.kind) } } diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 5a842714e5dad..78758e2db28ab 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -582,10 +582,9 @@ impl WriteInfo { | StatementKind::Nop | StatementKind::Coverage(_) | StatementKind::StorageLive(_) - | StatementKind::StorageDead(_) => (), - StatementKind::FakeRead(_) - | StatementKind::AscribeUserType(_, _) - | StatementKind::PlaceMention(_) => { + | StatementKind::StorageDead(_) + | StatementKind::PlaceMention(_) => (), + StatementKind::FakeRead(_) | StatementKind::AscribeUserType(_, _) => { bug!("{:?} not found in this MIR phase", statement) } } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 7a2420a6d940d..03e9fdef56ee5 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -48,6 +48,7 @@ mod add_retag; mod check_const_item_mutation; mod check_packed_ref; pub mod check_unsafety; +mod remove_place_mention; // This pass is public to allow external drivers to perform MIR cleanup pub mod cleanup_post_borrowck; mod const_debuginfo; @@ -460,8 +461,11 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { /// Returns the sequence of passes that do the initial cleanup of runtime MIR. fn run_runtime_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let passes: &[&dyn MirPass<'tcx>] = - &[&lower_intrinsics::LowerIntrinsics, &simplify::SimplifyCfg::ElaborateDrops]; + let passes: &[&dyn MirPass<'tcx>] = &[ + &lower_intrinsics::LowerIntrinsics, + &remove_place_mention::RemovePlaceMention, + &simplify::SimplifyCfg::ElaborateDrops, + ]; pm::run_passes(tcx, body, passes, Some(MirPhase::Runtime(RuntimePhase::PostCleanup))); diff --git a/compiler/rustc_mir_transform/src/remove_place_mention.rs b/compiler/rustc_mir_transform/src/remove_place_mention.rs new file mode 100644 index 0000000000000..8be1c37572d14 --- /dev/null +++ b/compiler/rustc_mir_transform/src/remove_place_mention.rs @@ -0,0 +1,23 @@ +//! This pass removes `PlaceMention` statement, which has no effect at codegen. + +use crate::MirPass; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; + +pub struct RemovePlaceMention; + +impl<'tcx> MirPass<'tcx> for RemovePlaceMention { + fn is_enabled(&self, sess: &rustc_session::Session) -> bool { + !sess.opts.unstable_opts.mir_keep_place_mention + } + + fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + trace!("Running RemovePlaceMention on {:?}", body.source); + for data in body.basic_blocks.as_mut_preserves_cfg() { + data.statements.retain(|statement| match statement.kind { + StatementKind::PlaceMention(..) | StatementKind::Nop => false, + _ => true, + }) + } + } +} diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 8e8ad72ec8a3f..d9f03fe14072e 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1558,6 +1558,9 @@ options! { "use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be \ enabled, overriding all other checks. Passes that are not specified are enabled or \ disabled by other flags as usual."), + mir_keep_place_mention: bool = (false, parse_bool, [TRACKED], + "keep place mention MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \ + (default: no)"), #[rustc_lint_opt_deny_field_access("use `Session::mir_opt_level` instead of this field")] mir_opt_level: Option = (None, parse_opt_number, [TRACKED], "MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"), diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index f67a718ba73a9..fc938080a0efd 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -130,6 +130,7 @@ pub const MIRI_DEFAULT_ARGS: &[&str] = &[ "-Zalways-encode-mir", "-Zextra-const-ub-checks", "-Zmir-emit-retag", + "-Zmir-keep-place-mention", "-Zmir-opt-level=0", "-Zmir-enable-passes=-CheckAlignment", ]; diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs index 3b2aba67a686c..7c5f440b774f2 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.rs @@ -6,6 +6,8 @@ fn main() { let b = Box::new(42); &*b as *const i32 }; - let _ = unsafe { *p }; //~ ERROR: dereferenced after this allocation got freed + unsafe { + let _ = *p; //~ ERROR: dereferenced after this allocation got freed + } panic!("this should never print"); } diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr index e047c3287b558..7b76389c75359 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_underscore.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed --> $DIR/dangling_pointer_deref_underscore.rs:LL:CC | -LL | let _ = unsafe { *p }; - | ^^ pointer to ALLOC was dereferenced after this allocation got freed +LL | let _ = *p; + | ^^ pointer to ALLOC was dereferenced after this allocation got freed | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information From e18d1f8d2ea0b0feabf7794fb7f5868e3b243709 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 16 Feb 2023 15:28:29 +0000 Subject: [PATCH 15/42] Leave it to the query system to invoke the typeck query instead of invoking it eagerly. Later queries that are run on all body owners will invoke typeck as they need information from its result to perform their own logic --- compiler/rustc_hir_analysis/src/lib.rs | 2 -- compiler/rustc_hir_typeck/src/lib.rs | 5 ----- compiler/rustc_middle/src/query/mod.rs | 4 ---- src/librustdoc/core.rs | 2 -- .../bugs/ice-substitution.stderr | 2 +- tests/ui/privacy/privacy2.stderr | 8 +------- tests/ui/privacy/privacy3.stderr | 8 +------- 7 files changed, 3 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 4c28e28f9646d..a4b797f77f7fe 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -496,8 +496,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> { tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module)) }); - tcx.sess.time("item_bodies_checking", || tcx.typeck_item_bodies(())); - check_unused::check_crate(tcx); check_for_entry_fn(tcx); diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 08d3593f91ff8..5ccac9a69252d 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -152,10 +152,6 @@ fn used_trait_imports(tcx: TyCtxt<'_>, def_id: LocalDefId) -> &UnordSet, (): ()) { - tcx.hir().par_body_owners(|body_owner_def_id| tcx.ensure().typeck(body_owner_def_id)); -} - fn typeck<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &ty::TypeckResults<'tcx> { let fallback = move || tcx.type_of(def_id.to_def_id()).subst_identity(); typeck_with_fallback(tcx, def_id, fallback) @@ -479,7 +475,6 @@ fn has_expected_num_generic_args( pub fn provide(providers: &mut Providers) { method::provide(providers); *providers = Providers { - typeck_item_bodies, typeck, diagnostic_only_typeck, has_typeck_results, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f81c1c39fc147..3b8f833a9bd6a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -871,10 +871,6 @@ rustc_queries! { separate_provide_extern } - query typeck_item_bodies(_: ()) -> () { - desc { "type-checking all item bodies" } - } - query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) } cache_on_disk_if { true } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b392ba058360d..46834a1d7f4e9 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -258,8 +258,6 @@ pub(crate) fn create_config( override_queries: Some(|_sess, providers, _external_providers| { // Most lints will require typechecking, so just don't run them. providers.lint_mod = |_, _| {}; - // Prevent `rustc_hir_analysis::check_crate` from calling `typeck` on all bodies. - providers.typeck_item_bodies = |_, _| {}; // hack so that `used_trait_imports` won't try to call typeck providers.used_trait_imports = |_, _| { static EMPTY_SET: LazyLock> = LazyLock::new(UnordSet::default); diff --git a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr b/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr index 7b0d1c5051624..1648cfb266b56 100644 --- a/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr +++ b/tests/ui/associated-inherent-types/bugs/ice-substitution.stderr @@ -2,5 +2,5 @@ error: the compiler unexpectedly panicked. this is a bug. query stack during panic: #0 [typeck] type-checking `weird` -#1 [typeck_item_bodies] type-checking all item bodies +#1 [used_trait_imports] finding used_trait_imports `weird` end of query stack diff --git a/tests/ui/privacy/privacy2.stderr b/tests/ui/privacy/privacy2.stderr index 882f314655d83..c2a33ce1f59b3 100644 --- a/tests/ui/privacy/privacy2.stderr +++ b/tests/ui/privacy/privacy2.stderr @@ -23,13 +23,7 @@ LL | pub fn foo() {} error: requires `sized` lang_item -error: requires `sized` lang_item - -error: requires `sized` lang_item - -error: requires `sized` lang_item - -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0432, E0603. For more information about an error, try `rustc --explain E0432`. diff --git a/tests/ui/privacy/privacy3.stderr b/tests/ui/privacy/privacy3.stderr index 42ce456d962a1..22c1e48b07d94 100644 --- a/tests/ui/privacy/privacy3.stderr +++ b/tests/ui/privacy/privacy3.stderr @@ -6,12 +6,6 @@ LL | use bar::gpriv; error: requires `sized` lang_item -error: requires `sized` lang_item - -error: requires `sized` lang_item - -error: requires `sized` lang_item - -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0432`. From 1ce80e210d152619caa99b1bc030f57a352b657a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 16 Feb 2023 09:25:11 +0000 Subject: [PATCH 16/42] Allow `LocalDefId` as the argument to `def_path_str` --- compiler/rustc_borrowck/src/lib.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 2 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +- .../rustc_hir_analysis/src/coherence/mod.rs | 2 +- .../src/variance/constraints.rs | 2 +- .../rustc_middle/src/dep_graph/dep_node.rs | 2 +- compiler/rustc_middle/src/hir/map/mod.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 66 +++++++++---------- compiler/rustc_middle/src/ty/context.rs | 5 +- compiler/rustc_middle/src/ty/print/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 17 ++++- compiler/rustc_middle/src/ty/query.rs | 2 +- compiler/rustc_middle/src/values.rs | 4 +- .../rustc_mir_transform/src/inline/cycle.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 2 +- compiler/rustc_symbol_mangling/src/test.rs | 2 +- .../src/default_union_representation.rs | 2 +- .../clippy_lints/src/trailing_empty_array.rs | 2 +- 18 files changed, 68 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 6a5a7e08d3836..7f46614423cb9 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -124,7 +124,7 @@ pub fn provide(providers: &mut Providers) { fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> { let (input_body, promoted) = tcx.mir_promoted(def); - debug!("run query mir_borrowck: {}", tcx.def_path_str(def.to_def_id())); + debug!("run query mir_borrowck: {}", tcx.def_path_str(def)); if input_body.borrow().should_skip() { debug!("Skipping borrowck because of injected body"); diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 51ec5dd7a285f..ad2624a5d2d7b 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -494,7 +494,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) { debug!( "check_item_type(it.def_id={:?}, it.name={})", id.owner_id, - tcx.def_path_str(id.owner_id.to_def_id()) + tcx.def_path_str(id.owner_id) ); let _indenter = indenter(); match tcx.def_kind(id.owner_id) { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 53197bc849106..b2ebbf993a1cc 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -155,7 +155,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) { debug!( ?item.owner_id, - item.name = ? tcx.def_path_str(def_id.to_def_id()) + item.name = ? tcx.def_path_str(def_id) ); match item.kind { @@ -251,7 +251,7 @@ fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) { debug!( ?item.owner_id, - item.name = ? tcx.def_path_str(def_id.to_def_id()) + item.name = ? tcx.def_path_str(def_id) ); match item.kind { diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 465e787c92ae6..ac393ee15a684 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -22,7 +22,7 @@ fn check_impl(tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_ref: ty::TraitRef< debug!( "(checking implementation) adding impl for trait '{:?}', item '{}'", trait_ref, - tcx.def_path_str(impl_def_id.to_def_id()) + tcx.def_path_str(impl_def_id) ); // Skip impls where one of the self type is an error type. diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index 408bec71ee015..6f0afae1b4c68 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -92,7 +92,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { fn build_constraints_for_item(&mut self, def_id: LocalDefId) { let tcx = self.tcx(); - debug!("build_constraints_for_item({})", tcx.def_path_str(def_id.to_def_id())); + debug!("build_constraints_for_item({})", tcx.def_path_str(def_id)); // Skip items with no generics - there's nothing to infer in them. if tcx.generics_of(def_id).count() == 0 { diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index 82e396a9dd3f9..2dc5b8969934f 100644 --- a/compiler/rustc_middle/src/dep_graph/dep_node.rs +++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs @@ -364,7 +364,7 @@ impl<'tcx> DepNodeParams> for HirId { #[inline(always)] fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String { let HirId { owner, local_id } = *self; - format!("{}.{}", tcx.def_path_str(owner.to_def_id()), local_id.as_u32()) + format!("{}.{}", tcx.def_path_str(owner), local_id.as_u32()) } #[inline(always)] diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 64aff27744fd1..5c01a6613263d 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1217,7 +1217,7 @@ fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> { } fn hir_id_to_string(map: Map<'_>, id: HirId) -> String { - let path_str = |def_id: LocalDefId| map.tcx.def_path_str(def_id.to_def_id()); + let path_str = |def_id: LocalDefId| map.tcx.def_path_str(def_id); let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default(); let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str()); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3b8f833a9bd6a..52cf7145b2136 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -83,7 +83,7 @@ rustc_queries! { /// Avoid calling this query directly. query hir_module_items(key: LocalDefId) -> &'tcx rustc_middle::hir::ModuleItems { arena_cache - desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR module items in `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } @@ -92,14 +92,14 @@ rustc_queries! { /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. query hir_owner(key: hir::OwnerId) -> Option> { - desc { |tcx| "getting HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR owner of `{}`", tcx.def_path_str(key) } } /// Gives access to the HIR ID for the given `LocalDefId` owner `key` if any. /// /// Definitions that were generated with no HIR, would be fed to return `None`. query opt_local_def_id_to_hir_id(key: LocalDefId) -> Option{ - desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key) } feedable } @@ -108,7 +108,7 @@ rustc_queries! { /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. query hir_owner_parent(key: hir::OwnerId) -> hir::HirId { - desc { |tcx| "getting HIR parent of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR parent of `{}`", tcx.def_path_str(key) } } /// Gives access to the HIR nodes and bodies inside the HIR owner `key`. @@ -116,7 +116,7 @@ rustc_queries! { /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. query hir_owner_nodes(key: hir::OwnerId) -> hir::MaybeOwner<&'tcx hir::OwnerNodes<'tcx>> { - desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR owner items in `{}`", tcx.def_path_str(key) } } /// Gives access to the HIR attributes inside the HIR owner `key`. @@ -124,7 +124,7 @@ rustc_queries! { /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. query hir_attrs(key: hir::OwnerId) -> &'tcx hir::AttributeMap<'tcx> { - desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting HIR owner attributes in `{}`", tcx.def_path_str(key) } } /// Given the def_id of a const-generic parameter, computes the associated default const @@ -295,7 +295,7 @@ rustc_queries! { query shallow_lint_levels_on(key: hir::OwnerId) -> &'tcx rustc_middle::lint::ShallowLintLevelMap { eval_always // fetches `resolutions` arena_cache - desc { |tcx| "looking up lint levels for `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "looking up lint levels for `{}`", tcx.def_path_str(key) } } query lint_expectations(_: ()) -> &'tcx Vec<(LintExpectationId, LintExpectation)> { @@ -305,7 +305,7 @@ rustc_queries! { query parent_module_from_def_id(key: LocalDefId) -> LocalDefId { eval_always - desc { |tcx| "getting the parent module of `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "getting the parent module of `{}`", tcx.def_path_str(key) } } query expn_that_defined(key: DefId) -> rustc_span::ExpnId { @@ -321,7 +321,7 @@ rustc_queries! { /// Checks whether a type is representable or infinitely sized query representability(_: LocalDefId) -> rustc_middle::ty::Representability { - desc { "checking if `{}` is representable", tcx.def_path_str(key.to_def_id()) } + desc { "checking if `{}` is representable", tcx.def_path_str(key) } // infinitely sized types will cause a cycle cycle_delay_bug // we don't want recursive representability calls to be forced with @@ -349,21 +349,21 @@ rustc_queries! { query thir_body(key: LocalDefId) -> Result<(&'tcx Steal>, thir::ExprId), ErrorGuaranteed> { // Perf tests revealed that hashing THIR is inefficient (see #85729). no_hash - desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key) } } /// Create a THIR tree for debugging. query thir_tree(key: LocalDefId) -> &'tcx String { no_hash arena_cache - desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key) } } /// Create a list-like THIR representation for debugging. query thir_flat(key: LocalDefId) -> &'tcx String { no_hash arena_cache - desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key) } } /// Set of all the `DefId`s in this crate that have MIR associated with @@ -386,7 +386,7 @@ rustc_queries! { /// Fetch the MIR for a given `DefId` right after it's built - this includes /// unreachable code. query mir_built(key: LocalDefId) -> &'tcx Steal> { - desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "building MIR for `{}`", tcx.def_path_str(key) } } /// Fetch the MIR for a given `DefId` up till the point where it is @@ -394,7 +394,7 @@ rustc_queries! { /// /// See the README for the `mir` module for details. query mir_const(key: LocalDefId) -> &'tcx Steal> { - desc { |tcx| "preparing `{}` for borrow checking", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "preparing `{}` for borrow checking", tcx.def_path_str(key) } no_hash } @@ -410,7 +410,7 @@ rustc_queries! { query mir_drops_elaborated_and_const_checked(key: LocalDefId) -> &'tcx Steal> { no_hash - desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "elaborating drops for `{}`", tcx.def_path_str(key) } } query mir_for_ctfe( @@ -426,13 +426,13 @@ rustc_queries! { &'tcx Steal>> ) { no_hash - desc { |tcx| "promoting constants in MIR for `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "promoting constants in MIR for `{}`", tcx.def_path_str(key) } } query closure_typeinfo(key: LocalDefId) -> ty::ClosureTypeInfo<'tcx> { desc { |tcx| "finding symbols for captures of closure `{}`", - tcx.def_path_str(key.to_def_id()) + tcx.def_path_str(key) } } @@ -444,7 +444,7 @@ rustc_queries! { } query check_generator_obligations(key: LocalDefId) { - desc { |tcx| "verify auto trait bounds for generator interior type `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "verify auto trait bounds for generator interior type `{}`", tcx.def_path_str(key) } } /// MIR after our optimization passes have run. This is MIR that is ready @@ -526,7 +526,7 @@ rustc_queries! { /// `explicit_predicates_of` and `explicit_item_bounds` will then take /// the appropriate subsets of the predicates here. query trait_explicit_predicates_and_bounds(key: LocalDefId) -> ty::GenericPredicates<'tcx> { - desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "computing explicit predicates of trait `{}`", tcx.def_path_str(key) } } /// Returns the predicates written explicitly by the user. @@ -768,14 +768,14 @@ rustc_queries! { /// The result of unsafety-checking this `LocalDefId`. query unsafety_check_result(key: LocalDefId) -> &'tcx mir::UnsafetyCheckResult { - desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } /// Unsafety-check this `LocalDefId` with THIR unsafeck. This should be /// used with `-Zthir-unsafeck`. query thir_check_unsafety(key: LocalDefId) { - desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } @@ -872,16 +872,16 @@ rustc_queries! { } query typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { - desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } query diagnostic_only_typeck(key: LocalDefId) -> &'tcx ty::TypeckResults<'tcx> { - desc { |tcx| "type-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "type-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } query used_trait_imports(key: LocalDefId) -> &'tcx UnordSet { - desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "finding used_trait_imports `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } @@ -896,7 +896,7 @@ rustc_queries! { /// Borrow-checks the function body. If this is a closure, returns /// additional requirements that the closure's creator must verify. query mir_borrowck(key: LocalDefId) -> &'tcx mir::BorrowCheckResult<'tcx> { - desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "borrow-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if(tcx) { tcx.is_typeck_child(key.to_def_id()) } } @@ -918,7 +918,7 @@ rustc_queries! { query orphan_check_impl(key: LocalDefId) -> Result<(), ErrorGuaranteed> { desc { |tcx| "checking whether impl `{}` follows the orphan rules", - tcx.def_path_str(key.to_def_id()), + tcx.def_path_str(key), } } @@ -930,7 +930,7 @@ rustc_queries! { desc { |tcx| "computing if `{}` (transitively) calls `{}`", key.0, - tcx.def_path_str(key.1.to_def_id()), + tcx.def_path_str(key.1), } } @@ -1368,7 +1368,7 @@ rustc_queries! { separate_provide_extern } query has_ffi_unwind_calls(key: LocalDefId) -> bool { - desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "checking if `{}` contains FFI-unwind calls", tcx.def_path_str(key) } cache_on_disk_if { true } } query required_panic_strategy(_: CrateNum) -> Option { @@ -1414,7 +1414,7 @@ rustc_queries! { } query check_well_formed(key: hir::OwnerId) -> () { - desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) } } // The `DefId`s of all non-generic functions and statics in the given crate @@ -1443,7 +1443,7 @@ rustc_queries! { query is_unreachable_local_definition(def_id: LocalDefId) -> bool { desc { |tcx| "checking whether `{}` is reachable from outside the crate", - tcx.def_path_str(def_id.to_def_id()), + tcx.def_path_str(def_id), } } @@ -1637,7 +1637,7 @@ rustc_queries! { separate_provide_extern } query extern_mod_stmt_cnum(def_id: LocalDefId) -> Option { - desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id.to_def_id()) } + desc { |tcx| "computing crate imported by `{}`", tcx.def_path_str(def_id) } } query lib_features(_: ()) -> &'tcx LibFeatures { @@ -1741,7 +1741,7 @@ rustc_queries! { desc { "fetching potentially unused trait imports" } } query names_imported_by_glob_use(def_id: LocalDefId) -> &'tcx UnordSet { - desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id.to_def_id()) } + desc { |tcx| "finding names imported by glob use for `{}`", tcx.def_path_str(def_id) } } query stability_index(_: ()) -> &'tcx stability::Index { @@ -2064,7 +2064,7 @@ rustc_queries! { query compare_impl_const( key: (LocalDefId, DefId) ) -> Result<(), ErrorGuaranteed> { - desc { |tcx| "checking assoc const `{}` has the same type as trait item", tcx.def_path_str(key.0.to_def_id()) } + desc { |tcx| "checking assoc const `{}` has the same type as trait item", tcx.def_path_str(key.0) } } query deduced_param_attrs(def_id: DefId) -> &'tcx [ty::DeducedParamAttrs] { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index af3a54148e114..8feabc02f9354 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -80,6 +80,8 @@ use std::iter; use std::mem; use std::ops::{Bound, Deref}; +use super::query::IntoQueryParam; + const TINY_CONST_EVAL_LIMIT: Limit = Limit(20); pub trait OnDiskCache<'tcx>: rustc_data_structures::sync::Sync { @@ -822,7 +824,8 @@ impl<'tcx> TyCtxt<'tcx> { self.features_query(()) } - pub fn def_key(self, id: DefId) -> rustc_hir::definitions::DefKey { + pub fn def_key(self, id: impl IntoQueryParam) -> rustc_hir::definitions::DefKey { + let id = id.into_query_param(); // Accessing the DefKey is ok, since it is part of DefPathHash. if let Some(id) = id.as_local() { self.definitions_untracked().def_key(id) diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index d947d96041ef7..5ce32c7aaaa30 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -327,6 +327,6 @@ pub fn describe_as_module(def_id: LocalDefId, tcx: TyCtxt<'_>) -> String { if def_id.is_top_level_module() { "top-level module".to_string() } else { - format!("module `{}`", tcx.def_path_str(def_id.to_def_id())) + format!("module `{}`", tcx.def_path_str(def_id)) } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 5315aa155a831..8f143c1362578 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1,4 +1,5 @@ use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; +use crate::ty::query::IntoQueryParam; use crate::ty::{ self, ConstInt, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, @@ -1787,17 +1788,27 @@ fn guess_def_namespace(tcx: TyCtxt<'_>, def_id: DefId) -> Namespace { impl<'t> TyCtxt<'t> { /// Returns a string identifying this `DefId`. This string is /// suitable for user output. - pub fn def_path_str(self, def_id: DefId) -> String { + pub fn def_path_str(self, def_id: impl IntoQueryParam) -> String { self.def_path_str_with_substs(def_id, &[]) } - pub fn def_path_str_with_substs(self, def_id: DefId, substs: &'t [GenericArg<'t>]) -> String { + pub fn def_path_str_with_substs( + self, + def_id: impl IntoQueryParam, + substs: &'t [GenericArg<'t>], + ) -> String { + let def_id = def_id.into_query_param(); let ns = guess_def_namespace(self, def_id); debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns); FmtPrinter::new(self, ns).print_def_path(def_id, substs).unwrap().into_buffer() } - pub fn value_path_str_with_substs(self, def_id: DefId, substs: &'t [GenericArg<'t>]) -> String { + pub fn value_path_str_with_substs( + self, + def_id: impl IntoQueryParam, + substs: &'t [GenericArg<'t>], + ) -> String { + let def_id = def_id.into_query_param(); let ns = guess_def_namespace(self, def_id); debug!("value_path_str: def_id={:?}, ns={:?}", def_id, ns); FmtPrinter::new(self, ns).print_value_path(def_id, substs).unwrap().into_buffer() diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index e46cfb8dd1655..bd8a22473fb51 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -587,7 +587,7 @@ mod sealed { } } -use sealed::IntoQueryParam; +pub use sealed::IntoQueryParam; impl<'tcx> TyCtxt<'tcx> { pub fn def_kind(self, def_id: impl IntoQueryParam) -> DefKind { diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 55aa4fcff2cdb..5c38c0acc7f86 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -158,8 +158,8 @@ pub fn recursive_type_error( } let items_list = { let mut s = String::new(); - for (i, (item_id, _)) in item_and_field_ids.iter().enumerate() { - let path = tcx.def_path_str(item_id.to_def_id()); + for (i, &(item_id, _)) in item_and_field_ids.iter().enumerate() { + let path = tcx.def_path_str(item_id); write!(&mut s, "`{path}`").unwrap(); if i == (ITEM_LIMIT - 1) && cycle_len > ITEM_LIMIT { write!(&mut s, " and {} more", cycle_len - 5).unwrap(); diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 8b811d7e87086..098ce0391fcd2 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -13,7 +13,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( tcx: TyCtxt<'tcx>, (root, target): (ty::Instance<'tcx>, LocalDefId), ) -> bool { - trace!(%root, target = %tcx.def_path_str(target.to_def_id())); + trace!(%root, target = %tcx.def_path_str(target)); let param_env = tcx.param_env_reveal_all_normalized(target); assert_ne!( root.def_id().expect_local(), diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 2ed628871d2d7..5ac9c8e2073dd 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1230,7 +1230,7 @@ impl<'v> RootCollector<'_, 'v> { DefKind::GlobalAsm => { debug!( "RootCollector: ItemKind::GlobalAsm({})", - self.tcx.def_path_str(id.owner_id.to_def_id()) + self.tcx.def_path_str(id.owner_id) ); self.output.push(dummy_spanned(MonoItem::GlobalAsm(id))); } diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index b4d5b7f3621c8..985b2210745f4 100644 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs @@ -83,7 +83,7 @@ impl SymbolNamesTest<'_> { tcx.sess.emit_err(TestOutput { span: attr.span, kind: Kind::DefPath, - content: with_no_trimmed_paths!(tcx.def_path_str(def_id.to_def_id())), + content: with_no_trimmed_paths!(tcx.def_path_str(def_id)), }); } } diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs index dec357ab75c36..03b5a2d6d0829 100644 --- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs +++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs @@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation { None, &format!( "consider annotating `{}` with `#[repr(C)]` to explicitly specify memory layout", - cx.tcx.def_path_str(item.owner_id.to_def_id()) + cx.tcx.def_path_str(item.owner_id) ), ); } diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs index 1382c1a40da24..98f5b47f7a0e4 100644 --- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs +++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs @@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray { None, &format!( "consider annotating `{}` with `#[repr(C)]` or another `repr` attribute", - cx.tcx.def_path_str(item.owner_id.to_def_id()) + cx.tcx.def_path_str(item.owner_id) ), ); } From 5bb58a68de2dbc7c122c4bb2438b0d88a2897470 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 16 Feb 2023 09:34:53 +0000 Subject: [PATCH 17/42] Make `check_match` and `check_liveness` take a `LocalDefId` --- compiler/rustc_interface/src/passes.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 4 ++-- compiler/rustc_passes/src/liveness.rs | 17 ++++++----------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 5fe9d3446540b..8e8e29fd4cfb7 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -775,7 +775,7 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { // "not all control paths return a value" is reported here. // // maybe move the check to a MIR pass? - tcx.ensure().check_liveness(def_id.to_def_id()); + tcx.ensure().check_liveness(def_id); }); }); } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 52cf7145b2136..088c1585e1364 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -832,7 +832,7 @@ rustc_queries! { desc { |tcx| "checking privacy in {}", describe_as_module(key, tcx) } } - query check_liveness(key: DefId) { + query check_liveness(key: LocalDefId) { desc { |tcx| "checking liveness of variables in `{}`", tcx.def_path_str(key) } } @@ -1021,7 +1021,7 @@ rustc_queries! { } query check_match(key: LocalDefId) { - desc { |tcx| "match-checking `{}`", tcx.def_path_str(key.to_def_id()) } + desc { |tcx| "match-checking `{}`", tcx.def_path_str(key) } cache_on_disk_if { true } } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index a8471ce3b6fb2..cd1dcb315cfdc 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -90,7 +90,7 @@ use rustc_errors::Applicability; use rustc_errors::Diagnostic; use rustc_hir as hir; use rustc_hir::def::*; -use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet}; use rustc_index::vec::IndexVec; @@ -137,14 +137,9 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String { } } -fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { - let local_def_id = match def_id.as_local() { - None => return, - Some(def_id) => def_id, - }; - +fn check_liveness(tcx: TyCtxt<'_>, def_id: LocalDefId) { // Don't run unused pass for #[derive()] - let parent = tcx.local_parent(local_def_id); + let parent = tcx.local_parent(def_id); if let DefKind::Impl { .. } = tcx.def_kind(parent) && tcx.has_attr(parent, sym::automatically_derived) { @@ -152,12 +147,12 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { } // Don't run unused pass for #[naked] - if tcx.has_attr(def_id, sym::naked) { + if tcx.has_attr(def_id.to_def_id(), sym::naked) { return; } let mut maps = IrMaps::new(tcx); - let body_id = tcx.hir().body_owned_by(local_def_id); + let body_id = tcx.hir().body_owned_by(def_id); let hir_id = tcx.hir().body_owner(body_id); let body = tcx.hir().body(body_id); @@ -173,7 +168,7 @@ fn check_liveness(tcx: TyCtxt<'_>, def_id: DefId) { maps.visit_body(body); // compute liveness - let mut lsets = Liveness::new(&mut maps, local_def_id); + let mut lsets = Liveness::new(&mut maps, def_id); let entry_ln = lsets.compute(&body, hir_id); lsets.log_liveness(entry_ln, body_id.hir_id); From 334423263a347b38ed0040be788feb3a4197c056 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 16 Feb 2023 10:06:59 +0000 Subject: [PATCH 18/42] Run `check_match` and `check_liveness` when MIR is built instead of having an explicit phase for them --- compiler/rustc_interface/src/passes.rs | 21 --- compiler/rustc_mir_build/src/build/mod.rs | 7 + compiler/rustc_passes/src/liveness.rs | 10 +- ...d[0].SimplifyCfg-elaborate-drops.after.mir | 6 +- ...motion_extern_static.FOO.PromoteTemps.diff | 6 +- ...atterns-slice-patterns-box-patterns.stderr | 32 ++-- .../match/pattern-matching-should-fail.stderr | 28 ++-- tests/ui/lint/lint-uppercase-variables.stderr | 12 +- .../expect_nested_lint_levels.stderr | 24 +-- ...force_warn_expected_lints_fulfilled.stderr | 12 +- .../lint/unused/lint-unused-variables.stderr | 12 +- tests/ui/liveness/liveness-consts.stderr | 53 +++---- .../borrowck-pat-at-and-box.stderr | 16 +- ...orrowck-pat-by-move-and-ref-inverse.stderr | 144 +++++++++--------- .../borrowck-pat-by-move-and-ref.stderr | 84 +++++----- .../borrowck-pat-ref-mut-and-ref.stderr | 82 +++++----- .../borrowck-pat-ref-mut-twice.stderr | 88 +++++------ .../param-attrs-cfg.stderr | 12 +- 18 files changed, 321 insertions(+), 328 deletions(-) diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 8e8e29fd4cfb7..4a45c9e4f3ed1 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -761,27 +761,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> { // passes are timed inside typeck rustc_hir_analysis::check_crate(tcx)?; - sess.time("misc_checking_2", || { - parallel!( - { - sess.time("match_checking", || { - tcx.hir().par_body_owners(|def_id| tcx.ensure().check_match(def_id)) - }); - }, - { - sess.time("liveness_checking", || { - tcx.hir().par_body_owners(|def_id| { - // this must run before MIR dump, because - // "not all control paths return a value" is reported here. - // - // maybe move the check to a MIR pass? - tcx.ensure().check_liveness(def_id); - }); - }); - } - ); - }); - sess.time("MIR_borrow_checking", || { tcx.hir().par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id)); }); diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index b05c3056cbaee..82274318dcf32 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -51,6 +51,13 @@ fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { // of `mir_build`, so now we can steal it let thir = thir.steal(); + tcx.ensure().check_match(def); + // this must run before MIR dump, because + // "not all control paths return a value" is reported here. + // + // maybe move the check to a MIR pass? + tcx.ensure().check_liveness(def); + match thir.body_type { thir::BodyTy::Fn(fn_sig) => construct_fn(tcx, def, &thir, expr, fn_sig), thir::BodyTy::Const(ty) => construct_const(tcx, def, &thir, expr, ty), diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index cd1dcb315cfdc..b6d4ee313af87 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -98,6 +98,7 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt}; use rustc_session::lint; use rustc_span::symbol::{kw, sym, Symbol}; +use rustc_span::DUMMY_SP; use rustc_span::{BytePos, Span}; use std::collections::VecDeque; @@ -586,8 +587,13 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } fn assigned_on_exit(&self, ln: LiveNode, var: Variable) -> bool { - let successor = self.successors[ln].unwrap(); - self.assigned_on_entry(successor, var) + match self.successors[ln] { + Some(successor) => self.assigned_on_entry(successor, var), + None => { + self.ir.tcx.sess.delay_span_bug(DUMMY_SP, "no successor"); + true + } + } } fn write_vars(&self, wr: &mut dyn Write, mut test: F) -> io::Result<()> diff --git a/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir index 19daae86589cd..41657b53fc12c 100644 --- a/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir +++ b/tests/mir-opt/const_promotion_extern_static.FOO-promoted[0].SimplifyCfg-elaborate-drops.after.mir @@ -7,10 +7,10 @@ promoted[0] in FOO: &[&i32; 1] = { let mut _3: *const i32; // in scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 bb0: { - _3 = const {alloc2: *const i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 + _3 = const {alloc3: *const i32}; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 // mir::Constant // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43 - // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) } + // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } _2 = &(*_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43 _1 = [move _2]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 _0 = &_1; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 @@ -18,4 +18,4 @@ promoted[0] in FOO: &[&i32; 1] = { } } -alloc2 (extern static: X) +alloc3 (extern static: X) diff --git a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff index 5b13d60052fe1..25ba0face6bd8 100644 --- a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff +++ b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff @@ -18,11 +18,11 @@ - StorageLive(_3); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 - StorageLive(_4); // scope 0 at $DIR/const_promotion_extern_static.rs:+0:32: +0:45 - StorageLive(_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 -- _5 = const {alloc2: *const i32}; // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 +- _5 = const {alloc3: *const i32}; // scope 1 at $DIR/const_promotion_extern_static.rs:+0:42: +0:43 + _6 = const _; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 // mir::Constant - // + span: $DIR/const_promotion_extern_static.rs:13:42: 13:43 -- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc2)) } +- // + literal: Const { ty: *const i32, val: Value(Scalar(alloc3)) } - _4 = &(*_5); // scope 1 at $DIR/const_promotion_extern_static.rs:+0:41: +0:43 - _3 = [move _4]; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:46 - _2 = &_3; // scope 0 at $DIR/const_promotion_extern_static.rs:+0:31: +0:55 @@ -50,5 +50,5 @@ } } - -- alloc2 (extern static: X) +- alloc3 (extern static: X) diff --git a/tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr b/tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr index 0ca14c3f3bc66..047175626e366 100644 --- a/tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr +++ b/tests/ui/borrowck/bindings-after-at-or-patterns-slice-patterns-box-patterns.stderr @@ -1,19 +1,3 @@ -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:36:9 - | -LL | ref foo @ [.., ref mut bar] => (), - | ^^^^^^^ ----------- value is mutably borrowed by `bar` here - | | - | value is borrowed by `foo` here - -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:120:9 - | -LL | ref foo @ Some(box ref mut s) => (), - | ^^^^^^^ --------- value is mutably borrowed by `s` here - | | - | value is borrowed by `foo` here - error[E0382]: borrow of moved value: `x` --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:18:5 | @@ -43,6 +27,14 @@ LL | &x; LL | drop(r); | - mutable borrow later used here +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:36:9 + | +LL | ref foo @ [.., ref mut bar] => (), + | ^^^^^^^ ----------- value is mutably borrowed by `bar` here + | | + | value is borrowed by `foo` here + error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:50:5 | @@ -120,6 +112,14 @@ LL | &mut x; LL | drop(r); | - immutable borrow later used here +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:120:9 + | +LL | ref foo @ Some(box ref mut s) => (), + | ^^^^^^^ --------- value is mutably borrowed by `s` here + | | + | value is borrowed by `foo` here + error[E0382]: borrow of moved value: `x` --> $DIR/bindings-after-at-or-patterns-slice-patterns-box-patterns.rs:134:5 | diff --git a/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr b/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr index ad061d93cb242..8a32f0d99e757 100644 --- a/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr +++ b/tests/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr @@ -1,17 +1,3 @@ -error[E0004]: non-exhaustive patterns: type `u8` is non-empty - --> $DIR/pattern-matching-should-fail.rs:67:23 - | -LL | let c1 = || match x { }; - | ^ - | - = note: the matched value is of type `u8` -help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown - | -LL ~ let c1 = || match x { -LL + _ => todo!(), -LL ~ }; - | - error[E0381]: used binding `x` isn't initialized --> $DIR/pattern-matching-should-fail.rs:8:23 | @@ -69,6 +55,20 @@ LL | let t: !; LL | match t { }; | ^ `t` used here but it isn't initialized +error[E0004]: non-exhaustive patterns: type `u8` is non-empty + --> $DIR/pattern-matching-should-fail.rs:67:23 + | +LL | let c1 = || match x { }; + | ^ + | + = note: the matched value is of type `u8` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + | +LL ~ let c1 = || match x { +LL + _ => todo!(), +LL ~ }; + | + error[E0381]: used binding `x` isn't initialized --> $DIR/pattern-matching-should-fail.rs:67:23 | diff --git a/tests/ui/lint/lint-uppercase-variables.stderr b/tests/ui/lint/lint-uppercase-variables.stderr index 42ec9364bc6e6..9220828014fda 100644 --- a/tests/ui/lint/lint-uppercase-variables.stderr +++ b/tests/ui/lint/lint-uppercase-variables.stderr @@ -12,12 +12,6 @@ error[E0170]: pattern binding `Foo` is named the same as one of the variants of LL | let Foo = foo::Foo::Foo; | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo` -error[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo` - --> $DIR/lint-uppercase-variables.rs:33:17 - | -LL | fn in_param(Foo: foo::Foo) {} - | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo` - warning: unused variable: `Foo` --> $DIR/lint-uppercase-variables.rs:22:9 | @@ -37,6 +31,12 @@ warning: unused variable: `Foo` LL | let Foo = foo::Foo::Foo; | ^^^ help: if this is intentional, prefix it with an underscore: `_Foo` +error[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo` + --> $DIR/lint-uppercase-variables.rs:33:17 + | +LL | fn in_param(Foo: foo::Foo) {} + | ^^^ help: to match on the variant, qualify the path: `foo::Foo::Foo` + warning: unused variable: `Foo` --> $DIR/lint-uppercase-variables.rs:33:17 | diff --git a/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr b/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr index 2c35647b8a3d9..4852c3313969e 100644 --- a/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr +++ b/tests/ui/lint/rfc-2383-lint-reason/expect_nested_lint_levels.stderr @@ -1,15 +1,3 @@ -error: unused variable: `this_is_my_function` - --> $DIR/expect_nested_lint_levels.rs:48:9 - | -LL | let this_is_my_function = 3; - | ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_is_my_function` - | -note: the lint level is defined here - --> $DIR/expect_nested_lint_levels.rs:45:10 - | -LL | #[forbid(unused_variables)] - | ^^^^^^^^^^^^^^^^ - warning: variable does not need to be mutable --> $DIR/expect_nested_lint_levels.rs:36:13 | @@ -25,6 +13,18 @@ note: the lint level is defined here LL | unused_mut, | ^^^^^^^^^^ +error: unused variable: `this_is_my_function` + --> $DIR/expect_nested_lint_levels.rs:48:9 + | +LL | let this_is_my_function = 3; + | ^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_is_my_function` + | +note: the lint level is defined here + --> $DIR/expect_nested_lint_levels.rs:45:10 + | +LL | #[forbid(unused_variables)] + | ^^^^^^^^^^^^^^^^ + warning: this lint expectation is unfulfilled --> $DIR/expect_nested_lint_levels.rs:7:5 | diff --git a/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr index 5942fa8aeb4f0..169f03aed9417 100644 --- a/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr +++ b/tests/ui/lint/rfc-2383-lint-reason/force_warn_expected_lints_fulfilled.stderr @@ -12,12 +12,6 @@ warning: unused variable: `fox_name` LL | let fox_name = "Sir Nibbles"; | ^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_fox_name` -warning: unused variable: `this_should_fulfill_the_expectation` - --> $DIR/force_warn_expected_lints_fulfilled.rs:43:9 - | -LL | let this_should_fulfill_the_expectation = "The `#[allow]` has no power here"; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_should_fulfill_the_expectation` - warning: variable does not need to be mutable --> $DIR/force_warn_expected_lints_fulfilled.rs:32:9 | @@ -28,6 +22,12 @@ LL | let mut what_does_the_fox_say = "*ding* *deng* *dung*"; | = note: requested on the command line with `--force-warn unused-mut` +warning: unused variable: `this_should_fulfill_the_expectation` + --> $DIR/force_warn_expected_lints_fulfilled.rs:43:9 + | +LL | let this_should_fulfill_the_expectation = "The `#[allow]` has no power here"; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_this_should_fulfill_the_expectation` + warning: denote infinite loops with `loop { ... }` --> $DIR/force_warn_expected_lints_fulfilled.rs:10:5 | diff --git a/tests/ui/lint/unused/lint-unused-variables.stderr b/tests/ui/lint/unused/lint-unused-variables.stderr index fd9a5bcbfc49b..09729eeba7923 100644 --- a/tests/ui/lint/unused/lint-unused-variables.stderr +++ b/tests/ui/lint/unused/lint-unused-variables.stderr @@ -10,18 +10,18 @@ note: the lint level is defined here LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ -error: unused variable: `b` - --> $DIR/lint-unused-variables.rs:14:5 - | -LL | b: i32, - | ^ help: if this is intentional, prefix it with an underscore: `_b` - error: unused variable: `a` --> $DIR/lint-unused-variables.rs:22:9 | LL | a: i32, | ^ help: if this is intentional, prefix it with an underscore: `_a` +error: unused variable: `b` + --> $DIR/lint-unused-variables.rs:14:5 + | +LL | b: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_b` + error: unused variable: `b` --> $DIR/lint-unused-variables.rs:29:9 | diff --git a/tests/ui/liveness/liveness-consts.stderr b/tests/ui/liveness/liveness-consts.stderr index 6199ea96c981f..016debdd39608 100644 --- a/tests/ui/liveness/liveness-consts.stderr +++ b/tests/ui/liveness/liveness-consts.stderr @@ -1,10 +1,9 @@ -warning: variable `a` is assigned to, but never used - --> $DIR/liveness-consts.rs:7:13 +warning: unused variable: `e` + --> $DIR/liveness-consts.rs:24:13 | -LL | let mut a = 0; - | ^ +LL | let e = 1; + | ^ help: if this is intentional, prefix it with an underscore: `_e` | - = note: consider using `_a` instead note: the lint level is defined here --> $DIR/liveness-consts.rs:2:9 | @@ -12,21 +11,6 @@ LL | #![warn(unused)] | ^^^^^^ = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]` -warning: value assigned to `b` is never read - --> $DIR/liveness-consts.rs:17:5 - | -LL | b += 1; - | ^ - | - = help: maybe it is overwritten before being read? - = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` - -warning: unused variable: `e` - --> $DIR/liveness-consts.rs:24:13 - | -LL | let e = 1; - | ^ help: if this is intentional, prefix it with an underscore: `_e` - warning: unused variable: `s` --> $DIR/liveness-consts.rs:33:24 | @@ -39,6 +23,29 @@ warning: unused variable: `z` LL | pub fn f(x: [u8; { let s = 17; 100 }]) -> [u8; { let z = 18; 100 }] { | ^ help: if this is intentional, prefix it with an underscore: `_z` +warning: unused variable: `z` + --> $DIR/liveness-consts.rs:60:13 + | +LL | let z = 42; + | ^ help: if this is intentional, prefix it with an underscore: `_z` + +warning: variable `a` is assigned to, but never used + --> $DIR/liveness-consts.rs:7:13 + | +LL | let mut a = 0; + | ^ + | + = note: consider using `_a` instead + +warning: value assigned to `b` is never read + --> $DIR/liveness-consts.rs:17:5 + | +LL | b += 1; + | ^ + | + = help: maybe it is overwritten before being read? + = note: `#[warn(unused_assignments)]` implied by `#[warn(unused)]` + warning: value assigned to `t` is never read --> $DIR/liveness-consts.rs:42:9 | @@ -53,11 +60,5 @@ warning: unused variable: `w` LL | let w = 10; | ^ help: if this is intentional, prefix it with an underscore: `_w` -warning: unused variable: `z` - --> $DIR/liveness-consts.rs:60:13 - | -LL | let z = 42; - | ^ help: if this is intentional, prefix it with an underscore: `_z` - warning: 8 warnings emitted diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr index 9305facc406f6..3ce48b1a72fca 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr @@ -54,14 +54,6 @@ LL | ref mut a @ box ref b => { | | | value is mutably borrowed by `a` here -error: cannot borrow value as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:54:11 - | -LL | fn f5(ref mut a @ box ref b: Box) { - | ^^^^^^^^^ ----- value is borrowed by `b` here - | | - | value is mutably borrowed by `a` here - error[E0382]: borrow of moved value --> $DIR/borrowck-pat-at-and-box.rs:31:9 | @@ -120,6 +112,14 @@ LL | ref mut a @ box ref b => { LL | drop(b); | - immutable borrow later used here +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-at-and-box.rs:54:11 + | +LL | fn f5(ref mut a @ box ref b: Box) { + | ^^^^^^^^^ ----- value is borrowed by `b` here + | | + | value is mutably borrowed by `a` here + error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable --> $DIR/borrowck-pat-at-and-box.rs:54:11 | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr index 13989ebadcb50..1ed019f0a6927 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr @@ -286,78 +286,6 @@ help: borrow this binding in the pattern to avoid moving the value LL | ref mut a @ Some([ref b, ref mut c]) => {} | +++ -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:11:11 - | -LL | fn f1(a @ ref b: U) {} - | ^ ----- value borrowed here after move - | | - | value moved into `a` here - | move occurs because `a` has type `U` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f1(ref a @ ref b: U) {} - | +++ - -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 - | -LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | ^^^^^ ----- ----- value borrowed here after move - | | | - | | value borrowed here after move - | value moved into `a` here - | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f2(ref mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | +++ - -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:20 - | -LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | ^ ----- value borrowed here after move - | | - | value moved into `b` here - | move occurs because `b` has type `U` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f2(mut a @ (ref b @ ref c, mut d @ ref e): (U, U)) {} - | +++ - -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:31 - | -LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} - | ^^^^^ ----- value borrowed here after move - | | - | value moved into `d` here - | move occurs because `d` has type `U` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f2(mut a @ (b @ ref c, ref mut d @ ref e): (U, U)) {} - | +++ - -error: borrow of moved value - --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:19:11 - | -LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} - | ^ --------- ----- value borrowed here after move - | | | - | | value borrowed here after move - | value moved into `a` here - | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait - | -help: borrow this binding in the pattern to avoid moving the value - | -LL | fn f3(ref a @ [ref mut b, ref c]: [U; 2]) {} - | +++ - error[E0382]: use of partially moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:24:9 | @@ -447,6 +375,63 @@ LL | mut a @ Some([ref b, ref mut c]) => {} | | | value moved here +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:11:11 + | +LL | fn f1(a @ ref b: U) {} + | ^ ----- value borrowed here after move + | | + | value moved into `a` here + | move occurs because `a` has type `U` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f1(ref a @ ref b: U) {} + | +++ + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | ^^^^^ ----- ----- value borrowed here after move + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f2(ref mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | +++ + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:20 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | ^ ----- value borrowed here after move + | | + | value moved into `b` here + | move occurs because `b` has type `U` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f2(mut a @ (ref b @ ref c, mut d @ ref e): (U, U)) {} + | +++ + +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:31 + | +LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} + | ^^^^^ ----- value borrowed here after move + | | + | value moved into `d` here + | move occurs because `d` has type `U` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f2(mut a @ (b @ ref c, ref mut d @ ref e): (U, U)) {} + | +++ + error[E0382]: use of partially moved value --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:14:11 | @@ -457,6 +442,21 @@ LL | fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {} | = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait +error: borrow of moved value + --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:19:11 + | +LL | fn f3(a @ [ref mut b, ref c]: [U; 2]) {} + | ^ --------- ----- value borrowed here after move + | | | + | | value borrowed here after move + | value moved into `a` here + | move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait + | +help: borrow this binding in the pattern to avoid moving the value + | +LL | fn f3(ref a @ [ref mut b, ref c]: [U; 2]) {} + | +++ + error: aborting due to 33 previous errors For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr index 00593b2a98f2b..c8c4d9b8fdb13 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr @@ -166,48 +166,6 @@ LL | ref mut a @ Some([b, mut c]) => {} | | value is moved into `b` here | value is mutably borrowed by `a` here -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11 - | -LL | fn f1(ref a @ b: U) {} - | ^^^^^ - value is moved into `b` here - | | - | value is borrowed by `a` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:14:11 - | -LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} - | ^^^^^ ----- - value is moved into `e` here - | | | - | | value is moved into `c` here - | value is borrowed by `a` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:14:20 - | -LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} - | ^^^^^ ----- value is moved into `c` here - | | - | value is borrowed by `b` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:14:35 - | -LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} - | ^^^^^ - value is moved into `e` here - | | - | value is borrowed by `d` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 - | -LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {} - | ^^^^^^^^^ - ----- value is moved into `c` here - | | | - | | value is moved into `b` here - | value is mutably borrowed by `a` here - error[E0382]: borrow of partially moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:30:9 | @@ -306,6 +264,14 @@ help: borrow this binding in the pattern to avoid moving the value LL | ref a @ Some((ref b @ mut c, ref d @ ref e)) => {} | +++ +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11 + | +LL | fn f1(ref a @ b: U) {} + | ^^^^^ - value is moved into `b` here + | | + | value is borrowed by `a` here + error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11 | @@ -315,6 +281,31 @@ LL | fn f1(ref a @ b: U) {} | value borrowed here after move | move occurs because value has type `U`, which does not implement the `Copy` trait +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:14:11 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | ^^^^^ ----- - value is moved into `e` here + | | | + | | value is moved into `c` here + | value is borrowed by `a` here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:14:20 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | ^^^^^ ----- value is moved into `c` here + | | + | value is borrowed by `b` here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:14:35 + | +LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} + | ^^^^^ - value is moved into `e` here + | | + | value is borrowed by `d` here + error[E0382]: borrow of moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:14:20 | @@ -335,6 +326,15 @@ LL | fn f2(ref a @ (ref b @ mut c, ref d @ e): (U, U)) {} | = note: move occurs because value has type `U`, which does not implement the `Copy` trait +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 + | +LL | fn f3(ref mut a @ [b, mut c]: [U; 2]) {} + | ^^^^^^^^^ - ----- value is moved into `c` here + | | | + | | value is moved into `b` here + | value is mutably borrowed by `a` here + error[E0382]: borrow of partially moved value --> $DIR/borrowck-pat-by-move-and-ref.rs:20:11 | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index d6409d1b643b9..c0a6558a1bf3b 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -221,47 +221,6 @@ LL | let ref mut a @ (ref b, ref c) = (U, U); | | value is borrowed by `b` here | value is mutably borrowed by `a` here -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:22:11 - | -LL | fn f1(ref a @ ref mut b: U) {} - | ^^^^^ --------- value is mutably borrowed by `b` here - | | - | value is borrowed by `a` here - -error: cannot borrow value as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 - | -LL | fn f2(ref mut a @ ref b: U) {} - | ^^^^^^^^^ ----- value is borrowed by `b` here - | | - | value is mutably borrowed by `a` here - -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 - | -LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} - | ^^^^^ ----------- value is mutably borrowed by `mid` here - | | - | value is borrowed by `a` here - -error: cannot borrow value as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:22 - | -LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} - | ^^^^^ --------- - value is moved into `c` here - | | | - | | value is mutably borrowed by `b` here - | value is borrowed by `a` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30 - | -LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} - | ^^^^^^^^^ - value is moved into `c` here - | | - | value is mutably borrowed by `b` here - error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable --> $DIR/borrowck-pat-ref-mut-and-ref.rs:8:31 | @@ -398,6 +357,47 @@ LL | LL | *b = U; | ------ mutable borrow later used here +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:22:11 + | +LL | fn f1(ref a @ ref mut b: U) {} + | ^^^^^ --------- value is mutably borrowed by `b` here + | | + | value is borrowed by `a` here + +error: cannot borrow value as immutable because it is also borrowed as mutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 + | +LL | fn f2(ref mut a @ ref b: U) {} + | ^^^^^^^^^ ----- value is borrowed by `b` here + | | + | value is mutably borrowed by `a` here + +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 + | +LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} + | ^^^^^ ----------- value is mutably borrowed by `mid` here + | | + | value is borrowed by `a` here + +error: cannot borrow value as mutable because it is also borrowed as immutable + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:22 + | +LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} + | ^^^^^ --------- - value is moved into `c` here + | | | + | | value is mutably borrowed by `b` here + | value is borrowed by `a` here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30 + | +LL | fn f4_also_moved(ref a @ ref mut b @ c: U) {} + | ^^^^^^^^^ - value is moved into `c` here + | | + | value is mutably borrowed by `b` here + error[E0382]: borrow of moved value --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:30 | diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index 24189d0615c70..c634ea470c5d5 100644 --- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -194,50 +194,6 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | | | value is mutably borrowed by `a` here -error: cannot borrow value as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:8:11 - | -LL | fn f1(ref mut a @ ref mut b: U) {} - | ^^^^^^^^^ --------- value is mutably borrowed by `b` here - | | - | value is mutably borrowed by `a` here - -error: cannot borrow value as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11 - | -LL | fn f2(ref mut a @ ref mut b: U) {} - | ^^^^^^^^^ --------- value is mutably borrowed by `b` here - | | - | value is mutably borrowed by `a` here - -error: cannot borrow value as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:13:9 - | -LL | ref mut a @ [ - | ^^^^^^^^^ value is mutably borrowed by `a` here -LL | -LL | [ref b @ .., _], - | ----- value is borrowed by `b` here -LL | [_, ref mut mid @ ..], - | ----------- value is mutably borrowed by `mid` here - -error: cannot borrow value as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:21:22 - | -LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} - | ^^^^^^^^^ --------- - value is moved into `c` here - | | | - | | value is mutably borrowed by `b` here - | value is mutably borrowed by `a` here - -error: cannot move out of value because it is borrowed - --> $DIR/borrowck-pat-ref-mut-twice.rs:21:34 - | -LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} - | ^^^^^^^^^ - value is moved into `c` here - | | - | value is mutably borrowed by `b` here - error[E0499]: cannot borrow value as mutable more than once at a time --> $DIR/borrowck-pat-ref-mut-twice.rs:29:9 | @@ -304,6 +260,50 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { LL | drop(a); | - first borrow later used here +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:8:11 + | +LL | fn f1(ref mut a @ ref mut b: U) {} + | ^^^^^^^^^ --------- value is mutably borrowed by `b` here + | | + | value is mutably borrowed by `a` here + +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11 + | +LL | fn f2(ref mut a @ ref mut b: U) {} + | ^^^^^^^^^ --------- value is mutably borrowed by `b` here + | | + | value is mutably borrowed by `a` here + +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:13:9 + | +LL | ref mut a @ [ + | ^^^^^^^^^ value is mutably borrowed by `a` here +LL | +LL | [ref b @ .., _], + | ----- value is borrowed by `b` here +LL | [_, ref mut mid @ ..], + | ----------- value is mutably borrowed by `mid` here + +error: cannot borrow value as mutable more than once at a time + --> $DIR/borrowck-pat-ref-mut-twice.rs:21:22 + | +LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + | ^^^^^^^^^ --------- - value is moved into `c` here + | | | + | | value is mutably borrowed by `b` here + | value is mutably borrowed by `a` here + +error: cannot move out of value because it is borrowed + --> $DIR/borrowck-pat-ref-mut-twice.rs:21:34 + | +LL | fn f4_also_moved(ref mut a @ ref mut b @ c: U) {} + | ^^^^^^^^^ - value is moved into `c` here + | | + | value is mutably borrowed by `b` here + error[E0382]: borrow of moved value --> $DIR/borrowck-pat-ref-mut-twice.rs:21:34 | diff --git a/tests/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr b/tests/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr index 6d18d295cfc64..16e1af46059a4 100644 --- a/tests/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr +++ b/tests/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr @@ -10,6 +10,12 @@ note: the lint level is defined here LL | #![deny(unused_variables)] | ^^^^^^^^^^^^^^^^ +error: unused variable: `a` + --> $DIR/param-attrs-cfg.rs:41:27 + | +LL | #[cfg(something)] a: i32, + | ^ help: if this is intentional, prefix it with an underscore: `_a` + error: unused variable: `b` --> $DIR/param-attrs-cfg.rs:30:23 | @@ -22,12 +28,6 @@ error: unused variable: `c` LL | #[cfg_attr(nothing, cfg(nothing))] c: i32, | ^ help: if this is intentional, prefix it with an underscore: `_c` -error: unused variable: `a` - --> $DIR/param-attrs-cfg.rs:41:27 - | -LL | #[cfg(something)] a: i32, - | ^ help: if this is intentional, prefix it with an underscore: `_a` - error: unused variable: `b` --> $DIR/param-attrs-cfg.rs:48:27 | From 5cefe75436e18ed54a78cd883f00aacc50ce2f4f Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 21 Apr 2023 16:28:05 -0700 Subject: [PATCH 19/42] rustdoc: remove unneeded handleKey from settings.js This code was added in 9dc5dfb97504c538bc72f367a77bb9f714c30097 and 704050da2334c465784954d81c8990c4bc7a92c5 because the browser- native checkbox was `display: none`, breaking native keyboard accessibility. The native checkbox is now merely `appearance: none`, which does not turn off [behavior semantics], so JavaScript to reimplement it isn't needed any more. [behavior semantics]: https://w3c.github.io/csswg-drafts/css-ui/#appearance-semantics --- src/librustdoc/html/static/js/settings.js | 19 +------------------ tests/rustdoc-gui/settings.goml | 9 +++++++++ 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index ebbe6c1ca9a24..2cba32c1b507a 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -1,5 +1,5 @@ // Local js definitions: -/* global getSettingValue, getVirtualKey, updateLocalStorage, updateTheme */ +/* global getSettingValue, updateLocalStorage, updateTheme */ /* global addClass, removeClass, onEach, onEachLazy, blurHandler, elemIsInParent */ /* global MAIN_ID, getVar, getSettingsButton */ @@ -32,21 +32,6 @@ } } - function handleKey(ev) { - // Don't interfere with browser shortcuts - if (ev.ctrlKey || ev.altKey || ev.metaKey) { - return; - } - switch (getVirtualKey(ev)) { - case "Enter": - case "Return": - case "Space": - ev.target.checked = !ev.target.checked; - ev.preventDefault(); - break; - } - } - function showLightAndDark() { removeClass(document.getElementById("preferred-light-theme"), "hidden"); removeClass(document.getElementById("preferred-dark-theme"), "hidden"); @@ -77,8 +62,6 @@ toggle.onchange = function() { changeSetting(this.id, this.checked); }; - toggle.onkeyup = handleKey; - toggle.onkeyrelease = handleKey; }); onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"), elem => { const settingId = elem.name; diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml index 733be9bebbabc..a44ff9d3e4a9d 100644 --- a/tests/rustdoc-gui/settings.goml +++ b/tests/rustdoc-gui/settings.goml @@ -256,6 +256,15 @@ set-local-storage: {"rustdoc-disable-shortcuts": "false"} click: ".setting-line:last-child .setting-check span" assert-local-storage: {"rustdoc-disable-shortcuts": "true"} +// We now check that focusing a toggle and pressing Space is like clicking on it. +assert-local-storage: {"rustdoc-disable-shortcuts": "true"} +focus: ".setting-line:last-child .setting-check input" +press-key: "Space" +assert-local-storage: {"rustdoc-disable-shortcuts": "false"} +focus: ".setting-line:last-child .setting-check input" +press-key: "Space" +assert-local-storage: {"rustdoc-disable-shortcuts": "true"} + // Make sure that "Disable keyboard shortcuts" actually took effect. press-key: "Escape" press-key: "?" From 1d0f34fd771004ed515cb7120df1898c2ef5322e Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 21 Apr 2023 17:07:42 -0700 Subject: [PATCH 20/42] rustdoc: remove unused CSS `color: inherit` This code was added back when `border-color: currentColor` was used. Since it was changed in ad9a89eef2857a24ef049b9eee2d1db5bcbf1d11, the current color is not used any more. --- src/librustdoc/html/static/css/settings.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css index d13c783d2e4fb..99cf8e443f032 100644 --- a/src/librustdoc/html/static/css/settings.css +++ b/src/librustdoc/html/static/css/settings.css @@ -7,7 +7,6 @@ margin-right: 0.3em; height: 1.2rem; width: 1.2rem; - color: inherit; border: 2px solid var(--settings-input-border-color); outline: none; -webkit-appearance: none; From 6ecdd0377c0db8e1d0446abf7cff5d15f53b0c8f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Fri, 21 Apr 2023 20:56:59 -0400 Subject: [PATCH 21/42] Add note about change in bootstrap defaults --- RELEASES.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 699735de6fb4d..e72905c15bd25 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -88,7 +88,11 @@ Compatibility Notes - [When `default-features` is set to false of a workspace dependency, and an inherited dependency of a member has `default-features = true`, Cargo will enable default features of that dependency.](https://github.com/rust-lang/cargo/pull/11409/) - [Cargo denies `CARGO_HOME` in the `[env]` configuration table. Cargo itself doesn't pick up this value, but recursive calls to cargo would, which was not intended.](https://github.com/rust-lang/cargo/pull/11644/) - [Debuginfo for build dependencies is now off if not explicitly set. This is expected to improve the overall build time.](https://github.com/rust-lang/cargo/pull/11252/) - +- [The Rust distribution no longer always includes rustdoc](https://github.com/rust-lang/rust/pull/106886) + If `tools = [...]` is set in config.toml, we will respect a missing rustdoc in that list. By + default rustdoc remains included. To retain the prior behavior explicitly add `"rustdoc"` to the + list. + Internal Changes From e9c52a5cbbe03b56e8fe7b35c3b488b4bad5b17e Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Sat, 22 Apr 2023 13:25:38 +1200 Subject: [PATCH 22/42] stop `x fmt` formatting alt build dirs --- src/bootstrap/format.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index b79969663ca2e..d8d3f300a3500 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -145,10 +145,8 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { let untracked_paths = untracked_paths_output .lines() .filter(|entry| entry.starts_with("??")) - .filter_map(|entry| { - let path = - entry.split(' ').nth(1).expect("every git status entry should list a path"); - path.ends_with(".rs").then_some(path) + .map(|entry| { + entry.split(' ').nth(1).expect("every git status entry should list a path") }); for untracked_path in untracked_paths { println!("skip untracked path {} during rustfmt invocations", untracked_path); From 6041030c0f2ac5b56074384dc79fe122889abba7 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 22 Apr 2023 06:06:34 +0000 Subject: [PATCH 23/42] Expect that equating a projection term always succeeds in new solver --- .../src/solve/project_goals.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 3a2acbeb32e15..f0840e0443c19 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -73,7 +73,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { goal.predicate.projection_ty, assumption_projection_pred.projection_ty, )?; - ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term)?; + ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term) + .expect("expected goal term to be fully unconstrained"); ecx.add_goals(requirements); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) @@ -114,7 +115,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { .into_iter() .map(|pred| goal.with(tcx, pred)), ); - ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term)?; + ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term) + .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } else { @@ -206,7 +208,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ty.map_bound(|ty| ty.into()) }; - ecx.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs))?; + ecx.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs)) + .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } @@ -375,7 +378,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ), }; - ecx.eq(goal.param_env, goal.predicate.term, metadata_ty.into())?; + ecx.eq(goal.param_env, goal.predicate.term, metadata_ty.into()) + .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } @@ -513,7 +517,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { }; ecx.probe(|ecx| { - ecx.eq(goal.param_env, goal.predicate.term, discriminant_ty.into())?; + ecx.eq(goal.param_env, goal.predicate.term, discriminant_ty.into()) + .expect("expected goal term to be fully unconstrained"); ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } From 0cc1b86a3a7ca831f31b64b0f96bb25238113221 Mon Sep 17 00:00:00 2001 From: Caleb Robson <94545082+Spartan2909@users.noreply.github.com> Date: Sat, 22 Apr 2023 15:58:44 +0100 Subject: [PATCH 24/42] Fix grammar --- library/core/src/hint.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index a205565773a71..f6698589ccd92 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -73,8 +73,8 @@ use crate::intrinsics; /// ``` /// /// While using `unreachable_unchecked()` is perfectly sound in the following -/// example, the compiler is able to prove that a division by zero is not -/// possible. Benchmarking reveals that `unreachable_unchecked()` provides +/// example, as the compiler is able to prove that a division by zero is not +/// possible, benchmarking reveals that `unreachable_unchecked()` provides /// no benefit over using [`unreachable!`], while the latter does not introduce /// the possibility of Undefined Behavior. /// From c8874e24458e7ba88fad7969562a45c951d002a8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 22 Apr 2023 19:29:30 +0000 Subject: [PATCH 25/42] Don't infer fn return type to return itself --- compiler/rustc_hir_analysis/src/collect.rs | 31 ++++++++++++------- .../ui/typeck/bad-recursive-type-sig-infer.rs | 11 +++++++ .../bad-recursive-type-sig-infer.stderr | 15 +++++++++ 3 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 tests/ui/typeck/bad-recursive-type-sig-infer.rs create mode 100644 tests/ui/typeck/bad-recursive-type-sig-infer.stderr diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 36e294e8aa29f..9fe0c07814ed8 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1146,8 +1146,14 @@ fn infer_return_ty_for_fn_sig<'tcx>( let mut visitor = HirPlaceholderCollector::default(); visitor.visit_ty(ty); + let mut diag = bad_placeholder(tcx, visitor.0, "return type"); let ret_ty = fn_sig.output(); + // Don't leak types into signatures unless they're nameable! + // For example, if a function returns itself, we don't want that + // recursive function definition to leak out into the fn sig. + let mut should_recover = false; + if let Some(ret_ty) = ret_ty.make_suggestable(tcx, false) { diag.span_suggestion( ty.span, @@ -1155,15 +1161,7 @@ fn infer_return_ty_for_fn_sig<'tcx>( ret_ty, Applicability::MachineApplicable, ); - } else if matches!(ret_ty.kind(), ty::FnDef(..)) - && let Some(fn_sig) = ret_ty.fn_sig(tcx).make_suggestable(tcx, false) - { - diag.span_suggestion( - ty.span, - "replace with the correct return type", - fn_sig, - Applicability::MachineApplicable, - ); + should_recover = true; } else if let Some(sugg) = suggest_impl_trait(tcx, ret_ty, ty.span, def_id) { diag.span_suggestion( ty.span, @@ -1181,9 +1179,20 @@ fn infer_return_ty_for_fn_sig<'tcx>( https://doc.rust-lang.org/book/ch13-01-closures.html", ); } - diag.emit(); - ty::Binder::dummy(fn_sig) + let guar = diag.emit(); + + if should_recover { + ty::Binder::dummy(fn_sig) + } else { + ty::Binder::dummy(tcx.mk_fn_sig( + fn_sig.inputs().iter().copied(), + tcx.ty_error(guar), + fn_sig.c_variadic, + fn_sig.unsafety, + fn_sig.abi, + )) + } } None => icx.astconv().ty_of_fn( hir_id, diff --git a/tests/ui/typeck/bad-recursive-type-sig-infer.rs b/tests/ui/typeck/bad-recursive-type-sig-infer.rs new file mode 100644 index 0000000000000..9812d8c381117 --- /dev/null +++ b/tests/ui/typeck/bad-recursive-type-sig-infer.rs @@ -0,0 +1,11 @@ +fn a() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + &a +} + +fn b() -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + &a +} + +fn main() {} diff --git a/tests/ui/typeck/bad-recursive-type-sig-infer.stderr b/tests/ui/typeck/bad-recursive-type-sig-infer.stderr new file mode 100644 index 0000000000000..e145da5623ac0 --- /dev/null +++ b/tests/ui/typeck/bad-recursive-type-sig-infer.stderr @@ -0,0 +1,15 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/bad-recursive-type-sig-infer.rs:1:11 + | +LL | fn a() -> _ { + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/bad-recursive-type-sig-infer.rs:6:11 + | +LL | fn b() -> _ { + | ^ not allowed in type signatures + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0121`. From f77541adb63ecb7d00374e7969de066120ade6e5 Mon Sep 17 00:00:00 2001 From: nils <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 11 Apr 2023 13:46:41 +0200 Subject: [PATCH 26/42] Update chrono/spdx-rs This gets rid of https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-26235 --- Cargo.lock | 310 ++++++++++++++++++++++++++++++++----- src/tools/tidy/src/deps.rs | 9 +- 2 files changed, 276 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f2dab5e63503..2cc891bcb77b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -78,6 +78,15 @@ dependencies = [ "url", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "annotate-snippets" version = "0.9.1" @@ -306,6 +315,12 @@ dependencies = [ "toml", ] +[[package]] +name = "bumpalo" +version = "3.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" + [[package]] name = "bytecount" version = "0.6.2" @@ -456,15 +471,14 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ - "libc", + "iana-time-zone", "num-integer", "num-traits", "serde", - "time", "winapi", ] @@ -637,6 +651,16 @@ dependencies = [ "rustc-semver", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + [[package]] name = "collect-license-metadata" version = "0.1.0" @@ -717,7 +741,7 @@ dependencies = [ "tracing-subscriber", "unified-diff", "walkdir", - "windows", + "windows 0.46.0", ] [[package]] @@ -772,6 +796,12 @@ dependencies = [ "rand_xorshift", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + [[package]] name = "coverage_test_macros" version = "0.0.0" @@ -887,6 +917,50 @@ dependencies = [ "winapi", ] +[[package]] +name = "cxx" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 2.0.8", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.8", +] + [[package]] name = "datafrog" version = "2.0.1" @@ -1555,6 +1629,30 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" +[[package]] +name = "iana-time-zone" +version = "0.1.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows 0.48.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + [[package]] name = "icu_list" version = "1.1.0" @@ -1778,6 +1876,15 @@ dependencies = [ "libc", ] +[[package]] +name = "js-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "jsondocck" version = "0.1.0" @@ -1885,6 +1992,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "link-cplusplus" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +dependencies = [ + "cc", +] + [[package]] name = "linkchecker" version = "0.1.0" @@ -3192,7 +3308,7 @@ dependencies = [ "tempfile", "thin-vec", "tracing", - "windows", + "windows 0.46.0", ] [[package]] @@ -3252,7 +3368,7 @@ dependencies = [ "rustc_ty_utils", "serde_json", "tracing", - "windows", + "windows 0.46.0", ] [[package]] @@ -3302,7 +3418,7 @@ dependencies = [ "termize", "tracing", "unicode-width", - "windows", + "windows 0.46.0", ] [[package]] @@ -3974,7 +4090,7 @@ dependencies = [ "smallvec", "termize", "tracing", - "windows", + "windows 0.46.0", ] [[package]] @@ -4302,6 +4418,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "scratch" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" + [[package]] name = "self_cell" version = "0.10.2" @@ -4440,9 +4562,9 @@ dependencies = [ [[package]] name = "spdx-rs" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3c02f6eb7e7b4100c272f685a9ccaccaab302324e8c7ec3e2ee72340fb29ff3" +checksum = "6b1ec09829bf2d82c175c121b20de11ffab2def83bd55979002099b1f9956c9b" dependencies = [ "chrono", "log", @@ -4806,16 +4928,6 @@ dependencies = [ name = "tier-check" version = "0.1.0" -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "tinystr" version = "0.7.1" @@ -5240,9 +5352,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "0.8.2" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +checksum = "5b55a3fef2a1e3b3a00ce878640918820d3c51081576ac657d23af9fc7928fdb" dependencies = [ "getrandom", ] @@ -5287,6 +5399,60 @@ dependencies = [ "rustc-std-workspace-core", ] +[[package]] +name = "wasm-bindgen" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 1.0.102", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.102", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + [[package]] name = "winapi" version = "0.3.9" @@ -5324,7 +5490,16 @@ version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", +] + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.0", ] [[package]] @@ -5333,13 +5508,13 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -5348,7 +5523,7 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.2", ] [[package]] @@ -5357,13 +5532,28 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] @@ -5372,42 +5562,84 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + [[package]] name = "windows_i686_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + [[package]] name = "windows_i686_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + [[package]] name = "writeable" version = "0.5.1" diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 0e0a517ae49db..411cbc760e09d 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -36,10 +36,11 @@ const EXCEPTIONS: &[(&str, &str)] = &[ ("mdbook", "MPL-2.0"), // mdbook ("colored", "MPL-2.0"), // rustfmt ("ryu", "Apache-2.0 OR BSL-1.0"), // cargo/... (because of serde) - ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot - ("snap", "BSD-3-Clause"), // rustc - ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations) - ("self_cell", "Apache-2.0"), // rustc (fluent translations) + ("codespan-reporting", "Apache-2.0"), // cxx via iana-time-zone-haiku via time, only on haiku + ("instant", "BSD-3-Clause"), // rustc_driver/tracing-subscriber/parking_lot + ("snap", "BSD-3-Clause"), // rustc + ("fluent-langneg", "Apache-2.0"), // rustc (fluent translations) + ("self_cell", "Apache-2.0"), // rustc (fluent translations) // FIXME: this dependency violates the documentation comment above: ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target ("dissimilar", "Apache-2.0"), // rustdoc, rustc_lexer (few tests) via expect-test, (dev deps) From ed8d67d8ba32baa864b8db692f7eb74a4a7b1e72 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 25 Mar 2023 11:19:03 +0000 Subject: [PATCH 27/42] Impl `Copy` for almost all HIR types This simplifies the invocation of the `arena_types` macro and probably makes working with HIR nicer in general. --- compiler/rustc_hir/src/arena.rs | 42 +-------- compiler/rustc_hir/src/hir.rs | 128 +++++++++++++------------- compiler/rustc_passes/src/liveness.rs | 2 +- 3 files changed, 66 insertions(+), 106 deletions(-) diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index 3e5b3c498eee9..efd8c440f5c6c 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -1,56 +1,16 @@ /// This higher-order macro declares a list of types which can be allocated by `Arena`. -/// -/// Specifying the `decode` modifier will add decode impls for `&T` and `&[T]`, -/// where `T` is the type listed. These impls will appear in the implement_ty_decoder! macro. +/// Note that all `Copy` types can be allocated by default and need not be specified here. #[macro_export] macro_rules! arena_types { ($macro:path) => ( $macro!([ // HIR types [] hir_krate: rustc_hir::Crate<'tcx>, - [] arm: rustc_hir::Arm<'tcx>, - [] asm_operand: (rustc_hir::InlineAsmOperand<'tcx>, rustc_span::Span), [] asm_template: rustc_ast::InlineAsmTemplatePiece, [] attribute: rustc_ast::Attribute, - [] closure: rustc_hir::Closure<'tcx>, - [] block: rustc_hir::Block<'tcx>, - [] bare_fn_ty: rustc_hir::BareFnTy<'tcx>, - [] body: rustc_hir::Body<'tcx>, - [] generics: rustc_hir::Generics<'tcx>, - [] generic_arg: rustc_hir::GenericArg<'tcx>, - [] generic_args: rustc_hir::GenericArgs<'tcx>, - [] generic_bound: rustc_hir::GenericBound<'tcx>, - [] generic_param: rustc_hir::GenericParam<'tcx>, - [] expr: rustc_hir::Expr<'tcx>, - [] impl_: rustc_hir::Impl<'tcx>, - [] let_expr: rustc_hir::Let<'tcx>, - [] expr_field: rustc_hir::ExprField<'tcx>, - [] pat_field: rustc_hir::PatField<'tcx>, - [] fn_decl: rustc_hir::FnDecl<'tcx>, - [] foreign_item: rustc_hir::ForeignItem<'tcx>, - [] foreign_item_ref: rustc_hir::ForeignItemRef, - [] impl_item: rustc_hir::ImplItem<'tcx>, - [] impl_item_ref: rustc_hir::ImplItemRef, [] item: rustc_hir::Item<'tcx>, - [] inline_asm: rustc_hir::InlineAsm<'tcx>, - [] local: rustc_hir::Local<'tcx>, - [] mod_: rustc_hir::Mod<'tcx>, [] owner_info: rustc_hir::OwnerInfo<'tcx>, - [] param: rustc_hir::Param<'tcx>, - [] pat: rustc_hir::Pat<'tcx>, - [] path: rustc_hir::Path<'tcx>, [] use_path: rustc_hir::UsePath<'tcx>, - [] path_segment: rustc_hir::PathSegment<'tcx>, - [] poly_trait_ref: rustc_hir::PolyTraitRef<'tcx>, - [] qpath: rustc_hir::QPath<'tcx>, - [] stmt: rustc_hir::Stmt<'tcx>, - [] field_def: rustc_hir::FieldDef<'tcx>, - [] trait_item: rustc_hir::TraitItem<'tcx>, - [] trait_item_ref: rustc_hir::TraitItemRef, - [] ty: rustc_hir::Ty<'tcx>, - [] type_binding: rustc_hir::TypeBinding<'tcx>, - [] variant: rustc_hir::Variant<'tcx>, - [] where_predicate: rustc_hir::WherePredicate<'tcx>, [] lit: rustc_hir::Lit, ]); ) diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 52ed9660256cb..0ecb1bf4c5993 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -182,7 +182,7 @@ impl Lifetime { /// A `Path` is essentially Rust's notion of a name; for instance, /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers, /// along with a bunch of supporting information. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Path<'hir, R = Res> { pub span: Span, /// The resolution for the path. @@ -202,7 +202,7 @@ impl Path<'_> { /// A segment of a path: an identifier, an optional lifetime, and a set of /// types. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct PathSegment<'hir> { /// The identifier portion of this path segment. pub ident: Ident, @@ -243,13 +243,13 @@ impl<'hir> PathSegment<'hir> { } } -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Clone, Copy, Debug, HashStable_Generic)] pub struct ConstArg { pub value: AnonConst, pub span: Span, } -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Clone, Copy, Debug, HashStable_Generic)] pub struct InferArg { pub hir_id: HirId, pub span: Span, @@ -261,7 +261,7 @@ impl InferArg { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum GenericArg<'hir> { Lifetime(&'hir Lifetime), Type(&'hir Ty<'hir>), @@ -318,7 +318,7 @@ impl GenericArg<'_> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct GenericArgs<'hir> { /// The generic arguments for this path segment. pub args: &'hir [GenericArg<'hir>], @@ -447,7 +447,7 @@ pub enum TraitBoundModifier { /// `typeck::collect::compute_bounds` matches these against /// the "special" built-in traits (see `middle::lang_items`) and /// detects `Copy`, `Send` and `Sync`. -#[derive(Clone, Debug, HashStable_Generic)] +#[derive(Clone, Copy, Debug, HashStable_Generic)] pub enum GenericBound<'hir> { Trait(PolyTraitRef<'hir>, TraitBoundModifier), // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem` @@ -488,7 +488,7 @@ pub enum LifetimeParamKind { Error, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum GenericParamKind<'hir> { /// A lifetime definition (e.g., `'a: 'b + 'c + 'd`). Lifetime { @@ -505,7 +505,7 @@ pub enum GenericParamKind<'hir> { }, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct GenericParam<'hir> { pub hir_id: HirId, pub def_id: LocalDefId, @@ -557,7 +557,7 @@ pub struct GenericParamCount { /// Represents lifetimes and type parameters attached to a declaration /// of a function, enum, trait, etc. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Generics<'hir> { pub params: &'hir [GenericParam<'hir>], pub predicates: &'hir [WherePredicate<'hir>], @@ -729,7 +729,7 @@ impl<'hir> Generics<'hir> { } /// A single predicate in a where-clause. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum WherePredicate<'hir> { /// A type binding (e.g., `for<'c> Foo: Send + Clone + 'c`). BoundPredicate(WhereBoundPredicate<'hir>), @@ -773,7 +773,7 @@ pub enum PredicateOrigin { } /// A type bound (e.g., `for<'c> Foo: Send + Clone + 'c`). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct WhereBoundPredicate<'hir> { pub hir_id: HirId, pub span: Span, @@ -795,7 +795,7 @@ impl<'hir> WhereBoundPredicate<'hir> { } /// A lifetime predicate (e.g., `'a: 'b + 'c`). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct WhereRegionPredicate<'hir> { pub span: Span, pub in_where_clause: bool, @@ -811,7 +811,7 @@ impl<'hir> WhereRegionPredicate<'hir> { } /// An equality predicate (e.g., `T = int`); currently unsupported. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct WhereEqPredicate<'hir> { pub span: Span, pub lhs_ty: &'hir Ty<'hir>, @@ -821,7 +821,7 @@ pub struct WhereEqPredicate<'hir> { /// HIR node coupled with its parent's id in the same HIR owner. /// /// The parent is trash when the node is a HIR owner. -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub struct ParentedNode<'tcx> { pub parent: ItemLocalId, pub node: Node<'tcx>, @@ -959,7 +959,7 @@ pub struct Crate<'hir> { pub opt_hir_hash: Option, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Closure<'hir> { pub def_id: LocalDefId, pub binder: ClosureBinder, @@ -978,7 +978,7 @@ pub struct Closure<'hir> { /// A block of statements `{ .. }`, which may have a label (in this case the /// `targeted_by_break` field will be `true`) and may be `unsafe` by means of /// the `rules` being anything but `DefaultBlock`. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Block<'hir> { /// Statements in a block. pub stmts: &'hir [Stmt<'hir>], @@ -1006,7 +1006,7 @@ impl<'hir> Block<'hir> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Pat<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1085,7 +1085,7 @@ impl<'hir> Pat<'hir> { /// Patterns like the fields of Foo `{ x, ref y, ref mut z }` /// are treated the same as` x: x, y: ref y, z: ref mut z`, /// except `is_shorthand` is true. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct PatField<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1141,7 +1141,7 @@ impl fmt::Debug for DotDotPos { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum PatKind<'hir> { /// Represents a wildcard pattern (i.e., `_`). Wild, @@ -1351,7 +1351,7 @@ impl UnOp { } /// A statement. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Stmt<'hir> { pub hir_id: HirId, pub kind: StmtKind<'hir>, @@ -1359,7 +1359,7 @@ pub struct Stmt<'hir> { } /// The contents of a statement. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum StmtKind<'hir> { /// A local (`let`) binding. Local(&'hir Local<'hir>), @@ -1375,7 +1375,7 @@ pub enum StmtKind<'hir> { } /// Represents a `let` statement (i.e., `let : = ;`). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Local<'hir> { pub pat: &'hir Pat<'hir>, /// Type annotation, if any (otherwise the type will be inferred). @@ -1393,7 +1393,7 @@ pub struct Local<'hir> { /// Represents a single arm of a `match` expression, e.g. /// ` (if ) => `. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Arm<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1411,7 +1411,7 @@ pub struct Arm<'hir> { /// /// In an if-let, imagine it as `if (let = ) { ... }`; in a let-else, it is part of the /// desugaring to if-let. Only let-else supports the type annotation at present. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Let<'hir> { pub hir_id: HirId, pub span: Span, @@ -1420,7 +1420,7 @@ pub struct Let<'hir> { pub init: &'hir Expr<'hir>, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum Guard<'hir> { If(&'hir Expr<'hir>), IfLet(&'hir Let<'hir>), @@ -1440,7 +1440,7 @@ impl<'hir> Guard<'hir> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ExprField<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -1488,7 +1488,7 @@ pub struct BodyId { /// /// All bodies have an **owner**, which can be accessed via the HIR /// map using `body_owner_def_id()`. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Body<'hir> { pub params: &'hir [Param<'hir>], pub value: &'hir Expr<'hir>, @@ -1679,7 +1679,7 @@ pub struct AnonConst { } /// An expression. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Expr<'hir> { pub hir_id: HirId, pub kind: ExprKind<'hir>, @@ -1922,7 +1922,7 @@ pub fn is_range_literal(expr: &Expr<'_>) -> bool { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ExprKind<'hir> { /// Allow anonymous constants from an inline `const` block ConstBlock(AnonConst), @@ -2051,7 +2051,7 @@ pub enum ExprKind<'hir> { /// To resolve the path to a `DefId`, call [`qpath_res`]. /// /// [`qpath_res`]: ../../rustc_middle/ty/struct.TypeckResults.html#method.qpath_res -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum QPath<'hir> { /// Path to a definition, optionally "fully-qualified" with a `Self` /// type, if the path points to an associated item in a trait. @@ -2243,7 +2243,7 @@ impl From for YieldSource { // N.B., if you change this, you'll probably want to change the corresponding // type structure in middle/ty.rs as well. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct MutTy<'hir> { pub ty: &'hir Ty<'hir>, pub mutbl: Mutability, @@ -2251,7 +2251,7 @@ pub struct MutTy<'hir> { /// Represents a function's signature in a trait declaration, /// trait implementation, or a free function. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct FnSig<'hir> { pub header: FnHeader, pub decl: &'hir FnDecl<'hir>, @@ -2278,7 +2278,7 @@ impl TraitItemId { /// possibly including a default implementation. A trait item is /// either required (meaning it doesn't have an implementation, just a /// signature) or provided (meaning it has a default implementation). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct TraitItem<'hir> { pub ident: Ident, pub owner_id: OwnerId, @@ -2327,7 +2327,7 @@ impl<'hir> TraitItem<'hir> { } /// Represents a trait method's body (or just argument names). -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)] pub enum TraitFn<'hir> { /// No default body in the trait, just a signature. Required(&'hir [Ident]), @@ -2337,7 +2337,7 @@ pub enum TraitFn<'hir> { } /// Represents a trait method or associated constant or type -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TraitItemKind<'hir> { /// An associated constant with an optional value (otherwise `impl`s must contain a value). Const(&'hir Ty<'hir>, Option), @@ -2365,7 +2365,7 @@ impl ImplItemId { } /// Represents anything within an `impl` block. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ImplItem<'hir> { pub ident: Ident, pub owner_id: OwnerId, @@ -2415,7 +2415,7 @@ impl<'hir> ImplItem<'hir> { } /// Represents various kinds of content within an `impl`. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ImplItemKind<'hir> { /// An associated constant of the given type, set to the constant result /// of the expression. @@ -2444,7 +2444,7 @@ pub const FN_OUTPUT_NAME: Symbol = sym::Output; /// Binding(...), /// } /// ``` -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct TypeBinding<'hir> { pub hir_id: HirId, pub ident: Ident, @@ -2453,7 +2453,7 @@ pub struct TypeBinding<'hir> { pub span: Span, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum Term<'hir> { Ty(&'hir Ty<'hir>), Const(AnonConst), @@ -2472,7 +2472,7 @@ impl<'hir> From for Term<'hir> { } // Represents the two kinds of type bindings. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TypeBindingKind<'hir> { /// E.g., `Foo`. Constraint { bounds: &'hir [GenericBound<'hir>] }, @@ -2495,7 +2495,7 @@ impl TypeBinding<'_> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Ty<'hir> { pub hir_id: HirId, pub kind: TyKind<'hir>, @@ -2640,7 +2640,7 @@ impl PrimTy { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct BareFnTy<'hir> { pub unsafety: Unsafety, pub abi: Abi, @@ -2649,7 +2649,7 @@ pub struct BareFnTy<'hir> { pub param_names: &'hir [Ident], } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct OpaqueTy<'hir> { pub generics: &'hir Generics<'hir>, pub bounds: GenericBounds<'hir>, @@ -2669,7 +2669,7 @@ pub enum OpaqueTyOrigin { } /// The various kinds of types recognized by the compiler. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum TyKind<'hir> { /// A variable length slice (i.e., `[T]`). Slice(&'hir Ty<'hir>), @@ -2709,7 +2709,7 @@ pub enum TyKind<'hir> { Err(rustc_span::ErrorGuaranteed), } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum InlineAsmOperand<'hir> { In { reg: InlineAsmRegOrRegClass, @@ -2762,7 +2762,7 @@ impl<'hir> InlineAsmOperand<'hir> { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct InlineAsm<'hir> { pub template: &'hir [InlineAsmTemplatePiece], pub template_strs: &'hir [(Symbol, Option, Span)], @@ -2772,7 +2772,7 @@ pub struct InlineAsm<'hir> { } /// Represents a parameter in a function header. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Param<'hir> { pub hir_id: HirId, pub pat: &'hir Pat<'hir>, @@ -2781,7 +2781,7 @@ pub struct Param<'hir> { } /// Represents the header (not the body) of a function declaration. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct FnDecl<'hir> { /// The types of the function's parameters. /// @@ -2854,7 +2854,7 @@ impl Defaultness { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum FnRetTy<'hir> { /// Return type is not specified. /// @@ -2887,7 +2887,7 @@ pub enum ClosureBinder { For { span: Span }, } -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)] pub struct Mod<'hir> { pub spans: ModSpans, pub item_ids: &'hir [ItemId], @@ -2902,12 +2902,12 @@ pub struct ModSpans { pub inject_use_span: Span, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct EnumDef<'hir> { pub variants: &'hir [Variant<'hir>], } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Variant<'hir> { /// Name of the variant. pub ident: Ident, @@ -2944,7 +2944,7 @@ pub enum UseKind { /// that the `ref_id` is for. Note that `ref_id`'s value is not the `HirId` of the /// trait being referred to but just a unique `HirId` that serves as a key /// within the resolution map. -#[derive(Clone, Debug, HashStable_Generic)] +#[derive(Clone, Debug, Copy, HashStable_Generic)] pub struct TraitRef<'hir> { pub path: &'hir Path<'hir>, // Don't hash the `ref_id`. It is tracked via the thing it is used to access. @@ -2963,7 +2963,7 @@ impl TraitRef<'_> { } } -#[derive(Clone, Debug, HashStable_Generic)] +#[derive(Clone, Debug, Copy, HashStable_Generic)] pub struct PolyTraitRef<'hir> { /// The `'a` in `for<'a> Foo<&'a T>`. pub bound_generic_params: &'hir [GenericParam<'hir>], @@ -2974,7 +2974,7 @@ pub struct PolyTraitRef<'hir> { pub span: Span, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct FieldDef<'hir> { pub span: Span, pub vis_span: Span, @@ -2993,7 +2993,7 @@ impl FieldDef<'_> { } /// Fields and constructor IDs of enum variants and structs. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum VariantData<'hir> { /// A struct variant. /// @@ -3318,7 +3318,7 @@ pub enum ItemKind<'hir> { Impl(&'hir Impl<'hir>), } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Impl<'hir> { pub unsafety: Unsafety, pub polarity: ImplPolarity, @@ -3381,7 +3381,7 @@ impl ItemKind<'_> { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Encodable, Debug, HashStable_Generic)] +#[derive(Encodable, Debug, Clone, Copy, HashStable_Generic)] pub struct TraitItemRef { pub id: TraitItemId, pub ident: Ident, @@ -3395,7 +3395,7 @@ pub struct TraitItemRef { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ImplItemRef { pub id: ImplItemId, pub ident: Ident, @@ -3434,14 +3434,14 @@ impl ForeignItemId { /// type or method, and whether it is public). This allows other /// passes to find the impl they want without loading the ID (which /// means fewer edges in the incremental compilation graph). -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ForeignItemRef { pub id: ForeignItemId, pub ident: Ident, pub span: Span, } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct ForeignItem<'hir> { pub ident: Ident, pub kind: ForeignItemKind<'hir>, @@ -3463,7 +3463,7 @@ impl ForeignItem<'_> { } /// An item within an `extern` block. -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ForeignItemKind<'hir> { /// A foreign function. Fn(&'hir FnDecl<'hir>, &'hir [Ident], &'hir Generics<'hir>), @@ -3483,7 +3483,7 @@ pub struct Upvar { // The TraitCandidate's import_ids is empty if the trait is defined in the same module, and // has length > 0 if the trait is found through an chain of imports, starting with the // import/use statement in the scope where the trait is used. -#[derive(Encodable, Decodable, Debug, HashStable_Generic)] +#[derive(Encodable, Decodable, Debug, Clone, HashStable_Generic)] pub struct TraitCandidate { pub def_id: DefId, pub import_ids: SmallVec<[LocalDefId; 1]>, diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index b39a8c5598f91..10ef12ed314d3 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -331,7 +331,7 @@ impl<'tcx> IrMaps<'tcx> { pats.extend(inner_pat.iter()); } Struct(_, fields, _) => { - let (short, not_short): (Vec<_>, _) = + let (short, not_short): (Vec>, _) = fields.iter().partition(|f| f.is_shorthand); shorthand_field_ids.extend(short.iter().map(|f| f.pat.hir_id)); pats.extend(not_short.iter().map(|f| f.pat)); From 74e31ec64c4d896598b7e70c389143230ddb006d Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 25 Mar 2023 21:09:11 +0100 Subject: [PATCH 28/42] Also arena-allocate `ast::MacroDef` to make `Item: Copy` --- compiler/rustc_ast_lowering/src/item.rs | 3 ++- compiler/rustc_hir/src/arena.rs | 2 +- compiler/rustc_hir/src/hir.rs | 6 +++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 08e7a4dfe5d5d..9fac4ffaf1c2d 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -443,7 +443,8 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::MacroDef(MacroDef { body, macro_rules }) => { let body = P(self.lower_delim_args(body)); let macro_kind = self.resolver.decl_macro_kind(self.local_def_id(id)); - hir::ItemKind::Macro(ast::MacroDef { body, macro_rules: *macro_rules }, macro_kind) + let macro_def = self.arena.alloc(ast::MacroDef { body, macro_rules: *macro_rules }); + hir::ItemKind::Macro(macro_def, macro_kind) } ItemKind::MacCall(..) => { panic!("`TyMac` should have been expanded by now") diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs index efd8c440f5c6c..e213623e06d91 100644 --- a/compiler/rustc_hir/src/arena.rs +++ b/compiler/rustc_hir/src/arena.rs @@ -8,10 +8,10 @@ macro_rules! arena_types { [] hir_krate: rustc_hir::Crate<'tcx>, [] asm_template: rustc_ast::InlineAsmTemplatePiece, [] attribute: rustc_ast::Attribute, - [] item: rustc_hir::Item<'tcx>, [] owner_info: rustc_hir::OwnerInfo<'tcx>, [] use_path: rustc_hir::UsePath<'tcx>, [] lit: rustc_hir::Lit, + [] macro_def: rustc_ast::MacroDef, ]); ) } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 0ecb1bf4c5993..68db8f3e2728f 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3063,7 +3063,7 @@ impl ItemId { /// An item /// /// The name might be a dummy name in case of anonymous items -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Item<'hir> { pub ident: Ident, pub owner_id: OwnerId, @@ -3271,7 +3271,7 @@ impl FnHeader { } } -#[derive(Debug, HashStable_Generic)] +#[derive(Debug, Clone, Copy, HashStable_Generic)] pub enum ItemKind<'hir> { /// An `extern crate` item, with optional *original* crate name if the crate was renamed. /// @@ -3292,7 +3292,7 @@ pub enum ItemKind<'hir> { /// A function declaration. Fn(FnSig<'hir>, &'hir Generics<'hir>, BodyId), /// A MBE macro definition (`macro_rules!` or `macro`). - Macro(ast::MacroDef, MacroKind), + Macro(&'hir ast::MacroDef, MacroKind), /// A module. Mod(&'hir Mod<'hir>), /// An external module, e.g. `extern { .. }`. From da5d01d53dfd8e8546e89f555430d6e505490e0a Mon Sep 17 00:00:00 2001 From: clubby789 Date: Sat, 22 Apr 2023 22:03:33 +0100 Subject: [PATCH 29/42] Remove unused `synstructure` dep --- Cargo.lock | 1 - compiler/rustc_fluent_macro/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f2dab5e63503..10f19bfe28f3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3348,7 +3348,6 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.8", - "synstructure 0.13.0", "unic-langid", ] diff --git a/compiler/rustc_fluent_macro/Cargo.toml b/compiler/rustc_fluent_macro/Cargo.toml index a45559af71382..f5a6585b5c68a 100644 --- a/compiler/rustc_fluent_macro/Cargo.toml +++ b/compiler/rustc_fluent_macro/Cargo.toml @@ -10,7 +10,6 @@ proc-macro = true annotate-snippets = "0.9" fluent-bundle = "0.15.2" fluent-syntax = "0.11" -synstructure = "0.13.0" syn = { version = "2", features = ["full"] } proc-macro2 = "1" quote = "1" From 4ad04ad8419577f5dec37a80f3b46506edb84c96 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 25 Feb 2023 16:20:55 +0000 Subject: [PATCH 30/42] Set debug location to debug operand spill. --- compiler/rustc_codegen_ssa/src/mir/debuginfo.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index d049bafb821bd..b67230cf498c4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -494,6 +494,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let Some(dbg_loc) = self.dbg_loc(var.source_info) else { continue }; if let Ok(operand) = self.eval_mir_constant_to_operand(bx, &c) { + self.set_debug_loc(bx, var.source_info); let base = Self::spill_operand_to_stack( &operand, Some(var.name.to_string()), From 4e8b642646f4e36ad23313d5ecf3332adb3e6f21 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Fri, 28 Oct 2022 15:01:05 -0400 Subject: [PATCH 31/42] Turn on ConstDebugInfo pass. --- .../src/const_debuginfo.rs | 2 +- tests/codegen/debuginfo-constant-locals.rs | 28 +++++++++++++++ tests/incremental/hashes/enum_constructors.rs | 4 +-- tests/incremental/hashes/let_expressions.rs | 12 +++---- ...o_variable.main.PreCodegen.after.32bit.mir | 13 ++----- ...o_variable.main.PreCodegen.after.64bit.mir | 13 ++----- ....main.SimplifyLocals-final.after.32bit.mir | 13 ++----- ....main.SimplifyLocals-final.after.64bit.mir | 13 ++----- .../inline/issue_106141.outer.Inline.diff | 2 +- ...ue_59352.num_to_digit.PreCodegen.after.mir | 35 +++++++++---------- ..._intrinsics_e2e.f_u64.PreCodegen.after.mir | 9 ++--- 11 files changed, 69 insertions(+), 75 deletions(-) create mode 100644 tests/codegen/debuginfo-constant-locals.rs diff --git a/compiler/rustc_mir_transform/src/const_debuginfo.rs b/compiler/rustc_mir_transform/src/const_debuginfo.rs index 692b3182f7d23..b9bfbefcad9bb 100644 --- a/compiler/rustc_mir_transform/src/const_debuginfo.rs +++ b/compiler/rustc_mir_transform/src/const_debuginfo.rs @@ -16,7 +16,7 @@ pub struct ConstDebugInfo; impl<'tcx> MirPass<'tcx> for ConstDebugInfo { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { - sess.opts.unstable_opts.unsound_mir_opts && sess.mir_opt_level() > 0 + sess.mir_opt_level() > 0 } fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { diff --git a/tests/codegen/debuginfo-constant-locals.rs b/tests/codegen/debuginfo-constant-locals.rs new file mode 100644 index 0000000000000..95a1b8c9d214e --- /dev/null +++ b/tests/codegen/debuginfo-constant-locals.rs @@ -0,0 +1,28 @@ +// compile-flags: -g -O + +// Check that simple constant values are preserved in debuginfo across both MIR opts and LLVM opts + +#![crate_type = "lib"] + +#[no_mangle] +pub fn check_it() { + let a = 1; + let b = 42; + + foo(a + b); +} + +#[inline(never)] +fn foo(x: i32) { + std::process::exit(x); +} + +// CHECK-LABEL: @check_it +// CHECK: call void @llvm.dbg.value(metadata i32 1, metadata ![[a_metadata:[0-9]+]], metadata !DIExpression()) +// CHECK: call void @llvm.dbg.value(metadata i32 42, metadata ![[b_metadata:[0-9]+]], metadata !DIExpression()) + +// CHECK: ![[a_metadata]] = !DILocalVariable(name: "a" +// CHECK-SAME: line: 9 + +// CHECK: ![[b_metadata]] = !DILocalVariable(name: "b" +// CHECK-SAME: line: 10 diff --git a/tests/incremental/hashes/enum_constructors.rs b/tests/incremental/hashes/enum_constructors.rs index db367d07094d7..f685fe46d70d0 100644 --- a/tests/incremental/hashes/enum_constructors.rs +++ b/tests/incremental/hashes/enum_constructors.rs @@ -334,9 +334,9 @@ pub fn change_constructor_variant_c_like() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")] +#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn change_constructor_variant_c_like() { let _x = Clike::C; diff --git a/tests/incremental/hashes/let_expressions.rs b/tests/incremental/hashes/let_expressions.rs index 7aca4324233bf..a835b8eef8ce7 100644 --- a/tests/incremental/hashes/let_expressions.rs +++ b/tests/incremental/hashes/let_expressions.rs @@ -91,7 +91,7 @@ pub fn change_mutability_of_slot() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail6")] @@ -176,7 +176,7 @@ pub fn change_mutability_of_binding_in_pattern() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail6")] @@ -193,9 +193,9 @@ pub fn add_initializer() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck")] +#[rustc_clean(cfg="cfail5", except="hir_owner_nodes,typeck,optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn add_initializer() { let _x: i16 = 3i16; @@ -210,9 +210,9 @@ pub fn change_initializer() { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner_nodes")] +#[rustc_clean(cfg="cfail2", except="hir_owner_nodes, optimized_mir")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(cfg="cfail5", except="hir_owner_nodes")] +#[rustc_clean(cfg="cfail5", except="hir_owner_nodes, optimized_mir")] #[rustc_clean(cfg="cfail6")] pub fn change_initializer() { let _x = 5u16; diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir index 81cfd22db6c50..7886bf19e0c17 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.32bit.mir @@ -2,24 +2,17 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } } } bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir index 81cfd22db6c50..7886bf19e0c17 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.PreCodegen.after.64bit.mir @@ -2,24 +2,17 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } } } bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir index 002e914e8fa16..5bea94c7fe839 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.32bit.mir @@ -2,24 +2,17 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } } } bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir index 002e914e8fa16..5bea94c7fe839 100644 --- a/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir +++ b/tests/mir-opt/const_prop/optimizes_into_variable.main.SimplifyLocals-final.after.64bit.mir @@ -2,24 +2,17 @@ fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/optimizes_into_variable.rs:+0:11: +0:11 - let _1: i32; // in scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let mut _3: u32; // in scope 0 at $DIR/optimizes_into_variable.rs:+3:13: +3:36 scope 1 { - debug x => _1; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - let _2: i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug x => const 4_i32; // in scope 1 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 scope 2 { - debug y => _2; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 + debug y => const 3_i32; // in scope 2 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 scope 3 { - debug z => _3; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 + debug z => const 42_u32; // in scope 3 at $DIR/optimizes_into_variable.rs:+3:9: +3:10 } } } bb0: { - StorageLive(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+2:9: +2:10 - StorageDead(_2); // scope 1 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 - StorageDead(_1); // scope 0 at $DIR/optimizes_into_variable.rs:+4:1: +4:2 return; // scope 0 at $DIR/optimizes_into_variable.rs:+4:2: +4:2 } } diff --git a/tests/mir-opt/inline/issue_106141.outer.Inline.diff b/tests/mir-opt/inline/issue_106141.outer.Inline.diff index 18df6f9af5fae..3aebfb69e0ae1 100644 --- a/tests/mir-opt/inline/issue_106141.outer.Inline.diff +++ b/tests/mir-opt/inline/issue_106141.outer.Inline.diff @@ -8,7 +8,7 @@ + let mut _2: bool; // in scope 1 at $DIR/issue_106141.rs:14:8: 14:21 + let mut _3: &[bool; 1]; // in scope 1 at $DIR/issue_106141.rs:12:18: 12:25 + scope 2 { -+ debug buffer => _3; // in scope 2 at $DIR/issue_106141.rs:12:9: 12:15 ++ debug buffer => const _; // in scope 2 at $DIR/issue_106141.rs:12:9: 12:15 + scope 3 { + debug index => _0; // in scope 3 at $DIR/issue_106141.rs:13:9: 13:14 + } diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir index 42b605326908e..9f955b4717bc3 100644 --- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir +++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.mir @@ -4,31 +4,29 @@ fn num_to_digit(_1: char) -> u32 { debug num => _1; // in scope 0 at $DIR/issue_59352.rs:+0:21: +0:24 let mut _0: u32; // return place in scope 0 at $DIR/issue_59352.rs:+0:35: +0:38 let mut _2: std::option::Option; // in scope 0 at $DIR/issue_59352.rs:+2:26: +2:41 - let mut _3: u32; // in scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 scope 1 (inlined char::methods::::is_digit) { // at $DIR/issue_59352.rs:15:12: 15:23 debug self => _1; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - debug radix => _3; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - let mut _4: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - let _5: std::option::Option; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + debug radix => const 8_u32; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let mut _3: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + let _4: std::option::Option; // in scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL scope 2 (inlined Option::::is_some) { // at $SRC_DIR/core/src/char/methods.rs:LL:COL - debug self => _4; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _6: isize; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _3; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _5: isize; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL } } scope 3 (inlined #[track_caller] Option::::unwrap) { // at $DIR/issue_59352.rs:15:42: 15:50 debug self => _2; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _7: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL - let mut _8: !; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _6: isize; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _7: !; // in scope 3 at $SRC_DIR/core/src/option.rs:LL:COL scope 4 { debug val => _0; // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL } } bb0: { - StorageLive(_3); // scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 + StorageLive(_3); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageLive(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - StorageLive(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - _5 = char::methods::::to_digit(_1, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _4 = char::methods::::to_digit(_1, const 8_u32) -> bb5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/char/methods.rs:LL:COL // + literal: Const { ty: fn(char, u32) -> Option {char::methods::::to_digit}, val: Value() } @@ -43,8 +41,8 @@ fn num_to_digit(_1: char) -> u32 { } bb2: { - _7 = discriminant(_2); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL - switchInt(move _7) -> [0: bb6, 1: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + _6 = discriminant(_2); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _6) -> [0: bb6, 1: bb8, otherwise: bb7]; // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL } bb3: { @@ -57,16 +55,15 @@ fn num_to_digit(_1: char) -> u32 { } bb5: { - _4 = &_5; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - _6 = discriminant((*_4)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + _3 = &_4; // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL + _5 = discriminant((*_3)); // scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_3); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL StorageDead(_4); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - StorageDead(_5); // scope 1 at $SRC_DIR/core/src/char/methods.rs:LL:COL - StorageDead(_3); // scope 0 at $DIR/issue_59352.rs:+2:12: +2:23 - switchInt(move _6) -> [1: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 + switchInt(move _5) -> [1: bb1, otherwise: bb3]; // scope 0 at $DIR/issue_59352.rs:+2:8: +2:23 } bb6: { - _8 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value"); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL + _7 = core::panicking::panic(const "called `Option::unwrap()` on a `None` value"); // scope 3 at $SRC_DIR/core/src/option.rs:LL:COL // mir::Constant // + span: $SRC_DIR/core/src/option.rs:LL:COL // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value() } diff --git a/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir b/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir index 4f5df13318129..f1f7857a1bd0a 100644 --- a/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir +++ b/tests/mir-opt/lower_intrinsics_e2e.f_u64.PreCodegen.after.mir @@ -2,24 +2,21 @@ fn f_u64() -> () { let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:16: +0:16 - let mut _1: u64; // in scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21 scope 1 (inlined f_dispatch::) { // at $DIR/lower_intrinsics_e2e.rs:15:5: 15:21 - debug t => _1; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23 - let _2: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 + debug t => const 0_u64; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23 + let _1: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 scope 2 (inlined std::mem::size_of::) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32 } } bb0: { - StorageLive(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21 - _2 = f_non_zst::(const 0_u64) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 + _1 = f_non_zst::(const 0_u64) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21 // mir::Constant // + span: $DIR/lower_intrinsics_e2e.rs:23:9: 23:18 // + literal: Const { ty: fn(u64) {f_non_zst::}, val: Value() } } bb1: { - StorageDead(_1); // scope 0 at $DIR/lower_intrinsics_e2e.rs:+1:5: +1:21 return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2 } } From 95e8b6a196fbf4bbd4038e7c0b51363ed0bc7cf6 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 21 Apr 2023 23:04:32 +0000 Subject: [PATCH 32/42] Group entire build steps in the gha logs --- src/bootstrap/bootstrap.py | 10 +++- src/bootstrap/check.rs | 66 +++---------------------- src/bootstrap/compile.rs | 59 ++++++----------------- src/bootstrap/install.rs | 4 +- src/bootstrap/lib.rs | 82 +++++++++++++++++++++++++++++++- src/bootstrap/llvm.rs | 12 ++--- src/bootstrap/test.rs | 49 +++++++++---------- src/bootstrap/tool.rs | 61 +++++++++--------------- src/tools/build_helper/src/ci.rs | 24 ++++++++++ 9 files changed, 190 insertions(+), 177 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index e6788ee6feeca..680a8da6adf20 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -722,11 +722,14 @@ def bootstrap_binary(self): def build_bootstrap(self, color, verbose_count): """Build bootstrap""" - print("Building bootstrap") + env = os.environ.copy() + if "GITHUB_ACTIONS" in env: + print("::group::Building bootstrap") + else: + print("Building bootstrap") build_dir = os.path.join(self.build_dir, "bootstrap") if self.clean and os.path.exists(build_dir): shutil.rmtree(build_dir) - env = os.environ.copy() # `CARGO_BUILD_TARGET` breaks bootstrap build. # See also: . if "CARGO_BUILD_TARGET" in env: @@ -798,6 +801,9 @@ def build_bootstrap(self, color, verbose_count): # Run this from the source directory so cargo finds .cargo/config run(args, env=env, verbose=self.verbose, cwd=self.rust_root) + if "GITHUB_ACTIONS" in env: + print("::endgroup::") + def build_triple(self): """Build triple as in LLVM diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 44efc502e39d4..60de46ce64c15 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -105,15 +105,7 @@ impl Step for Std { cargo.arg("--lib"); } - let msg = if compiler.host == target { - format!("Checking stage{} library artifacts ({target})", builder.top_stage) - } else { - format!( - "Checking stage{} library artifacts ({} -> {})", - builder.top_stage, &compiler.host, target - ) - }; - builder.info(&msg); + let _guard = builder.msg_check("library artifacts", target); run_cargo( builder, cargo, @@ -167,18 +159,7 @@ impl Step for Std { cargo.arg("-p").arg(krate.name); } - let msg = if compiler.host == target { - format!( - "Checking stage{} library test/bench/example targets ({target})", - builder.top_stage - ) - } else { - format!( - "Checking stage{} library test/bench/example targets ({} -> {})", - builder.top_stage, &compiler.host, target - ) - }; - builder.info(&msg); + let _guard = builder.msg_check("library test/bench/example targets", target); run_cargo( builder, cargo, @@ -252,15 +233,7 @@ impl Step for Rustc { cargo.arg("-p").arg(krate.name); } - let msg = if compiler.host == target { - format!("Checking stage{} compiler artifacts ({target})", builder.top_stage) - } else { - format!( - "Checking stage{} compiler artifacts ({} -> {})", - builder.top_stage, &compiler.host, target - ) - }; - builder.info(&msg); + let _guard = builder.msg_check("compiler artifacts", target); run_cargo( builder, cargo, @@ -317,15 +290,7 @@ impl Step for CodegenBackend { .arg(builder.src.join(format!("compiler/rustc_codegen_{}/Cargo.toml", backend))); rustc_cargo_env(builder, &mut cargo, target, compiler.stage); - let msg = if compiler.host == target { - format!("Checking stage{} {} artifacts ({target})", builder.top_stage, backend) - } else { - format!( - "Checking stage{} {} library ({} -> {})", - builder.top_stage, backend, &compiler.host.triple, target.triple - ) - }; - builder.info(&msg); + let _guard = builder.msg_check(&backend, target); run_cargo( builder, @@ -385,15 +350,7 @@ impl Step for RustAnalyzer { cargo.arg("--benches"); } - let msg = if compiler.host == target { - format!("Checking stage{} {} artifacts ({target})", compiler.stage, "rust-analyzer") - } else { - format!( - "Checking stage{} {} artifacts ({} -> {})", - compiler.stage, "rust-analyzer", &compiler.host.triple, target.triple - ) - }; - builder.info(&msg); + let _guard = builder.msg_check("rust-analyzer artifacts", target); run_cargo( builder, cargo, @@ -460,18 +417,7 @@ macro_rules! tool_check_step { // NOTE: this doesn't enable lints for any other tools unless they explicitly add `#![warn(rustc::internal)]` // See https://github.com/rust-lang/rust/pull/80573#issuecomment-754010776 cargo.rustflag("-Zunstable-options"); - let msg = if compiler.host == target { - format!("Checking stage{} {} artifacts ({target})", builder.top_stage, stringify!($name).to_lowercase()) - } else { - format!( - "Checking stage{} {} artifacts ({} -> {})", - builder.top_stage, - stringify!($name).to_lowercase(), - &compiler.host.triple, - target.triple - ) - }; - builder.info(&msg); + let _guard = builder.msg_check(&concat!(stringify!($name), " artifacts").to_lowercase(), target); run_cargo( builder, cargo, diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 8af5927e27fbf..51c1cab7001c2 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -143,23 +143,13 @@ impl Step for Std { cargo.arg("-p").arg(krate); } - let msg = if compiler.host == target { - format!( - "Building{} stage{} library artifacts ({}) ", - crate_description(&self.crates), - compiler.stage, - compiler.host - ) - } else { - format!( - "Building{} stage{} library artifacts ({} -> {})", - crate_description(&self.crates), - compiler.stage, - compiler.host, - target, - ) - }; - builder.info(&msg); + let _guard = builder.msg( + Kind::Build, + compiler.stage, + format_args!("library artifacts{}", crate_description(&self.crates)), + compiler.host, + target, + ); run_cargo( builder, cargo, @@ -790,24 +780,13 @@ impl Step for Rustc { cargo.arg("-p").arg(krate); } - let msg = if compiler.host == target { - format!( - "Building{} compiler artifacts (stage{} -> stage{})", - crate_description(&self.crates), - compiler.stage, - compiler.stage + 1 - ) - } else { - format!( - "Building{} compiler artifacts (stage{}:{} -> stage{}:{})", - crate_description(&self.crates), - compiler.stage, - compiler.host, - compiler.stage + 1, - target, - ) - }; - builder.info(&msg); + let _guard = builder.msg_sysroot_tool( + Kind::Build, + compiler.stage, + format_args!("compiler artifacts{}", crate_description(&self.crates)), + compiler.host, + target, + ); run_cargo( builder, cargo, @@ -1114,15 +1093,7 @@ impl Step for CodegenBackend { let tmp_stamp = out_dir.join(".tmp.stamp"); - let msg = if compiler.host == target { - format!("Building stage{} codegen backend {}", compiler.stage, backend) - } else { - format!( - "Building stage{} codegen backend {} ({} -> {})", - compiler.stage, backend, compiler.host, target - ) - }; - builder.info(&msg); + let _guard = builder.msg_build(compiler, format_args!("codegen backend {backend}"), target); let files = run_cargo(builder, cargo, vec![], &tmp_stamp, vec![], false, false); if builder.config.dry_run() { return; diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 42d895a3413fb..b62aa9992469b 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -12,7 +12,7 @@ use crate::util::t; use crate::dist; use crate::tarball::GeneratedTarball; -use crate::Compiler; +use crate::{Compiler, Kind}; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::config::{Config, TargetSelection}; @@ -52,7 +52,7 @@ fn install_sh( host: Option, tarball: &GeneratedTarball, ) { - builder.info(&format!("Install {} stage{} ({:?})", package, stage, host)); + let _guard = builder.msg(Kind::Install, stage, package, host, host); let prefix = default_path(&builder.config.prefix, "/usr/local"); let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc")); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index bfdb029951f29..238d167c4c276 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -19,13 +19,14 @@ use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet}; use std::env; +use std::fmt::Display; use std::fs::{self, File}; use std::io; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::str; -use build_helper::ci::CiEnv; +use build_helper::ci::{gha, CiEnv}; use channel::GitInfo; use config::{DryRun, Target}; use filetime::FileTime; @@ -993,6 +994,85 @@ impl Build { } } + fn msg_check( + &self, + what: impl Display, + target: impl Into>, + ) -> Option { + self.msg(Kind::Check, self.config.stage, what, self.config.build, target) + } + + fn msg_build( + &self, + compiler: Compiler, + what: impl Display, + target: impl Into>, + ) -> Option { + self.msg(Kind::Build, compiler.stage, what, compiler.host, target) + } + + /// Return a `Group` guard for a [`Step`] that is built for each `--stage`. + fn msg( + &self, + action: impl Into, + stage: u32, + what: impl Display, + host: impl Into>, + target: impl Into>, + ) -> Option { + let action = action.into(); + let msg = |fmt| format!("{action:?}ing stage{stage} {what}{fmt}"); + let msg = if let Some(target) = target.into() { + let host = host.into().unwrap(); + if host == target { + msg(format_args!(" ({target})")) + } else { + msg(format_args!(" ({host} -> {target})")) + } + } else { + msg(format_args!("")) + }; + self.group(&msg) + } + + /// Return a `Group` guard for a [`Step`] that is only built once and isn't affected by `--stage`. + fn msg_unstaged( + &self, + action: impl Into, + what: impl Display, + target: TargetSelection, + ) -> Option { + let action = action.into(); + let msg = format!("{action:?}ing {what} for {target}"); + self.group(&msg) + } + + fn msg_sysroot_tool( + &self, + action: impl Into, + stage: u32, + what: impl Display, + host: TargetSelection, + target: TargetSelection, + ) -> Option { + let action = action.into(); + let msg = |fmt| format!("{action:?}ing {what} {fmt}"); + let msg = if host == target { + msg(format_args!("(stage{stage} -> stage{}, {target})", stage + 1)) + } else { + msg(format_args!("(stage{stage}:{host} -> stage{}:{target})", stage + 1)) + }; + self.group(&msg) + } + + fn group(&self, msg: &str) -> Option { + self.info(&msg); + match self.config.dry_run { + DryRun::SelfCheck => None, + DryRun::Disabled | DryRun::UserSelected => Some(gha::group(&msg)), + } + } + /// Returns the number of parallel jobs that have been configured for this /// build. fn jobs(&self) -> u32 { diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index cfc7418631368..67cb88373910c 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -21,7 +21,7 @@ use crate::channel; use crate::config::{Config, TargetSelection}; use crate::util::get_clang_cl_resource_dir; use crate::util::{self, exe, output, t, up_to_date}; -use crate::{CLang, GitRepo}; +use crate::{CLang, GitRepo, Kind}; use build_helper::ci::CiEnv; @@ -271,7 +271,7 @@ impl Step for Llvm { panic!("shared linking to LLVM is not currently supported on {}", target.triple); } - builder.info(&format!("Building LLVM for {}", target)); + let _guard = builder.msg_unstaged(Kind::Build, "LLVM", target); t!(stamp.remove()); let _time = util::timeit(&builder); t!(fs::create_dir_all(&out_dir)); @@ -813,7 +813,7 @@ impl Step for Lld { return out_dir; } - builder.info(&format!("Building LLD for {}", target)); + let _guard = builder.msg_unstaged(Kind::Build, "LLD", target); let _time = util::timeit(&builder); t!(fs::create_dir_all(&out_dir)); @@ -911,7 +911,7 @@ impl Step for Sanitizers { return runtimes; } - builder.info(&format!("Building sanitizers for {}", self.target)); + let _guard = builder.msg_unstaged(Kind::Build, "sanitizers", self.target); t!(stamp.remove()); let _time = util::timeit(&builder); @@ -1103,7 +1103,7 @@ impl Step for CrtBeginEnd { return out_dir; } - builder.info("Building crtbegin.o and crtend.o"); + let _guard = builder.msg_unstaged(Kind::Build, "crtbegin.o and crtend.o", self.target); t!(fs::create_dir_all(&out_dir)); let mut cfg = cc::Build::new(); @@ -1168,7 +1168,7 @@ impl Step for Libunwind { return out_dir; } - builder.info(&format!("Building libunwind.a for {}", self.target.triple)); + let _guard = builder.msg_unstaged(Kind::Build, "libunwind.a", self.target); t!(fs::create_dir_all(&out_dir)); let mut cc_cfg = cc::Build::new(); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index ccf83974b8c2f..601351ea8e3c0 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -5,7 +5,6 @@ use std::env; use std::ffi::OsString; -use std::fmt; use std::fs; use std::iter; use std::path::{Path, PathBuf}; @@ -57,12 +56,12 @@ impl TestKind { } } -impl fmt::Display for TestKind { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(match *self { - TestKind::Test => "Testing", - TestKind::Bench => "Benchmarking", - }) +impl Into for TestKind { + fn into(self) -> Kind { + match self { + TestKind::Test => Kind::Test, + TestKind::Bench => Kind::Bench, + } } } @@ -1905,7 +1904,13 @@ impl BookTest { rustbook_cmd.env("RUSTC_BOOTSTRAP", "1"); rustbook_cmd.env("PATH", new_path).arg("test").arg(path); builder.add_rust_test_threads(&mut rustbook_cmd); - builder.info(&format!("Testing rustbook {}", self.path.display())); + let _guard = builder.msg( + Kind::Test, + compiler.stage, + format_args!("rustbook {}", self.path.display()), + compiler.host, + compiler.host, + ); let _time = util::timeit(&builder); let toolstate = if try_run(builder, &mut rustbook_cmd) { ToolState::TestPass @@ -2033,7 +2038,8 @@ impl Step for ErrorIndex { let mut tool = tool::ErrorIndex::command(builder); tool.arg("markdown").arg(&output); - builder.info(&format!("Testing error-index stage{}", compiler.stage)); + let _guard = + builder.msg(Kind::Test, compiler.stage, "error-index", compiler.host, compiler.host); let _time = util::timeit(&builder); builder.run_quiet(&mut tool); // The tests themselves need to link to std, so make sure it is @@ -2263,14 +2269,13 @@ impl Step for Crate { ); } - builder.info(&format!( - "{}{} stage{} ({} -> {})", + let _guard = builder.msg( test_kind, - crate_description(&self.crates), compiler.stage, - &compiler.host, - target - )); + crate_description(&self.crates), + compiler.host, + target, + ); let _time = util::timeit(&builder); crate::render_tests::try_run_tests(builder, &mut cargo.into()); } @@ -2386,10 +2391,8 @@ impl Step for CrateRustdoc { cargo.arg("--quiet"); } - builder.info(&format!( - "{} rustdoc stage{} ({} -> {})", - test_kind, compiler.stage, &compiler.host, target - )); + let _guard = builder.msg(test_kind, compiler.stage, "rustdoc", compiler.host, target); + let _time = util::timeit(&builder); add_flags_and_try_run_tests(builder, &mut cargo.into()); @@ -2453,10 +2456,8 @@ impl Step for CrateRustdocJsonTypes { cargo.arg("'-Ctarget-feature=-crt-static'"); } - builder.info(&format!( - "{} rustdoc-json-types stage{} ({} -> {})", - test_kind, compiler.stage, &compiler.host, target - )); + let _guard = + builder.msg(test_kind, compiler.stage, "rustdoc-json-types", compiler.host, target); let _time = util::timeit(&builder); add_flags_and_try_run_tests(builder, &mut cargo.into()); @@ -2845,7 +2846,7 @@ impl Step for TestHelpers { return; } - builder.info("Building test helpers"); + let _guard = builder.msg_unstaged(Kind::Build, "test helpers", target); t!(fs::create_dir_all(&dst)); let mut cfg = cc::Build::new(); // FIXME: Workaround for https://github.com/emscripten-core/emscripten/issues/9013 diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 79eec6f848c27..5faef76fafe23 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -11,6 +11,7 @@ use crate::toolstate::ToolState; use crate::util::{add_dylib_path, exe, t}; use crate::Compiler; use crate::Mode; +use crate::{gha, Kind}; #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum SourceType { @@ -32,41 +33,27 @@ struct ToolBuild { allow_features: &'static str, } -fn tooling_output( - mode: Mode, - tool: &str, - build_stage: u32, - host: &TargetSelection, - target: &TargetSelection, -) -> String { - match mode { - // depends on compiler stage, different to host compiler - Mode::ToolRustc => { - if host == target { - format!("Building tool {} (stage{} -> stage{})", tool, build_stage, build_stage + 1) - } else { - format!( - "Building tool {} (stage{}:{} -> stage{}:{})", - tool, - build_stage, - host, - build_stage + 1, - target - ) - } - } - // doesn't depend on compiler, same as host compiler - Mode::ToolStd => { - if host == target { - format!("Building tool {} (stage{})", tool, build_stage) - } else { - format!( - "Building tool {} (stage{}:{} -> stage{}:{})", - tool, build_stage, host, build_stage, target - ) - } +impl Builder<'_> { + fn msg_tool( + &self, + mode: Mode, + tool: &str, + build_stage: u32, + host: &TargetSelection, + target: &TargetSelection, + ) -> Option { + match mode { + // depends on compiler stage, different to host compiler + Mode::ToolRustc => self.msg_sysroot_tool( + Kind::Build, + build_stage, + format_args!("tool {tool}"), + *host, + *target, + ), + // doesn't depend on compiler, same as host compiler + _ => self.msg(Kind::Build, build_stage, format_args!("tool {tool}"), *host, *target), } - _ => format!("Building tool {} (stage{})", tool, build_stage), } } @@ -111,14 +98,13 @@ impl Step for ToolBuild { if !self.allow_features.is_empty() { cargo.allow_features(self.allow_features); } - let msg = tooling_output( + let _guard = builder.msg_tool( self.mode, self.tool, self.compiler.stage, &self.compiler.host, &self.target, ); - builder.info(&msg); let mut cargo = Command::from(cargo); let is_expected = builder.try_run(&mut cargo); @@ -492,14 +478,13 @@ impl Step for Rustdoc { cargo.rustflag("--cfg=parallel_compiler"); } - let msg = tooling_output( + let _guard = builder.msg_tool( Mode::ToolRustc, "rustdoc", build_compiler.stage, &self.compiler.host, &target, ); - builder.info(&msg); builder.run(&mut cargo.into()); // Cargo adds a number of paths to the dylib search path on windows, which results in diff --git a/src/tools/build_helper/src/ci.rs b/src/tools/build_helper/src/ci.rs index 9f113c72b9338..d2e9c324af8c6 100644 --- a/src/tools/build_helper/src/ci.rs +++ b/src/tools/build_helper/src/ci.rs @@ -38,3 +38,27 @@ impl CiEnv { } } } + +pub mod gha { + /// All github actions log messages from this call to the Drop of the return value + /// will be grouped and hidden by default in logs. Note that nesting these does + /// not really work. + pub fn group(name: impl std::fmt::Display) -> Group { + if std::env::var_os("GITHUB_ACTIONS").is_some() { + eprintln!("::group::{name}"); + } + Group(()) + } + + /// A guard that closes the current github actions log group on drop. + #[must_use] + pub struct Group(()); + + impl Drop for Group { + fn drop(&mut self) { + if std::env::var_os("GITHUB_ACTIONS").is_some() { + eprintln!("::endgroup::"); + } + } + } +} From b8c67d82d3b4f152a38711de3466875b270e33de Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 23 Apr 2023 00:34:46 +0200 Subject: [PATCH 33/42] Fortify test. --- tests/debuginfo/auxiliary/macro-stepping.rs | 2 +- tests/debuginfo/macro-stepping.rs | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/tests/debuginfo/auxiliary/macro-stepping.rs b/tests/debuginfo/auxiliary/macro-stepping.rs index 4447dd22ddbd7..ae50e11440bc4 100644 --- a/tests/debuginfo/auxiliary/macro-stepping.rs +++ b/tests/debuginfo/auxiliary/macro-stepping.rs @@ -5,6 +5,6 @@ #[macro_export] macro_rules! new_scope { () => { - let x = 1; + let x = 1; opaque(x); } } diff --git a/tests/debuginfo/macro-stepping.rs b/tests/debuginfo/macro-stepping.rs index e4b2b7b79bcb9..a7287cffd029b 100644 --- a/tests/debuginfo/macro-stepping.rs +++ b/tests/debuginfo/macro-stepping.rs @@ -79,22 +79,28 @@ extern crate macro_stepping; // exports new_scope!() // lldb-check:[...]#inc-loc2[...] // lldb-command:next // lldb-command:frame select +// lldb-check:[...]#inc-loc1[...] +// lldb-command:next +// lldb-command:frame select +// lldb-check:[...]#inc-loc2[...] +// lldb-command:next +// lldb-command:frame select // lldb-check:[...]#inc-loc3[...] macro_rules! foo { () => { - let a = 1; - let b = 2; - let c = 3; - } + let a = 1; opaque(a); + let b = 2; opaque(b); + let c = 3; opaque(c); + }; } macro_rules! foo2 { () => { foo!(); - let x = 1; + let x = 1; opaque(x); foo!(); - } + }; } fn main() { @@ -118,4 +124,6 @@ fn main() { fn zzz() {()} +fn opaque(_: u32) {} + include!("macro-stepping.inc"); From 173845ce0e4d2ae1c9f809caae352b6da5f339ce Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 22 Apr 2023 19:15:39 -0400 Subject: [PATCH 34/42] Remove the size of locals heuristic in MIR inlining --- compiler/rustc_mir_transform/src/inline.rs | 34 ----- ...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 ++++++++++++++-- 5 files changed, 450 insertions(+), 82 deletions(-) diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 1525933aee3f4..552bf43329c2d 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -26,8 +26,6 @@ const CALL_PENALTY: usize = 25; const LANDINGPAD_PENALTY: usize = 50; const RESUME_PENALTY: usize = 45; -const UNKNOWN_SIZE_COST: usize = 10; - const TOP_DOWN_DEPTH_LIMIT: usize = 5; pub struct Inline; @@ -464,12 +462,6 @@ impl<'tcx> Inliner<'tcx> { } } - // Count up the cost of local variables and temps, if we know the size - // use that, otherwise we use a moderately-large dummy cost. - for v in callee_body.vars_and_temps_iter() { - checker.visit_local_decl(v, &callee_body.local_decls[v]); - } - // Abort if type validation found anything fishy. checker.validation?; @@ -764,14 +756,6 @@ impl<'tcx> Inliner<'tcx> { } } -fn type_size_of<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ty: Ty<'tcx>, -) -> Option { - tcx.layout_of(param_env.and(ty)).ok().map(|layout| layout.size.bytes()) -} - /// Verify that the callee body is compatible with the caller. /// /// This visitor mostly computes the inlining cost, @@ -845,24 +829,6 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { self.super_terminator(terminator, location); } - /// Count up the cost of local variables and temps, if we know the size - /// use that, otherwise we use a moderately-large dummy cost. - fn visit_local_decl(&mut self, local: Local, local_decl: &LocalDecl<'tcx>) { - let tcx = self.tcx; - let ptr_size = tcx.data_layout.pointer_size.bytes(); - - let ty = self.instance.subst_mir(tcx, &local_decl.ty); - // Cost of the var is the size in machine-words, if we know - // it. - if let Some(size) = type_size_of(tcx, self.param_env, ty) { - self.cost += ((size + ptr_size - 1) / ptr_size) as usize; - } else { - self.cost += UNKNOWN_SIZE_COST; - } - - self.super_local_decl(local, local_decl) - } - /// This method duplicates code from MIR validation in an attempt to detect type mismatches due /// to normalization failure. fn visit_projection_elem( 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 473e02f1cb1c8..d76cd0e2bb818 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 9b7b11ef659aa..3c175ed1504f6 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 9638ddda46b71..f3d3e6090bb3c 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 afe6d08741b47..724b3c56723a3 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 - } } From 1de2257c3f6579028f2b8d97908ba12896abca61 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 22 Apr 2023 17:14:19 -0700 Subject: [PATCH 35/42] Add `intrinsics::transmute_unchecked` This takes a whole 3 lines in `compiler/` since it lowers to `CastKind::Transmute` in MIR *exactly* the same as the existing `intrinsics::transmute` does, it just doesn't have the fancy checking in `hir_typeck`. Added to enable experimenting with the request in and because the portable-simd folks might be interested for dependently-sized array-vector conversions. It also simplifies a couple places in `core`. --- .../rustc_hir_analysis/src/check/intrinsic.rs | 2 +- .../src/lower_intrinsics.rs | 2 +- compiler/rustc_span/src/symbol.rs | 1 + library/core/src/array/iter.rs | 18 +++----- library/core/src/intrinsics.rs | 22 ++++++++++ library/core/src/mem/maybe_uninit.rs | 10 ++--- tests/codegen/intrinsics/transmute.rs | 42 ++++--------------- 7 files changed, 43 insertions(+), 54 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 854974d1605a5..0fcbaa2efabb8 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -198,7 +198,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { | sym::assert_zero_valid | sym::assert_mem_uninitialized_valid => (1, Vec::new(), tcx.mk_unit()), sym::forget => (1, vec![param(0)], tcx.mk_unit()), - sym::transmute => (2, vec![param(0)], param(1)), + sym::transmute | sym::transmute_unchecked => (2, vec![param(0)], param(1)), sym::prefetch_read_data | sym::prefetch_write_data | sym::prefetch_read_instruction diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index c136642dff277..c7d3f6c9f044c 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -221,7 +221,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { terminator.kind = TerminatorKind::Goto { target }; } } - sym::transmute => { + sym::transmute | sym::transmute_unchecked => { let dst_ty = destination.ty(local_decls, tcx).ty; let Ok([arg]) = <[_; 1]>::try_from(std::mem::take(args)) else { span_bug!( diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9891915d076dd..70b9088de5064 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1505,6 +1505,7 @@ symbols! { transmute_generic_consts, transmute_opts, transmute_trait, + transmute_unchecked, transparent, transparent_enums, transparent_unions, diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index 73e2c2cfbbef6..587877dff552f 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -3,8 +3,9 @@ use crate::num::NonZeroUsize; use crate::{ fmt, + intrinsics::transmute_unchecked, iter::{self, ExactSizeIterator, FusedIterator, TrustedLen}, - mem::{self, MaybeUninit}, + mem::MaybeUninit, ops::{IndexRange, Range}, ptr, }; @@ -63,18 +64,11 @@ impl IntoIterator for [T; N] { // an array of `T`. // // With that, this initialization satisfies the invariants. - - // FIXME(LukasKalbertodt): actually use `mem::transmute` here, once it - // works with const generics: - // `mem::transmute::<[T; N], [MaybeUninit; N]>(array)` // - // Until then, we can use `mem::transmute_copy` to create a bitwise copy - // as a different type, then forget `array` so that it is not dropped. - unsafe { - let iter = IntoIter { data: mem::transmute_copy(&self), alive: IndexRange::zero_to(N) }; - mem::forget(self); - iter - } + // FIXME: If normal `transmute` ever gets smart enough to allow this + // directly, use it instead of `transmute_unchecked`. + let data: [MaybeUninit; N] = unsafe { transmute_unchecked(self) }; + IntoIter { data, alive: IndexRange::zero_to(N) } } } diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index ba03da411e34e..39edfd8265b41 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -1376,6 +1376,20 @@ extern "rust-intrinsic" { #[rustc_nounwind] pub fn transmute(src: Src) -> Dst; + /// Like [`transmute`], but even less checked at compile-time: rather than + /// giving an error for `size_of::() != size_of::()`, it's + /// **Undefined Behaviour** at runtime. + /// + /// Prefer normal `transmute` where possible, for the extra checking, since + /// both do exactly the same thing at runtime, if they both compile. + /// + /// This is not expected to ever be exposed directly to users, rather it + /// may eventually be exposed through some more-constrained API. + #[cfg(not(bootstrap))] + #[rustc_const_stable(feature = "const_transmute", since = "1.56.0")] + #[rustc_nounwind] + pub fn transmute_unchecked(src: Src) -> Dst; + /// Returns `true` if the actual type given as `T` requires drop /// glue; returns `false` if the actual type provided for `T` /// implements `Copy`. @@ -2798,3 +2812,11 @@ pub const unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { write_bytes(dst, val, count) } } + +/// Polyfill for bootstrap +#[cfg(bootstrap)] +pub const unsafe fn transmute_unchecked(src: Src) -> Dst { + use crate::mem::*; + // SAFETY: It's a transmute -- the caller promised it's fine. + unsafe { transmute_copy(&ManuallyDrop::new(src)) } +} diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 9c6d48675a6b1..2588b7d2befac 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -945,14 +945,10 @@ impl MaybeUninit { // * `MaybeUninit` and T are guaranteed to have the same layout // * `MaybeUninit` does not drop, so there are no double-frees // And thus the conversion is safe - let ret = unsafe { + unsafe { intrinsics::assert_inhabited::<[T; N]>(); - (&array as *const _ as *const [T; N]).read() - }; - - // FIXME: required to avoid `~const Destruct` bound - super::forget(array); - ret + intrinsics::transmute_unchecked(array) + } } /// Assuming all the elements are initialized, get a slice to them. diff --git a/tests/codegen/intrinsics/transmute.rs b/tests/codegen/intrinsics/transmute.rs index 51c000b82ea8a..664e697c2a5d2 100644 --- a/tests/codegen/intrinsics/transmute.rs +++ b/tests/codegen/intrinsics/transmute.rs @@ -8,10 +8,10 @@ #![feature(inline_const)] #![allow(unreachable_code)] -use std::mem::{transmute, MaybeUninit}; +use std::mem::MaybeUninit; +use std::intrinsics::{transmute, transmute_unchecked}; -// Some of the cases here are statically rejected by `mem::transmute`, so -// we need to generate custom MIR for those cases to get to codegen. +// Some of these need custom MIR to not get removed by MIR optimizations. use std::intrinsics::mir::*; enum Never {} @@ -30,59 +30,35 @@ pub struct Aggregate8(u8); // CHECK-LABEL: @check_bigger_size( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] pub unsafe fn check_bigger_size(x: u16) -> u32 { // CHECK: call void @llvm.trap - mir!{ - { - RET = CastTransmute(x); - Return() - } - } + transmute_unchecked(x) } // CHECK-LABEL: @check_smaller_size( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] pub unsafe fn check_smaller_size(x: u32) -> u16 { // CHECK: call void @llvm.trap - mir!{ - { - RET = CastTransmute(x); - Return() - } - } + transmute_unchecked(x) } // CHECK-LABEL: @check_smaller_array( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] pub unsafe fn check_smaller_array(x: [u32; 7]) -> [u32; 3] { // CHECK: call void @llvm.trap - mir!{ - { - RET = CastTransmute(x); - Return() - } - } + transmute_unchecked(x) } // CHECK-LABEL: @check_bigger_array( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] pub unsafe fn check_bigger_array(x: [u32; 3]) -> [u32; 7] { // CHECK: call void @llvm.trap - mir!{ - { - RET = CastTransmute(x); - Return() - } - } + transmute_unchecked(x) } // CHECK-LABEL: @check_to_uninhabited( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] +#[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_to_uninhabited(x: u16) -> BigNever { // CHECK: call void @llvm.trap mir!{ @@ -95,7 +71,7 @@ pub unsafe fn check_to_uninhabited(x: u16) -> BigNever { // CHECK-LABEL: @check_from_uninhabited( #[no_mangle] -#[custom_mir(dialect = "runtime", phase = "initial")] +#[custom_mir(dialect = "runtime", phase = "optimized")] pub unsafe fn check_from_uninhabited(x: BigNever) -> u16 { // CHECK: ret i16 poison mir!{ From 7efcf67a3b96c8ff27bd80ce9df9fa84e93eb3a3 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 14 Apr 2023 18:59:17 +0000 Subject: [PATCH 36/42] Also reveal constants before MIR opts. --- compiler/rustc_mir_transform/src/reveal_all.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs index abe6cb285f505..23442f8b97b7e 100644 --- a/compiler/rustc_mir_transform/src/reveal_all.rs +++ b/compiler/rustc_mir_transform/src/reveal_all.rs @@ -34,11 +34,23 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> { self.tcx } + #[inline] + fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _: Location) { + // We have to use `try_normalize_erasing_regions` here, since it's + // possible that we visit impossible-to-satisfy where clauses here, + // see #91745 + if let Ok(c) = self.tcx.try_normalize_erasing_regions(self.param_env, constant.literal) { + constant.literal = c; + } + } + #[inline] fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) { // We have to use `try_normalize_erasing_regions` here, since it's // possible that we visit impossible-to-satisfy where clauses here, // see #91745 - *ty = self.tcx.try_normalize_erasing_regions(self.param_env, *ty).unwrap_or(*ty); + if let Ok(t) = self.tcx.try_normalize_erasing_regions(self.param_env, *ty) { + *ty = t; + } } } From 4fe51365d7a58b34ad0fb0e9b0d2523920743d1d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 15 Apr 2023 08:34:05 +0000 Subject: [PATCH 37/42] Use param_env_reveal_all_normalized in MIR opts. --- compiler/rustc_mir_transform/src/dataflow_const_prop.rs | 2 +- compiler/rustc_mir_transform/src/large_enums.rs | 2 +- compiler/rustc_mir_transform/src/match_branches.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 4 ++-- compiler/rustc_mir_transform/src/simplify_branches.rs | 2 +- .../rustc_mir_transform/src/simplify_comparison_integral.rs | 2 +- .../rustc_mir_transform/src/uninhabited_enum_branching.rs | 4 +++- 7 files changed, 10 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index a56c5cc5c12f9..c0861f99620d1 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -323,7 +323,7 @@ impl<'tcx> std::fmt::Debug for ScalarTy<'tcx> { impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> { pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, map: Map) -> Self { - let param_env = tcx.param_env(body.source.def_id()); + let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); Self { map, tcx, diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 9447a2ff04095..430a6f6cef5be 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -120,7 +120,7 @@ impl EnumSizeOpt { fn optim<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let mut alloc_cache = FxHashMap::default(); let body_did = body.source.def_id(); - let param_env = tcx.param_env(body_did); + let param_env = tcx.param_env_reveal_all_normalized(body_did); let blocks = body.basic_blocks.as_mut(); let local_decls = &mut body.local_decls; diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs index ce05db5b762ac..59942dc76f9aa 100644 --- a/compiler/rustc_mir_transform/src/match_branches.rs +++ b/compiler/rustc_mir_transform/src/match_branches.rs @@ -46,7 +46,7 @@ impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let def_id = body.source.def_id(); - let param_env = tcx.param_env(def_id); + let param_env = tcx.param_env_reveal_all_normalized(def_id); let bbs = body.basic_blocks.as_mut(); let mut should_cleanup = false; diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 4396a83e8b818..d4debae5c581a 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -355,7 +355,7 @@ fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'t fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> { debug!("build_clone_shim(def_id={:?})", def_id); - let param_env = tcx.param_env(def_id); + let param_env = tcx.param_env_reveal_all_normalized(def_id); let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty); let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env); @@ -836,7 +836,7 @@ fn build_call_shim<'tcx>( pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { debug_assert!(tcx.is_constructor(ctor_id)); - let param_env = tcx.param_env(ctor_id); + let param_env = tcx.param_env_reveal_all_normalized(ctor_id); // Normalize the sig. let sig = tcx diff --git a/compiler/rustc_mir_transform/src/simplify_branches.rs b/compiler/rustc_mir_transform/src/simplify_branches.rs index c65a7ec6783fa..1ff488169864b 100644 --- a/compiler/rustc_mir_transform/src/simplify_branches.rs +++ b/compiler/rustc_mir_transform/src/simplify_branches.rs @@ -16,7 +16,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyConstCondition { } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let param_env = tcx.param_env(body.source.def_id()); + let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); for block in body.basic_blocks_mut() { let terminator = block.terminator_mut(); terminator.kind = match terminator.kind { diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs index dcad1518eb63e..113ca2fc5ada5 100644 --- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs +++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs @@ -37,7 +37,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral { let opts = helper.find_optimizations(); let mut storage_deads_to_insert = vec![]; let mut storage_deads_to_remove: Vec<(usize, BasicBlock)> = vec![]; - let param_env = tcx.param_env(body.source.def_id()); + let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); for opt in opts { trace!("SUCCESS: Applying {:?}", opt); // replace terminator with a switchInt that switches on the integer directly diff --git a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs index be0aa0fc4c1d0..5389b9f52eb2d 100644 --- a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs +++ b/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs @@ -109,7 +109,9 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching { continue; }; - let layout = tcx.layout_of(tcx.param_env(body.source.def_id()).and(discriminant_ty)); + let layout = tcx.layout_of( + tcx.param_env_reveal_all_normalized(body.source.def_id()).and(discriminant_ty), + ); let allowed_variants = if let Ok(layout) = layout { variant_discriminants(&layout, discriminant_ty, tcx) From e4e4110dc6a0dcd2bade2fd789e81a518618e9c0 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Fri, 21 Apr 2023 19:29:32 -0700 Subject: [PATCH 38/42] Fix printing native CPU on cross-compiled compiler. --- compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index c9acbab253e10..78f29532ffbd2 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -310,12 +310,14 @@ static size_t getLongestEntryLength(ArrayRef Table) { extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) { const TargetMachine *Target = unwrap(TM); const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo(); - const Triple::ArchType HostArch = Triple(sys::getProcessTriple()).getArch(); + const Triple::ArchType HostArch = Triple(sys::getDefaultTargetTriple()).getArch(); const Triple::ArchType TargetArch = Target->getTargetTriple().getArch(); const ArrayRef CPUTable = MCInfo->getCPUTable(); unsigned MaxCPULen = getLongestEntryLength(CPUTable); printf("Available CPUs for this target:\n"); + // Don't print the "native" entry when the user specifies --target with a + // different arch since that could be wrong or misleading. if (HostArch == TargetArch) { const StringRef HostCPU = sys::getHostCPUName(); printf(" %-*s - Select the CPU of the current host (currently %.*s).\n", From cde5bcafe89658a43b7cf865f58057db29f4d531 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 19 Apr 2023 23:38:02 +0000 Subject: [PATCH 39/42] Don't create projection ty for const projection --- .../src/traits/project.rs | 31 ++++++++++++++----- .../projection-unspecified-but-bounded.rs | 16 ++++++++++ .../projection-unspecified-but-bounded.stderr | 17 ++++++++++ 3 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 tests/ui/associated-consts/projection-unspecified-but-bounded.rs create mode 100644 tests/ui/associated-consts/projection-unspecified-but-bounded.stderr diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 6ba0538717348..ea45412e47f11 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1272,14 +1272,29 @@ fn project<'cx, 'tcx>( ProjectionCandidateSet::Single(candidate) => { Ok(Projected::Progress(confirm_candidate(selcx, obligation, candidate))) } - ProjectionCandidateSet::None => Ok(Projected::NoProgress( - // FIXME(associated_const_generics): this may need to change in the future? - // need to investigate whether or not this is fine. - selcx - .tcx() - .mk_projection(obligation.predicate.def_id, obligation.predicate.substs) - .into(), - )), + ProjectionCandidateSet::None => { + let tcx = selcx.tcx(); + let term = match tcx.def_kind(obligation.predicate.def_id) { + DefKind::AssocTy | DefKind::ImplTraitPlaceholder => tcx + .mk_projection(obligation.predicate.def_id, obligation.predicate.substs) + .into(), + DefKind::AssocConst => tcx + .mk_const( + ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new( + obligation.predicate.def_id, + obligation.predicate.substs, + )), + tcx.type_of(obligation.predicate.def_id) + .subst(tcx, obligation.predicate.substs), + ) + .into(), + kind => { + bug!("unknown projection def-id: {}", kind.descr(obligation.predicate.def_id)) + } + }; + + Ok(Projected::NoProgress(term)) + } // Error occurred while trying to processing impls. ProjectionCandidateSet::Error(e) => Err(ProjectionError::TraitSelectionError(e)), // Inherent ambiguity that prevents us from even enumerating the diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.rs b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs new file mode 100644 index 0000000000000..b1a0f39962b61 --- /dev/null +++ b/tests/ui/associated-consts/projection-unspecified-but-bounded.rs @@ -0,0 +1,16 @@ +#![feature(associated_const_equality)] + +// Issue 110549 + +pub trait TraitWAssocConst { + const A: usize; +} + +fn foo>() {} + +fn bar() { + foo::(); + //~^ ERROR type mismatch resolving `::A == 32` +} + +fn main() {} diff --git a/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr b/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr new file mode 100644 index 0000000000000..8175e510a093f --- /dev/null +++ b/tests/ui/associated-consts/projection-unspecified-but-bounded.stderr @@ -0,0 +1,17 @@ +error[E0271]: type mismatch resolving `::A == 32` + --> $DIR/projection-unspecified-but-bounded.rs:12:11 + | +LL | foo::(); + | ^ expected `32`, found `::A` + | + = note: expected constant `32` + found constant `::A` +note: required by a bound in `foo` + --> $DIR/projection-unspecified-but-bounded.rs:9:28 + | +LL | fn foo>() {} + | ^^^^^^ required by this bound in `foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. From 26e299cea6375293f6f175201864b88f63d1c848 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 24 Apr 2023 11:58:59 +0200 Subject: [PATCH 40/42] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 7ea0a3e3a3e9c..0c165006022e9 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -3128fd8ddfde44f09f7c3920c552122f5aec2395 +f65615f02d22b85e9205f2716ab36182d34bab2b From adee37a080c7415f7ba496726557531ddf950919 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Apr 2023 16:40:59 +0200 Subject: [PATCH 41/42] repr attribute needs to be stored to be used in doc(inline) by rustdoc --- compiler/rustc_feature/src/builtin_attrs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index c77292fdd1647..103e0f344070d 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -344,7 +344,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ ), ungated!(link_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding), ungated!(no_link, Normal, template!(Word), WarnFollowing), - ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, @only_local: true), + ungated!(repr, Normal, template!(List: "C"), DuplicatesOk), ungated!(export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding), ungated!(link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding), ungated!(no_mangle, Normal, template!(Word), WarnFollowing, @only_local: true), From 3f082843aa19d2bb51531688770eeae401249ceb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 27 Apr 2023 16:41:22 +0200 Subject: [PATCH 42/42] Add regression test for #110698 --- tests/rustdoc/inline_cross/auxiliary/repr.rs | 4 ++++ tests/rustdoc/inline_cross/repr.rs | 13 +++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/rustdoc/inline_cross/auxiliary/repr.rs create mode 100644 tests/rustdoc/inline_cross/repr.rs diff --git a/tests/rustdoc/inline_cross/auxiliary/repr.rs b/tests/rustdoc/inline_cross/auxiliary/repr.rs new file mode 100644 index 0000000000000..64a98f1814626 --- /dev/null +++ b/tests/rustdoc/inline_cross/auxiliary/repr.rs @@ -0,0 +1,4 @@ +#[repr(C)] +pub struct Foo { + field: u8, +} diff --git a/tests/rustdoc/inline_cross/repr.rs b/tests/rustdoc/inline_cross/repr.rs new file mode 100644 index 0000000000000..7e1f2799af1cd --- /dev/null +++ b/tests/rustdoc/inline_cross/repr.rs @@ -0,0 +1,13 @@ +// Regression test for . +// This test ensures that the re-exported items still have the `#[repr(...)]` attribute. + +// aux-build:repr.rs + +#![crate_name = "foo"] + +extern crate repr; + +// @has 'foo/struct.Foo.html' +// @has - '//*[@class="rust item-decl"]//*[@class="code-attribute"]' '#[repr(C)]' +#[doc(inline)] +pub use repr::Foo;