From 4913ab8f779582dc9da099a148a4670ede0e15aa Mon Sep 17 00:00:00 2001
From: Peter Jaszkowiak
Date: Tue, 20 Feb 2024 20:55:13 -0700
Subject: [PATCH 001/101] Stabilize `LazyCell` and `LazyLock` (`lazy_cell`)
---
.../rustc_const_eval/src/check_consts/ops.rs | 2 +-
compiler/rustc_data_structures/src/lib.rs | 1 -
compiler/rustc_error_messages/src/lib.rs | 1 -
compiler/rustc_feature/src/lib.rs | 1 -
compiler/rustc_hir_analysis/src/lib.rs | 1 -
compiler/rustc_interface/src/lib.rs | 1 -
compiler/rustc_lint_defs/src/builtin.rs | 10 ++---
compiler/rustc_session/src/lib.rs | 1 -
library/core/src/cell.rs | 2 +-
library/core/src/cell/lazy.rs | 20 ++++-----
library/core/tests/lib.rs | 1 -
library/std/src/lib.rs | 1 -
library/std/src/sync/lazy_lock.rs | 41 +++++++++++--------
library/std/src/sync/mod.rs | 2 +-
src/librustdoc/lib.rs | 1 -
src/tools/clippy/clippy_dev/src/lib.rs | 1 -
src/tools/clippy/src/driver.rs | 1 -
src/tools/clippy/tests/compile-test.rs | 1 -
src/tools/clippy/tests/dogfood.rs | 1 -
.../clippy/tests/lint_message_convention.rs | 1 -
src/tools/clippy/tests/workspace.rs | 2 -
tests/ui/borrowck/issue-64453.stderr | 2 +-
tests/ui/consts/issue-16538.stderr | 2 +-
tests/ui/consts/issue-32829-2.stderr | 4 +-
tests/ui/consts/mir_check_nonconst.stderr | 2 +-
tests/ui/issues/issue-25901.stderr | 2 +-
tests/ui/issues/issue-7364.stderr | 2 +-
tests/ui/lint/suspicious-double-ref-op.rs | 1 -
tests/ui/lint/suspicious-double-ref-op.stderr | 10 ++---
.../issue-35813-postfix-after-cast.stderr | 2 +-
.../nested-closure.rs | 2 +-
.../ui/static/static-mut-not-constant.stderr | 2 +-
.../static-vec-repeat-not-constant.stderr | 2 +-
.../statics/check-values-constraints.stderr | 16 ++++----
34 files changed, 60 insertions(+), 82 deletions(-)
diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
index 8406e0f48762..90b622cae656 100644
--- a/compiler/rustc_const_eval/src/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
@@ -309,7 +309,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
}
if let ConstContext::Static(_) = ccx.const_kind() {
- err.note("consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell");
+ err.note("consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`");
}
err
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 85b5a3cdb7c3..9781aae22eb3 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -24,7 +24,6 @@
#![feature(extend_one)]
#![feature(hash_raw_entry)]
#![feature(hasher_prefixfree_extras)]
-#![feature(lazy_cell)]
#![feature(lint_reasons)]
#![feature(macro_metavar_expr)]
#![feature(map_try_insert)]
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 2a8f42220640..08388c5a58ed 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -1,6 +1,5 @@
#![doc(rust_logo)]
#![feature(rustdoc_internals)]
-#![feature(lazy_cell)]
#![feature(rustc_attrs)]
#![feature(type_alias_impl_trait)]
#![allow(internal_features)]
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index 36ef8fe7816f..9cbf836ec76f 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -14,7 +14,6 @@
#![allow(internal_features)]
#![feature(rustdoc_internals)]
#![doc(rust_logo)]
-#![feature(lazy_cell)]
mod accepted;
mod builtin_attrs;
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index d1e50e13894a..8fe81851f932 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -68,7 +68,6 @@ This API is completely unstable and subject to change.
#![feature(iter_intersperse)]
#![feature(let_chains)]
#![feature(never_type)]
-#![feature(lazy_cell)]
#![feature(slice_partition_dedup)]
#![feature(try_blocks)]
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index c1d460ddd086..8b1d9b706cac 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -1,5 +1,4 @@
#![feature(decl_macro)]
-#![feature(lazy_cell)]
#![feature(let_chains)]
#![feature(thread_spawn_unchecked)]
#![feature(try_blocks)]
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 617fe99ef6a7..747b7292a199 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -1316,10 +1316,8 @@ declare_lint! {
/// * If you are trying to perform a one-time initialization of a global:
/// * If the value can be computed at compile-time, consider using
/// const-compatible values (see [Constant Evaluation]).
- /// * For more complex single-initialization cases, consider using a
- /// third-party crate, such as [`lazy_static`] or [`once_cell`].
- /// * If you are using the [nightly channel], consider the new
- /// [`lazy`] module in the standard library.
+ /// * For more complex single-initialization cases, consider using
+ /// [`std::sync::LazyLock`].
/// * If you truly need a mutable global, consider using a [`static`],
/// which has a variety of options:
/// * Simple data types can be directly defined and mutated with an
@@ -1334,9 +1332,7 @@ declare_lint! {
/// [Constant Evaluation]: https://doc.rust-lang.org/reference/const_eval.html
/// [`static`]: https://doc.rust-lang.org/reference/items/static-items.html
/// [mutable `static`]: https://doc.rust-lang.org/reference/items/static-items.html#mutable-statics
- /// [`lazy`]: https://doc.rust-lang.org/nightly/std/lazy/index.html
- /// [`lazy_static`]: https://crates.io/crates/lazy_static
- /// [`once_cell`]: https://crates.io/crates/once_cell
+ /// [`std::sync::LazyLock`]: https://doc.rust-lang.org/stable/std/sync/struct.LazyLock.html
/// [`atomic`]: https://doc.rust-lang.org/std/sync/atomic/index.html
/// [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
pub CONST_ITEM_MUTATION,
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index ce866906e1e6..cb02fbdfee9e 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -1,5 +1,4 @@
#![feature(let_chains)]
-#![feature(lazy_cell)]
#![feature(option_get_or_insert_default)]
#![feature(rustc_attrs)]
#![feature(map_many_mut)]
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 4b491ffdafa7..ac026de95da1 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -245,7 +245,7 @@ use crate::ptr::{self, NonNull};
mod lazy;
mod once;
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub use lazy::LazyCell;
#[stable(feature = "once_cell", since = "1.70.0")]
pub use once::OnceCell;
diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs
index 1b213f6a2941..47eab6fd0163 100644
--- a/library/core/src/cell/lazy.rs
+++ b/library/core/src/cell/lazy.rs
@@ -18,8 +18,6 @@ enum State {
/// # Examples
///
/// ```
-/// #![feature(lazy_cell)]
-///
/// use std::cell::LazyCell;
///
/// let lazy: LazyCell = LazyCell::new(|| {
@@ -36,7 +34,7 @@ enum State {
/// // 92
/// // 92
/// ```
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub struct LazyCell T> {
state: UnsafeCell>,
}
@@ -47,8 +45,6 @@ impl T> LazyCell {
/// # Examples
///
/// ```
- /// #![feature(lazy_cell)]
- ///
/// use std::cell::LazyCell;
///
/// let hello = "Hello, World!".to_string();
@@ -58,7 +54,8 @@ impl T> LazyCell {
/// assert_eq!(&*lazy, "HELLO, WORLD!");
/// ```
#[inline]
- #[unstable(feature = "lazy_cell", issue = "109736")]
+ #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub const fn new(f: F) -> LazyCell {
LazyCell { state: UnsafeCell::new(State::Uninit(f)) }
}
@@ -70,7 +67,6 @@ impl T> LazyCell {
/// # Examples
///
/// ```
- /// #![feature(lazy_cell)]
/// #![feature(lazy_cell_consume)]
///
/// use std::cell::LazyCell;
@@ -99,8 +95,6 @@ impl T> LazyCell {
/// # Examples
///
/// ```
- /// #![feature(lazy_cell)]
- ///
/// use std::cell::LazyCell;
///
/// let lazy = LazyCell::new(|| 92);
@@ -109,7 +103,7 @@ impl T> LazyCell {
/// assert_eq!(&*lazy, &92);
/// ```
#[inline]
- #[unstable(feature = "lazy_cell", issue = "109736")]
+ #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub fn force(this: &LazyCell) -> &T {
// SAFETY:
// This invalidates any mutable references to the data. The resulting
@@ -173,7 +167,7 @@ impl LazyCell {
}
}
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl T> Deref for LazyCell {
type Target = T;
#[inline]
@@ -182,7 +176,7 @@ impl T> Deref for LazyCell {
}
}
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl Default for LazyCell {
/// Creates a new lazy value using `Default` as the initializing function.
#[inline]
@@ -191,7 +185,7 @@ impl Default for LazyCell {
}
}
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl fmt::Debug for LazyCell {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut d = f.debug_tuple("LazyCell");
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 797108a8425d..e6828f6cb4ea 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -96,7 +96,6 @@
#![feature(pointer_is_aligned_to)]
#![feature(portable_simd)]
#![feature(ptr_metadata)]
-#![feature(lazy_cell)]
#![feature(unsized_tuple_coercion)]
#![feature(const_option)]
#![feature(const_option_ext)]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 4a18db3d5a3f..9d6576fa8411 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -395,7 +395,6 @@
#![feature(edition_panic)]
#![feature(format_args_nl)]
#![feature(get_many_mut)]
-#![feature(lazy_cell)]
#![feature(log_syntax)]
#![feature(test)]
#![feature(trace_macros)]
diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs
index 27b59cfc8c24..16d5dc30552f 100644
--- a/library/std/src/sync/lazy_lock.rs
+++ b/library/std/src/sync/lazy_lock.rs
@@ -31,8 +31,6 @@ union Data {
/// Initialize static variables with `LazyLock`.
///
/// ```
-/// #![feature(lazy_cell)]
-///
/// use std::collections::HashMap;
///
/// use std::sync::LazyLock;
@@ -61,8 +59,6 @@ union Data {
/// ```
/// Initialize fields with `LazyLock`.
/// ```
-/// #![feature(lazy_cell)]
-///
/// use std::sync::LazyLock;
///
/// #[derive(Debug)]
@@ -76,8 +72,7 @@ union Data {
/// println!("{}", *data.number);
/// }
/// ```
-
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub struct LazyLock T> {
once: Once,
data: UnsafeCell>,
@@ -85,8 +80,21 @@ pub struct LazyLock T> {
impl T> LazyLock {
/// Creates a new lazy value with the given initializing function.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::sync::LazyLock;
+ ///
+ /// let hello = "Hello, World!".to_string();
+ ///
+ /// let lazy = LazyLock::new(|| hello.to_uppercase());
+ ///
+ /// assert_eq!(&*lazy, "HELLO, WORLD!");
+ /// ```
#[inline]
- #[unstable(feature = "lazy_cell", issue = "109736")]
+ #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
+ #[rustc_const_stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub const fn new(f: F) -> LazyLock {
LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) }
}
@@ -107,7 +115,6 @@ impl T> LazyLock {
/// # Examples
///
/// ```
- /// #![feature(lazy_cell)]
/// #![feature(lazy_cell_consume)]
///
/// use std::sync::LazyLock;
@@ -145,8 +152,6 @@ impl T> LazyLock {
/// # Examples
///
/// ```
- /// #![feature(lazy_cell)]
- ///
/// use std::sync::LazyLock;
///
/// let lazy = LazyLock::new(|| 92);
@@ -155,7 +160,7 @@ impl T> LazyLock {
/// assert_eq!(&*lazy, &92);
/// ```
#[inline]
- #[unstable(feature = "lazy_cell", issue = "109736")]
+ #[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub fn force(this: &LazyLock) -> &T {
this.once.call_once(|| {
// SAFETY: `call_once` only runs this closure once, ever.
@@ -191,7 +196,7 @@ impl LazyLock {
}
}
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl Drop for LazyLock {
fn drop(&mut self) {
match self.once.state() {
@@ -204,7 +209,7 @@ impl Drop for LazyLock {
}
}
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl T> Deref for LazyLock {
type Target = T;
@@ -219,7 +224,7 @@ impl T> Deref for LazyLock {
}
}
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl Default for LazyLock {
/// Creates a new lazy value using `Default` as the initializing function.
#[inline]
@@ -228,7 +233,7 @@ impl Default for LazyLock {
}
}
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl fmt::Debug for LazyLock {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut d = f.debug_tuple("LazyLock");
@@ -242,13 +247,13 @@ impl fmt::Debug for LazyLock {
// We never create a `&F` from a `&LazyLock` so it is fine
// to not impl `Sync` for `F`.
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
unsafe impl Sync for LazyLock {}
// auto-derived `Send` impl is OK.
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl RefUnwindSafe for LazyLock {}
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
impl UnwindSafe for LazyLock {}
#[cfg(test)]
diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs
index e8c35bd48a70..fb7d601b0947 100644
--- a/library/std/src/sync/mod.rs
+++ b/library/std/src/sync/mod.rs
@@ -179,7 +179,7 @@ pub use self::rwlock::{MappedRwLockReadGuard, MappedRwLockWriteGuard};
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
-#[unstable(feature = "lazy_cell", issue = "109736")]
+#[stable(feature = "lazy_cell", since = "CURRENT_RUSTC_VERSION")]
pub use self::lazy_lock::LazyLock;
#[stable(feature = "once_cell", since = "1.70.0")]
pub use self::once_lock::OnceLock;
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 0650afb90c7e..55346c768b66 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -8,7 +8,6 @@
#![feature(if_let_guard)]
#![feature(impl_trait_in_assoc_type)]
#![feature(iter_intersperse)]
-#![feature(lazy_cell)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(round_char_boundary)]
diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs
index 385191e0361b..3aa43dbe23ed 100644
--- a/src/tools/clippy/clippy_dev/src/lib.rs
+++ b/src/tools/clippy/clippy_dev/src/lib.rs
@@ -1,4 +1,3 @@
-#![feature(lazy_cell)]
#![feature(let_chains)]
#![feature(rustc_private)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index 9e42abbc9aa9..f79da26964f3 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -2,7 +2,6 @@
#![allow(rustc::untranslatable_diagnostic)]
#![feature(rustc_private)]
#![feature(let_chains)]
-#![feature(lazy_cell)]
#![feature(lint_reasons)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
// warn on lints, that are included in `rust-lang/rust`s bootstrap
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index b06a11702ec8..333a2ab58575 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -1,4 +1,3 @@
-#![feature(lazy_cell)]
#![feature(is_sorted)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![warn(rust_2018_idioms, unused_lifetimes)]
diff --git a/src/tools/clippy/tests/dogfood.rs b/src/tools/clippy/tests/dogfood.rs
index 3f16c180ea78..36a7a651c4d2 100644
--- a/src/tools/clippy/tests/dogfood.rs
+++ b/src/tools/clippy/tests/dogfood.rs
@@ -3,7 +3,6 @@
//!
//! See [Eating your own dog food](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) for context
-#![feature(lazy_cell)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![warn(rust_2018_idioms, unused_lifetimes)]
diff --git a/src/tools/clippy/tests/lint_message_convention.rs b/src/tools/clippy/tests/lint_message_convention.rs
index 98019c755276..6ce7e44474d8 100644
--- a/src/tools/clippy/tests/lint_message_convention.rs
+++ b/src/tools/clippy/tests/lint_message_convention.rs
@@ -1,4 +1,3 @@
-#![feature(lazy_cell)]
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
#![warn(rust_2018_idioms, unused_lifetimes)]
diff --git a/src/tools/clippy/tests/workspace.rs b/src/tools/clippy/tests/workspace.rs
index 699ab2be199a..19ccc7ae9607 100644
--- a/src/tools/clippy/tests/workspace.rs
+++ b/src/tools/clippy/tests/workspace.rs
@@ -1,5 +1,3 @@
-#![feature(lazy_cell)]
-
use std::path::PathBuf;
use std::process::Command;
use test_utils::{CARGO_CLIPPY_PATH, IS_RUSTC_TEST_SUITE};
diff --git a/tests/ui/borrowck/issue-64453.stderr b/tests/ui/borrowck/issue-64453.stderr
index 0e4a8d42f6e8..e671817633be 100644
--- a/tests/ui/borrowck/issue-64453.stderr
+++ b/tests/ui/borrowck/issue-64453.stderr
@@ -14,7 +14,7 @@ LL | static settings_dir: String = format!("");
| ^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0507]: cannot move out of static item `settings_dir`
diff --git a/tests/ui/consts/issue-16538.stderr b/tests/ui/consts/issue-16538.stderr
index 3981b4ada491..c4f5364b4d78 100644
--- a/tests/ui/consts/issue-16538.stderr
+++ b/tests/ui/consts/issue-16538.stderr
@@ -5,7 +5,7 @@ LL | static foo: &Y::X = &*Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
--> $DIR/issue-16538.rs:11:22
diff --git a/tests/ui/consts/issue-32829-2.stderr b/tests/ui/consts/issue-32829-2.stderr
index 0fec3581873e..bd0b8c15b558 100644
--- a/tests/ui/consts/issue-32829-2.stderr
+++ b/tests/ui/consts/issue-32829-2.stderr
@@ -13,7 +13,7 @@ LL | invalid();
| ^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
error[E0015]: cannot call non-const fn `invalid` in statics
--> $DIR/issue-32829-2.rs:54:9
@@ -22,7 +22,7 @@ LL | invalid();
| ^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
error: aborting due to 3 previous errors
diff --git a/tests/ui/consts/mir_check_nonconst.stderr b/tests/ui/consts/mir_check_nonconst.stderr
index ea6a8b8ee4a5..95d64622ad7a 100644
--- a/tests/ui/consts/mir_check_nonconst.stderr
+++ b/tests/ui/consts/mir_check_nonconst.stderr
@@ -5,7 +5,7 @@ LL | static foo: Foo = bar();
| ^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
error: aborting due to 1 previous error
diff --git a/tests/ui/issues/issue-25901.stderr b/tests/ui/issues/issue-25901.stderr
index 5c19abffa029..3fedfd964170 100644
--- a/tests/ui/issues/issue-25901.stderr
+++ b/tests/ui/issues/issue-25901.stderr
@@ -16,7 +16,7 @@ note: impl defined here, but it is not `const`
LL | impl Deref for A {
| ^^^^^^^^^^^^^^^^
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
diff --git a/tests/ui/issues/issue-7364.stderr b/tests/ui/issues/issue-7364.stderr
index 3bf59a6d7114..d5b6dde1f10e 100644
--- a/tests/ui/issues/issue-7364.stderr
+++ b/tests/ui/issues/issue-7364.stderr
@@ -18,7 +18,7 @@ LL | static boxed: Box> = Box::new(RefCell::new(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
error: aborting due to 2 previous errors
diff --git a/tests/ui/lint/suspicious-double-ref-op.rs b/tests/ui/lint/suspicious-double-ref-op.rs
index bc8c23c7b895..5aeb81dbd65a 100644
--- a/tests/ui/lint/suspicious-double-ref-op.rs
+++ b/tests/ui/lint/suspicious-double-ref-op.rs
@@ -1,4 +1,3 @@
-#![feature(lazy_cell)]
#![deny(suspicious_double_ref_op, noop_method_call)]
use std::borrow::Borrow;
diff --git a/tests/ui/lint/suspicious-double-ref-op.stderr b/tests/ui/lint/suspicious-double-ref-op.stderr
index f5a71d40fc13..c956843c5078 100644
--- a/tests/ui/lint/suspicious-double-ref-op.stderr
+++ b/tests/ui/lint/suspicious-double-ref-op.stderr
@@ -1,29 +1,29 @@
error: using `.clone()` on a double reference, which returns `&Vec` instead of cloning the inner type
- --> $DIR/suspicious-double-ref-op.rs:15:23
+ --> $DIR/suspicious-double-ref-op.rs:14:23
|
LL | let z: &Vec<_> = y.clone();
| ^^^^^^^^
|
note: the lint level is defined here
- --> $DIR/suspicious-double-ref-op.rs:2:9
+ --> $DIR/suspicious-double-ref-op.rs:1:9
|
LL | #![deny(suspicious_double_ref_op, noop_method_call)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: using `.clone()` on a double reference, which returns `&CloneType` instead of cloning the inner type
- --> $DIR/suspicious-double-ref-op.rs:33:63
+ --> $DIR/suspicious-double-ref-op.rs:32:63
|
LL | let clone_type_ref_clone: &CloneType = clone_type_ref.clone();
| ^^^^^^^^
error: using `.deref()` on a double reference, which returns `&PlainType` instead of dereferencing the inner type
- --> $DIR/suspicious-double-ref-op.rs:37:63
+ --> $DIR/suspicious-double-ref-op.rs:36:63
|
LL | let non_deref_type_deref: &PlainType = non_deref_type.deref();
| ^^^^^^^^
error: using `.clone()` on a double reference, which returns `&str` instead of cloning the inner type
- --> $DIR/suspicious-double-ref-op.rs:41:44
+ --> $DIR/suspicious-double-ref-op.rs:40:44
|
LL | let _v: Vec<&str> = xs.iter().map(|x| x.clone()).collect(); // could use `*x` instead
| ^^^^^^^^
diff --git a/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr b/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr
index 7b896ce14266..66b57c772d54 100644
--- a/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr
+++ b/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr
@@ -352,7 +352,7 @@ LL | static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]);
| ^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs
index d43fabcedec5..7bd372c16952 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/nested-closure.rs
@@ -1,6 +1,6 @@
//@ check-pass
-#![feature(const_trait_impl, lazy_cell)]
+#![feature(const_trait_impl)]
use std::sync::LazyLock;
diff --git a/tests/ui/static/static-mut-not-constant.stderr b/tests/ui/static/static-mut-not-constant.stderr
index d125bec59435..46dc175cb298 100644
--- a/tests/ui/static/static-mut-not-constant.stderr
+++ b/tests/ui/static/static-mut-not-constant.stderr
@@ -5,7 +5,7 @@ LL | static mut a: Box = Box::new(3);
| ^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
error: aborting due to 1 previous error
diff --git a/tests/ui/static/static-vec-repeat-not-constant.stderr b/tests/ui/static/static-vec-repeat-not-constant.stderr
index db0c7eb8d35f..a3b930323d5b 100644
--- a/tests/ui/static/static-vec-repeat-not-constant.stderr
+++ b/tests/ui/static/static-vec-repeat-not-constant.stderr
@@ -5,7 +5,7 @@ LL | static a: [isize; 2] = [foo(); 2];
| ^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
error: aborting due to 1 previous error
diff --git a/tests/ui/statics/check-values-constraints.stderr b/tests/ui/statics/check-values-constraints.stderr
index 45a699f575fb..24763c175fc8 100644
--- a/tests/ui/statics/check-values-constraints.stderr
+++ b/tests/ui/statics/check-values-constraints.stderr
@@ -26,7 +26,7 @@ LL | static STATIC11: Vec = vec![MyOwned];
| ^^^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0015]: cannot call non-const fn `::to_string` in statics
@@ -36,7 +36,7 @@ LL | field2: SafeEnum::Variant4("str".to_string()),
| ^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
LL + #![feature(const_trait_impl)]
@@ -57,7 +57,7 @@ LL | vec![MyOwned],
| ^^^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0010]: allocations are not allowed in statics
@@ -75,7 +75,7 @@ LL | vec![MyOwned],
| ^^^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0010]: allocations are not allowed in statics
@@ -93,7 +93,7 @@ LL | &vec![MyOwned],
| ^^^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0010]: allocations are not allowed in statics
@@ -111,7 +111,7 @@ LL | &vec![MyOwned],
| ^^^^^^^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0010]: allocations are not allowed in statics
@@ -129,7 +129,7 @@ LL | static STATIC19: Vec = vec![3];
| ^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0010]: allocations are not allowed in statics
@@ -147,7 +147,7 @@ LL | static x: Vec = vec![3];
| ^^^^^^^
|
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
- = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+ = note: consider wrapping this expression in `std::sync::LazyLock::new(|| ...)`
= note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
error[E0507]: cannot move out of static item `x`
From 214c49837a56c402ab28f7dd5eff08c7ae709c09 Mon Sep 17 00:00:00 2001
From: Tobias Bucher
Date: Wed, 6 Mar 2024 12:42:32 +0100
Subject: [PATCH 002/101] Less syscalls for the `copy_file_range` probe
If it's obvious from the actual syscall results themselves that the
syscall is supported or unsupported, don't do an extra syscall with an
invalid file descriptor.
CC #122052
---
library/std/src/sys/pal/unix/kernel_copy.rs | 71 ++++++++++++++-------
1 file changed, 48 insertions(+), 23 deletions(-)
diff --git a/library/std/src/sys/pal/unix/kernel_copy.rs b/library/std/src/sys/pal/unix/kernel_copy.rs
index 18acd5ecccd5..60f4e55755d7 100644
--- a/library/std/src/sys/pal/unix/kernel_copy.rs
+++ b/library/std/src/sys/pal/unix/kernel_copy.rs
@@ -560,6 +560,12 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) ->
// We store the availability in a global to avoid unnecessary syscalls
static HAS_COPY_FILE_RANGE: AtomicU8 = AtomicU8::new(NOT_PROBED);
+ let mut have_probed = match HAS_COPY_FILE_RANGE.load(Ordering::Relaxed) {
+ NOT_PROBED => false,
+ UNAVAILABLE => return CopyResult::Fallback(0),
+ _ => true,
+ };
+
syscall! {
fn copy_file_range(
fd_in: libc::c_int,
@@ -571,26 +577,6 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) ->
) -> libc::ssize_t
}
- match HAS_COPY_FILE_RANGE.load(Ordering::Relaxed) {
- NOT_PROBED => {
- // EPERM can indicate seccomp filters or an immutable file.
- // To distinguish these cases we probe with invalid file descriptors which should result in EBADF if the syscall is supported
- // and some other error (ENOSYS or EPERM) if it's not available
- let result = unsafe {
- cvt(copy_file_range(INVALID_FD, ptr::null_mut(), INVALID_FD, ptr::null_mut(), 1, 0))
- };
-
- if matches!(result.map_err(|e| e.raw_os_error()), Err(Some(EBADF))) {
- HAS_COPY_FILE_RANGE.store(AVAILABLE, Ordering::Relaxed);
- } else {
- HAS_COPY_FILE_RANGE.store(UNAVAILABLE, Ordering::Relaxed);
- return CopyResult::Fallback(0);
- }
- }
- UNAVAILABLE => return CopyResult::Fallback(0),
- _ => {}
- };
-
let mut written = 0u64;
while written < max_len {
let bytes_to_copy = cmp::min(max_len - written, usize::MAX as u64);
@@ -604,6 +590,11 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) ->
cvt(copy_file_range(reader, ptr::null_mut(), writer, ptr::null_mut(), bytes_to_copy, 0))
};
+ if !have_probed && copy_result.is_ok() {
+ have_probed = true;
+ HAS_COPY_FILE_RANGE.store(AVAILABLE, Ordering::Relaxed);
+ }
+
match copy_result {
Ok(0) if written == 0 => {
// fallback to work around several kernel bugs where copy_file_range will fail to
@@ -616,10 +607,44 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) ->
Ok(0) => return CopyResult::Ended(written), // reached EOF
Ok(ret) => written += ret as u64,
Err(err) => {
- return match err.raw_os_error() {
+ let raw_os_error = match err.raw_os_error() {
+ Some(raw) => raw,
+ _ => return CopyResult::Error(err, written),
+ };
+ return match raw_os_error {
// when file offset + max_length > u64::MAX
- Some(EOVERFLOW) => CopyResult::Fallback(written),
- Some(ENOSYS | EXDEV | EINVAL | EPERM | EOPNOTSUPP | EBADF) if written == 0 => {
+ EOVERFLOW => CopyResult::Fallback(written),
+ ENOSYS | EXDEV | EINVAL | EPERM | EOPNOTSUPP | EBADF if written == 0 => {
+ if !have_probed {
+ if raw_os_error == ENOSYS {
+ HAS_COPY_FILE_RANGE.store(UNAVAILABLE, Ordering::Relaxed);
+ } else {
+ // EPERM can indicate seccomp filters or an
+ // immutable file. To distinguish these cases
+ // we probe with invalid file descriptors which
+ // should result in EBADF if the syscall is
+ // supported and some other error (ENOSYS or
+ // EPERM) if it's not available.
+ let result = unsafe {
+ cvt(copy_file_range(
+ INVALID_FD,
+ ptr::null_mut(),
+ INVALID_FD,
+ ptr::null_mut(),
+ 1,
+ 0,
+ ))
+ };
+
+ if matches!(result.map_err(|e| e.raw_os_error()), Err(Some(EBADF)))
+ {
+ HAS_COPY_FILE_RANGE.store(AVAILABLE, Ordering::Relaxed);
+ } else {
+ HAS_COPY_FILE_RANGE.store(UNAVAILABLE, Ordering::Relaxed);
+ }
+ }
+ }
+
// Try fallback io::copy if either:
// - Kernel version is < 4.5 (ENOSYS¹)
// - Files are mounted on different fs (EXDEV)
From 5073475b0e5477c3d02c219a4c2e7075891240a7 Mon Sep 17 00:00:00 2001
From: Tobias Bucher
Date: Wed, 6 Mar 2024 14:37:25 +0100
Subject: [PATCH 003/101] Be stricter with `copy_file_range` probe results
---
library/std/src/sys/pal/unix/kernel_copy.rs | 68 +++++++++++----------
1 file changed, 35 insertions(+), 33 deletions(-)
diff --git a/library/std/src/sys/pal/unix/kernel_copy.rs b/library/std/src/sys/pal/unix/kernel_copy.rs
index 60f4e55755d7..1db86bdb180f 100644
--- a/library/std/src/sys/pal/unix/kernel_copy.rs
+++ b/library/std/src/sys/pal/unix/kernel_copy.rs
@@ -607,42 +607,44 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) ->
Ok(0) => return CopyResult::Ended(written), // reached EOF
Ok(ret) => written += ret as u64,
Err(err) => {
- let raw_os_error = match err.raw_os_error() {
- Some(raw) => raw,
- _ => return CopyResult::Error(err, written),
- };
- return match raw_os_error {
+ return match err.raw_os_error() {
// when file offset + max_length > u64::MAX
- EOVERFLOW => CopyResult::Fallback(written),
- ENOSYS | EXDEV | EINVAL | EPERM | EOPNOTSUPP | EBADF if written == 0 => {
+ Some(EOVERFLOW) => CopyResult::Fallback(written),
+ Some(raw_os_error @ (ENOSYS | EXDEV | EINVAL | EPERM | EOPNOTSUPP | EBADF))
+ if written == 0 =>
+ {
if !have_probed {
- if raw_os_error == ENOSYS {
- HAS_COPY_FILE_RANGE.store(UNAVAILABLE, Ordering::Relaxed);
- } else {
- // EPERM can indicate seccomp filters or an
- // immutable file. To distinguish these cases
- // we probe with invalid file descriptors which
- // should result in EBADF if the syscall is
- // supported and some other error (ENOSYS or
- // EPERM) if it's not available.
- let result = unsafe {
- cvt(copy_file_range(
- INVALID_FD,
- ptr::null_mut(),
- INVALID_FD,
- ptr::null_mut(),
- 1,
- 0,
- ))
- };
-
- if matches!(result.map_err(|e| e.raw_os_error()), Err(Some(EBADF)))
- {
- HAS_COPY_FILE_RANGE.store(AVAILABLE, Ordering::Relaxed);
- } else {
- HAS_COPY_FILE_RANGE.store(UNAVAILABLE, Ordering::Relaxed);
+ let available = match raw_os_error {
+ EPERM => {
+ // EPERM can indicate seccomp filters or an
+ // immutable file. To distinguish these
+ // cases we probe with invalid file
+ // descriptors which should result in EBADF
+ // if the syscall is supported and EPERM or
+ // ENOSYS if it's not available.
+ match unsafe {
+ cvt(copy_file_range(
+ INVALID_FD,
+ ptr::null_mut(),
+ INVALID_FD,
+ ptr::null_mut(),
+ 1,
+ 0,
+ ))
+ .map_err(|e| e.raw_os_error())
+ } {
+ Err(Some(EPERM | ENOSYS)) => UNAVAILABLE,
+ Err(Some(EBADF)) => AVAILABLE,
+ Ok(_) => panic!("unexpected copy_file_range probe success"),
+ // Treat other errors as the syscall
+ // being unavailable.
+ Err(_) => UNAVAILABLE,
+ }
}
- }
+ ENOSYS => UNAVAILABLE,
+ _ => AVAILABLE,
+ };
+ HAS_COPY_FILE_RANGE.store(available, Ordering::Relaxed);
}
// Try fallback io::copy if either:
From 62a104df983522de8fe06ff866a47b3938fbd561 Mon Sep 17 00:00:00 2001
From: Veera
Date: Tue, 16 Apr 2024 18:15:37 -0400
Subject: [PATCH 004/101] Update Tests
---
.../c-variadic/variadic-ffi-no-fixed-args.rs | 5 +-
.../variadic-ffi-no-fixed-args.stderr | 8 --
.../variadic-ffi-semantic-restrictions.rs | 8 --
.../variadic-ffi-semantic-restrictions.stderr | 114 ++++++------------
4 files changed, 40 insertions(+), 95 deletions(-)
delete mode 100644 tests/ui/c-variadic/variadic-ffi-no-fixed-args.stderr
diff --git a/tests/ui/c-variadic/variadic-ffi-no-fixed-args.rs b/tests/ui/c-variadic/variadic-ffi-no-fixed-args.rs
index 588c15a18297..b8841e88c4f4 100644
--- a/tests/ui/c-variadic/variadic-ffi-no-fixed-args.rs
+++ b/tests/ui/c-variadic/variadic-ffi-no-fixed-args.rs
@@ -1,6 +1,9 @@
+//@ build-pass
+
+// Supported since C23
+// https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2975.pdf
extern "C" {
fn foo(...);
-//~^ ERROR C-variadic function must be declared with at least one named argument
}
fn main() {}
diff --git a/tests/ui/c-variadic/variadic-ffi-no-fixed-args.stderr b/tests/ui/c-variadic/variadic-ffi-no-fixed-args.stderr
deleted file mode 100644
index e268ef3fa681..000000000000
--- a/tests/ui/c-variadic/variadic-ffi-no-fixed-args.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: C-variadic function must be declared with at least one named argument
- --> $DIR/variadic-ffi-no-fixed-args.rs:2:12
- |
-LL | fn foo(...);
- | ^^^
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs
index a2d2388ff508..11126dbc65d2 100644
--- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs
+++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs
@@ -8,14 +8,12 @@ fn f1_1(x: isize, ...) {}
fn f1_2(...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
-//~| ERROR C-variadic function must be declared with at least one named argument
extern "C" fn f2_1(x: isize, ...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
extern "C" fn f2_2(...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
-//~| ERROR C-variadic function must be declared with at least one named argument
extern "C" fn f2_3(..., x: isize) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
@@ -26,7 +24,6 @@ extern "C" fn f3_1(x: isize, ...) {}
extern "C" fn f3_2(...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
-//~| ERROR C-variadic function must be declared with at least one named argument
extern "C" fn f3_3(..., x: isize) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
@@ -47,8 +44,6 @@ const extern "C" fn f4_3(..., x: isize, ...) {}
//~| ERROR `...` must be the last argument of a C-variadic function
extern "C" {
- fn e_f1(...);
- //~^ ERROR C-variadic function must be declared with at least one named argument
fn e_f2(..., x: isize);
//~^ ERROR `...` must be the last argument of a C-variadic function
}
@@ -60,7 +55,6 @@ impl X {
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
fn i_f2(...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
- //~| ERROR C-variadic function must be declared with at least one named argument
fn i_f3(..., x: isize, ...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~| ERROR `...` must be the last argument of a C-variadic function
@@ -80,10 +74,8 @@ trait T {
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
fn t_f3(...) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
- //~| ERROR C-variadic function must be declared with at least one named argument
fn t_f4(...);
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
- //~| ERROR C-variadic function must be declared with at least one named argument
fn t_f5(..., x: isize) {}
//~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
//~| ERROR `...` must be the last argument of a C-variadic function
diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr
index 6a65ed79d4fb..f71e3863440f 100644
--- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr
+++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr
@@ -4,12 +4,6 @@ error: only foreign or `unsafe extern "C"` functions may be C-variadic
LL | fn f1_1(x: isize, ...) {}
| ^^^
-error: C-variadic function must be declared with at least one named argument
- --> $DIR/variadic-ffi-semantic-restrictions.rs:9:9
- |
-LL | fn f1_2(...) {}
- | ^^^
-
error: only foreign or `unsafe extern "C"` functions may be C-variadic
--> $DIR/variadic-ffi-semantic-restrictions.rs:9:9
|
@@ -17,91 +11,79 @@ LL | fn f1_2(...) {}
| ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:13:30
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:12:30
|
LL | extern "C" fn f2_1(x: isize, ...) {}
| ^^^
-error: C-variadic function must be declared with at least one named argument
- --> $DIR/variadic-ffi-semantic-restrictions.rs:16:20
- |
-LL | extern "C" fn f2_2(...) {}
- | ^^^
-
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:16:20
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:15:20
|
LL | extern "C" fn f2_2(...) {}
| ^^^
error: `...` must be the last argument of a C-variadic function
- --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20
|
LL | extern "C" fn f2_3(..., x: isize) {}
| ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:20:20
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:18:20
|
LL | extern "C" fn f2_3(..., x: isize) {}
| ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:24:30
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:22:30
|
LL | extern "C" fn f3_1(x: isize, ...) {}
| ^^^
-error: C-variadic function must be declared with at least one named argument
- --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20
- |
-LL | extern "C" fn f3_2(...) {}
- | ^^^
-
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:27:20
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:25:20
|
LL | extern "C" fn f3_2(...) {}
| ^^^
error: `...` must be the last argument of a C-variadic function
- --> $DIR/variadic-ffi-semantic-restrictions.rs:31:20
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:28:20
|
LL | extern "C" fn f3_3(..., x: isize) {}
| ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:31:20
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:28:20
|
LL | extern "C" fn f3_3(..., x: isize) {}
| ^^^
error: functions cannot be both `const` and C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:35:1
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:32:1
|
LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
| ^^^^^ `const` because of this ^^^ C-variadic because of this
error: functions cannot be both `const` and C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:39:1
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:36:1
|
LL | const extern "C" fn f4_2(x: isize, ...) {}
| ^^^^^ `const` because of this ^^^ C-variadic because of this
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:39:36
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:36:36
|
LL | const extern "C" fn f4_2(x: isize, ...) {}
| ^^^
error: `...` must be the last argument of a C-variadic function
- --> $DIR/variadic-ffi-semantic-restrictions.rs:44:26
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:41:26
|
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
| ^^^
error: functions cannot be both `const` and C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:44:1
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:41:1
|
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
| ^^^^^ ^^^ ^^^ C-variadic because of this
@@ -110,67 +92,55 @@ LL | const extern "C" fn f4_3(..., x: isize, ...) {}
| `const` because of this
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:44:26
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:41:26
|
LL | const extern "C" fn f4_3(..., x: isize, ...) {}
| ^^^ ^^^
-error: C-variadic function must be declared with at least one named argument
- --> $DIR/variadic-ffi-semantic-restrictions.rs:50:13
- |
-LL | fn e_f1(...);
- | ^^^
-
error: `...` must be the last argument of a C-variadic function
- --> $DIR/variadic-ffi-semantic-restrictions.rs:52:13
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:47:13
|
LL | fn e_f2(..., x: isize);
| ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:59:23
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:54:23
|
LL | fn i_f1(x: isize, ...) {}
| ^^^
-error: C-variadic function must be declared with at least one named argument
- --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13
- |
-LL | fn i_f2(...) {}
- | ^^^
-
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:56:13
|
LL | fn i_f2(...) {}
| ^^^
error: `...` must be the last argument of a C-variadic function
- --> $DIR/variadic-ffi-semantic-restrictions.rs:64:13
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:58:13
|
LL | fn i_f3(..., x: isize, ...) {}
| ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:64:13
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:58:13
|
LL | fn i_f3(..., x: isize, ...) {}
| ^^^ ^^^
error: `...` must be the last argument of a C-variadic function
- --> $DIR/variadic-ffi-semantic-restrictions.rs:67:13
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13
|
LL | fn i_f4(..., x: isize, ...) {}
| ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:67:13
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13
|
LL | fn i_f4(..., x: isize, ...) {}
| ^^^ ^^^
error: functions cannot be both `const` and C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:70:5
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:64:5
|
LL | const fn i_f5(x: isize, ...) {}
| ^^^^^ ^^^ C-variadic because of this
@@ -178,73 +148,61 @@ LL | const fn i_f5(x: isize, ...) {}
| `const` because of this
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:70:29
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:64:29
|
LL | const fn i_f5(x: isize, ...) {}
| ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:77:23
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:71:23
|
LL | fn t_f1(x: isize, ...) {}
| ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:79:23
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:73:23
|
LL | fn t_f2(x: isize, ...);
| ^^^
-error: C-variadic function must be declared with at least one named argument
- --> $DIR/variadic-ffi-semantic-restrictions.rs:81:13
+error: only foreign or `unsafe extern "C"` functions may be C-variadic
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:75:13
|
LL | fn t_f3(...) {}
| ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:81:13
- |
-LL | fn t_f3(...) {}
- | ^^^
-
-error: C-variadic function must be declared with at least one named argument
- --> $DIR/variadic-ffi-semantic-restrictions.rs:84:13
- |
-LL | fn t_f4(...);
- | ^^^
-
-error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:84:13
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:77:13
|
LL | fn t_f4(...);
| ^^^
error: `...` must be the last argument of a C-variadic function
- --> $DIR/variadic-ffi-semantic-restrictions.rs:87:13
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:79:13
|
LL | fn t_f5(..., x: isize) {}
| ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:87:13
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:79:13
|
LL | fn t_f5(..., x: isize) {}
| ^^^
error: `...` must be the last argument of a C-variadic function
- --> $DIR/variadic-ffi-semantic-restrictions.rs:90:13
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:82:13
|
LL | fn t_f6(..., x: isize);
| ^^^
error: only foreign or `unsafe extern "C"` functions may be C-variadic
- --> $DIR/variadic-ffi-semantic-restrictions.rs:90:13
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:82:13
|
LL | fn t_f6(..., x: isize);
| ^^^
error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
- --> $DIR/variadic-ffi-semantic-restrictions.rs:35:43
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:32:43
|
LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
| ^^^ - value is dropped here
@@ -252,7 +210,7 @@ LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
| the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
- --> $DIR/variadic-ffi-semantic-restrictions.rs:39:36
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:36:36
|
LL | const extern "C" fn f4_2(x: isize, ...) {}
| ^^^ - value is dropped here
@@ -260,13 +218,13 @@ LL | const extern "C" fn f4_2(x: isize, ...) {}
| the destructor for this type cannot be evaluated in constant functions
error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
- --> $DIR/variadic-ffi-semantic-restrictions.rs:70:29
+ --> $DIR/variadic-ffi-semantic-restrictions.rs:64:29
|
LL | const fn i_f5(x: isize, ...) {}
| ^^^ - value is dropped here
| |
| the destructor for this type cannot be evaluated in constant functions
-error: aborting due to 43 previous errors
+error: aborting due to 36 previous errors
For more information about this error, try `rustc --explain E0493`.
From f005b451c2eeb018e3c2c6e6653636981cfa7f1a Mon Sep 17 00:00:00 2001
From: Veera
Date: Tue, 16 Apr 2024 18:53:05 -0400
Subject: [PATCH 005/101] Support C23's Variadics Without a Named Parameter
This PR removes the static check that disallowed extern functions
with ellipsis (varargs) as the only parameter since this is now
valid in C23.
Also, adds a doc comment for `check_decl_cvariadic_pos()` and
fixes the name of the function (`varadic` -> `variadic`).
---
compiler/rustc_ast_passes/messages.ftl | 3 ---
compiler/rustc_ast_passes/src/ast_validation.rs | 12 +++++-------
compiler/rustc_ast_passes/src/errors.rs | 7 -------
3 files changed, 5 insertions(+), 17 deletions(-)
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index a3731e94276b..f578165f369c 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -97,9 +97,6 @@ ast_passes_fn_body_extern = incorrect function inside `extern` block
ast_passes_fn_param_c_var_args_not_last =
`...` must be the last argument of a C-variadic function
-ast_passes_fn_param_c_var_args_only =
- C-variadic function must be declared with at least one named argument
-
ast_passes_fn_param_doc_comment =
documentation comments cannot be applied to function parameters
.label = doc comments are not allowed here
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 495e90e967b9..63aed6493dc4 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -365,7 +365,7 @@ impl<'a> AstValidator<'a> {
fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
self.check_decl_num_args(fn_decl);
- self.check_decl_cvaradic_pos(fn_decl);
+ self.check_decl_cvariadic_pos(fn_decl);
self.check_decl_attrs(fn_decl);
self.check_decl_self_param(fn_decl, self_semantic);
}
@@ -380,13 +380,11 @@ impl<'a> AstValidator<'a> {
}
}
- fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) {
+ /// Emits an error if a function declaration has a variadic parameter in the
+ /// beginning or middle of parameter list.
+ /// Example: `fn foo(..., x: i32)` will emit an error.
+ fn check_decl_cvariadic_pos(&self, fn_decl: &FnDecl) {
match &*fn_decl.inputs {
- [Param { ty, span, .. }] => {
- if let TyKind::CVarArgs = ty.kind {
- self.dcx().emit_err(errors::FnParamCVarArgsOnly { span: *span });
- }
- }
[ps @ .., _] => {
for Param { ty, span, .. } in ps {
if let TyKind::CVarArgs = ty.kind {
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index f397c949e048..0e4599f55ba5 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -92,13 +92,6 @@ pub struct FnParamTooMany {
pub max_num_args: usize,
}
-#[derive(Diagnostic)]
-#[diag(ast_passes_fn_param_c_var_args_only)]
-pub struct FnParamCVarArgsOnly {
- #[primary_span]
- pub span: Span,
-}
-
#[derive(Diagnostic)]
#[diag(ast_passes_fn_param_c_var_args_not_last)]
pub struct FnParamCVarArgsNotLast {
From 7d67ee5aba849939f64ed821a757518f211620a7 Mon Sep 17 00:00:00 2001
From: Tobias Bucher
Date: Sat, 27 Apr 2024 18:44:30 +0200
Subject: [PATCH 006/101] Lift the probe code of `copy_file_range` into a
function
---
library/std/src/sys/pal/unix/kernel_copy.rs | 60 +++++++++++----------
1 file changed, 31 insertions(+), 29 deletions(-)
diff --git a/library/std/src/sys/pal/unix/kernel_copy.rs b/library/std/src/sys/pal/unix/kernel_copy.rs
index 1db86bdb180f..cd38b7c07e2b 100644
--- a/library/std/src/sys/pal/unix/kernel_copy.rs
+++ b/library/std/src/sys/pal/unix/kernel_copy.rs
@@ -577,6 +577,23 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) ->
) -> libc::ssize_t
}
+ fn probe_copy_file_range_support() -> u8 {
+ // In some cases, we cannot determine availability from the first
+ // `copy_file_range` call. In this case, we probe with an invalid file
+ // descriptor so that the results are easily interpretable.
+ match unsafe {
+ cvt(copy_file_range(INVALID_FD, ptr::null_mut(), INVALID_FD, ptr::null_mut(), 1, 0))
+ .map_err(|e| e.raw_os_error())
+ } {
+ Err(Some(EPERM | ENOSYS)) => UNAVAILABLE,
+ Err(Some(EBADF)) => AVAILABLE,
+ Ok(_) => panic!("unexpected copy_file_range probe success"),
+ // Treat other errors as the syscall
+ // being unavailable.
+ Err(_) => UNAVAILABLE,
+ }
+ }
+
let mut written = 0u64;
while written < max_len {
let bytes_to_copy = cmp::min(max_len - written, usize::MAX as u64);
@@ -614,35 +631,20 @@ pub(super) fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) ->
if written == 0 =>
{
if !have_probed {
- let available = match raw_os_error {
- EPERM => {
- // EPERM can indicate seccomp filters or an
- // immutable file. To distinguish these
- // cases we probe with invalid file
- // descriptors which should result in EBADF
- // if the syscall is supported and EPERM or
- // ENOSYS if it's not available.
- match unsafe {
- cvt(copy_file_range(
- INVALID_FD,
- ptr::null_mut(),
- INVALID_FD,
- ptr::null_mut(),
- 1,
- 0,
- ))
- .map_err(|e| e.raw_os_error())
- } {
- Err(Some(EPERM | ENOSYS)) => UNAVAILABLE,
- Err(Some(EBADF)) => AVAILABLE,
- Ok(_) => panic!("unexpected copy_file_range probe success"),
- // Treat other errors as the syscall
- // being unavailable.
- Err(_) => UNAVAILABLE,
- }
- }
- ENOSYS => UNAVAILABLE,
- _ => AVAILABLE,
+ let available = if matches!(raw_os_error, ENOSYS | EOPNOTSUPP | EPERM) {
+ // EPERM can indicate seccomp filters or an
+ // immutable file. To distinguish these
+ // cases we probe with invalid file
+ // descriptors which should result in EBADF
+ // if the syscall is supported and EPERM or
+ // ENOSYS if it's not available.
+ //
+ // For EOPNOTSUPP, see below. In the case of
+ // ENOSYS, we try to cover for faulty FUSE
+ // drivers.
+ probe_copy_file_range_support()
+ } else {
+ AVAILABLE
};
HAS_COPY_FILE_RANGE.store(available, Ordering::Relaxed);
}
From 39a653f632a4d5a2d3da54496b221e66923625ce Mon Sep 17 00:00:00 2001
From: morine0122
Date: Fri, 26 Apr 2024 22:02:58 +0900
Subject: [PATCH 007/101] Fix coercion of async block
---
.../crates/hir-ty/src/infer/expr.rs | 17 +++++++++++-
.../crates/ide/src/inlay_hints/bind_pat.rs | 26 +++++++++++++++++++
2 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
index 38076fce8f8f..bccad751fc20 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs
@@ -933,8 +933,23 @@ impl InferenceContext<'_> {
let prev_ret_coercion =
mem::replace(&mut self.return_coercion, Some(CoerceMany::new(ret_ty.clone())));
+ let expected = &Expectation::has_type(ret_ty);
let (_, inner_ty) = self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
- this.infer_block(tgt_expr, *id, statements, *tail, None, &Expectation::has_type(ret_ty))
+ let ty = this.infer_block(tgt_expr, *id, statements, *tail, None, expected);
+ if let Some(target) = expected.only_has_type(&mut this.table) {
+ match this.coerce(Some(tgt_expr), &ty, &target) {
+ Ok(res) => res,
+ Err(_) => {
+ this.result.type_mismatches.insert(
+ tgt_expr.into(),
+ TypeMismatch { expected: target.clone(), actual: ty.clone() },
+ );
+ target
+ }
+ }
+ } else {
+ ty
+ }
});
self.diverges = prev_diverges;
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
index 0cb8c485b2f2..3311bb48ad65 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/bind_pat.rs
@@ -1120,4 +1120,30 @@ fn test() {
"#,
);
}
+
+ #[test]
+ fn type_hints_async_block() {
+ check_types(
+ r#"
+//- minicore: future
+async fn main() {
+ let _x = async { 8_i32 };
+ //^^ impl Future