mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-31 00:53:48 +00:00
Auto merge of #114272 - workingjubilee:rollup-ll9lwon, r=workingjubilee
Rollup of 4 pull requests Successful merges: - #95965 (Stabilize const-weak-new) - #109075 (Use `LazyLock` to lazily resolve backtraces) - #113741 (Don't install default projection bound for return-position `impl Trait` in trait methods with no body) - #114268 (Fix empty_write since rust version attribute) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
dfc9d3fee6
@ -1144,13 +1144,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
|
||||
let assoc_item = tcx.associated_item(def_id);
|
||||
match assoc_item.container {
|
||||
ty::AssocItemContainer::ImplContainer => true,
|
||||
// Always encode RPITITs, since we need to be able to project
|
||||
// from an RPITIT associated item to an opaque when installing
|
||||
// the default projection predicates in default trait methods
|
||||
// with RPITITs.
|
||||
ty::AssocItemContainer::TraitContainer => {
|
||||
assoc_item.defaultness(tcx).has_value() || assoc_item.is_impl_trait_in_trait()
|
||||
}
|
||||
ty::AssocItemContainer::TraitContainer => assoc_item.defaultness(tcx).has_value(),
|
||||
}
|
||||
}
|
||||
DefKind::TyParam => {
|
||||
|
@ -129,7 +129,9 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||
// sure that this will succeed without errors anyway.
|
||||
|
||||
if tcx.def_kind(def_id) == DefKind::AssocFn
|
||||
&& tcx.associated_item(def_id).container == ty::AssocItemContainer::TraitContainer
|
||||
&& let assoc_item = tcx.associated_item(def_id)
|
||||
&& assoc_item.container == ty::AssocItemContainer::TraitContainer
|
||||
&& assoc_item.defaultness(tcx).has_value()
|
||||
{
|
||||
let sig = tcx.fn_sig(def_id).instantiate_identity();
|
||||
// We accounted for the binder of the fn sig, so skip the binder.
|
||||
|
@ -2719,7 +2719,7 @@ impl<T> Weak<T> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "downgraded_weak", since = "1.10.0")]
|
||||
#[rustc_const_unstable(feature = "const_weak_new", issue = "95091", reason = "recently added")]
|
||||
#[rustc_const_stable(feature = "const_weak_new", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[must_use]
|
||||
pub const fn new() -> Weak<T> {
|
||||
Weak {
|
||||
|
@ -2503,7 +2503,7 @@ impl<T> Weak<T> {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "downgraded_weak", since = "1.10.0")]
|
||||
#[rustc_const_unstable(feature = "const_weak_new", issue = "95091", reason = "recently added")]
|
||||
#[rustc_const_stable(feature = "const_weak_new", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[must_use]
|
||||
pub const fn new() -> Weak<T> {
|
||||
Weak {
|
||||
|
@ -89,12 +89,11 @@ mod tests;
|
||||
// a backtrace or actually symbolizing it.
|
||||
|
||||
use crate::backtrace_rs::{self, BytesOrWideString};
|
||||
use crate::cell::UnsafeCell;
|
||||
use crate::env;
|
||||
use crate::ffi::c_void;
|
||||
use crate::fmt;
|
||||
use crate::sync::atomic::{AtomicUsize, Ordering::Relaxed};
|
||||
use crate::sync::Once;
|
||||
use crate::sync::LazyLock;
|
||||
use crate::sys_common::backtrace::{lock, output_filename};
|
||||
use crate::vec::Vec;
|
||||
|
||||
@ -133,12 +132,11 @@ pub enum BacktraceStatus {
|
||||
enum Inner {
|
||||
Unsupported,
|
||||
Disabled,
|
||||
Captured(LazilyResolvedCapture),
|
||||
Captured(LazyLock<Capture, LazyResolve>),
|
||||
}
|
||||
|
||||
struct Capture {
|
||||
actual_start: usize,
|
||||
resolved: bool,
|
||||
frames: Vec<BacktraceFrame>,
|
||||
}
|
||||
|
||||
@ -179,7 +177,7 @@ impl fmt::Debug for Backtrace {
|
||||
let capture = match &self.inner {
|
||||
Inner::Unsupported => return fmt.write_str("<unsupported>"),
|
||||
Inner::Disabled => return fmt.write_str("<disabled>"),
|
||||
Inner::Captured(c) => c.force(),
|
||||
Inner::Captured(c) => &**c,
|
||||
};
|
||||
|
||||
let frames = &capture.frames[capture.actual_start..];
|
||||
@ -347,11 +345,10 @@ impl Backtrace {
|
||||
let inner = if frames.is_empty() {
|
||||
Inner::Unsupported
|
||||
} else {
|
||||
Inner::Captured(LazilyResolvedCapture::new(Capture {
|
||||
Inner::Captured(LazyLock::new(lazy_resolve(Capture {
|
||||
actual_start: actual_start.unwrap_or(0),
|
||||
frames,
|
||||
resolved: false,
|
||||
}))
|
||||
})))
|
||||
};
|
||||
|
||||
Backtrace { inner }
|
||||
@ -376,7 +373,7 @@ impl<'a> Backtrace {
|
||||
#[must_use]
|
||||
#[unstable(feature = "backtrace_frames", issue = "79676")]
|
||||
pub fn frames(&'a self) -> &'a [BacktraceFrame] {
|
||||
if let Inner::Captured(c) = &self.inner { &c.force().frames } else { &[] }
|
||||
if let Inner::Captured(c) = &self.inner { &c.frames } else { &[] }
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,7 +383,7 @@ impl fmt::Display for Backtrace {
|
||||
let capture = match &self.inner {
|
||||
Inner::Unsupported => return fmt.write_str("unsupported backtrace"),
|
||||
Inner::Disabled => return fmt.write_str("disabled backtrace"),
|
||||
Inner::Captured(c) => c.force(),
|
||||
Inner::Captured(c) => &**c,
|
||||
};
|
||||
|
||||
let full = fmt.alternate();
|
||||
@ -430,46 +427,15 @@ impl fmt::Display for Backtrace {
|
||||
}
|
||||
}
|
||||
|
||||
struct LazilyResolvedCapture {
|
||||
sync: Once,
|
||||
capture: UnsafeCell<Capture>,
|
||||
}
|
||||
|
||||
impl LazilyResolvedCapture {
|
||||
fn new(capture: Capture) -> Self {
|
||||
LazilyResolvedCapture { sync: Once::new(), capture: UnsafeCell::new(capture) }
|
||||
}
|
||||
|
||||
fn force(&self) -> &Capture {
|
||||
self.sync.call_once(|| {
|
||||
// SAFETY: This exclusive reference can't overlap with any others
|
||||
// `Once` guarantees callers will block until this closure returns
|
||||
// `Once` also guarantees only a single caller will enter this closure
|
||||
unsafe { &mut *self.capture.get() }.resolve();
|
||||
});
|
||||
|
||||
// SAFETY: This shared reference can't overlap with the exclusive reference above
|
||||
unsafe { &*self.capture.get() }
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: Access to the inner value is synchronized using a thread-safe `Once`
|
||||
// So long as `Capture` is `Sync`, `LazilyResolvedCapture` is too
|
||||
unsafe impl Sync for LazilyResolvedCapture where Capture: Sync {}
|
||||
|
||||
impl Capture {
|
||||
fn resolve(&mut self) {
|
||||
// If we're already resolved, nothing to do!
|
||||
if self.resolved {
|
||||
return;
|
||||
}
|
||||
self.resolved = true;
|
||||
type LazyResolve = impl (FnOnce() -> Capture) + Send + Sync;
|
||||
|
||||
fn lazy_resolve(mut capture: Capture) -> LazyResolve {
|
||||
move || {
|
||||
// Use the global backtrace lock to synchronize this as it's a
|
||||
// requirement of the `backtrace` crate, and then actually resolve
|
||||
// everything.
|
||||
let _lock = lock();
|
||||
for frame in self.frames.iter_mut() {
|
||||
for frame in capture.frames.iter_mut() {
|
||||
let symbols = &mut frame.symbols;
|
||||
let frame = match &frame.frame {
|
||||
RawFrame::Actual(frame) => frame,
|
||||
@ -490,6 +456,8 @@ impl Capture {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
capture
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,9 +43,8 @@ fn generate_fake_frames() -> Vec<BacktraceFrame> {
|
||||
#[test]
|
||||
fn test_debug() {
|
||||
let backtrace = Backtrace {
|
||||
inner: Inner::Captured(LazilyResolvedCapture::new(Capture {
|
||||
inner: Inner::Captured(LazyLock::preinit(Capture {
|
||||
actual_start: 1,
|
||||
resolved: true,
|
||||
frames: generate_fake_frames(),
|
||||
})),
|
||||
};
|
||||
@ -66,9 +65,8 @@ fn test_debug() {
|
||||
#[test]
|
||||
fn test_frames() {
|
||||
let backtrace = Backtrace {
|
||||
inner: Inner::Captured(LazilyResolvedCapture::new(Capture {
|
||||
inner: Inner::Captured(LazyLock::preinit(Capture {
|
||||
actual_start: 1,
|
||||
resolved: true,
|
||||
frames: generate_fake_frames(),
|
||||
})),
|
||||
};
|
||||
|
@ -100,7 +100,7 @@ impl SizeHint for Empty {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "empty_write", since = "1.64.0")]
|
||||
#[stable(feature = "empty_write", since = "CURRENT_RUSTC_VERSION")]
|
||||
impl Write for Empty {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
@ -124,7 +124,7 @@ impl Write for Empty {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "empty_write", since = "1.64.0")]
|
||||
#[stable(feature = "empty_write", since = "CURRENT_RUSTC_VERSION")]
|
||||
impl Write for &Empty {
|
||||
#[inline]
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
|
@ -272,6 +272,7 @@
|
||||
#![feature(staged_api)]
|
||||
#![feature(thread_local)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(utf8_chunks)]
|
||||
// tidy-alphabetical-end
|
||||
//
|
||||
|
@ -89,6 +89,15 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
|
||||
LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) }
|
||||
}
|
||||
|
||||
/// Creates a new lazy value that is already initialized.
|
||||
#[inline]
|
||||
#[cfg(test)]
|
||||
pub(crate) fn preinit(value: T) -> LazyLock<T, F> {
|
||||
let once = Once::new();
|
||||
once.call_once(|| {});
|
||||
LazyLock { once, data: UnsafeCell::new(Data { value: ManuallyDrop::new(value) }) }
|
||||
}
|
||||
|
||||
/// Consumes this `LazyLock` returning the stored value.
|
||||
///
|
||||
/// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
|
||||
|
@ -0,0 +1,10 @@
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
||||
struct Wrapper<G: Send>(G);
|
||||
|
||||
trait Foo {
|
||||
fn bar() -> Wrapper<impl Sized>;
|
||||
//~^ ERROR `impl Sized` cannot be sent between threads safely
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,16 @@
|
||||
error[E0277]: `impl Sized` cannot be sent between threads safely
|
||||
--> $DIR/check-wf-on-non-defaulted-rpitit.rs:6:17
|
||||
|
|
||||
LL | fn bar() -> Wrapper<impl Sized>;
|
||||
| ^^^^^^^^^^^^^^^^^^^ `impl Sized` cannot be sent between threads safely
|
||||
|
|
||||
= help: the trait `Send` is not implemented for `impl Sized`
|
||||
note: required by a bound in `Wrapper`
|
||||
--> $DIR/check-wf-on-non-defaulted-rpitit.rs:3:19
|
||||
|
|
||||
LL | struct Wrapper<G: Send>(G);
|
||||
| ^^^^ required by this bound in `Wrapper`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Reference in New Issue
Block a user