mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #154412 - JonathanBrouwer:rollup-4EpQJse, r=JonathanBrouwer
Rollup of 2 pull requests Successful merges: - rust-lang/rust#154229 (Ensure `ErasedData` only implements appropriate auto traits) - rust-lang/rust#154409 (Update `try_blocks` to a new tracking issue number)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/// This module provides types and traits for buffering lints until later in compilation.
|
||||
use rustc_ast::node_id::NodeId;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::sync::DynSend;
|
||||
use rustc_data_structures::sync::{DynSend, DynSync};
|
||||
use rustc_error_messages::MultiSpan;
|
||||
use rustc_lint_defs::{BuiltinLintDiag, Lint, LintId};
|
||||
|
||||
@@ -10,7 +10,14 @@
|
||||
/// We can't implement `Diagnostic` for `BuiltinLintDiag`, because decorating some of its
|
||||
/// variants requires types we don't have yet. So, handle that case separately.
|
||||
pub enum DecorateDiagCompat {
|
||||
Dynamic(Box<dyn for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + 'static>),
|
||||
Dynamic(
|
||||
Box<
|
||||
dyn for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()>
|
||||
+ DynSync
|
||||
+ DynSend
|
||||
+ 'static,
|
||||
>,
|
||||
),
|
||||
Builtin(BuiltinLintDiag),
|
||||
}
|
||||
|
||||
@@ -20,7 +27,7 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: for<'a> Diagnostic<'a, ()> + DynSend + 'static> From<D> for DecorateDiagCompat {
|
||||
impl<D: for<'a> Diagnostic<'a, ()> + DynSync + DynSend + 'static> From<D> for DecorateDiagCompat {
|
||||
#[inline]
|
||||
fn from(d: D) -> Self {
|
||||
Self::Dynamic(Box::new(|dcx, level| d.into_diag(dcx, level)))
|
||||
@@ -83,7 +90,7 @@ pub fn buffer_lint(
|
||||
}
|
||||
|
||||
pub fn dyn_buffer_lint<
|
||||
F: for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + 'static,
|
||||
F: for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSync + DynSend + 'static,
|
||||
>(
|
||||
&mut self,
|
||||
lint: &'static Lint,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
use std::path::PathBuf;
|
||||
use std::thread::panicking;
|
||||
|
||||
use rustc_data_structures::sync::DynSend;
|
||||
use rustc_data_structures::sync::{DynSend, DynSync};
|
||||
use rustc_error_messages::{DiagArgMap, DiagArgName, DiagArgValue, IntoDiagArg};
|
||||
use rustc_lint_defs::{Applicability, LintExpectationId};
|
||||
use rustc_macros::{Decodable, Encodable};
|
||||
@@ -120,7 +120,9 @@ fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
|
||||
}
|
||||
|
||||
impl<'a> Diagnostic<'a, ()>
|
||||
for Box<dyn for<'b> FnOnce(DiagCtxtHandle<'b>, Level) -> Diag<'b, ()> + DynSend + 'static>
|
||||
for Box<
|
||||
dyn for<'b> FnOnce(DiagCtxtHandle<'b>, Level) -> Diag<'b, ()> + DynSync + DynSend + 'static,
|
||||
>
|
||||
{
|
||||
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
|
||||
self(dcx, level)
|
||||
|
||||
@@ -693,7 +693,7 @@ pub fn internal(&self, feature: Symbol) -> bool {
|
||||
/// Allows inconsistent bounds in where clauses.
|
||||
(unstable, trivial_bounds, "1.28.0", Some(48214)),
|
||||
/// Allows using `try {...}` expressions.
|
||||
(unstable, try_blocks, "1.29.0", Some(31436)),
|
||||
(unstable, try_blocks, "1.29.0", Some(154391)),
|
||||
/// Allows using `try bikeshed TargetType {...}` expressions.
|
||||
(unstable, try_blocks_heterogeneous, "1.94.0", Some(149488)),
|
||||
/// Allows `impl Trait` to be used inside type aliases (RFC 2515).
|
||||
|
||||
@@ -7,24 +7,37 @@
|
||||
|
||||
use std::ffi::OsStr;
|
||||
use std::intrinsics::transmute_unchecked;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
use rustc_ast::tokenstream::TokenStream;
|
||||
use rustc_data_structures::steal::Steal;
|
||||
use rustc_data_structures::sync::{DynSend, DynSync};
|
||||
use rustc_span::{ErrorGuaranteed, Spanned};
|
||||
|
||||
use crate::mir::mono::{MonoItem, NormalizationErrorInMono};
|
||||
use crate::ty::{self, Ty, TyCtxt};
|
||||
use crate::{mir, thir, traits};
|
||||
|
||||
unsafe extern "C" {
|
||||
type NoAutoTraits;
|
||||
}
|
||||
|
||||
/// Internal implementation detail of [`Erased`].
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ErasedData<Storage: Copy> {
|
||||
/// We use `MaybeUninit` here to make sure it's legal to store a transmuted
|
||||
/// value that isn't actually of type `Storage`.
|
||||
data: MaybeUninit<Storage>,
|
||||
/// `Storage` is an erased type, so we use an external type here to opt-out of auto traits
|
||||
/// as those would be incorrect.
|
||||
no_auto_traits: PhantomData<NoAutoTraits>,
|
||||
}
|
||||
|
||||
// SAFETY: The bounds on `erase_val` ensure the types we erase are `DynSync` and `DynSend`
|
||||
unsafe impl<Storage: Copy> DynSync for ErasedData<Storage> {}
|
||||
unsafe impl<Storage: Copy> DynSend for ErasedData<Storage> {}
|
||||
|
||||
/// Trait for types that can be erased into [`Erased<Self>`].
|
||||
///
|
||||
/// Erasing and unerasing values is performed by [`erase_val`] and [`restore_val`].
|
||||
@@ -54,13 +67,11 @@ pub trait Erasable: Copy {
|
||||
///
|
||||
/// `Erased<T>` and `Erased<U>` are type-checked as distinct types, but codegen
|
||||
/// can see whether they actually have the same storage type.
|
||||
///
|
||||
/// FIXME: This might have soundness issues with erasable types that don't
|
||||
/// implement the same auto-traits as `[u8; _]`; see
|
||||
/// <https://github.com/rust-lang/rust/pull/151715#discussion_r2740113250>
|
||||
#[inline(always)]
|
||||
#[define_opaque(Erased)]
|
||||
pub fn erase_val<T: Erasable>(value: T) -> Erased<T> {
|
||||
// The `DynSend` and `DynSync` bounds on `T` are used to
|
||||
// justify the safety of the implementations of these traits for `ErasedData`.
|
||||
pub fn erase_val<T: Erasable + DynSend + DynSync>(value: T) -> Erased<T> {
|
||||
// Ensure the sizes match
|
||||
const {
|
||||
if size_of::<T>() != size_of::<T::Storage>() {
|
||||
@@ -78,6 +89,7 @@ pub fn erase_val<T: Erasable>(value: T) -> Erased<T> {
|
||||
//
|
||||
// SAFETY: It is safe to transmute to MaybeUninit for types with the same sizes.
|
||||
data: unsafe { transmute_unchecked::<T, MaybeUninit<T::Storage>>(value) },
|
||||
no_auto_traits: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +100,7 @@ pub fn erase_val<T: Erasable>(value: T) -> Erased<T> {
|
||||
#[inline(always)]
|
||||
#[define_opaque(Erased)]
|
||||
pub fn restore_val<T: Erasable>(erased_value: Erased<T>) -> T {
|
||||
let ErasedData { data }: ErasedData<<T as Erasable>::Storage> = erased_value;
|
||||
let ErasedData { data, .. }: ErasedData<<T as Erasable>::Storage> = erased_value;
|
||||
// See comment in `erase_val` for why we use `transmute_unchecked`.
|
||||
//
|
||||
// SAFETY: Due to the use of impl Trait in `Erased` the only way to safely create an instance
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
use rustc_ast::attr::AttrIdGenerator;
|
||||
use rustc_ast::node_id::NodeId;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
||||
use rustc_data_structures::sync::{AppendOnlyVec, DynSend, Lock};
|
||||
use rustc_data_structures::sync::{AppendOnlyVec, DynSend, DynSync, Lock};
|
||||
use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter;
|
||||
use rustc_errors::emitter::{EmitterWithNote, stderr_destination};
|
||||
use rustc_errors::{
|
||||
@@ -332,7 +332,7 @@ pub fn buffer_lint(
|
||||
}
|
||||
|
||||
pub fn dyn_buffer_lint<
|
||||
F: for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + 'static,
|
||||
F: for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSync + DynSend + 'static,
|
||||
>(
|
||||
&self,
|
||||
lint: &'static Lint,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# `try_blocks`
|
||||
|
||||
The tracking issue for this feature is: [#31436]
|
||||
The tracking issue for this feature is: [#154391]
|
||||
|
||||
[#31436]: https://github.com/rust-lang/rust/issues/31436
|
||||
[#154391]: https://github.com/rust-lang/rust/issues/154391
|
||||
|
||||
------------------------
|
||||
|
||||
@@ -14,14 +14,14 @@ block creates a new scope one can use the `?` operator in.
|
||||
|
||||
use std::num::ParseIntError;
|
||||
|
||||
let result: Result<i32, ParseIntError> = try {
|
||||
let result = try {
|
||||
"1".parse::<i32>()?
|
||||
+ "2".parse::<i32>()?
|
||||
+ "3".parse::<i32>()?
|
||||
};
|
||||
assert_eq!(result, Ok(6));
|
||||
|
||||
let result: Result<i32, ParseIntError> = try {
|
||||
let result = try {
|
||||
"1".parse::<i32>()?
|
||||
+ "foo".parse::<i32>()?
|
||||
+ "3".parse::<i32>()?
|
||||
|
||||
@@ -11576,9 +11576,9 @@ pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable.
|
||||
label: "try_blocks",
|
||||
description: r##"# `try_blocks`
|
||||
|
||||
The tracking issue for this feature is: [#31436]
|
||||
The tracking issue for this feature is: [#154391]
|
||||
|
||||
[#31436]: https://github.com/rust-lang/rust/issues/31436
|
||||
[#154391]: https://github.com/rust-lang/rust/issues/154391
|
||||
|
||||
------------------------
|
||||
|
||||
@@ -11590,14 +11590,14 @@ pub union GenericUnion<T: Copy> { // Unions with non-`Copy` fields are unstable.
|
||||
|
||||
use std::num::ParseIntError;
|
||||
|
||||
let result: Result<i32, ParseIntError> = try {
|
||||
let result = try {
|
||||
"1".parse::<i32>()?
|
||||
+ "2".parse::<i32>()?
|
||||
+ "3".parse::<i32>()?
|
||||
};
|
||||
assert_eq!(result, Ok(6));
|
||||
|
||||
let result: Result<i32, ParseIntError> = try {
|
||||
let result = try {
|
||||
"1".parse::<i32>()?
|
||||
+ "foo".parse::<i32>()?
|
||||
+ "3".parse::<i32>()?
|
||||
|
||||
+1
-1
@@ -1420,7 +1420,7 @@ Tests for the `#[doc(hidden)]` items.
|
||||
|
||||
## `tests/ui/try-block/`
|
||||
|
||||
`#![feature(try_blocks)]`. See [Tracking issue for `?` operator and `try` blocks (RFC 243, `question_mark` & `try_blocks` features)](https://github.com/rust-lang/rust/issues/31436).
|
||||
`#![feature(try_blocks)]` & `#![feature(try_blocks_heterogeneous)]`. See [Tracking Issue for homogeneous `try_blocks`](https://github.com/rust-lang/rust/issues/154391) & [Experimental Tracking Issue for Heterogeneous Try Blocks](https://github.com/rust-lang/rust/issues/149488).
|
||||
|
||||
## `tests/ui/try-trait/`
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ LL | | x
|
||||
LL | | };
|
||||
| |_____^
|
||||
|
|
||||
= note: see issue #31436 <https://github.com/rust-lang/rust/issues/31436> for more information
|
||||
= note: see issue #154391 <https://github.com/rust-lang/rust/issues/154391> for more information
|
||||
= help: add `#![feature(try_blocks)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ warning: `try` blocks are unstable
|
||||
LL | try {}
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: see issue #31436 <https://github.com/rust-lang/rust/issues/31436> for more information
|
||||
= note: see issue #154391 <https://github.com/rust-lang/rust/issues/154391> for more information
|
||||
= help: add `#![feature(try_blocks)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= warning: unstable syntax can change at any point in the future, causing a hard error!
|
||||
|
||||
Reference in New Issue
Block a user