Skip to content

Commit f556e4f

Browse files
stepanchegfacebook-github-bot
authored andcommitted
Repro incorrect StarlarkTypeRepr::Canonical for StarlarkValue
Summary: Because the implementation is incorrect, `ValueOfUnchecked::cast` does not work for `StarlarkValue` parameters. `non_static_type_id` is provided by David Tolnay [here](rrevenantt/better_any#8 (comment)). Reviewed By: JakobDegen Differential Revision: D59600076 fbshipit-source-id: 967de23f9690e0050c7c1854c13e590706833943
1 parent b807b68 commit f556e4f

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

starlark/src/util.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@
1616
*/
1717

1818
pub(crate) mod arc_or_static;
19+
pub(crate) mod non_static_type_id;
1920
pub(crate) mod rtabort;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2018 The Starlark in Rust Authors.
3+
* Copyright (c) Facebook, Inc. and its affiliates.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* https://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#![cfg(test)]
19+
20+
use std::any::TypeId;
21+
use std::marker::PhantomData;
22+
use std::mem;
23+
24+
pub(crate) fn non_static_type_id<T: ?Sized>() -> TypeId {
25+
trait NonStaticAny {
26+
fn get_type_id(&self) -> TypeId
27+
where
28+
Self: 'static;
29+
}
30+
31+
impl<T: ?Sized> NonStaticAny for PhantomData<T> {
32+
fn get_type_id(&self) -> TypeId
33+
where
34+
Self: 'static,
35+
{
36+
TypeId::of::<T>()
37+
}
38+
}
39+
40+
let phantom_data = PhantomData::<T>;
41+
NonStaticAny::get_type_id(unsafe {
42+
mem::transmute::<&dyn NonStaticAny, &(dyn NonStaticAny + 'static)>(&phantom_data)
43+
})
44+
}
45+
46+
#[cfg(test)]
47+
mod tests {
48+
use std::any::TypeId;
49+
50+
use crate::util::non_static_type_id::non_static_type_id;
51+
52+
#[test]
53+
fn test_non_static_type_id() {
54+
assert_eq!(non_static_type_id::<&str>(), TypeId::of::<&'static str>());
55+
}
56+
}

starlark/src/values/type_repr.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,21 @@ pub fn type_repr_from_attr_impl<'v, T: StarlarkTypeRepr>(
138138
) -> Ty {
139139
T::starlark_type_repr()
140140
}
141+
142+
#[cfg(test)]
143+
mod tests {
144+
use crate::tests::util::TestComplexValue;
145+
use crate::util::non_static_type_id::non_static_type_id;
146+
use crate::values::type_repr::StarlarkTypeRepr;
147+
use crate::values::FrozenValue;
148+
use crate::values::Value;
149+
150+
#[test]
151+
fn test_canonical_for_complex_value() {
152+
// TODO(nga): `StarlarkTypeRepr::Canonical` should be equal.
153+
assert_ne!(
154+
non_static_type_id::<<TestComplexValue<Value> as StarlarkTypeRepr>::Canonical>(),
155+
non_static_type_id::<<TestComplexValue<FrozenValue> as StarlarkTypeRepr>::Canonical>(),
156+
);
157+
}
158+
}

0 commit comments

Comments
 (0)