Skip to content

Commit 42c2174

Browse files
stepanchegfacebook-github-bot
authored andcommitted
StarlarkTypeRepr::Canonical
Summary: If `A` and `B` represent the same starlark type, `A::Canonical == B::Canonical`. For example `String::Canonical == <&str>::Canonical`. This is useful with `ValueOfUnchecked::cast` in D59380757. This diff unfortunately makes starlark API harder to use. It would be better if we had [`associated_type_defaults`](rust-lang/rust#29661), but that won't happen soon. Reviewed By: JakobDegen Differential Revision: D59380699 fbshipit-source-id: 8b658203c2d46cd03ac722170ba3858d19eee001
1 parent dd0e519 commit 42c2174

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+179
-7
lines changed

starlark/src/macros.rs

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ macro_rules! starlark_complex_value {
4949
}
5050

5151
impl<'v> $crate::values::type_repr::StarlarkTypeRepr for &'v $x<'v> {
52+
type Canonical = $x<'v>;
53+
5254
#[inline]
5355
fn starlark_type_repr() -> $crate::typing::Ty {
5456
<$x as $crate::values::StarlarkValue>::get_type_starlark_repr()
@@ -197,6 +199,8 @@ macro_rules! starlark_simple_value {
197199
}
198200

199201
impl<'v> $crate::values::type_repr::StarlarkTypeRepr for &'v $x {
202+
type Canonical = $x;
203+
200204
fn starlark_type_repr() -> $crate::typing::Ty {
201205
<$x as $crate::values::StarlarkValue>::get_type_starlark_repr()
202206
}

starlark/src/stdlib/json.rs

+12
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,16 @@ use crate::values::Heap;
3939
use crate::values::Value;
4040

4141
impl StarlarkTypeRepr for serde_json::Number {
42+
type Canonical = Either<i32, f64>;
43+
4244
fn starlark_type_repr() -> Ty {
4345
Either::<i32, f64>::starlark_type_repr()
4446
}
4547
}
4648

4749
impl<'a> StarlarkTypeRepr for &'a serde_json::Number {
50+
type Canonical = serde_json::Number;
51+
4852
fn starlark_type_repr() -> Ty {
4953
serde_json::Number::starlark_type_repr()
5054
}
@@ -99,12 +103,16 @@ impl AllocFrozenValue for serde_json::Number {
99103
}
100104

101105
impl<'a, K: StarlarkTypeRepr, V: StarlarkTypeRepr> StarlarkTypeRepr for &'a serde_json::Map<K, V> {
106+
type Canonical = <serde_json::Map<K, V> as StarlarkTypeRepr>::Canonical;
107+
102108
fn starlark_type_repr() -> Ty {
103109
AllocDict::<SmallMap<K, V>>::starlark_type_repr()
104110
}
105111
}
106112

107113
impl<K: StarlarkTypeRepr, V: StarlarkTypeRepr> StarlarkTypeRepr for serde_json::Map<K, V> {
114+
type Canonical = <SmallMap<K, V> as StarlarkTypeRepr>::Canonical;
115+
108116
fn starlark_type_repr() -> Ty {
109117
AllocDict::<SmallMap<K, V>>::starlark_type_repr()
110118
}
@@ -141,13 +149,17 @@ impl AllocFrozenValue for serde_json::Map<String, serde_json::Value> {
141149
}
142150

143151
impl<'a> StarlarkTypeRepr for &'a serde_json::Value {
152+
type Canonical = <serde_json::Value as StarlarkTypeRepr>::Canonical;
153+
144154
fn starlark_type_repr() -> Ty {
145155
// Any.
146156
Value::starlark_type_repr()
147157
}
148158
}
149159

150160
impl StarlarkTypeRepr for serde_json::Value {
161+
type Canonical = <FrozenValue as StarlarkTypeRepr>::Canonical;
162+
151163
fn starlark_type_repr() -> Ty {
152164
// Any.
153165
Value::starlark_type_repr()

starlark/src/values/layout/complex.rs

+2
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ where
9292
T: ComplexValue<'v>,
9393
T::Frozen: StarlarkValue<'static>,
9494
{
95+
type Canonical = <T as StarlarkTypeRepr>::Canonical;
96+
9597
fn starlark_type_repr() -> Ty {
9698
T::starlark_type_repr()
9799
}

starlark/src/values/layout/typed.rs

+4
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,8 @@ impl<'v, T: StarlarkValue<'v>> Deref for ValueTyped<'v, T> {
343343
}
344344

345345
impl<'v, T: StarlarkValue<'v>> StarlarkTypeRepr for ValueTyped<'v, T> {
346+
type Canonical = <T as StarlarkTypeRepr>::Canonical;
347+
346348
fn starlark_type_repr() -> Ty {
347349
T::starlark_type_repr()
348350
}
@@ -377,6 +379,8 @@ impl<'v> AllocStringValue<'v> for StringValue<'v> {
377379
}
378380

379381
impl<'v, T: StarlarkValue<'v>> StarlarkTypeRepr for FrozenValueTyped<'v, T> {
382+
type Canonical = <T as StarlarkTypeRepr>::Canonical;
383+
380384
fn starlark_type_repr() -> Ty {
381385
T::starlark_type_repr()
382386
}

starlark/src/values/layout/value.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1137,12 +1137,16 @@ impl Serialize for FrozenValue {
11371137
}
11381138

11391139
impl<'v> StarlarkTypeRepr for Value<'v> {
1140+
type Canonical = <FrozenValue as StarlarkTypeRepr>::Canonical;
1141+
11401142
fn starlark_type_repr() -> Ty {
11411143
FrozenValue::starlark_type_repr()
11421144
}
11431145
}
11441146

11451147
impl StarlarkTypeRepr for FrozenValue {
1148+
type Canonical = Self;
1149+
11461150
fn starlark_type_repr() -> Ty {
11471151
Ty::any()
11481152
}

starlark/src/values/owned.rs

+2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ impl Display for OwnedFrozenValue {
7171
}
7272

7373
impl StarlarkTypeRepr for OwnedFrozenValue {
74+
type Canonical = <FrozenValue as StarlarkTypeRepr>::Canonical;
75+
7476
fn starlark_type_repr() -> Ty {
7577
FrozenValue::starlark_type_repr()
7678
}

starlark/src/values/type_repr.rs

+25
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ use crate::values::Value;
5050
///
5151
/// This derive is useful in combination with derive of [`UnpackValue`](crate::values::UnpackValue).
5252
pub trait StarlarkTypeRepr {
53+
/// Different Rust type representing the same Starlark Type.
54+
///
55+
/// For example, `bool` and `StarlarkBool` Rust types represent the same Starlark type `bool`.
56+
///
57+
/// Formal requirement: `Self::starlark_type_repr() == Self::Canonical::starlark_type_repr()`.
58+
///
59+
/// If unsure, it is safe to put `= Self` here.
60+
/// When [`associated_type_defaults`](https://github.com/rust-lang/rust/issues/29661)
61+
/// is stabilized, this will be the default.
62+
type Canonical: StarlarkTypeRepr;
63+
5364
/// The representation of a type that a user would use verbatim in starlark type annotations
5465
fn starlark_type_repr() -> Ty;
5566
}
@@ -64,42 +75,56 @@ pub struct DictType<K: StarlarkTypeRepr, V: StarlarkTypeRepr> {
6475
}
6576

6677
impl<K: StarlarkTypeRepr, V: StarlarkTypeRepr> StarlarkTypeRepr for DictType<K, V> {
78+
type Canonical = DictType<K::Canonical, V::Canonical>;
79+
6780
fn starlark_type_repr() -> Ty {
6881
Ty::dict(K::starlark_type_repr(), V::starlark_type_repr())
6982
}
7083
}
7184

7285
impl<'v, T: StarlarkValue<'v> + ?Sized> StarlarkTypeRepr for T {
86+
type Canonical = Self;
87+
7388
fn starlark_type_repr() -> Ty {
7489
Self::get_type_starlark_repr()
7590
}
7691
}
7792

7893
impl StarlarkTypeRepr for String {
94+
type Canonical = StarlarkStr;
95+
7996
fn starlark_type_repr() -> Ty {
8097
StarlarkStr::starlark_type_repr()
8198
}
8299
}
83100

84101
impl StarlarkTypeRepr for &str {
102+
type Canonical = StarlarkStr;
103+
85104
fn starlark_type_repr() -> Ty {
86105
StarlarkStr::starlark_type_repr()
87106
}
88107
}
89108

90109
impl<T: StarlarkTypeRepr> StarlarkTypeRepr for Option<T> {
110+
type Canonical = <Either<NoneType, T> as StarlarkTypeRepr>::Canonical;
111+
91112
fn starlark_type_repr() -> Ty {
92113
Either::<NoneType, T>::starlark_type_repr()
93114
}
94115
}
95116

96117
impl<T: StarlarkTypeRepr> StarlarkTypeRepr for Vec<T> {
118+
type Canonical = Vec<T::Canonical>;
119+
97120
fn starlark_type_repr() -> Ty {
98121
Ty::list(T::starlark_type_repr())
99122
}
100123
}
101124

102125
impl<TLeft: StarlarkTypeRepr, TRight: StarlarkTypeRepr> StarlarkTypeRepr for Either<TLeft, TRight> {
126+
type Canonical = Either<TLeft::Canonical, TRight::Canonical>;
127+
103128
fn starlark_type_repr() -> Ty {
104129
Ty::union2(TLeft::starlark_type_repr(), TRight::starlark_type_repr())
105130
}

starlark/src/values/types/bigint/convert.rs

+12
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ use crate::values::UnpackValue;
3030
use crate::values::Value;
3131

3232
impl StarlarkTypeRepr for u32 {
33+
type Canonical = <i32 as StarlarkTypeRepr>::Canonical;
34+
3335
fn starlark_type_repr() -> Ty {
3436
i32::starlark_type_repr()
3537
}
@@ -50,6 +52,8 @@ impl AllocFrozenValue for u32 {
5052
}
5153

5254
impl StarlarkTypeRepr for u64 {
55+
type Canonical = <i32 as StarlarkTypeRepr>::Canonical;
56+
5357
fn starlark_type_repr() -> Ty {
5458
i32::starlark_type_repr()
5559
}
@@ -70,6 +74,8 @@ impl AllocFrozenValue for u64 {
7074
}
7175

7276
impl StarlarkTypeRepr for i64 {
77+
type Canonical = <i32 as StarlarkTypeRepr>::Canonical;
78+
7379
fn starlark_type_repr() -> Ty {
7480
i32::starlark_type_repr()
7581
}
@@ -90,6 +96,8 @@ impl AllocFrozenValue for i64 {
9096
}
9197

9298
impl StarlarkTypeRepr for usize {
99+
type Canonical = <i32 as StarlarkTypeRepr>::Canonical;
100+
93101
fn starlark_type_repr() -> Ty {
94102
i32::starlark_type_repr()
95103
}
@@ -110,6 +118,8 @@ impl AllocFrozenValue for usize {
110118
}
111119

112120
impl StarlarkTypeRepr for isize {
121+
type Canonical = <i32 as StarlarkTypeRepr>::Canonical;
122+
113123
fn starlark_type_repr() -> Ty {
114124
i32::starlark_type_repr()
115125
}
@@ -130,6 +140,8 @@ impl AllocFrozenValue for isize {
130140
}
131141

132142
impl StarlarkTypeRepr for BigInt {
143+
type Canonical = <i32 as StarlarkTypeRepr>::Canonical;
144+
133145
fn starlark_type_repr() -> Ty {
134146
i32::starlark_type_repr()
135147
}

starlark/src/values/types/bool.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ use crate::values::ValueError;
5454
/// The result of calling `type()` on booleans.
5555
pub const BOOL_TYPE: &str = "bool";
5656

57-
// We have to alias bool so we can have a Display that uses True/False.
57+
/// `bool` value.
5858
#[derive(ProvidesStaticType, Debug, Serialize, StarlarkDocs, Allocative)]
5959
#[starlark_docs(builtin = "standard")]
6060
#[serde(transparent)]
61-
pub(crate) struct StarlarkBool(pub(crate) bool);
61+
pub struct StarlarkBool(pub(crate) bool);
6262

6363
impl Display for StarlarkBool {
6464
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -88,6 +88,8 @@ impl AllocFrozenValue for bool {
8888
}
8989

9090
impl StarlarkTypeRepr for bool {
91+
type Canonical = <StarlarkBool as StarlarkTypeRepr>::Canonical;
92+
9193
fn starlark_type_repr() -> Ty {
9294
StarlarkBool::get_type_starlark_repr()
9395
}

starlark/src/values/types/dict/alloc.rs

+2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ where
6565
K: StarlarkTypeRepr,
6666
V: StarlarkTypeRepr,
6767
{
68+
type Canonical = DictType<K::Canonical, V::Canonical>;
69+
6870
fn starlark_type_repr() -> Ty {
6971
DictType::<K, V>::starlark_type_repr()
7072
}

starlark/src/values/types/dict/of.rs

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ impl<'v, K: UnpackValue<'v> + Hash + Eq, V: UnpackValue<'v>> DictOf<'v, K, V> {
8080
}
8181

8282
impl<'v, K: UnpackValue<'v>, V: UnpackValue<'v>> StarlarkTypeRepr for DictOf<'v, K, V> {
83+
type Canonical = <DictType<K, V> as StarlarkTypeRepr>::Canonical;
84+
8385
fn starlark_type_repr() -> Ty {
8486
DictType::<K, V>::starlark_type_repr()
8587
}

starlark/src/values/types/dict/refs.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use crate::typing::Ty;
2929
use crate::values::dict::value::DictGen;
3030
use crate::values::dict::value::FrozenDictData;
3131
use crate::values::dict::Dict;
32+
use crate::values::type_repr::DictType;
3233
use crate::values::type_repr::StarlarkTypeRepr;
3334
use crate::values::FrozenValue;
3435
use crate::values::UnpackValue;
@@ -153,8 +154,10 @@ impl<'v> DerefMut for DictMut<'v> {
153154
}
154155

155156
impl<'v> StarlarkTypeRepr for DictRef<'v> {
157+
type Canonical = <DictType<FrozenValue, FrozenValue> as StarlarkTypeRepr>::Canonical;
158+
156159
fn starlark_type_repr() -> Ty {
157-
Dict::<'v>::starlark_type_repr()
160+
DictType::<FrozenValue, FrozenValue>::starlark_type_repr()
158161
}
159162
}
160163

starlark/src/values/types/dict/traits.rs

+8
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,16 @@ where
6868
}
6969

7070
impl<'a, K: StarlarkTypeRepr, V: StarlarkTypeRepr> StarlarkTypeRepr for &'a SmallMap<K, V> {
71+
type Canonical = <SmallMap<K, V> as StarlarkTypeRepr>::Canonical;
72+
7173
fn starlark_type_repr() -> Ty {
7274
DictType::<K, V>::starlark_type_repr()
7375
}
7476
}
7577

7678
impl<K: StarlarkTypeRepr, V: StarlarkTypeRepr> StarlarkTypeRepr for SmallMap<K, V> {
79+
type Canonical = <DictType<K, V> as StarlarkTypeRepr>::Canonical;
80+
7781
fn starlark_type_repr() -> Ty {
7882
DictType::<K, V>::starlark_type_repr()
7983
}
@@ -131,12 +135,16 @@ where
131135
}
132136

133137
impl<'a, K: StarlarkTypeRepr, V: StarlarkTypeRepr> StarlarkTypeRepr for &'a BTreeMap<K, V> {
138+
type Canonical = <BTreeMap<K, V> as StarlarkTypeRepr>::Canonical;
139+
134140
fn starlark_type_repr() -> Ty {
135141
DictType::<K, V>::starlark_type_repr()
136142
}
137143
}
138144

139145
impl<K: StarlarkTypeRepr, V: StarlarkTypeRepr> StarlarkTypeRepr for BTreeMap<K, V> {
146+
type Canonical = <DictType<K, V> as StarlarkTypeRepr>::Canonical;
147+
140148
fn starlark_type_repr() -> Ty {
141149
DictType::<K, V>::starlark_type_repr()
142150
}

starlark/src/values/types/dict/value.rs

+5
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ use crate::values::layout::avalue::AValueImpl;
5555
use crate::values::layout::avalue::AValueSimple;
5656
use crate::values::layout::heap::repr::AValueRepr;
5757
use crate::values::string::str_type::hash_string_value;
58+
use crate::values::type_repr::DictType;
5859
use crate::values::type_repr::StarlarkTypeRepr;
5960
use crate::values::AllocFrozenValue;
6061
use crate::values::AllocValue;
@@ -103,6 +104,8 @@ pub struct Dict<'v> {
103104
}
104105

105106
impl<'v> StarlarkTypeRepr for Dict<'v> {
107+
type Canonical = <DictType<FrozenValue, FrozenValue> as StarlarkTypeRepr>::Canonical;
108+
106109
fn starlark_type_repr() -> Ty {
107110
DictOf::<Value<'v>, Value<'v>>::starlark_type_repr()
108111
}
@@ -135,6 +138,8 @@ impl<'v> AllocValue<'v> for Dict<'v> {
135138
}
136139

137140
impl StarlarkTypeRepr for FrozenDictData {
141+
type Canonical = <DictType<FrozenValue, FrozenValue> as StarlarkTypeRepr>::Canonical;
142+
138143
fn starlark_type_repr() -> Ty {
139144
Ty::dict(Ty::any(), Ty::any())
140145
}

starlark/src/values/types/float.rs

+2
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ impl StarlarkFloat {
213213
}
214214

215215
impl StarlarkTypeRepr for f64 {
216+
type Canonical = <StarlarkFloat as StarlarkTypeRepr>::Canonical;
217+
216218
fn starlark_type_repr() -> Ty {
217219
StarlarkFloat::starlark_type_repr()
218220
}

starlark/src/values/types/function.rs

+2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ pub const FUNCTION_TYPE: &str = "function";
7676
pub(crate) enum StarlarkFunction {}
7777

7878
impl StarlarkTypeRepr for StarlarkFunction {
79+
type Canonical = Self;
80+
7981
fn starlark_type_repr() -> Ty {
8082
Ty::any_callable()
8183
}

0 commit comments

Comments
 (0)