From 1abe485e8952d6b6254b5d06d677e9842e6a7158 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Fri, 20 Dec 2024 13:37:45 +0100 Subject: [PATCH 01/10] fix missing ns units in bootstrap's benchmark rendering --- src/bootstrap/src/utils/render_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs index eb2c8254dc0f4..46b250555f2d5 100644 --- a/src/bootstrap/src/utils/render_tests.rs +++ b/src/bootstrap/src/utils/render_tests.rs @@ -242,7 +242,7 @@ impl<'a> Renderer<'a> { for bench in &self.benches { rows.push(( &bench.name, - format!("{:.2?}/iter", bench.median), + format!("{:.2?}ns/iter", bench.median), format!("+/- {:.2?}", bench.deviation), )); } From 8b2b6359f97ee9ac8fb1b5c35e86211222d02574 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 20 Dec 2024 15:03:51 +0100 Subject: [PATCH 02/10] mri: add track_caller to thread spawning methods for better backtraces --- library/std/src/sys/pal/unix/thread.rs | 1 + library/std/src/sys/pal/windows/thread.rs | 1 + library/std/src/thread/mod.rs | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 131a6e81b1e92..e360ba0f6d7d8 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -45,6 +45,7 @@ unsafe impl Sync for Thread {} impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn new(stack: usize, p: Box) -> io::Result { let p = Box::into_raw(Box::new(p)); let mut native: libc::pthread_t = mem::zeroed(); diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs index 2c8ce42f4148b..45e52cf4d047f 100644 --- a/library/std/src/sys/pal/windows/thread.rs +++ b/library/std/src/sys/pal/windows/thread.rs @@ -19,6 +19,7 @@ pub struct Thread { impl Thread { // unsafe: see thread::Builder::spawn_unchecked for safety requirements + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn new(stack: usize, p: Box) -> io::Result { let p = Box::into_raw(Box::new(p)); diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index cfbf6548a380c..85ee369ca2b66 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -391,6 +391,7 @@ impl Builder { /// handler.join().unwrap(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub fn spawn(self, f: F) -> io::Result> where F: FnOnce() -> T, @@ -458,6 +459,7 @@ impl Builder { /// /// [`io::Result`]: crate::io::Result #[stable(feature = "thread_spawn_unchecked", since = "1.82.0")] + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn spawn_unchecked(self, f: F) -> io::Result> where F: FnOnce() -> T, @@ -467,6 +469,7 @@ impl Builder { Ok(JoinHandle(unsafe { self.spawn_unchecked_(f, None) }?)) } + #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces unsafe fn spawn_unchecked_<'scope, F, T>( self, f: F, @@ -721,6 +724,7 @@ impl Builder { /// [`join`]: JoinHandle::join /// [`Err`]: crate::result::Result::Err #[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub fn spawn(f: F) -> JoinHandle where F: FnOnce() -> T, From 701e2f708b95d508f90ffd5a3b234335662ae521 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 14:08:24 +0000 Subject: [PATCH 03/10] Reduce the amount of explicit FatalError.raise() Instead use dcx.abort_if_error() or guar.raise_fatal() instead. These guarantee that an error actually happened previously and thus we don't silently abort. --- compiler/rustc_codegen_ssa/src/back/link.rs | 12 ++++++------ compiler/rustc_driver_impl/src/pretty.rs | 9 ++------- compiler/rustc_parse/src/parser/diagnostics.rs | 17 +++++------------ compiler/rustc_parse/src/parser/path.rs | 3 +-- compiler/rustc_session/src/output.rs | 15 ++++++--------- .../src/error_reporting/traits/overflow.rs | 7 ++----- 6 files changed, 22 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index f4f6161ebbccd..60e2d1978913f 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -15,7 +15,7 @@ use rustc_ast::CRATE_NODE_ID; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::memmap::Mmap; use rustc_data_structures::temp_dir::MaybeTempDir; -use rustc_errors::{DiagCtxtHandle, FatalError}; +use rustc_errors::DiagCtxtHandle; use rustc_fs_util::{fix_windows_verbatim_for_gcc, try_canonicalize}; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; use rustc_metadata::fs::{METADATA_FILENAME, copy_to_stdout, emit_wrapper_file}; @@ -1039,22 +1039,22 @@ fn link_natively( Err(e) => { let linker_not_found = e.kind() == io::ErrorKind::NotFound; - if linker_not_found { - sess.dcx().emit_err(errors::LinkerNotFound { linker_path, error: e }); + let err = if linker_not_found { + sess.dcx().emit_err(errors::LinkerNotFound { linker_path, error: e }) } else { sess.dcx().emit_err(errors::UnableToExeLinker { linker_path, error: e, command_formatted: format!("{cmd:?}"), - }); - } + }) + }; if sess.target.is_like_msvc && linker_not_found { sess.dcx().emit_note(errors::MsvcMissingLinker); sess.dcx().emit_note(errors::CheckInstalledVisualStudio); sess.dcx().emit_note(errors::InsufficientVSCodeProduct); } - FatalError.raise(); + err.raise_fatal(); } } diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 5a1a873d4bde9..93f3d2ab911f8 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -4,7 +4,6 @@ use std::cell::Cell; use std::fmt::Write; use rustc_ast_pretty::pprust as pprust_ast; -use rustc_errors::FatalError; use rustc_middle::bug; use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty}; use rustc_middle::ty::{self, TyCtxt}; @@ -311,9 +310,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { let tcx = ex.tcx(); let mut out = String::new(); rustc_hir_analysis::check_crate(tcx); - if tcx.dcx().has_errors().is_some() { - FatalError.raise(); - } + tcx.dcx().abort_if_errors(); debug!("pretty printing THIR tree"); for did in tcx.hir().body_owners() { let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_tree(did)); @@ -324,9 +321,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) { let tcx = ex.tcx(); let mut out = String::new(); rustc_hir_analysis::check_crate(tcx); - if tcx.dcx().has_errors().is_some() { - FatalError.raise(); - } + tcx.dcx().abort_if_errors(); debug!("pretty printing THIR flat"); for did in tcx.hir().body_owners() { let _ = writeln!(out, "{:?}:\n{}\n", did, tcx.thir_flat(did)); diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 7e9b9219e7ac0..aab4e1b1afc1b 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -16,8 +16,8 @@ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; use rustc_errors::{ - Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PResult, Subdiagnostic, - Suggestions, pluralize, + Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, PResult, Subdiagnostic, Suggestions, + pluralize, }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::edit_distance::find_best_match_for_name; @@ -3023,17 +3023,10 @@ impl<'a> Parser<'a> { } pub(super) fn recover_vcs_conflict_marker(&mut self) { - if let Err(err) = self.err_vcs_conflict_marker() { - err.emit(); - FatalError.raise(); - } - } - - pub(crate) fn err_vcs_conflict_marker(&mut self) -> PResult<'a, ()> { // <<<<<<< let Some(start) = self.conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) else { - return Ok(()); + return; }; let mut spans = Vec::with_capacity(3); spans.push(start); @@ -3063,7 +3056,7 @@ impl<'a> Parser<'a> { self.bump(); } - let mut err = self.dcx().struct_span_err(spans, "encountered diff marker"); + let mut err = self.dcx().struct_span_fatal(spans, "encountered diff marker"); match middlediff3 { // We're using diff3 Some(middlediff3) => { @@ -3106,7 +3099,7 @@ impl<'a> Parser<'a> { visit ", ); - Err(err) + err.emit(); } /// Parse and throw away a parenthesized comma separated diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 73612d1da2954..39737b9e13798 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -597,8 +597,7 @@ impl<'a> Parser<'a> { // When encountering severely malformed code where there are several levels of // nested unclosed angle args (`f:: 0 => { self.angle_bracket_nesting -= 1; diff --git a/compiler/rustc_session/src/output.rs b/compiler/rustc_session/src/output.rs index bd103e86e2634..ff0419d06bff9 100644 --- a/compiler/rustc_session/src/output.rs +++ b/compiler/rustc_session/src/output.rs @@ -3,7 +3,6 @@ use std::path::Path; use rustc_ast::{self as ast, attr}; -use rustc_errors::FatalError; use rustc_span::{Span, Symbol, sym}; use crate::Session; @@ -90,11 +89,10 @@ pub fn find_crate_name(sess: &Session, attrs: &[ast::Attribute]) -> Symbol { } pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option) { - let mut err_count = 0; + let mut guar = None; { if s.is_empty() { - err_count += 1; - sess.dcx().emit_err(CrateNameEmpty { span: sp }); + guar = Some(sess.dcx().emit_err(CrateNameEmpty { span: sp })); } for c in s.as_str().chars() { if c.is_alphanumeric() { @@ -103,8 +101,7 @@ pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option) { if c == '_' { continue; } - err_count += 1; - sess.dcx().emit_err(InvalidCharacterInCrateName { + guar = Some(sess.dcx().emit_err(InvalidCharacterInCrateName { span: sp, character: c, crate_name: s, @@ -113,12 +110,12 @@ pub fn validate_crate_name(sess: &Session, s: Symbol, sp: Option) { } else { None }, - }); + })); } } - if err_count > 0 { - FatalError.raise(); + if let Some(guar) = guar { + guar.raise_fatal(); } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs index c47c21696911b..d82acc4e0543f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/overflow.rs @@ -1,8 +1,6 @@ use std::fmt; -use rustc_errors::{ - Diag, E0275, EmissionGuarantee, ErrorGuaranteed, FatalError, struct_span_code_err, -}; +use rustc_errors::{Diag, E0275, EmissionGuarantee, ErrorGuaranteed, struct_span_code_err}; use rustc_hir::def::Namespace; use rustc_hir::def_id::LOCAL_CRATE; use rustc_infer::traits::{Obligation, PredicateObligation}; @@ -52,8 +50,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { ) -> ! { let mut err = self.build_overflow_error(cause, span, suggest_increasing_limit); mutate(&mut err); - err.emit(); - FatalError.raise(); + err.emit().raise_fatal(); } pub fn build_overflow_error( From 96edf411947afdc7867d9515cff2557357a2f9c4 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Fri, 20 Dec 2024 23:19:12 +0900 Subject: [PATCH 04/10] tests/codegen/asm: Remove uses of rustc_attrs and lang_items features by using minicore --- tests/codegen/asm/aarch64-clobbers.rs | 12 ++++-------- tests/codegen/asm/avr-clobbers.rs | 12 ++++-------- tests/codegen/asm/hexagon-clobbers.rs | 12 ++++-------- tests/codegen/asm/msp430-clobbers.rs | 12 ++++-------- tests/codegen/asm/powerpc-clobbers.rs | 12 ++++-------- tests/codegen/asm/riscv-clobbers.rs | 12 ++++-------- tests/codegen/asm/s390x-clobbers.rs | 12 ++++-------- tests/codegen/asm/sanitize-llvm.rs | 14 ++++---------- tests/codegen/asm/sparc-clobbers.rs | 12 ++++-------- 9 files changed, 36 insertions(+), 74 deletions(-) diff --git a/tests/codegen/asm/aarch64-clobbers.rs b/tests/codegen/asm/aarch64-clobbers.rs index 900e6629fd2c2..dd3ba1510b5b1 100644 --- a/tests/codegen/asm/aarch64-clobbers.rs +++ b/tests/codegen/asm/aarch64-clobbers.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: aarch64 aarch64_fixed_x18 aarch64_no_x18 aarch64_reserve_x18 arm64ec //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu //@[aarch64] needs-llvm-components: aarch64 @@ -14,16 +15,11 @@ // ignore-tidy-linelength #![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items)] +#![feature(no_core)] #![no_core] -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} +extern crate minicore; +use minicore::*; // CHECK-LABEL: @cc_clobber // CHECK: call void asm sideeffect "", "~{cc}"() diff --git a/tests/codegen/asm/avr-clobbers.rs b/tests/codegen/asm/avr-clobbers.rs index 6e0c75368e23f..56218cd7bcffb 100644 --- a/tests/codegen/asm/avr-clobbers.rs +++ b/tests/codegen/asm/avr-clobbers.rs @@ -1,18 +1,14 @@ +//@ add-core-stubs //@ assembly-output: emit-asm //@ compile-flags: --target avr-unknown-gnu-atmega328 //@ needs-llvm-components: avr #![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![feature(no_core, asm_experimental_arch)] #![no_core] -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} +extern crate minicore; +use minicore::*; // CHECK-LABEL: @sreg_is_clobbered // CHECK: void asm sideeffect "", "~{sreg}"() diff --git a/tests/codegen/asm/hexagon-clobbers.rs b/tests/codegen/asm/hexagon-clobbers.rs index 6bb662ead9940..800b8964669c0 100644 --- a/tests/codegen/asm/hexagon-clobbers.rs +++ b/tests/codegen/asm/hexagon-clobbers.rs @@ -1,19 +1,15 @@ +//@ add-core-stubs //@ revisions: hexagon //@[hexagon] compile-flags: --target hexagon-unknown-linux-musl //@[hexagon] needs-llvm-components: hexagon //@ compile-flags: -Zmerge-functions=disabled #![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![feature(no_core, asm_experimental_arch)] #![no_core] -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} +extern crate minicore; +use minicore::*; // CHECK-LABEL: @flags_clobber // CHECK: call void asm sideeffect "", ""() diff --git a/tests/codegen/asm/msp430-clobbers.rs b/tests/codegen/asm/msp430-clobbers.rs index c00c04f3088cb..2c8d29cffc4be 100644 --- a/tests/codegen/asm/msp430-clobbers.rs +++ b/tests/codegen/asm/msp430-clobbers.rs @@ -1,18 +1,14 @@ +//@ add-core-stubs //@ assembly-output: emit-asm //@ compile-flags: --target msp430-none-elf //@ needs-llvm-components: msp430 #![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![feature(no_core, asm_experimental_arch)] #![no_core] -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} +extern crate minicore; +use minicore::*; // CHECK-LABEL: @sr_clobber // CHECK: call void asm sideeffect "", "~{sr}"() diff --git a/tests/codegen/asm/powerpc-clobbers.rs b/tests/codegen/asm/powerpc-clobbers.rs index 2832377cef00d..f7fc7eea5d506 100644 --- a/tests/codegen/asm/powerpc-clobbers.rs +++ b/tests/codegen/asm/powerpc-clobbers.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: powerpc powerpc64 powerpc64le aix64 //@[powerpc] compile-flags: --target powerpc-unknown-linux-gnu //@[powerpc] needs-llvm-components: powerpc @@ -10,16 +11,11 @@ // ignore-tidy-linelength #![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![feature(no_core, asm_experimental_arch)] #![no_core] -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} +extern crate minicore; +use minicore::*; // CHECK-LABEL: @cr_clobber // CHECK: call void asm sideeffect "", "~{cr}"() diff --git a/tests/codegen/asm/riscv-clobbers.rs b/tests/codegen/asm/riscv-clobbers.rs index 59b2705a4496a..e55b6731098e7 100644 --- a/tests/codegen/asm/riscv-clobbers.rs +++ b/tests/codegen/asm/riscv-clobbers.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ assembly-output: emit-asm //@ revisions: rv32i rv64i rv32e //@[rv32i] compile-flags: --target riscv32i-unknown-none-elf @@ -9,16 +10,11 @@ // ignore-tidy-linelength #![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items)] +#![feature(no_core)] #![no_core] -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} +extern crate minicore; +use minicore::*; // CHECK-LABEL: @flags_clobber // CHECK: call void asm sideeffect "", "~{vtype},~{vl},~{vxsat},~{vxrm}"() diff --git a/tests/codegen/asm/s390x-clobbers.rs b/tests/codegen/asm/s390x-clobbers.rs index 56d82b4b04400..cbb6630553cfa 100644 --- a/tests/codegen/asm/s390x-clobbers.rs +++ b/tests/codegen/asm/s390x-clobbers.rs @@ -1,18 +1,14 @@ +//@ add-core-stubs //@ revisions: s390x //@[s390x] compile-flags: --target s390x-unknown-linux-gnu //@[s390x] needs-llvm-components: systemz #![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items)] +#![feature(no_core)] #![no_core] -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} +extern crate minicore; +use minicore::*; // CHECK-LABEL: @cc_clobber // CHECK: call void asm sideeffect "", "~{cc}"() diff --git a/tests/codegen/asm/sanitize-llvm.rs b/tests/codegen/asm/sanitize-llvm.rs index fb332f9a0f3e6..97a7703328428 100644 --- a/tests/codegen/asm/sanitize-llvm.rs +++ b/tests/codegen/asm/sanitize-llvm.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs // FIXME(nagisa): remove the flags below once all targets support `asm!`. //@ compile-flags: --target x86_64-unknown-linux-gnu -Copt-level=0 //@ needs-llvm-components: x86 @@ -5,19 +6,12 @@ // Verify we sanitize the special tokens for the LLVM inline-assembly, ensuring people won't // inadvertently rely on the LLVM-specific syntax and features. #![no_core] -#![feature(no_core, lang_items, rustc_attrs)] +#![feature(no_core)] #![crate_type = "rlib"] #![allow(named_asm_labels)] -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} - -#[lang = "sized"] -trait Sized {} -#[lang = "copy"] -trait Copy {} +extern crate minicore; +use minicore::*; pub unsafe fn we_escape_dollar_signs() { // CHECK: call void asm sideeffect alignstack inteldialect "banana$$:" diff --git a/tests/codegen/asm/sparc-clobbers.rs b/tests/codegen/asm/sparc-clobbers.rs index 843abd553523e..a71715ed94d56 100644 --- a/tests/codegen/asm/sparc-clobbers.rs +++ b/tests/codegen/asm/sparc-clobbers.rs @@ -1,3 +1,4 @@ +//@ add-core-stubs //@ revisions: sparc sparcv8plus sparc64 //@[sparc] compile-flags: --target sparc-unknown-none-elf //@[sparc] needs-llvm-components: sparc @@ -7,16 +8,11 @@ //@[sparc64] needs-llvm-components: sparc #![crate_type = "rlib"] -#![feature(no_core, rustc_attrs, lang_items, asm_experimental_arch)] +#![feature(no_core, asm_experimental_arch)] #![no_core] -#[lang = "sized"] -trait Sized {} - -#[rustc_builtin_macro] -macro_rules! asm { - () => {}; -} +extern crate minicore; +use minicore::*; // CHECK-LABEL: @cc_clobber // CHECK: call void asm sideeffect "", "~{icc},~{fcc0},~{fcc1},~{fcc2},~{fcc3}"() From c02c311d84a919f6be3b797866100214c91c5b68 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:20:15 +0000 Subject: [PATCH 05/10] Remove some dead code around import library generation This was missed when replacing the usage of LLVM for generating import libraries. --- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 28 ----------- .../rustc_llvm/llvm-wrapper/RustWrapper.cpp | 50 ------------------- 2 files changed, 78 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index d62632d143168..9a2bfd95562f2 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -56,25 +56,6 @@ pub enum LLVMRustResult { Failure, } -// Rust version of the C struct with the same name in rustc_llvm/llvm-wrapper/RustWrapper.cpp. -#[repr(C)] -pub struct LLVMRustCOFFShortExport { - pub name: *const c_char, - pub ordinal_present: bool, - /// value of `ordinal` only important when `ordinal_present` is true - pub ordinal: u16, -} - -impl LLVMRustCOFFShortExport { - pub fn new(name: *const c_char, ordinal: Option) -> LLVMRustCOFFShortExport { - LLVMRustCOFFShortExport { - name, - ordinal_present: ordinal.is_some(), - ordinal: ordinal.unwrap_or(0), - } - } -} - /// Translation of LLVM's MachineTypes enum, defined in llvm\include\llvm\BinaryFormat\COFF.h. /// /// We include only architectures supported on Windows. @@ -2347,15 +2328,6 @@ unsafe extern "C" { ) -> &'a mut RustArchiveMember<'a>; pub fn LLVMRustArchiveMemberFree<'a>(Member: &'a mut RustArchiveMember<'a>); - pub fn LLVMRustWriteImportLibrary( - ImportName: *const c_char, - Path: *const c_char, - Exports: *const LLVMRustCOFFShortExport, - NumExports: usize, - Machine: u16, - MinGW: bool, - ) -> LLVMRustResult; - pub fn LLVMRustSetDataLayoutFromTargetMachine<'a>(M: &'a Module, TM: &'a TargetMachine); pub fn LLVMRustPositionBuilderAtStart<'a>(B: &Builder<'a>, BB: &'a BasicBlock); diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index b79205ff946d3..36441a95adbf9 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1796,56 +1796,6 @@ extern "C" LLVMValueRef LLVMRustBuildMaxNum(LLVMBuilderRef B, LLVMValueRef LHS, return wrap(unwrap(B)->CreateMaxNum(unwrap(LHS), unwrap(RHS))); } -// This struct contains all necessary info about a symbol exported from a DLL. -struct LLVMRustCOFFShortExport { - const char *name; - bool ordinal_present; - // The value of `ordinal` is only meaningful if `ordinal_present` is true. - uint16_t ordinal; -}; - -// Machine must be a COFF machine type, as defined in PE specs. -extern "C" LLVMRustResult -LLVMRustWriteImportLibrary(const char *ImportName, const char *Path, - const LLVMRustCOFFShortExport *Exports, - size_t NumExports, uint16_t Machine, bool MinGW) { - std::vector ConvertedExports; - ConvertedExports.reserve(NumExports); - - for (size_t i = 0; i < NumExports; ++i) { - bool ordinal_present = Exports[i].ordinal_present; - uint16_t ordinal = ordinal_present ? Exports[i].ordinal : 0; - ConvertedExports.push_back(llvm::object::COFFShortExport{ - Exports[i].name, // Name - std::string{}, // ExtName - std::string{}, // SymbolName - std::string{}, // AliasTarget -#if LLVM_VERSION_GE(19, 0) - std::string{}, // ExportAs -#endif - ordinal, // Ordinal - ordinal_present, // Noname - false, // Data - false, // Private - false // Constant - }); - } - - auto Error = llvm::object::writeImportLibrary( - ImportName, Path, ConvertedExports, - static_cast(Machine), MinGW); - if (Error) { - std::string errorString; - auto stream = llvm::raw_string_ostream(errorString); - stream << Error; - stream.flush(); - LLVMRustSetLastError(errorString.c_str()); - return LLVMRustResult::Failure; - } else { - return LLVMRustResult::Success; - } -} - // Transfers ownership of DiagnosticHandler unique_ptr to the caller. extern "C" DiagnosticHandler * LLVMRustContextGetDiagnosticHandler(LLVMContextRef C) { From 42c00cb6479d6e03742968e06c6d280a272acd53 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 20 Dec 2024 16:57:14 +0100 Subject: [PATCH 06/10] split up `#[rustc_deny_explicit_impl]` attribute This commit splits the `#[rustc_deny_explicit_impl(implement_via_object = ...)]` attribute into two attributes `#[rustc_deny_explicit_impl]` and `#[rustc_do_not_implement_via_object]`. This allows us to have special traits that can have user-defined impls but do not have the automatic trait impl for trait objects (`impl Trait for dyn Trait`). --- compiler/rustc_feature/src/builtin_attrs.rs | 11 +++- .../rustc_hir_analysis/src/coherence/mod.rs | 4 +- compiler/rustc_hir_analysis/src/collect.rs | 45 +---------------- compiler/rustc_middle/src/ty/trait_def.rs | 4 +- compiler/rustc_passes/src/check_attr.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + library/core/src/future/async_drop.rs | 4 +- library/core/src/marker.rs | 24 ++++++--- library/core/src/mem/transmutability.rs | 4 +- library/core/src/ptr/metadata.rs | 4 +- .../deny-builtin-object-impl.current.stderr | 50 ++++++++++++++----- .../deny-builtin-object-impl.next.stderr | 50 ++++++++++++++----- tests/ui/traits/deny-builtin-object-impl.rs | 41 +++++++++++---- 13 files changed, 152 insertions(+), 91 deletions(-) diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 4b9f62fa764c0..63e5ebb8688f6 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -912,11 +912,20 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!( rustc_deny_explicit_impl, AttributeType::Normal, - template!(List: "implement_via_object = (true|false)"), + template!(Word), ErrorFollowing, EncodeCrossCrate::No, "#[rustc_deny_explicit_impl] enforces that a trait can have no user-provided impls" ), + rustc_attr!( + rustc_do_not_implement_via_object, + AttributeType::Normal, + template!(Word), + ErrorFollowing, + EncodeCrossCrate::No, + "#[rustc_do_not_implement_via_object] opts out of the automatic trait impl for trait objects \ + (`impl Trait for dyn Trait`)" + ), rustc_attr!( rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index 3aad4bafeb5ab..1be4aa2f63ac4 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -206,7 +206,9 @@ fn check_object_overlap<'tcx>( // so this is valid. } else { let mut supertrait_def_ids = tcx.supertrait_def_ids(component_def_id); - if supertrait_def_ids.any(|d| d == trait_def_id) { + if supertrait_def_ids + .any(|d| d == trait_def_id && tcx.trait_def(d).implement_via_object) + { let span = tcx.def_span(impl_def_id); return Err(struct_span_code_err!( tcx.dcx(), diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 5e662bb96bc44..ada70117b626f 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1261,49 +1261,8 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { no_dups.then_some(list) }); - let mut deny_explicit_impl = false; - let mut implement_via_object = true; - if let Some(attr) = tcx.get_attr(def_id, sym::rustc_deny_explicit_impl) { - deny_explicit_impl = true; - let mut seen_attr = false; - for meta in attr.meta_item_list().iter().flatten() { - if let Some(meta) = meta.meta_item() - && meta.name_or_empty() == sym::implement_via_object - && let Some(lit) = meta.name_value_literal() - { - if seen_attr { - tcx.dcx().span_err(meta.span, "duplicated `implement_via_object` meta item"); - } - seen_attr = true; - - match lit.symbol { - kw::True => { - implement_via_object = true; - } - kw::False => { - implement_via_object = false; - } - _ => { - tcx.dcx().span_err( - meta.span, - format!( - "unknown literal passed to `implement_via_object` attribute: {}", - lit.symbol - ), - ); - } - } - } else { - tcx.dcx().span_err( - meta.span(), - format!("unknown meta item passed to `rustc_deny_explicit_impl` {meta:?}"), - ); - } - } - if !seen_attr { - tcx.dcx().span_err(attr.span, "missing `implement_via_object` meta item"); - } - } + let deny_explicit_impl = tcx.has_attr(def_id, sym::rustc_deny_explicit_impl); + let implement_via_object = !tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object); ty::TraitDef { def_id: def_id.to_def_id(), diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 188107e5d5498..743ea33b20a27 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -70,12 +70,12 @@ pub struct TraitDef { /// Whether to add a builtin `dyn Trait: Trait` implementation. /// This is enabled for all traits except ones marked with - /// `#[rustc_deny_explicit_impl(implement_via_object = false)]`. + /// `#[rustc_do_not_implement_via_object]`. pub implement_via_object: bool, /// Whether a trait is fully built-in, and any implementation is disallowed. /// This only applies to built-in traits, and is marked via - /// `#[rustc_deny_explicit_impl(implement_via_object = ...)]`. + /// `#[rustc_deny_explicit_impl]`. pub deny_explicit_impl: bool, } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 2310dd9dc72db..1f2d5671f7a84 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -186,6 +186,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { [sym::rustc_coinductive, ..] | [sym::rustc_must_implement_one_of, ..] | [sym::rustc_deny_explicit_impl, ..] + | [sym::rustc_do_not_implement_via_object, ..] | [sym::const_trait, ..] => self.check_must_be_applied_to_trait(attr, span, target), [sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target), [sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target), diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a7ff0576f92d6..123e4b1f01f26 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1717,6 +1717,7 @@ symbols! { rustc_diagnostic_macros, rustc_dirty, rustc_do_not_const_check, + rustc_do_not_implement_via_object, rustc_doc_primitive, rustc_driver, rustc_dummy, diff --git a/library/core/src/future/async_drop.rs b/library/core/src/future/async_drop.rs index 7de5fe67cd096..ea6d3b800e64d 100644 --- a/library/core/src/future/async_drop.rs +++ b/library/core/src/future/async_drop.rs @@ -133,7 +133,9 @@ pub trait AsyncDrop { } #[lang = "async_destruct"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] trait AsyncDestruct { type AsyncDestructor: Future; } diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 1620b949590d0..31b27b7ef2641 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -141,7 +141,9 @@ unsafe impl Send for &T {} )] #[fundamental] // for Default, for example, which requires that `[T]: !Default` be evaluatable #[rustc_specialization_trait] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] #[rustc_coinductive] pub trait Sized { // Empty. @@ -181,7 +183,9 @@ pub trait Sized { /// [^1]: Formerly known as *object safe*. #[unstable(feature = "unsize", issue = "18598")] #[lang = "unsize"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] pub trait Unsize { // Empty. } @@ -815,7 +819,9 @@ impl StructuralPartialEq for PhantomData {} reason = "this trait is unlikely to ever be stabilized, use `mem::discriminant` instead" )] #[lang = "discriminant_kind"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] pub trait DiscriminantKind { /// The type of the discriminant, which must satisfy the trait /// bounds required by `mem::Discriminant`. @@ -956,7 +962,9 @@ marker_impls! { #[unstable(feature = "const_destruct", issue = "133214")] #[lang = "destruct"] #[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] #[cfg_attr(not(bootstrap), const_trait)] pub trait Destruct {} @@ -967,7 +975,9 @@ pub trait Destruct {} #[unstable(feature = "tuple_trait", issue = "none")] #[lang = "tuple_trait"] #[diagnostic::on_unimplemented(message = "`{Self}` is not a tuple")] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] pub trait Tuple {} /// A marker for pointer-like types. @@ -1068,7 +1078,9 @@ marker_impls! { reason = "internal trait for implementing various traits for all function pointers" )] #[lang = "fn_ptr_trait"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] pub trait FnPtr: Copy + Clone { /// Returns the address of the function pointer. #[lang = "fn_ptr_addr"] diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs index 7fa3c33439170..9cf587650d949 100644 --- a/library/core/src/mem/transmutability.rs +++ b/library/core/src/mem/transmutability.rs @@ -84,7 +84,9 @@ use crate::marker::{ConstParamTy_, UnsizedConstParamTy}; /// `usize` is stable, but not portable. #[unstable(feature = "transmutability", issue = "99571")] #[lang = "transmute_trait"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] #[rustc_coinductive] pub unsafe trait TransmuteFrom where diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index ae9810e558aa1..b1d5e1fa3a059 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -53,7 +53,9 @@ use crate::ptr::NonNull; /// /// [`to_raw_parts`]: *const::to_raw_parts #[lang = "pointee_trait"] -#[rustc_deny_explicit_impl(implement_via_object = false)] +#[cfg_attr(bootstrap, rustc_deny_explicit_impl(implement_via_object = false))] +#[cfg_attr(not(bootstrap), rustc_deny_explicit_impl)] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] pub trait Pointee { /// The type for metadata in pointers and references to `Self`. #[lang = "metadata_type"] diff --git a/tests/ui/traits/deny-builtin-object-impl.current.stderr b/tests/ui/traits/deny-builtin-object-impl.current.stderr index 8423a2519b23b..d6f4762d09966 100644 --- a/tests/ui/traits/deny-builtin-object-impl.current.stderr +++ b/tests/ui/traits/deny-builtin-object-impl.current.stderr @@ -1,20 +1,44 @@ -error[E0277]: the trait bound `dyn NotObject: NotObject` is not satisfied - --> $DIR/deny-builtin-object-impl.rs:19:23 +error[E0322]: explicit impls for the `NotImplYesObject` trait are not permitted + --> $DIR/deny-builtin-object-impl.rs:20:1 | -LL | test_not_object::(); - | ^^^^^^^^^^^^^ the trait `NotObject` is not implemented for `dyn NotObject` +LL | impl NotImplYesObject for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `NotImplYesObject` not allowed + +error[E0277]: the trait bound `dyn NotImplNotObject: NotImplNotObject` is not satisfied + --> $DIR/deny-builtin-object-impl.rs:37:32 + | +LL | test_not_impl_not_object::(); + | ^^^^^^^^^^^^^^^^^^^^ the trait `NotImplNotObject` is not implemented for `dyn NotImplNotObject` + | +help: this trait has no implementations, consider adding one + --> $DIR/deny-builtin-object-impl.rs:12:1 + | +LL | trait NotImplNotObject {} + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `test_not_impl_not_object` + --> $DIR/deny-builtin-object-impl.rs:28:32 + | +LL | fn test_not_impl_not_object() {} + | ^^^^^^^^^^^^^^^^ required by this bound in `test_not_impl_not_object` + +error[E0277]: the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied + --> $DIR/deny-builtin-object-impl.rs:40:32 + | +LL | test_yes_impl_not_object::(); + | ^^^^^^^^^^^^^^^^^^^^ the trait `YesImplNotObject` is not implemented for `dyn YesImplNotObject` | help: this trait has no implementations, consider adding one - --> $DIR/deny-builtin-object-impl.rs:11:1 + --> $DIR/deny-builtin-object-impl.rs:15:1 | -LL | trait NotObject {} - | ^^^^^^^^^^^^^^^ -note: required by a bound in `test_not_object` - --> $DIR/deny-builtin-object-impl.rs:15:23 +LL | trait YesImplNotObject {} + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `test_yes_impl_not_object` + --> $DIR/deny-builtin-object-impl.rs:30:32 | -LL | fn test_not_object() {} - | ^^^^^^^^^ required by this bound in `test_not_object` +LL | fn test_yes_impl_not_object() {} + | ^^^^^^^^^^^^^^^^ required by this bound in `test_yes_impl_not_object` -error: aborting due to 1 previous error +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0322. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/deny-builtin-object-impl.next.stderr b/tests/ui/traits/deny-builtin-object-impl.next.stderr index 8423a2519b23b..d6f4762d09966 100644 --- a/tests/ui/traits/deny-builtin-object-impl.next.stderr +++ b/tests/ui/traits/deny-builtin-object-impl.next.stderr @@ -1,20 +1,44 @@ -error[E0277]: the trait bound `dyn NotObject: NotObject` is not satisfied - --> $DIR/deny-builtin-object-impl.rs:19:23 +error[E0322]: explicit impls for the `NotImplYesObject` trait are not permitted + --> $DIR/deny-builtin-object-impl.rs:20:1 | -LL | test_not_object::(); - | ^^^^^^^^^^^^^ the trait `NotObject` is not implemented for `dyn NotObject` +LL | impl NotImplYesObject for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `NotImplYesObject` not allowed + +error[E0277]: the trait bound `dyn NotImplNotObject: NotImplNotObject` is not satisfied + --> $DIR/deny-builtin-object-impl.rs:37:32 + | +LL | test_not_impl_not_object::(); + | ^^^^^^^^^^^^^^^^^^^^ the trait `NotImplNotObject` is not implemented for `dyn NotImplNotObject` + | +help: this trait has no implementations, consider adding one + --> $DIR/deny-builtin-object-impl.rs:12:1 + | +LL | trait NotImplNotObject {} + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `test_not_impl_not_object` + --> $DIR/deny-builtin-object-impl.rs:28:32 + | +LL | fn test_not_impl_not_object() {} + | ^^^^^^^^^^^^^^^^ required by this bound in `test_not_impl_not_object` + +error[E0277]: the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied + --> $DIR/deny-builtin-object-impl.rs:40:32 + | +LL | test_yes_impl_not_object::(); + | ^^^^^^^^^^^^^^^^^^^^ the trait `YesImplNotObject` is not implemented for `dyn YesImplNotObject` | help: this trait has no implementations, consider adding one - --> $DIR/deny-builtin-object-impl.rs:11:1 + --> $DIR/deny-builtin-object-impl.rs:15:1 | -LL | trait NotObject {} - | ^^^^^^^^^^^^^^^ -note: required by a bound in `test_not_object` - --> $DIR/deny-builtin-object-impl.rs:15:23 +LL | trait YesImplNotObject {} + | ^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `test_yes_impl_not_object` + --> $DIR/deny-builtin-object-impl.rs:30:32 | -LL | fn test_not_object() {} - | ^^^^^^^^^ required by this bound in `test_not_object` +LL | fn test_yes_impl_not_object() {} + | ^^^^^^^^^^^^^^^^ required by this bound in `test_yes_impl_not_object` -error: aborting due to 1 previous error +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0322. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/deny-builtin-object-impl.rs b/tests/ui/traits/deny-builtin-object-impl.rs index c16dcca8fbc27..9d02ab7bd469e 100644 --- a/tests/ui/traits/deny-builtin-object-impl.rs +++ b/tests/ui/traits/deny-builtin-object-impl.rs @@ -4,18 +4,41 @@ #![feature(rustc_attrs)] -#[rustc_deny_explicit_impl(implement_via_object = true)] -trait YesObject {} +#[rustc_deny_explicit_impl] +trait NotImplYesObject {} -#[rustc_deny_explicit_impl(implement_via_object = false)] -trait NotObject {} +#[rustc_deny_explicit_impl] +#[rustc_do_not_implement_via_object] +trait NotImplNotObject {} -fn test_yes_object() {} +#[rustc_do_not_implement_via_object] +trait YesImplNotObject {} -fn test_not_object() {} +#[rustc_do_not_implement_via_object] +trait YesImplNotObject2 {} + +impl NotImplYesObject for () {} +//~^ ERROR explicit impls for the `NotImplYesObject` trait are not permitted + +// If there is no automatic impl then we can add a manual impl: +impl YesImplNotObject2 for dyn YesImplNotObject2 {} + +fn test_not_impl_yes_object() {} + +fn test_not_impl_not_object() {} + +fn test_yes_impl_not_object() {} + +fn test_yes_impl_not_object2() {} fn main() { - test_yes_object::(); - test_not_object::(); - //~^ ERROR the trait bound `dyn NotObject: NotObject` is not satisfied + test_not_impl_yes_object::(); + + test_not_impl_not_object::(); + //~^ ERROR the trait bound `dyn NotImplNotObject: NotImplNotObject` is not satisfied + + test_yes_impl_not_object::(); + //~^ ERROR the trait bound `dyn YesImplNotObject: YesImplNotObject` is not satisfied + + test_yes_impl_not_object2::(); } From 971a4f2d3b0c44fae115b39e4fa9607a911ed59c Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 20 Dec 2024 17:35:29 +0100 Subject: [PATCH 07/10] unimplement `PointerLike` for trait objects --- library/core/src/marker.rs | 1 + tests/ui/dyn-star/dyn-pointer-like.rs | 23 +++++++++++++ tests/ui/dyn-star/dyn-pointer-like.stderr | 39 +++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 tests/ui/dyn-star/dyn-pointer-like.rs create mode 100644 tests/ui/dyn-star/dyn-pointer-like.stderr diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 31b27b7ef2641..bdfa162919f21 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -990,6 +990,7 @@ pub trait Tuple {} message = "`{Self}` needs to have the same ABI as a pointer", label = "`{Self}` needs to be a pointer-like type" )] +#[cfg_attr(not(bootstrap), rustc_do_not_implement_via_object)] pub trait PointerLike {} #[cfg(not(bootstrap))] diff --git a/tests/ui/dyn-star/dyn-pointer-like.rs b/tests/ui/dyn-star/dyn-pointer-like.rs new file mode 100644 index 0000000000000..f26fa90505cf7 --- /dev/null +++ b/tests/ui/dyn-star/dyn-pointer-like.rs @@ -0,0 +1,23 @@ +// Test that `dyn PointerLike` and `dyn* PointerLike` do not implement `PointerLike`. +// This used to ICE during codegen. + +#![crate_type = "lib"] + +#![feature(pointer_like_trait, dyn_star)] +#![feature(unsized_fn_params)] +#![expect(incomplete_features)] +#![expect(internal_features)] + +use std::marker::PointerLike; + +pub fn lol(x: dyn* PointerLike) { + foo(x); //~ ERROR `dyn* PointerLike` needs to have the same ABI as a pointer +} + +pub fn uwu(x: dyn PointerLike) { + foo(x); //~ ERROR `dyn PointerLike` needs to have the same ABI as a pointer +} + +fn foo(x: T) { + let _: dyn* PointerLike = x; +} diff --git a/tests/ui/dyn-star/dyn-pointer-like.stderr b/tests/ui/dyn-star/dyn-pointer-like.stderr new file mode 100644 index 0000000000000..4c558e92d3f91 --- /dev/null +++ b/tests/ui/dyn-star/dyn-pointer-like.stderr @@ -0,0 +1,39 @@ +error[E0277]: `dyn* PointerLike` needs to have the same ABI as a pointer + --> $DIR/dyn-pointer-like.rs:14:9 + | +LL | foo(x); + | --- ^ the trait `PointerLike` is not implemented for `dyn* PointerLike` + | | + | required by a bound introduced by this call + | + = note: the trait bound `dyn* PointerLike: PointerLike` is not satisfied +note: required by a bound in `foo` + --> $DIR/dyn-pointer-like.rs:21:11 + | +LL | fn foo(x: T) { + | ^^^^^^^^^^^ required by this bound in `foo` +help: consider borrowing here + | +LL | foo(&x); + | + +LL | foo(&mut x); + | ++++ + +error[E0277]: `dyn PointerLike` needs to have the same ABI as a pointer + --> $DIR/dyn-pointer-like.rs:18:9 + | +LL | foo(x); + | --- ^ `dyn PointerLike` needs to be a pointer-like type + | | + | required by a bound introduced by this call + | + = help: the trait `PointerLike` is not implemented for `dyn PointerLike` +note: required by a bound in `foo` + --> $DIR/dyn-pointer-like.rs:21:11 + | +LL | fn foo(x: T) { + | ^^^^^^^^^^^ required by this bound in `foo` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. From 159dba89efa23c36eca92f1b63176314c357d2a4 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Fri, 20 Dec 2024 17:37:34 +0100 Subject: [PATCH 08/10] fix `PointerLike` docs --- library/core/src/marker.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index bdfa162919f21..3d79706f8ecf9 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -982,8 +982,8 @@ pub trait Tuple {} /// A marker for pointer-like types. /// -/// All types that have the same size and alignment as a `usize` or -/// `*const ()` automatically implement this trait. +/// This trait can only be implemented for types that have the same size and alignment +/// as a `usize` or `*const ()`. #[unstable(feature = "pointer_like_trait", issue = "none")] #[lang = "pointer_like"] #[diagnostic::on_unimplemented( From 496adcf36cbbba53f7f6ca04110924967b33baac Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Fri, 20 Dec 2024 18:20:40 +0100 Subject: [PATCH 09/10] remove reference to dangling from slice::Iter This aligns the comment with reality and with IterMut. Also dangling does not seem to take any arguments. --- library/core/src/slice/iter.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index c5746157d01b2..a27baf9db224c 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -68,7 +68,7 @@ pub struct Iter<'a, T: 'a> { ptr: NonNull, /// For non-ZSTs, the non-null pointer to the past-the-end element. /// - /// For ZSTs, this is `ptr::dangling(len)`. + /// For ZSTs, this is `ptr::without_provenance_mut(len)`. end_or_len: *const T, _marker: PhantomData<&'a T>, } From 6bc1fe1c3a40367abf3d54253fb1a478ced4b73b Mon Sep 17 00:00:00 2001 From: lcnr Date: Fri, 20 Dec 2024 18:35:31 +0100 Subject: [PATCH 10/10] next-solver: rm opaque type hack --- .../rustc_borrowck/src/region_infer/opaque_types.rs | 13 +++++++------ compiler/rustc_hir_typeck/src/writeback.rs | 12 +++++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 7164a129235f0..3e16a3ca157d2 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -134,12 +134,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { // the hidden type becomes the opaque type itself. In this case, this was an opaque // usage of the opaque type and we can ignore it. This check is mirrored in typeck's // writeback. - // FIXME(-Znext-solver): This should be unnecessary with the new solver. - if let ty::Alias(ty::Opaque, alias_ty) = ty.kind() - && alias_ty.def_id == opaque_type_key.def_id.to_def_id() - && alias_ty.args == opaque_type_key.args - { - continue; + if !infcx.next_trait_solver() { + if let ty::Alias(ty::Opaque, alias_ty) = ty.kind() + && alias_ty.def_id == opaque_type_key.def_id.to_def_id() + && alias_ty.args == opaque_type_key.args + { + continue; + } } // Sometimes two opaque types are the same only after we remap the generic parameters // back to the opaque type definition. E.g. we may have `OpaqueType` mapped to diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 303a07a5bf0cf..5612aa75aae44 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -554,11 +554,13 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { let hidden_type = self.resolve(decl.hidden_type, &decl.hidden_type.span); let opaque_type_key = self.resolve(opaque_type_key, &decl.hidden_type.span); - if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind() - && alias_ty.def_id == opaque_type_key.def_id.to_def_id() - && alias_ty.args == opaque_type_key.args - { - continue; + if !self.fcx.next_trait_solver() { + if let ty::Alias(ty::Opaque, alias_ty) = hidden_type.ty.kind() + && alias_ty.def_id == opaque_type_key.def_id.to_def_id() + && alias_ty.args == opaque_type_key.args + { + continue; + } } // Here we only detect impl trait definition conflicts when they