Skip to content

Commit 9187ddd

Browse files
JakobDegenfacebook-github-bot
authored andcommitted
Seal AnyLifetime instead of having it be unsafe
Summary: Doesn't have to be unsafe to implement if no one can implement it Reviewed By: Nero5023 Differential Revision: D74131158 fbshipit-source-id: 5e3550564bba20d85065cae6cdc8b000a3b981ba
1 parent 05e1d55 commit 9187ddd

File tree

1 file changed

+16
-11
lines changed
  • starlark-rust/starlark/src

1 file changed

+16
-11
lines changed

starlark-rust/starlark/src/any.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ pub unsafe trait ProvidesStaticType<'a> {
4545
/// Note `ProvidesStaticType` and `AnyLifetime` cannot be the same type,
4646
/// because `AnyLifetime` need to be object safe,
4747
/// and `ProvidesStaticType` has type member.
48-
unsafe impl<'a, T: ProvidesStaticType<'a> + 'a + ?Sized> AnyLifetime<'a> for T {
48+
impl<'a, T: ProvidesStaticType<'a> + 'a + ?Sized> AnyLifetime<'a> for T {
4949
fn static_type_id() -> TypeId
5050
where
5151
Self: Sized,
@@ -58,15 +58,14 @@ unsafe impl<'a, T: ProvidesStaticType<'a> + 'a + ?Sized> AnyLifetime<'a> for T {
5858
}
5959
}
6060

61-
/// Like [`Any`](std::any::Any), but while [`Any`](std::any::Any) requires `'static`,
62-
/// this version allows a lifetime parameter.
61+
/// Like [`Any`](std::any::Any), but while [`Any`](std::any::Any) requires `'static`, this version
62+
/// allows a lifetime parameter.
6363
///
64-
/// Code using this trait is _unsafe_ if your implementation of the inner
65-
/// methods do not meet the invariants listed. Therefore, it is recommended you
66-
/// use one of the helper macros.
64+
/// Code using this trait is _unsafe_ if your implementation of the inner methods do not meet the
65+
/// invariants listed. Therefore, it is recommended you use one of the helper macros.
6766
///
68-
/// If your data type is of the form `Foo` or `Foo<'v>` you can derive
69-
/// `AnyLifetime`:
67+
/// You cannot implement this trait directly. You should instead implement `ProvidesStaticType`,
68+
/// usually via the derive macro:
7069
///
7170
/// ```
7271
/// use starlark::any::ProvidesStaticType;
@@ -76,8 +75,8 @@ unsafe impl<'a, T: ProvidesStaticType<'a> + 'a + ?Sized> AnyLifetime<'a> for T {
7675
/// struct Foo2<'a>(&'a ());
7776
/// ```
7877
///
79-
/// For more complicated context or constraints, you can implement `ProvidesStaticType`
80-
/// directly.
78+
/// If your data type is not of the form `Foo` or `Foo<'v>` you may need to implement
79+
/// `ProvidesStaticType` directly.
8180
///
8281
/// ```
8382
/// use starlark::any::ProvidesStaticType;
@@ -94,7 +93,7 @@ unsafe impl<'a, T: ProvidesStaticType<'a> + 'a + ?Sized> AnyLifetime<'a> for T {
9493
/// }
9594
/// # }
9695
/// ```
97-
pub unsafe trait AnyLifetime<'a>: 'a {
96+
pub trait AnyLifetime<'a>: seal::ProvidesStaticTypeSealed<'a> + 'a {
9897
/// Must return the `TypeId` of `Self` but where the lifetimes are changed
9998
/// to `'static`. Must be consistent with `static_type_of`.
10099
fn static_type_id() -> TypeId
@@ -108,6 +107,12 @@ pub unsafe trait AnyLifetime<'a>: 'a {
108107
// Required so we can have a `dyn AnyLifetime`.
109108
}
110109

110+
mod seal {
111+
/// A bound required by `AnyLifetime<'a>` for sealing it
112+
pub trait ProvidesStaticTypeSealed<'a> {}
113+
impl<'a, T: super::ProvidesStaticType<'a> + ?Sized> ProvidesStaticTypeSealed<'a> for T {}
114+
}
115+
111116
impl<'a> dyn AnyLifetime<'a> {
112117
/// Is the value of type `T`.
113118
pub fn is<T: AnyLifetime<'a>>(&self) -> bool {

0 commit comments

Comments
 (0)