Skip to content

Commit 697ced3

Browse files
stepanchegfacebook-github-bot
authored andcommitted
Require only StarlarkTypeRepr in StarlarkValueAsType
Summary: `StarlarkValueAsType` utility is used to declare globals which are type symbols. With this diff, it is possible to use any `StarlarkTypeRepr` to declare a symbol, not just `StarlarkValue`. The diff is large because it changes internals. Previously `StarlarkValueAsType<T>` was a `StarlarkValue` itself. Now `StarlarkValueAsType<T>` only implements `AllocFrozenValue` and the actual `StarlarkValue` implementation lives in a separate struct `StarlarkValueAsTypeStarlarkValue`. Reviewed By: ianlevesque Differential Revision: D48892725 fbshipit-source-id: 2a1f4843b15e10e0c9c6692a081faabde625b295
1 parent 9eea1cb commit 697ced3

File tree

1 file changed

+50
-25
lines changed

1 file changed

+50
-25
lines changed

starlark/src/values/types/starlark_value_as_type.rs

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,45 @@
1717

1818
//! Convert a value implementing [`StarlarkValue`] into a type usable in type expression.
1919
20+
use std::fmt;
21+
use std::fmt::Debug;
22+
use std::fmt::Display;
23+
use std::fmt::Formatter;
2024
use std::marker::PhantomData;
2125

2226
use allocative::Allocative;
2327
use starlark_derive::starlark_value;
2428
use starlark_derive::NoSerialize;
25-
use starlark_derive::ProvidesStaticType;
2629

2730
use crate as starlark;
31+
use crate::any::ProvidesStaticType;
2832
use crate::typing::Ty;
2933
use crate::values::layout::avalue::alloc_static;
3034
use crate::values::layout::avalue::AValueImpl;
3135
use crate::values::layout::avalue::Basic;
3236
use crate::values::layout::heap::repr::AValueRepr;
33-
use crate::values::string::StarlarkStr;
3437
use crate::values::type_repr::StarlarkTypeRepr;
3538
use crate::values::AllocFrozenValue;
3639
use crate::values::FrozenHeap;
3740
use crate::values::FrozenValue;
3841
use crate::values::StarlarkValue;
3942

43+
#[derive(Debug, NoSerialize, Allocative, ProvidesStaticType)]
44+
struct StarlarkValueAsTypeStarlarkValue(fn() -> Ty);
45+
46+
#[starlark_value(type = "type")]
47+
impl<'v> StarlarkValue<'v> for StarlarkValueAsTypeStarlarkValue {
48+
fn eval_type(&self) -> Option<Ty> {
49+
Some((self.0)())
50+
}
51+
}
52+
53+
impl Display for StarlarkValueAsTypeStarlarkValue {
54+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
55+
Display::fmt(&(self.0)(), f)
56+
}
57+
}
58+
4059
/// Utility to declare a value usable in type expression.
4160
///
4261
/// # Example
@@ -63,44 +82,50 @@ use crate::values::StarlarkValue;
6382
/// const Temperature: StarlarkValueAsType<Temperature> = StarlarkValueAsType::new();
6483
/// }
6584
/// ```
66-
#[derive(
67-
Debug,
68-
derive_more::Display,
69-
Allocative,
70-
ProvidesStaticType,
71-
NoSerialize
72-
)]
73-
#[display(fmt = "{}", T::TYPE)]
74-
pub struct StarlarkValueAsType<T: StarlarkValue<'static> + 'static>(PhantomData<fn(&T)>);
75-
76-
impl<T: StarlarkValue<'static>> StarlarkValueAsType<T> {
85+
pub struct StarlarkValueAsType<T: StarlarkTypeRepr>(PhantomData<fn(&T)>);
86+
87+
impl<T: StarlarkTypeRepr> Debug for StarlarkValueAsType<T> {
88+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
89+
f.debug_tuple("StarlarkValueAsType")
90+
.field(&T::starlark_type_repr())
91+
.finish()
92+
}
93+
}
94+
95+
impl<T: StarlarkTypeRepr> Display for StarlarkValueAsType<T> {
96+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
97+
Display::fmt(&T::starlark_type_repr(), f)
98+
}
99+
}
100+
101+
impl<T: StarlarkTypeRepr> StarlarkValueAsType<T> {
77102
/// Constructor.
78103
pub const fn new() -> Self {
79104
Self(PhantomData)
80105
}
81106

82-
const INSTANCE: AValueRepr<AValueImpl<Basic, StarlarkValueAsType<T>>> =
83-
alloc_static(Basic, StarlarkValueAsType::<T>(PhantomData));
107+
const INSTANCE: AValueRepr<AValueImpl<Basic, StarlarkValueAsTypeStarlarkValue>> = alloc_static(
108+
Basic,
109+
StarlarkValueAsTypeStarlarkValue(T::starlark_type_repr),
110+
);
84111
}
85112

86-
impl<T: StarlarkValue<'static>> Default for StarlarkValueAsType<T> {
113+
impl<T: StarlarkTypeRepr> Default for StarlarkValueAsType<T> {
87114
fn default() -> Self {
88115
Self::new()
89116
}
90117
}
91118

92-
impl<T: StarlarkValue<'static>> AllocFrozenValue for StarlarkValueAsType<T> {
93-
fn alloc_frozen_value(self, _heap: &FrozenHeap) -> FrozenValue {
94-
FrozenValue::new_repr(&Self::INSTANCE)
119+
impl<T: StarlarkTypeRepr> StarlarkTypeRepr for StarlarkValueAsType<T> {
120+
fn starlark_type_repr() -> Ty {
121+
// TODO(nga): make it proper type.
122+
Ty::name_static("type")
95123
}
96124
}
97125

98-
#[starlark_value(type = "type")]
99-
impl<'v, T: StarlarkValue<'static>> StarlarkValue<'v> for StarlarkValueAsType<T> {
100-
type Canonical = StarlarkValueAsType<StarlarkStr>;
101-
102-
fn eval_type(&self) -> Option<Ty> {
103-
Some(T::starlark_type_repr())
126+
impl<T: StarlarkTypeRepr> AllocFrozenValue for StarlarkValueAsType<T> {
127+
fn alloc_frozen_value(self, _heap: &FrozenHeap) -> FrozenValue {
128+
FrozenValue::new_repr(&Self::INSTANCE)
104129
}
105130
}
106131

0 commit comments

Comments
 (0)