Skip to content

Commit 7c3b6c9

Browse files
committed
MaybeLazy: Permit non function-pointer as lazy input
1 parent 124f9fb commit 7c3b6c9

File tree

1 file changed

+42
-23
lines changed

1 file changed

+42
-23
lines changed

compiler/rustc_target/src/spec/maybe_lazy.rs

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use std::fmt::{Debug, Display};
55
use std::ops::Deref;
66
use std::sync::LazyLock;
77

8-
enum MaybeLazyInner<T: 'static + ToOwned + ?Sized> {
9-
Lazy(LazyLock<T::Owned>),
8+
enum MaybeLazyInner<T: 'static + ToOwned + ?Sized, F> {
9+
Lazy(LazyLock<T::Owned, F>),
1010
Cow(Cow<'static, T>),
1111
}
1212

@@ -16,16 +16,16 @@ enum MaybeLazyInner<T: 'static + ToOwned + ?Sized> {
1616
/// They can all be constructed from the [`MaybeLazy::borrowed`], [`MaybeLazy::owned`] and
1717
/// [`MaybeLazy::lazy`] methods.
1818
#[repr(transparent)]
19-
pub struct MaybeLazy<T: 'static + ToOwned + ?Sized> {
19+
pub struct MaybeLazy<T: 'static + ToOwned + ?Sized, F = fn() -> <T as ToOwned>::Owned> {
2020
// Inner state.
2121
//
2222
// Not to be inlined since we may want in the future to
2323
// make this struct usable to statics and we might need to
2424
// workaround const-eval limitation (particulary around drop).
25-
inner: MaybeLazyInner<T>,
25+
inner: MaybeLazyInner<T, F>,
2626
}
2727

28-
impl<T: 'static + ?Sized + ToOwned> MaybeLazy<T> {
28+
impl<T: 'static + ?Sized + ToOwned, F: FnOnce() -> T::Owned> MaybeLazy<T, F> {
2929
/// Create a [`MaybeLazy`] from an borrowed `T`.
3030
#[inline]
3131
pub const fn borrowed(a: &'static T) -> Self {
@@ -38,17 +38,24 @@ impl<T: 'static + ?Sized + ToOwned> MaybeLazy<T> {
3838
MaybeLazy { inner: MaybeLazyInner::Cow(Cow::Owned(a)) }
3939
}
4040

41-
/// Create a [`MaybeLazy`] that is lazy by taking a function pointer.
42-
///
43-
/// This function pointer cannot *ever* take a closure. User can potentially
44-
/// workaround that by using closure-to-fnptr or `const` items.
41+
/// Create a [`MaybeLazy`] from a function-able `F`.
42+
#[inline]
43+
pub const fn lazied(f: F) -> Self {
44+
MaybeLazy { inner: MaybeLazyInner::Lazy(LazyLock::new(f)) }
45+
}
46+
}
47+
48+
impl<T: 'static + ?Sized + ToOwned> MaybeLazy<T> {
49+
/// Create a [`MaybeLazy`] from a function pointer.
4550
#[inline]
4651
pub const fn lazy(a: fn() -> T::Owned) -> Self {
4752
MaybeLazy { inner: MaybeLazyInner::Lazy(LazyLock::new(a)) }
4853
}
4954
}
5055

51-
impl<T: 'static + ?Sized + ToOwned<Owned: Clone>> Clone for MaybeLazy<T> {
56+
impl<T: 'static + ?Sized + ToOwned<Owned: Clone>, F: FnOnce() -> T::Owned> Clone
57+
for MaybeLazy<T, F>
58+
{
5259
#[inline]
5360
fn clone(&self) -> Self {
5461
MaybeLazy {
@@ -60,15 +67,19 @@ impl<T: 'static + ?Sized + ToOwned<Owned: Clone>> Clone for MaybeLazy<T> {
6067
}
6168
}
6269

63-
impl<T: 'static + ?Sized + ToOwned<Owned: Default>> Default for MaybeLazy<T> {
70+
impl<T: 'static + ?Sized + ToOwned<Owned: Default>, F: FnOnce() -> T::Owned> Default
71+
for MaybeLazy<T, F>
72+
{
6473
#[inline]
65-
fn default() -> MaybeLazy<T> {
66-
MaybeLazy::lazy(T::Owned::default)
74+
fn default() -> MaybeLazy<T, F> {
75+
MaybeLazy::owned(T::Owned::default())
6776
}
6877
}
6978

7079
// `Debug`, `Display` and other traits below are implemented in terms of this `Deref`
71-
impl<T: 'static + ?Sized + ToOwned<Owned: Borrow<T>>> Deref for MaybeLazy<T> {
80+
impl<T: 'static + ?Sized + ToOwned<Owned: Borrow<T>>, F: FnOnce() -> T::Owned> Deref
81+
for MaybeLazy<T, F>
82+
{
7283
type Target = T;
7384

7485
#[inline]
@@ -80,46 +91,54 @@ impl<T: 'static + ?Sized + ToOwned<Owned: Borrow<T>>> Deref for MaybeLazy<T> {
8091
}
8192
}
8293

83-
impl<T: 'static + ?Sized + ToOwned<Owned: Debug> + Debug> Debug for MaybeLazy<T> {
94+
impl<T: 'static + ?Sized + ToOwned<Owned: Debug> + Debug, F: FnOnce() -> T::Owned> Debug
95+
for MaybeLazy<T, F>
96+
{
8497
#[inline]
8598
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8699
Debug::fmt(&**self, fmt)
87100
}
88101
}
89102

90-
impl<T: 'static + ?Sized + ToOwned<Owned: Display> + Display> Display for MaybeLazy<T> {
103+
impl<T: 'static + ?Sized + ToOwned<Owned: Display> + Display, F: FnOnce() -> T::Owned> Display
104+
for MaybeLazy<T, F>
105+
{
91106
#[inline]
92107
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
93108
Display::fmt(&**self, fmt)
94109
}
95110
}
96111

97-
impl<T: 'static + ?Sized + ToOwned> AsRef<T> for MaybeLazy<T> {
112+
impl<T: 'static + ?Sized + ToOwned, F: FnOnce() -> T::Owned> AsRef<T> for MaybeLazy<T, F> {
98113
#[inline]
99114
fn as_ref(&self) -> &T {
100115
&**self
101116
}
102117
}
103118

104-
impl<B: ?Sized + PartialEq<C> + ToOwned, C: ?Sized + ToOwned> PartialEq<MaybeLazy<C>>
105-
for MaybeLazy<B>
119+
impl<
120+
B: ?Sized + PartialEq<C> + ToOwned,
121+
C: ?Sized + ToOwned,
122+
F1: FnOnce() -> B::Owned,
123+
F2: FnOnce() -> C::Owned,
124+
> PartialEq<MaybeLazy<C, F2>> for MaybeLazy<B, F1>
106125
{
107126
#[inline]
108-
fn eq(&self, other: &MaybeLazy<C>) -> bool {
127+
fn eq(&self, other: &MaybeLazy<C, F2>) -> bool {
109128
PartialEq::eq(&**self, &**other)
110129
}
111130
}
112131

113-
impl PartialEq<&str> for MaybeLazy<str> {
132+
impl<F: FnOnce() -> String> PartialEq<&str> for MaybeLazy<str, F> {
114133
#[inline]
115134
fn eq(&self, other: &&str) -> bool {
116135
&**self == *other
117136
}
118137
}
119138

120-
impl From<&'static str> for MaybeLazy<str> {
139+
impl<F: FnOnce() -> String> From<&'static str> for MaybeLazy<str, F> {
121140
#[inline]
122-
fn from(s: &'static str) -> MaybeLazy<str> {
141+
fn from(s: &'static str) -> MaybeLazy<str, F> {
123142
MaybeLazy::borrowed(s)
124143
}
125144
}

0 commit comments

Comments
 (0)