From 1ea6cd715e01f14395ee3f7d944ecc68adf0dde4 Mon Sep 17 00:00:00 2001 From: ltdk Date: Sat, 19 Aug 2023 18:46:11 -0400 Subject: [PATCH 01/15] Add std::ffi::c_str modules --- library/alloc/src/ffi/c_str.rs | 2 ++ library/alloc/src/ffi/mod.rs | 10 +++++++--- library/core/src/ffi/c_str.rs | 17 ++++++++++++----- library/core/src/ffi/mod.rs | 14 ++++++++++++-- library/std/src/ffi/c_str.rs | 19 +++++++++++++++++++ library/std/src/ffi/mod.rs | 32 ++++++++++++++++++++++++++------ library/std/src/lib.rs | 1 + 7 files changed, 79 insertions(+), 16 deletions(-) create mode 100644 library/std/src/ffi/c_str.rs diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index 9419b0cfb24fa..35d1f681af605 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -1,3 +1,5 @@ +//! [`CString`] and its related types. + #[cfg(test)] mod tests; diff --git a/library/alloc/src/ffi/mod.rs b/library/alloc/src/ffi/mod.rs index e8530fbc1f08f..9fc1acc231bff 100644 --- a/library/alloc/src/ffi/mod.rs +++ b/library/alloc/src/ffi/mod.rs @@ -80,9 +80,13 @@ #![stable(feature = "alloc_ffi", since = "1.64.0")] +#[doc(no_inline)] #[stable(feature = "alloc_c_string", since = "1.64.0")] -pub use self::c_str::FromVecWithNulError; +pub use self::c_str::{FromVecWithNulError, IntoStringError, NulError}; + +#[doc(inline)] #[stable(feature = "alloc_c_string", since = "1.64.0")] -pub use self::c_str::{CString, IntoStringError, NulError}; +pub use self::c_str::CString; -mod c_str; +#[unstable(feature = "c_str_module", issue = "112134")] +pub mod c_str; diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index 248943cf02260..cf1427b21bc74 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -1,3 +1,5 @@ +//! [`CStr`] and its related types. + use crate::cmp::Ordering; use crate::error::Error; use crate::ffi::c_char; @@ -8,15 +10,20 @@ use crate::slice; use crate::slice::memchr; use crate::str; +// FIXME: because this is doc(inline)d, we *have* to use intra-doc links because the actual link +// depends on where the item is being documented. however, since this is libcore, we can't +// actually reference libstd or liballoc in intra-doc links. so, the best we can do is remove the +// links to `CString` and `String` for now until a solution is developed + /// Representation of a borrowed C string. /// /// This type represents a borrowed reference to a nul-terminated /// array of bytes. It can be constructed safely from a &[[u8]] /// slice, or unsafely from a raw `*const c_char`. It can then be /// converted to a Rust &[str] by performing UTF-8 validation, or -/// into an owned [`CString`]. +/// into an owned `CString`. /// -/// `&CStr` is to [`CString`] as &[str] is to [`String`]: the former +/// `&CStr` is to `CString` as &[str] is to `String`: the former /// in each pair are borrowed references; the latter are owned /// strings. /// @@ -25,9 +32,6 @@ use crate::str; /// Instead, safe wrappers of FFI functions may leverage the unsafe [`CStr::from_ptr`] constructor /// to provide a safe interface to other consumers. /// -/// [`CString`]: ../../std/ffi/struct.CString.html -/// [`String`]: ../../std/string/struct.String.html -/// /// # Examples /// /// Inspecting a foreign C string: @@ -124,10 +128,13 @@ enum FromBytesWithNulErrorKind { NotNulTerminated, } +// FIXME: const stability attributes should not be required here, I think impl FromBytesWithNulError { + #[rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0")] const fn interior_nul(pos: usize) -> FromBytesWithNulError { FromBytesWithNulError { kind: FromBytesWithNulErrorKind::InteriorNul(pos) } } + #[rustc_const_stable(feature = "const_cstr_methods", since = "1.72.0")] const fn not_nul_terminated() -> FromBytesWithNulError { FromBytesWithNulError { kind: FromBytesWithNulErrorKind::NotNulTerminated } } diff --git a/library/core/src/ffi/mod.rs b/library/core/src/ffi/mod.rs index 44200926a32eb..3627e844222ac 100644 --- a/library/core/src/ffi/mod.rs +++ b/library/core/src/ffi/mod.rs @@ -13,10 +13,20 @@ use crate::fmt; use crate::marker::PhantomData; use crate::ops::{Deref, DerefMut}; +#[doc(no_inline)] #[stable(feature = "core_c_str", since = "1.64.0")] -pub use self::c_str::{CStr, FromBytesUntilNulError, FromBytesWithNulError}; +pub use self::c_str::FromBytesWithNulError; -mod c_str; +#[doc(no_inline)] +#[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] +pub use self::c_str::FromBytesUntilNulError; + +#[doc(inline)] +#[stable(feature = "core_c_str", since = "1.64.0")] +pub use self::c_str::CStr; + +#[unstable(feature = "c_str_module", issue = "112134")] +pub mod c_str; macro_rules! type_alias { { diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs new file mode 100644 index 0000000000000..b59b0c5bba65a --- /dev/null +++ b/library/std/src/ffi/c_str.rs @@ -0,0 +1,19 @@ +//! [`CStr`], [`CString`], and related types. + +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::ffi::c_str::CStr; + +#[stable(feature = "cstr_from_bytes", since = "1.10.0")] +pub use core::ffi::c_str::FromBytesWithNulError; + +#[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] +pub use core::ffi::c_str::FromBytesUntilNulError; + +#[stable(feature = "rust1", since = "1.0.0")] +pub use alloc::ffi::c_str::{CString, NulError}; + +#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] +pub use alloc::ffi::c_str::FromVecWithNulError; + +#[stable(feature = "cstring_into", since = "1.7.0")] +pub use alloc::ffi::c_str::IntoStringError; diff --git a/library/std/src/ffi/mod.rs b/library/std/src/ffi/mod.rs index 818571ddaaa16..a14a3fe760da0 100644 --- a/library/std/src/ffi/mod.rs +++ b/library/std/src/ffi/mod.rs @@ -161,12 +161,32 @@ #![stable(feature = "rust1", since = "1.0.0")] -#[stable(feature = "alloc_c_string", since = "1.64.0")] -pub use alloc::ffi::{CString, FromVecWithNulError, IntoStringError, NulError}; -#[stable(feature = "cstr_from_bytes_until_nul", since = "1.73.0")] -pub use core::ffi::FromBytesUntilNulError; -#[stable(feature = "core_c_str", since = "1.64.0")] -pub use core::ffi::{CStr, FromBytesWithNulError}; +#[unstable(feature = "c_str_module", issue = "112134")] +pub mod c_str; + +#[doc(inline)] +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::c_str::{CStr, CString}; + +#[doc(no_inline)] +#[stable(feature = "cstr_from_bytes", since = "1.10.0")] +pub use self::c_str::FromBytesWithNulError; + +#[doc(no_inline)] +#[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")] +pub use self::c_str::FromBytesUntilNulError; + +#[doc(no_inline)] +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::c_str::NulError; + +#[doc(no_inline)] +#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] +pub use self::c_str::FromVecWithNulError; + +#[doc(no_inline)] +#[stable(feature = "cstring_into", since = "1.7.0")] +pub use self::c_str::IntoStringError; #[stable(feature = "rust1", since = "1.0.0")] pub use self::os_str::{OsStr, OsString}; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index c6cd2c6786ad6..87d9a0c9185e8 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -314,6 +314,7 @@ // // Library features (core): // tidy-alphabetical-start +#![feature(c_str_module)] #![feature(char_internals)] #![feature(core_intrinsics)] #![feature(core_io_borrowed_buf)] From 05a6f65d81978fa9db4fec8c6a54bd894c9eb74d Mon Sep 17 00:00:00 2001 From: Tim Neumann Date: Fri, 16 Feb 2024 09:32:55 +0100 Subject: [PATCH 02/15] Update a test to support Symbol Mangling V0 --- tests/codegen/debuginfo-inline-callsite-location.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/codegen/debuginfo-inline-callsite-location.rs b/tests/codegen/debuginfo-inline-callsite-location.rs index 833e8c0df912c..f690c9c0937ff 100644 --- a/tests/codegen/debuginfo-inline-callsite-location.rs +++ b/tests/codegen/debuginfo-inline-callsite-location.rs @@ -4,9 +4,9 @@ // can correctly merge the debug info if it merges the inlined code (e.g., for merging of tail // calls to panic. -// CHECK: tail call void @_ZN4core6option13unwrap_failed17h{{([0-9a-z]{16})}}E +// CHECK: tail call void @{{[A-Za-z0-9_]+4core6option13unwrap_failed}} // CHECK-SAME: !dbg ![[#first_dbg:]] -// CHECK: tail call void @_ZN4core6option13unwrap_failed17h{{([0-9a-z]{16})}}E +// CHECK: tail call void @{{[A-Za-z0-9_]+4core6option13unwrap_failed}} // CHECK-SAME: !dbg ![[#second_dbg:]] // CHECK-DAG: ![[#func_dbg:]] = distinct !DISubprogram(name: "unwrap" From 70639c8a6a45f52cd875d90bf847f6a81f680b83 Mon Sep 17 00:00:00 2001 From: Raoul Strackx Date: Tue, 27 Feb 2024 16:29:10 +0100 Subject: [PATCH 03/15] Fixing shellcheck comments on lvi test script --- .../x86_64-fortanix-unknown-sgx-lvi/script.sh | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh index 04a34724518e8..aacd0a67682b9 100644 --- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh +++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/script.sh @@ -1,20 +1,20 @@ -#!/bin/sh +#!/bin/bash set -exuo pipefail function build { CRATE=enclave - mkdir -p $WORK_DIR - pushd $WORK_DIR - rm -rf $CRATE - cp -a $TEST_DIR/enclave . + mkdir -p "${WORK_DIR}" + pushd "${WORK_DIR}" + rm -rf "${CRATE}" + cp -a "${TEST_DIR}"/enclave . pushd $CRATE - echo ${WORK_DIR} + echo "${WORK_DIR}" # HACK(eddyb) sets `RUSTC_BOOTSTRAP=1` so Cargo can accept nightly features. # These come from the top-level Rust workspace, that this crate is not a # member of, but Cargo tries to load the workspace `Cargo.toml` anyway. env RUSTC_BOOTSTRAP=1 - cargo -v run --target $TARGET + cargo -v run --target "${TARGET}" popd popd } @@ -22,17 +22,18 @@ function build { function check { local func_re="$1" local checks="${TEST_DIR}/$2" - local asm=$(mktemp) + local asm="" local objdump="${LLVM_BIN_DIR}/llvm-objdump" local filecheck="${LLVM_BIN_DIR}/FileCheck" local enclave=${WORK_DIR}/enclave/target/x86_64-fortanix-unknown-sgx/debug/enclave - func="$(${objdump} --syms --demangle ${enclave} | \ + asm=$(mktemp) + func="$(${objdump} --syms --demangle "${enclave}" | \ grep --only-matching -E "[[:blank:]]+${func_re}\$" | \ sed -e 's/^[[:space:]]*//' )" ${objdump} --disassemble-symbols="${func}" --demangle \ - ${enclave} > ${asm} - ${filecheck} --input-file ${asm} ${checks} + "${enclave}" > "${asm}" + ${filecheck} --input-file "${asm}" "${checks}" if [ "${func_re}" != "rust_plus_one_global_asm" && "${func_re}" != "cmake_plus_one_c_global_asm" ]; then @@ -40,7 +41,7 @@ function check { # of `shlq $0x0, (%rsp); lfence; retq` are used instead. # https://www.intel.com/content/www/us/en/developer/articles/technical/ # software-security-guidance/technical-documentation/load-value-injection.html - ${filecheck} --implicit-check-not ret --input-file ${asm} ${checks} + ${filecheck} --implicit-check-not ret --input-file "${asm}" "${checks}" fi } From 3e675bdb481820360c1105b2731f9258e1081b0d Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 29 Feb 2024 21:38:53 +0800 Subject: [PATCH 04/15] add myself to rotation --- triagebot.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/triagebot.toml b/triagebot.toml index ef3f3693e6174..de91cc8af824f 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -660,6 +660,7 @@ compiler-team-contributors = [ "@TaKO8Ki", "@nnethercote", "@fmease", + "@fee1-dead", ] compiler = [ "compiler-team", From f030d49536cf821a062ecc48497e027f7dbf2767 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 23 Feb 2024 11:53:25 +0000 Subject: [PATCH 05/15] Expose `Freeze` trait again --- library/core/src/marker.rs | 10 ++++++++-- .../auto-trait-bounds-by-associated-type-50159.rs | 9 ++++++--- tests/rustdoc/empty-section.rs | 4 ++-- tests/rustdoc/synthetic_auto/basic.rs | 2 +- tests/rustdoc/synthetic_auto/manual.rs | 2 +- tests/ui/associated-consts/freeze.rs | 12 ++++++++++++ 6 files changed, 30 insertions(+), 9 deletions(-) create mode 100644 tests/ui/associated-consts/freeze.rs diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 2e22129d7b64d..c5cacd12f7014 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -810,15 +810,21 @@ pub trait DiscriminantKind { type Discriminant: Clone + Copy + Debug + Eq + PartialEq + Hash + Send + Sync + Unpin; } -/// Compiler-internal trait used to determine whether a type contains +/// Used to determine whether a type contains /// any `UnsafeCell` internally, but not through an indirection. /// This affects, for example, whether a `static` of that type is /// placed in read-only static memory or writable static memory. +/// This can be used to declare that a constant with a generic type +/// will not contain interior mutability, and subsequently allow +/// placing the constant behind references. #[lang = "freeze"] -pub(crate) unsafe auto trait Freeze {} +#[unstable(feature = "freeze", issue = "60715")] +pub unsafe auto trait Freeze {} +#[unstable(feature = "freeze", issue = "60715")] impl !Freeze for UnsafeCell {} marker_impls! { + #[unstable(feature = "freeze", issue = "60715")] unsafe Freeze for {T: ?Sized} PhantomData, {T: ?Sized} *const T, diff --git a/tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs b/tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs index 0663ed5fc81ff..7d9133b85a613 100644 --- a/tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs +++ b/tests/rustdoc/auto-trait-bounds-by-associated-type-50159.rs @@ -1,5 +1,5 @@ // https://github.com/rust-lang/rust/issues/50159 -#![crate_name="foo"] +#![crate_name = "foo"] pub trait Signal { type Item; @@ -9,7 +9,10 @@ pub trait Signal2 { type Item2; } -impl Signal2 for B where B: Signal { +impl Signal2 for B +where + B: Signal, +{ type Item2 = C; } @@ -17,7 +20,7 @@ impl Signal2 for B where B: Signal { // @has - '//h3[@class="code-header"]' 'impl Send for Switchwhere ::Item: Send' // @has - '//h3[@class="code-header"]' 'impl Sync for Switchwhere ::Item: Sync' // @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0 -// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5 +// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 6 pub struct Switch { pub inner: ::Item2, } diff --git a/tests/rustdoc/empty-section.rs b/tests/rustdoc/empty-section.rs index d8241ab96f6dd..0d6afb0e44447 100644 --- a/tests/rustdoc/empty-section.rs +++ b/tests/rustdoc/empty-section.rs @@ -1,6 +1,5 @@ #![crate_name = "foo"] - -#![feature(negative_impls)] +#![feature(negative_impls, freeze_impls, freeze)] pub struct Foo; @@ -8,6 +7,7 @@ pub struct Foo; // @!hasraw - 'Auto Trait Implementations' impl !Send for Foo {} impl !Sync for Foo {} +impl !std::marker::Freeze for Foo {} impl !std::marker::Unpin for Foo {} impl !std::panic::RefUnwindSafe for Foo {} impl !std::panic::UnwindSafe for Foo {} diff --git a/tests/rustdoc/synthetic_auto/basic.rs b/tests/rustdoc/synthetic_auto/basic.rs index 043ac24148838..16b8cce490c84 100644 --- a/tests/rustdoc/synthetic_auto/basic.rs +++ b/tests/rustdoc/synthetic_auto/basic.rs @@ -2,7 +2,7 @@ // @has - '//h3[@class="code-header"]' 'impl Send for Foowhere T: Send' // @has - '//h3[@class="code-header"]' 'impl Sync for Foowhere T: Sync' // @count - '//*[@id="implementations-list"]//*[@class="impl"]' 0 -// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5 +// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 6 pub struct Foo { field: T, } diff --git a/tests/rustdoc/synthetic_auto/manual.rs b/tests/rustdoc/synthetic_auto/manual.rs index 7fc8447df3efc..692d68294a7ef 100644 --- a/tests/rustdoc/synthetic_auto/manual.rs +++ b/tests/rustdoc/synthetic_auto/manual.rs @@ -6,7 +6,7 @@ // 'impl Send for Foo' // // @count - '//*[@id="trait-implementations-list"]//*[@class="impl"]' 1 -// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 4 +// @count - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]' 5 pub struct Foo { field: T, } diff --git a/tests/ui/associated-consts/freeze.rs b/tests/ui/associated-consts/freeze.rs new file mode 100644 index 0000000000000..2364ee1f4956f --- /dev/null +++ b/tests/ui/associated-consts/freeze.rs @@ -0,0 +1,12 @@ +#![feature(freeze)] + +//@ check-pass + +use std::marker::Freeze; + +trait Trait { + const VALUE: T; + const VALUE_REF: &'static T = &Self::VALUE; +} + +fn main() {} From 78492307406520214f24ce2519f3891f0048bf8e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 23 Feb 2024 12:11:11 +0000 Subject: [PATCH 06/15] Forbid implementing `Freeze` even if the trait is stabilized --- .../example/mini_core.rs | 1 + .../rustc_codegen_gcc/example/mini_core.rs | 2 +- compiler/rustc_feature/src/unstable.rs | 2 ++ .../rustc_hir_analysis/src/coherence/mod.rs | 14 +++++++++++ compiler/rustc_span/src/symbol.rs | 1 + library/core/src/lib.rs | 1 + library/core/src/marker.rs | 6 ++--- .../min-global-align/min_global_align.rs | 2 +- .../feature-gate-freeze-impls.rs | 15 ++++++++++++ .../feature-gate-freeze-impls.stderr | 23 +++++++++++++++++++ 10 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-freeze-impls.rs create mode 100644 tests/ui/feature-gates/feature-gate-freeze-impls.stderr diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs index a79909ce0c878..47db7ee369186 100644 --- a/compiler/rustc_codegen_cranelift/example/mini_core.rs +++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs @@ -8,6 +8,7 @@ rustc_attrs, transparent_unions, auto_traits, + freeze_impls, thread_local )] #![no_core] diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs index 230009741dc41..1f364f78ece76 100644 --- a/compiler/rustc_codegen_gcc/example/mini_core.rs +++ b/compiler/rustc_codegen_gcc/example/mini_core.rs @@ -1,6 +1,6 @@ #![feature( no_core, lang_items, intrinsics, unboxed_closures, type_ascription, extern_types, - decl_macro, rustc_attrs, transparent_unions, auto_traits, + decl_macro, rustc_attrs, transparent_unions, auto_traits, freeze_impls, thread_local )] #![no_core] diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index 53254d567ccf2..db192ae9a3519 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -469,6 +469,8 @@ declare_features! ( (unstable, fn_align, "1.53.0", Some(82232)), /// Support delegating implementation of functions to other already implemented functions. (incomplete, fn_delegation, "1.76.0", Some(118212)), + /// Allows impls for the Freeze trait. + (internal, freeze_impls, "CURRENT_RUSTC_VERSION", Some(121675)), /// Allows defining gen blocks and `gen fn`. (unstable, gen_blocks, "1.75.0", Some(117078)), /// Infer generic args for both consts and types. diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index d6281fa08f745..52acc10b9fe7f 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -10,6 +10,7 @@ use rustc_errors::{codes::*, struct_span_code_err}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::query::Providers; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; +use rustc_session::parse::feature_err; use rustc_span::{sym, ErrorGuaranteed}; use rustc_trait_selection::traits; @@ -49,6 +50,19 @@ fn enforce_trait_manually_implementable( ) -> Result<(), ErrorGuaranteed> { let impl_header_span = tcx.def_span(impl_def_id); + if tcx.lang_items().freeze_trait() == Some(trait_def_id) { + if !tcx.features().freeze_impls { + feature_err( + &tcx.sess, + sym::freeze_impls, + impl_header_span, + "explicit impls for the `Freeze` trait are not permitted", + ) + .with_span_label(impl_header_span, format!("impl of `Freeze` not allowed")) + .emit(); + } + } + // Disallow *all* explicit impls of traits marked `#[rustc_deny_explicit_impl]` if trait_def.deny_explicit_impl { let trait_name = tcx.item_name(trait_def_id); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4d8475bef54c8..f52f187973fa0 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -841,6 +841,7 @@ symbols! { format_placeholder, format_unsafe_arg, freeze, + freeze_impls, freg, frem_algebraic, frem_fast, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 7b735d48bdfce..6ea7fda15389d 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -203,6 +203,7 @@ // Language features: // tidy-alphabetical-start #![cfg_attr(bootstrap, feature(platform_intrinsics))] +#![cfg_attr(not(bootstrap), feature(freeze_impls))] #![feature(abi_unadjusted)] #![feature(adt_const_params)] #![feature(allow_internal_unsafe)] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index c5cacd12f7014..a56a2578c2241 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -818,13 +818,13 @@ pub trait DiscriminantKind { /// will not contain interior mutability, and subsequently allow /// placing the constant behind references. #[lang = "freeze"] -#[unstable(feature = "freeze", issue = "60715")] +#[unstable(feature = "freeze", issue = "121675")] pub unsafe auto trait Freeze {} -#[unstable(feature = "freeze", issue = "60715")] +#[unstable(feature = "freeze", issue = "121675")] impl !Freeze for UnsafeCell {} marker_impls! { - #[unstable(feature = "freeze", issue = "60715")] + #[unstable(feature = "freeze", issue = "121675")] unsafe Freeze for {T: ?Sized} PhantomData, {T: ?Sized} *const T, diff --git a/tests/run-make/min-global-align/min_global_align.rs b/tests/run-make/min-global-align/min_global_align.rs index 135792e937205..cd1ef8cb351ff 100644 --- a/tests/run-make/min-global-align/min_global_align.rs +++ b/tests/run-make/min-global-align/min_global_align.rs @@ -1,4 +1,4 @@ -#![feature(no_core, lang_items)] +#![feature(no_core, lang_items, freeze_impls)] #![crate_type = "rlib"] #![no_core] diff --git a/tests/ui/feature-gates/feature-gate-freeze-impls.rs b/tests/ui/feature-gates/feature-gate-freeze-impls.rs new file mode 100644 index 0000000000000..c14c9494874a2 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-freeze-impls.rs @@ -0,0 +1,15 @@ +#![feature(freeze, negative_impls)] + +use std::marker::Freeze; + +struct Foo; + +unsafe impl Freeze for Foo {} +//~^ explicit impls for the `Freeze` trait are not permitted + +struct Bar; + +impl !Freeze for Bar {} +//~^ explicit impls for the `Freeze` trait are not permitted + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-freeze-impls.stderr b/tests/ui/feature-gates/feature-gate-freeze-impls.stderr new file mode 100644 index 0000000000000..eef524fe78e8b --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-freeze-impls.stderr @@ -0,0 +1,23 @@ +error[E0658]: explicit impls for the `Freeze` trait are not permitted + --> $DIR/feature-gate-freeze-impls.rs:7:1 + | +LL | unsafe impl Freeze for Foo {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ impl of `Freeze` not allowed + | + = note: see issue #121675 for more information + = help: add `#![feature(freeze_impls)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error[E0658]: explicit impls for the `Freeze` trait are not permitted + --> $DIR/feature-gate-freeze-impls.rs:12:1 + | +LL | impl !Freeze for Bar {} + | ^^^^^^^^^^^^^^^^^^^^ impl of `Freeze` not allowed + | + = note: see issue #121675 for more information + = help: add `#![feature(freeze_impls)]` to the crate attributes to enable + = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. From c3954b358f9e2be96d0dd553a8efaefc49f0bba7 Mon Sep 17 00:00:00 2001 From: r0cky Date: Sun, 3 Mar 2024 00:57:37 +0800 Subject: [PATCH 07/15] Add a tidy check that checks whether the fluent slugs only appear once --- src/tools/tidy/src/fluent_alphabetical.rs | 58 ++++++++++++++++++++--- src/tools/tidy/src/fluent_used.rs | 43 +++++++++++++++++ src/tools/tidy/src/lib.rs | 1 + 3 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 src/tools/tidy/src/fluent_used.rs diff --git a/src/tools/tidy/src/fluent_alphabetical.rs b/src/tools/tidy/src/fluent_alphabetical.rs index 67b745373f019..9803b6eab2db5 100644 --- a/src/tools/tidy/src/fluent_alphabetical.rs +++ b/src/tools/tidy/src/fluent_alphabetical.rs @@ -1,6 +1,7 @@ //! Checks that all Flunt files have messages in alphabetical order use crate::walk::{filter_dirs, walk}; +use std::collections::HashMap; use std::{fs::OpenOptions, io::Write, path::Path}; use regex::Regex; @@ -13,11 +14,27 @@ fn filter_fluent(path: &Path) -> bool { if let Some(ext) = path.extension() { ext.to_str() != Some("ftl") } else { true } } -fn check_alphabetic(filename: &str, fluent: &str, bad: &mut bool) { +fn check_alphabetic( + filename: &str, + fluent: &str, + bad: &mut bool, + all_defined_msgs: &mut HashMap, +) { let mut matches = MESSAGE.captures_iter(fluent).peekable(); while let Some(m) = matches.next() { + let name = m.get(1).unwrap(); + if let Some(defined_filename) = all_defined_msgs.get(name.as_str()) { + tidy_error!( + bad, + "{filename}: message `{}` is already defined in {}", + name.as_str(), + defined_filename, + ); + } + + all_defined_msgs.insert(name.as_str().to_owned(), filename.to_owned()); + if let Some(next) = matches.peek() { - let name = m.get(1).unwrap(); let next = next.get(1).unwrap(); if name.as_str() > next.as_str() { tidy_error!( @@ -34,13 +51,29 @@ run `./x.py test tidy --bless` to sort the file correctly", } } -fn sort_messages(fluent: &str) -> String { +fn sort_messages( + filename: &str, + fluent: &str, + bad: &mut bool, + all_defined_msgs: &mut HashMap, +) -> String { let mut chunks = vec![]; let mut cur = String::new(); for line in fluent.lines() { - if MESSAGE.is_match(line) { + if let Some(name) = MESSAGE.find(line) { + if let Some(defined_filename) = all_defined_msgs.get(name.as_str()) { + tidy_error!( + bad, + "{filename}: message `{}` is already defined in {}", + name.as_str(), + defined_filename, + ); + } + + all_defined_msgs.insert(name.as_str().to_owned(), filename.to_owned()); chunks.push(std::mem::take(&mut cur)); } + cur += line; cur.push('\n'); } @@ -53,20 +86,33 @@ fn sort_messages(fluent: &str) -> String { } pub fn check(path: &Path, bless: bool, bad: &mut bool) { + let mut all_defined_msgs = HashMap::new(); walk( path, |path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)), &mut |ent, contents| { if bless { - let sorted = sort_messages(contents); + let sorted = sort_messages( + ent.path().to_str().unwrap(), + contents, + bad, + &mut all_defined_msgs, + ); if sorted != contents { let mut f = OpenOptions::new().write(true).truncate(true).open(ent.path()).unwrap(); f.write(sorted.as_bytes()).unwrap(); } } else { - check_alphabetic(ent.path().to_str().unwrap(), contents, bad); + check_alphabetic( + ent.path().to_str().unwrap(), + contents, + bad, + &mut all_defined_msgs, + ); } }, ); + + crate::fluent_used::check(path, all_defined_msgs, bad); } diff --git a/src/tools/tidy/src/fluent_used.rs b/src/tools/tidy/src/fluent_used.rs new file mode 100644 index 0000000000000..b73e79cb38d94 --- /dev/null +++ b/src/tools/tidy/src/fluent_used.rs @@ -0,0 +1,43 @@ +//! Checks that all Fluent messages appear at least twice + +use crate::walk::{filter_dirs, walk}; +use regex::Regex; +use std::collections::HashMap; +use std::path::Path; + +lazy_static::lazy_static! { + static ref WORD: Regex = Regex::new(r"\w+").unwrap(); +} + +fn filter_used_messages( + contents: &str, + msgs_not_appeared_yet: &mut HashMap, + msgs_appeared_only_once: &mut HashMap, +) { + // we don't just check messages never appear in Rust files, + // because messages can be used as parts of other fluent messages in Fluent files, + // so we do checking messages appear only once in all Rust and Fluent files. + let mut matches = WORD.find_iter(contents); + while let Some(name) = matches.next() { + if let Some((name, filename)) = msgs_not_appeared_yet.remove_entry(name.as_str()) { + // if one msg appears for the first time, + // remove it from `msgs_not_appeared_yet` and insert it into `msgs_appeared_only_once`. + msgs_appeared_only_once.insert(name, filename); + } else { + // if one msg appears for the second time, + // remove it from `msgs_appeared_only_once`. + msgs_appeared_only_once.remove(name.as_str()); + } + } +} + +pub fn check(path: &Path, mut all_defined_msgs: HashMap, bad: &mut bool) { + let mut msgs_appear_only_once = HashMap::new(); + walk(path, |path, _| filter_dirs(path), &mut |_, contents| { + filter_used_messages(contents, &mut all_defined_msgs, &mut msgs_appear_only_once); + }); + + for (name, filename) in msgs_appear_only_once { + tidy_error!(bad, "{filename}: message `{}` is not used", name,); + } +} diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 6f3ade0ab58c7..670b7eb2be995 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -65,6 +65,7 @@ pub mod ext_tool_checks; pub mod extdeps; pub mod features; pub mod fluent_alphabetical; +mod fluent_used; pub(crate) mod iter_header; pub mod mir_opt_tests; pub mod pal; From d88c7ffc62d0f1ee15abf3e9e65af3eeedc7d003 Mon Sep 17 00:00:00 2001 From: r0cky Date: Sun, 3 Mar 2024 00:57:45 +0800 Subject: [PATCH 08/15] Remove unused fluent messages --- compiler/rustc_const_eval/messages.ftl | 3 --- compiler/rustc_infer/messages.ftl | 8 -------- compiler/rustc_lint/messages.ftl | 2 -- compiler/rustc_parse/messages.ftl | 4 ---- compiler/rustc_passes/messages.ftl | 5 ----- 5 files changed, 22 deletions(-) diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 2805ca360ad3d..1bad62c4103a3 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -146,9 +146,6 @@ const_eval_intern_kind = {$kind -> *[other] {""} } -const_eval_invalid_align = - align has to be a power of 2 - const_eval_invalid_align_details = invalid align passed to `{$name}`: {$align} is {$err_kind -> [not_power_of_two] not a power of 2 diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl index 2de87cbe631ac..e44a6ae3b3f2e 100644 --- a/compiler/rustc_infer/messages.ftl +++ b/compiler/rustc_infer/messages.ftl @@ -181,14 +181,6 @@ infer_more_targeted = {$has_param_name -> infer_msl_introduces_static = introduces a `'static` lifetime requirement infer_msl_unmet_req = because this has an unmet lifetime requirement -infer_need_type_info_in_coroutine = - type inside {$coroutine_kind -> - [async_block] `async` block - [async_closure] `async` closure - [async_fn] `async fn` body - *[coroutine] coroutine - } must be known in this context - infer_nothing = {""} diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 63e2fe47659db..8bf9d0b9d4aac 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -562,8 +562,6 @@ lint_suspicious_double_ref_clone = lint_suspicious_double_ref_deref = using `.deref()` on a double reference, which returns `{$ty}` instead of dereferencing the inner type -lint_trivial_untranslatable_diag = diagnostic with static strings only - lint_ty_qualified = usage of qualified `ty::{$ty}` .suggestion = try importing it and using it unqualified diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 60cc138fd7bc2..a100e2d47bbbb 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -392,9 +392,6 @@ parse_invalid_identifier_with_leading_number = identifiers cannot start with a n parse_invalid_interpolated_expression = invalid interpolated expression -parse_invalid_literal_suffix = suffixes on {$kind} literals are invalid - .label = invalid suffix `{$suffix}` - parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are invalid .label = invalid suffix `{$suffix}` .tuple_exception_line_1 = `{$suffix}` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases @@ -609,7 +606,6 @@ parse_nonterminal_expected_item_keyword = expected an item keyword parse_nonterminal_expected_lifetime = expected a lifetime, found `{$token}` parse_nonterminal_expected_statement = expected a statement -parse_not_supported = not supported parse_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index c223b8475288b..7fc523ffe0dea 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -302,9 +302,6 @@ passes_export_name = attribute should be applied to a free function, impl method or static .label = not a free function, impl method or static -passes_expr_not_allowed_in_context = - {$expr} is not allowed in a `{$context}` - passes_extern_main = the `main` function cannot be declared in an `extern` block @@ -405,8 +402,6 @@ passes_lang_item_on_incorrect_target = `{$name}` language item must be applied to a {$expected_target} .label = attribute should be applied to a {$expected_target}, not a {$actual_target} -passes_layout = - layout error: {$layout_error} passes_layout_abi = abi: {$abi} passes_layout_align = From d416a22e8a243e36ff88d18b5773df04daea1f71 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 3 Mar 2024 15:25:52 +0000 Subject: [PATCH 09/15] std::rand: enable getrandom for dragonflybsd too. --- library/std/src/sys/pal/unix/rand.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/unix/rand.rs b/library/std/src/sys/pal/unix/rand.rs index 5c32957bc519c..c9ed6825f6c21 100644 --- a/library/std/src/sys/pal/unix/rand.rs +++ b/library/std/src/sys/pal/unix/rand.rs @@ -62,7 +62,13 @@ mod imp { unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) } } - #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "freebsd", netbsd10))] + #[cfg(any( + target_os = "espidf", + target_os = "horizon", + target_os = "freebsd", + target_os = "dragonfly", + netbsd10 + ))] fn getrandom(buf: &mut [u8]) -> libc::ssize_t { unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) } } @@ -73,6 +79,7 @@ mod imp { target_os = "espidf", target_os = "horizon", target_os = "freebsd", + target_os = "dragonfly", netbsd10 )))] fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool { @@ -85,6 +92,7 @@ mod imp { target_os = "espidf", target_os = "horizon", target_os = "freebsd", + target_os = "dragonfly", netbsd10 ))] fn getrandom_fill_bytes(v: &mut [u8]) -> bool { From 7843e46f1793d9712220064c505a0aa8a483cd71 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 9 Mar 2024 01:45:34 +0100 Subject: [PATCH 10/15] Factor out non-branch-related pattern data --- .../rustc_mir_build/src/build/matches/mod.rs | 111 +++++++++--------- .../src/build/matches/simplify.rs | 17 +-- .../rustc_mir_build/src/build/matches/util.rs | 4 +- 3 files changed, 61 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 31591983101f3..cdb82f50b34aa 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -506,13 +506,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { traverse_candidate( candidate, &mut Vec::new(), - &mut |leaf_candidate, parent_bindings| { + &mut |leaf_candidate, parent_data| { if let Some(arm) = arm { self.clear_top_scope(arm.scope); } let binding_end = self.bind_and_guard_matched_candidate( leaf_candidate, - parent_bindings, + parent_data, fake_borrow_temps, scrutinee_span, arm_match_scope, @@ -524,12 +524,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } self.cfg.goto(binding_end, outer_source_info, target_block); }, - |inner_candidate, parent_bindings| { - parent_bindings.push((inner_candidate.bindings, inner_candidate.ascriptions)); + |inner_candidate, parent_data| { + parent_data.push(inner_candidate.extra_data); inner_candidate.subcandidates.into_iter() }, - |parent_bindings| { - parent_bindings.pop(); + |parent_data| { + parent_data.pop(); }, ); @@ -651,7 +651,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if set_match_place { let mut next = Some(&candidate); while let Some(candidate_ref) = next.take() { - for binding in &candidate_ref.bindings { + for binding in &candidate_ref.extra_data.bindings { let local = self.var_local_id(binding.var_id, OutsideGuard); // `try_to_place` may fail if it is unable to resolve the given // `PlaceBuilder` inside a closure. In this case, we don't want to include @@ -924,22 +924,29 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } -/// A pattern in a form suitable for generating code. +/// Data extracted from a pattern that doesn't affect which branch is taken. Collected during +/// pattern simplification and not mutated later. #[derive(Debug, Clone)] -struct FlatPat<'pat, 'tcx> { +struct PatternExtraData<'tcx> { /// [`Span`] of the original pattern. span: Span, + /// Bindings that must be established. + bindings: Vec>, + + /// Types that must be asserted. + ascriptions: Vec>, +} + +/// A pattern in a form suitable for generating code. +#[derive(Debug, Clone)] +struct FlatPat<'pat, 'tcx> { /// To match the pattern, all of these must be satisfied... // Invariant: all the `MatchPair`s are recursively simplified. // Invariant: or-patterns must be sorted to the end. match_pairs: Vec>, - /// ...these bindings established... - bindings: Vec>, - - /// ...and these types asserted. - ascriptions: Vec>, + extra_data: PatternExtraData<'tcx>, } impl<'tcx, 'pat> FlatPat<'pat, 'tcx> { @@ -948,43 +955,38 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> { pattern: &'pat Pat<'tcx>, cx: &mut Builder<'_, 'tcx>, ) -> Self { - let mut match_pairs = vec![MatchPair::new(place, pattern, cx)]; - let mut bindings = Vec::new(); - let mut ascriptions = Vec::new(); - - cx.simplify_match_pairs(&mut match_pairs, &mut bindings, &mut ascriptions); - - FlatPat { span: pattern.span, match_pairs, bindings, ascriptions } + let mut flat_pat = FlatPat { + match_pairs: vec![MatchPair::new(place, pattern, cx)], + extra_data: PatternExtraData { + span: pattern.span, + bindings: Vec::new(), + ascriptions: Vec::new(), + }, + }; + cx.simplify_match_pairs(&mut flat_pat.match_pairs, &mut flat_pat.extra_data); + flat_pat } } #[derive(Debug)] struct Candidate<'pat, 'tcx> { - /// [`Span`] of the original pattern that gave rise to this candidate. - span: Span, - - /// Whether this `Candidate` has a guard. - has_guard: bool, - - /// All of these must be satisfied... + /// For the candidate to match, &ll of these must be satisfied... // Invariant: all the `MatchPair`s are recursively simplified. // Invariant: or-patterns must be sorted at the end. match_pairs: Vec>, - /// ...these bindings established... - // Invariant: not mutated after candidate creation. - bindings: Vec>, - - /// ...and these types asserted... - // Invariant: not mutated after candidate creation. - ascriptions: Vec>, - /// ...and if this is non-empty, one of these subcandidates also has to match... subcandidates: Vec>, - /// ...and the guard must be evaluated; if it's `false` then branch to `otherwise_block`. + /// ...and the guard must be evaluated if there is one. + has_guard: bool, + + /// If the guard is `false` then branch to `otherwise_block`. otherwise_block: Option, + /// If the candidate matches, bindings and ascriptions must be established. + extra_data: PatternExtraData<'tcx>, + /// The block before the `bindings` have been established. pre_binding_block: Option, /// The pre-binding block of the next candidate. @@ -1003,10 +1005,8 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> { fn from_flat_pat(flat_pat: FlatPat<'pat, 'tcx>, has_guard: bool) -> Self { Candidate { - span: flat_pat.span, match_pairs: flat_pat.match_pairs, - bindings: flat_pat.bindings, - ascriptions: flat_pat.ascriptions, + extra_data: flat_pat.extra_data, has_guard, subcandidates: Vec::new(), otherwise_block: None, @@ -1519,8 +1519,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // FIXME(or_patterns; matthewjasper) Try to be more aggressive here. can_merge &= subcandidate.subcandidates.is_empty() - && subcandidate.bindings.is_empty() - && subcandidate.ascriptions.is_empty(); + && subcandidate.extra_data.bindings.is_empty() + && subcandidate.extra_data.ascriptions.is_empty(); } if can_merge { @@ -1943,7 +1943,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn bind_and_guard_matched_candidate<'pat>( &mut self, candidate: Candidate<'pat, 'tcx>, - parent_bindings: &[(Vec>, Vec>)], + parent_data: &[PatternExtraData<'tcx>], fake_borrows: &[(Place<'tcx>, Local)], scrutinee_span: Span, arm_match_scope: Option<(&Arm<'tcx>, region::Scope)>, @@ -1954,7 +1954,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { debug_assert!(candidate.match_pairs.is_empty()); - let candidate_source_info = self.source_info(candidate.span); + let candidate_source_info = self.source_info(candidate.extra_data.span); let mut block = candidate.pre_binding_block.unwrap(); @@ -1971,11 +1971,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.ascribe_types( block, - parent_bindings + parent_data .iter() - .flat_map(|(_, ascriptions)| ascriptions) + .flat_map(|d| &d.ascriptions) .cloned() - .chain(candidate.ascriptions), + .chain(candidate.extra_data.ascriptions), ); // rust-lang/rust#27282: The `autoref` business deserves some @@ -2063,10 +2063,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { && let Some(guard) = arm.guard { let tcx = self.tcx; - let bindings = parent_bindings - .iter() - .flat_map(|(bindings, _)| bindings) - .chain(&candidate.bindings); + let bindings = + parent_data.iter().flat_map(|d| &d.bindings).chain(&candidate.extra_data.bindings); self.bind_matched_candidate_for_guard(block, schedule_drops, bindings.clone()); let guard_frame = GuardFrame { @@ -2144,10 +2142,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // ``` // // and that is clearly not correct. - let by_value_bindings = parent_bindings + let by_value_bindings = parent_data .iter() - .flat_map(|(bindings, _)| bindings) - .chain(&candidate.bindings) + .flat_map(|d| &d.bindings) + .chain(&candidate.extra_data.bindings) .filter(|binding| matches!(binding.binding_mode, BindingMode::ByValue)); // Read all of the by reference bindings to ensure that the // place they refer to can't be modified by the guard. @@ -2172,10 +2170,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.bind_matched_candidate_for_arm_body( block, schedule_drops, - parent_bindings - .iter() - .flat_map(|(bindings, _)| bindings) - .chain(&candidate.bindings), + parent_data.iter().flat_map(|d| &d.bindings).chain(&candidate.extra_data.bindings), storages_alive, ); block diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index a3fccb7c31955..97b94a0b362af 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -12,20 +12,19 @@ //! sort of test: for example, testing which variant an enum is, or //! testing a value against a constant. -use crate::build::matches::{Ascription, Binding, Candidate, FlatPat, MatchPair, TestCase}; +use crate::build::matches::{Candidate, FlatPat, MatchPair, PatternExtraData, TestCase}; use crate::build::Builder; use std::mem; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Simplify a list of match pairs so they all require a test. Stores relevant bindings and - /// ascriptions in the provided `Vec`s. + /// ascriptions in `extra_data`. #[instrument(skip(self), level = "debug")] pub(super) fn simplify_match_pairs<'pat>( &mut self, match_pairs: &mut Vec>, - candidate_bindings: &mut Vec>, - candidate_ascriptions: &mut Vec>, + extra_data: &mut PatternExtraData<'tcx>, ) { // In order to please the borrow checker, in a pattern like `x @ pat` we must lower the // bindings in `pat` before `x`. E.g. (#69971): @@ -45,17 +44,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // after any bindings in `pat`. This doesn't work for or-patterns: the current structure of // match lowering forces us to lower bindings inside or-patterns last. for mut match_pair in mem::take(match_pairs) { - self.simplify_match_pairs( - &mut match_pair.subpairs, - candidate_bindings, - candidate_ascriptions, - ); + self.simplify_match_pairs(&mut match_pair.subpairs, extra_data); if let TestCase::Irrefutable { binding, ascription } = match_pair.test_case { if let Some(binding) = binding { - candidate_bindings.push(binding); + extra_data.bindings.push(binding); } if let Some(ascription) = ascription { - candidate_ascriptions.push(ascription); + extra_data.ascriptions.push(ascription); } // Simplifiable pattern; we replace it with its already simplified subpairs. match_pairs.append(&mut match_pair.subpairs); diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index 2351f69a9141f..d0d49c13f133d 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -280,7 +280,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> { } fn visit_candidate(&mut self, candidate: &Candidate<'_, 'tcx>) { - for binding in &candidate.bindings { + for binding in &candidate.extra_data.bindings { self.visit_binding(binding); } for match_pair in &candidate.match_pairs { @@ -289,7 +289,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> { } fn visit_flat_pat(&mut self, flat_pat: &FlatPat<'_, 'tcx>) { - for binding in &flat_pat.bindings { + for binding in &flat_pat.extra_data.bindings { self.visit_binding(binding); } for match_pair in &flat_pat.match_pairs { From 594cf1de61d9cf6e4d095f7d7ab19f8f5999ef72 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 9 Mar 2024 15:28:26 +0100 Subject: [PATCH 11/15] review --- compiler/rustc_mir_build/src/build/matches/mod.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index cdb82f50b34aa..48c3ee1ba0ff3 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -938,6 +938,12 @@ struct PatternExtraData<'tcx> { ascriptions: Vec>, } +impl<'tcx> PatternExtraData<'tcx> { + fn is_empty(&self) -> bool { + self.bindings.is_empty() && self.ascriptions.is_empty() + } +} + /// A pattern in a form suitable for generating code. #[derive(Debug, Clone)] struct FlatPat<'pat, 'tcx> { @@ -970,7 +976,7 @@ impl<'tcx, 'pat> FlatPat<'pat, 'tcx> { #[derive(Debug)] struct Candidate<'pat, 'tcx> { - /// For the candidate to match, &ll of these must be satisfied... + /// For the candidate to match, all of these must be satisfied... // Invariant: all the `MatchPair`s are recursively simplified. // Invariant: or-patterns must be sorted at the end. match_pairs: Vec>, @@ -1518,9 +1524,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.merge_trivial_subcandidates(subcandidate, source_info); // FIXME(or_patterns; matthewjasper) Try to be more aggressive here. - can_merge &= subcandidate.subcandidates.is_empty() - && subcandidate.extra_data.bindings.is_empty() - && subcandidate.extra_data.ascriptions.is_empty(); + can_merge &= + subcandidate.subcandidates.is_empty() && subcandidate.extra_data.is_empty(); } if can_merge { From 092a1ab001c93b98245a9f79cbf004a02f442b1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Vallotton?= Date: Sat, 9 Mar 2024 14:38:58 -0300 Subject: [PATCH 12/15] fix: remove memory leak due to missing drop implementation for local waker. Also, fix some of the stability attributes of LocalWaker's methods. --- library/core/src/task/wake.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs index 8fc942dedc9be..1b43c46bda515 100644 --- a/library/core/src/task/wake.rs +++ b/library/core/src/task/wake.rs @@ -622,7 +622,7 @@ impl LocalWaker { /// /// [`poll()`]: crate::future::Future::poll #[inline] - #[stable(feature = "futures_api", since = "1.36.0")] + #[unstable(feature = "local_waker", issue = "118959")] pub fn wake(self) { // The actual wakeup call is delegated through a virtual function call // to the implementation which is defined by the executor. @@ -644,7 +644,7 @@ impl LocalWaker { /// the case where an owned `Waker` is available. This method should be preferred to /// calling `waker.clone().wake()`. #[inline] - #[stable(feature = "futures_api", since = "1.36.0")] + #[unstable(feature = "local_waker", issue = "118959")] pub fn wake_by_ref(&self) { // The actual wakeup call is delegated through a virtual function call // to the implementation which is defined by the executor. @@ -664,7 +664,7 @@ impl LocalWaker { /// avoid cloning the waker when they would wake the same task anyway. #[inline] #[must_use] - #[stable(feature = "futures_api", since = "1.36.0")] + #[unstable(feature = "local_waker", issue = "118959")] pub fn will_wake(&self, other: &LocalWaker) -> bool { self.waker == other.waker } @@ -676,7 +676,7 @@ impl LocalWaker { /// Therefore this method is unsafe. #[inline] #[must_use] - #[stable(feature = "futures_api", since = "1.36.0")] + #[unstable(feature = "local_waker", issue = "118959")] #[rustc_const_unstable(feature = "const_waker", issue = "102012")] pub const unsafe fn from_raw(waker: RawWaker) -> LocalWaker { Self { waker } @@ -748,7 +748,18 @@ impl AsRef for Waker { } } -#[stable(feature = "futures_api", since = "1.36.0")] +#[unstable(feature = "local_waker", issue = "118959")] +impl Drop for LocalWaker { + #[inline] + fn drop(&mut self) { + // SAFETY: This is safe because `LocalWaker::from_raw` is the only way + // to initialize `drop` and `data` requiring the user to acknowledge + // that the contract of `RawWaker` is upheld. + unsafe { (self.waker.vtable.drop)(self.waker.data) } + } +} + +#[unstable(feature = "local_waker", issue = "118959")] impl fmt::Debug for LocalWaker { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let vtable_ptr = self.waker.vtable as *const RawWakerVTable; From ff1459a37022f002d28d1c116d8a073f5b9a6720 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Sat, 9 Mar 2024 18:24:45 +0000 Subject: [PATCH 13/15] Add test to check unused_lifetimes don't duplicate "parameter is never used" error --- tests/ui/single-use-lifetime/dedup.rs | 9 +++++++++ tests/ui/single-use-lifetime/dedup.stderr | 11 +++++++++++ 2 files changed, 20 insertions(+) create mode 100644 tests/ui/single-use-lifetime/dedup.rs create mode 100644 tests/ui/single-use-lifetime/dedup.stderr diff --git a/tests/ui/single-use-lifetime/dedup.rs b/tests/ui/single-use-lifetime/dedup.rs new file mode 100644 index 0000000000000..16b39609a6d34 --- /dev/null +++ b/tests/ui/single-use-lifetime/dedup.rs @@ -0,0 +1,9 @@ +// Check that `unused_lifetimes` lint doesn't duplicate a "parameter is never used" error. +// Fixed in . +// Issue: . + +#![warn(unused_lifetimes)] +struct Foo<'a>; +//~^ ERROR parameter `'a` is never used + +fn main() {} diff --git a/tests/ui/single-use-lifetime/dedup.stderr b/tests/ui/single-use-lifetime/dedup.stderr new file mode 100644 index 0000000000000..6d02cb3c7148e --- /dev/null +++ b/tests/ui/single-use-lifetime/dedup.stderr @@ -0,0 +1,11 @@ +error[E0392]: lifetime parameter `'a` is never used + --> $DIR/dedup.rs:6:12 + | +LL | struct Foo<'a>; + | ^^ unused lifetime parameter + | + = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0392`. From 1bad698b27e729ee9ecb7319629645b6b19a1b79 Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Sun, 10 Mar 2024 14:00:58 +0800 Subject: [PATCH 14/15] doc/rustc: Move loongarch64-unknown-linux-musl to Tier 3 Fixes #122266 --- src/doc/rustc/src/platform-support.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 308e32353706f..537a724579ebe 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -165,7 +165,6 @@ target | std | notes `i686-unknown-freebsd` | ✓ | 32-bit FreeBSD [^x86_32-floats-return-ABI] `i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 [^x86_32-floats-return-ABI] [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | 32-bit UEFI -[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | ? | | LoongArch64 Linux (LP64D ABI) with musl 1.2.3 [`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64D ABI) [`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64S ABI) [`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs] @@ -303,6 +302,7 @@ target | std | host | notes `i686-uwp-windows-msvc` | ? | | [^x86_32-floats-return-ABI] [`i686-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 32-bit Windows 7 support [^x86_32-floats-return-ABI] `i686-wrs-vxworks` | ? | | [^x86_32-floats-return-ABI] +[`loongarch64-unknown-linux-musl`](platform-support/loongarch-linux.md) | ? | | LoongArch64 Linux (LP64D ABI) with musl 1.2.3 [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux `mips-unknown-linux-gnu` | ✓ | ✓ | MIPS Linux (kernel 4.4, glibc 2.23) `mips-unknown-linux-musl` | ✓ | | MIPS Linux with musl 1.2.3 From 83590ac06945f9c7c776d25699c76ffc8558e860 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Sat, 9 Mar 2024 23:33:27 -0700 Subject: [PATCH 15/15] fix legacy numeric constant diag items - missed syms for usize/isize - missed diag items on unsigned integers --- compiler/rustc_span/src/symbol.rs | 10 ++++++++++ library/core/src/num/uint_macros.rs | 2 ++ 2 files changed, 12 insertions(+) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 337910763757d..708349e85aebc 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1000,6 +1000,11 @@ symbols! { is_val_statically_known, isa_attribute, isize, + isize_legacy_const_max, + isize_legacy_const_min, + isize_legacy_fn_max_value, + isize_legacy_fn_min_value, + isize_legacy_mod, issue, issue_5723_bootstrap, issue_tracker_base_url, @@ -1910,6 +1915,11 @@ symbols! { used_with_arg, using, usize, + usize_legacy_const_max, + usize_legacy_const_min, + usize_legacy_fn_max_value, + usize_legacy_fn_min_value, + usize_legacy_mod, va_arg, va_copy, va_end, diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index f2f29e4ad8194..081a3c0b118ea 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2972,6 +2972,7 @@ macro_rules! uint_impl { #[inline(always)] #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")] #[deprecated(since = "TBD", note = "replaced by the `MIN` associated constant on this type")] + #[rustc_diagnostic_item = concat!(stringify!($SelfT), "_legacy_fn_min_value")] pub const fn min_value() -> Self { Self::MIN } /// New code should prefer to use @@ -2983,6 +2984,7 @@ macro_rules! uint_impl { #[inline(always)] #[rustc_const_stable(feature = "const_max_value", since = "1.32.0")] #[deprecated(since = "TBD", note = "replaced by the `MAX` associated constant on this type")] + #[rustc_diagnostic_item = concat!(stringify!($SelfT), "_legacy_fn_max_value")] pub const fn max_value() -> Self { Self::MAX } } }