diff --git a/starlark-rust/starlark/src/values.rs b/starlark-rust/starlark/src/values.rs index 7a28cf08abb00..c7b62aa9b0511 100644 --- a/starlark-rust/starlark/src/values.rs +++ b/starlark-rust/starlark/src/values.rs @@ -31,6 +31,7 @@ //! so may serve as interesting inspiration for writing your own values, in addition to occurring in Starlark programs. pub use layout::alloc_static_simple::AllocStaticSimple; +pub use owned_frozen_ref::OwnedFrozenRef; pub use starlark_derive::starlark_attrs; pub use starlark_derive::starlark_value; pub use starlark_derive::AllocFrozenValue; @@ -50,7 +51,6 @@ pub use crate::values::demand::Demand; pub use crate::values::error::ValueError; pub use crate::values::freeze::Freeze; pub use crate::values::frozen_ref::FrozenRef; -pub use crate::values::frozen_ref::OwnedFrozenRef; pub use crate::values::iter::StarlarkIterator; pub use crate::values::layout::complex::ValueTypedComplex; pub use crate::values::layout::heap::heap_type::Freezer; @@ -114,6 +114,7 @@ pub(crate) mod iter; pub(crate) mod layout; pub(crate) mod num; mod owned; +pub(crate) mod owned_frozen_ref; pub(crate) mod recursive_repr_or_json_guard; mod stack_guard; pub(crate) mod starlark_type_id; diff --git a/starlark-rust/starlark/src/values/frozen_ref.rs b/starlark-rust/starlark/src/values/frozen_ref.rs index a09ccb6f2eb98..c1628373d57eb 100644 --- a/starlark-rust/starlark/src/values/frozen_ref.rs +++ b/starlark-rust/starlark/src/values/frozen_ref.rs @@ -29,12 +29,10 @@ use std::sync::atomic; use allocative::Allocative; use dupe::Clone_; use dupe::Copy_; -use dupe::Dupe; use dupe::Dupe_; use crate::values::Freeze; use crate::values::Freezer; -use crate::values::FrozenHeapRef; use crate::values::Trace; use crate::values::Tracer; @@ -208,92 +206,3 @@ impl AtomicFrozenRefOption { ); } } - -/// Same as a `FrozenRef`, but it keeps itself alive by storing a reference to the owning heap. -/// -/// Usually constructed from an `OwnedFrozenValueTyped`. -#[derive(Clone, Dupe, Allocative)] -pub struct OwnedFrozenRef { - owner: FrozenHeapRef, - // Invariant: this FrozenValue must be kept alive by the `owner` field. - value: FrozenRef<'static, T>, -} - -impl OwnedFrozenRef { - /// Creates a new `OwnedFrozenRef` pointing at the given value. - /// - /// ## Safety - /// - /// The reference must be kept alive by the owning heap - pub unsafe fn new_unchecked(value: &'static T, owner: FrozenHeapRef) -> OwnedFrozenRef { - OwnedFrozenRef { - owner, - value: FrozenRef::new(value), - } - } - - /// Returns a reference to the underlying value. - pub fn as_ref<'a>(&'a self) -> &'a T { - self.value.as_ref() - } - - /// Converts `self` into a new reference that points at something reachable from the previous. - /// - /// See the caveats on `[starlark::values::OwnedFrozenValue::map]` - pub fn map(self, f: F) -> OwnedFrozenRef - where - for<'v> F: FnOnce(&'v T) -> &'v U, - { - OwnedFrozenRef { - owner: self.owner, - value: self.value.map(f), - } - } - - /// Fallible map the reference to another one. - pub fn try_map_result(self, f: F) -> Result, E> - where - for<'v> F: FnOnce(&'v T) -> Result<&'v U, E>, - { - Ok(OwnedFrozenRef { - owner: self.owner, - value: self.value.try_map_result(f)?, - }) - } - - /// Optionally map the reference to another one. - pub fn try_map_option(self, f: F) -> Option> - where - for<'v> F: FnOnce(&'v T) -> Option<&'v U>, - { - Some(OwnedFrozenRef { - owner: self.owner, - value: self.value.try_map_option(f)?, - }) - } - - /// Get a reference to the owning frozen heap - pub fn owner(&self) -> &FrozenHeapRef { - &self.owner - } -} - -impl fmt::Debug for OwnedFrozenRef { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - fmt::Debug::fmt(&self.value, f) - } -} - -impl fmt::Display for OwnedFrozenRef { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.value, f) - } -} - -impl Deref for OwnedFrozenRef { - type Target = T; - - fn deref(&self) -> &T { - self.as_ref() - } -} diff --git a/starlark-rust/starlark/src/values/owned.rs b/starlark-rust/starlark/src/values/owned.rs index 2d51d3496b6f4..858e1d4f6dd6c 100644 --- a/starlark-rust/starlark/src/values/owned.rs +++ b/starlark-rust/starlark/src/values/owned.rs @@ -27,13 +27,13 @@ use dupe::Dupe_; use crate::cast::transmute; use crate::typing::Ty; use crate::values::none::NoneType; +use crate::values::owned_frozen_ref::OwnedFrozenRef; use crate::values::type_repr::StarlarkTypeRepr; use crate::values::AllocFrozenValue; use crate::values::FrozenHeap; use crate::values::FrozenHeapRef; use crate::values::FrozenValue; use crate::values::FrozenValueTyped; -use crate::values::OwnedFrozenRef; use crate::values::StarlarkValue; use crate::values::Value; diff --git a/starlark-rust/starlark/src/values/owned_frozen_ref.rs b/starlark-rust/starlark/src/values/owned_frozen_ref.rs new file mode 100644 index 0000000000000..cd05f01ba8513 --- /dev/null +++ b/starlark-rust/starlark/src/values/owned_frozen_ref.rs @@ -0,0 +1,115 @@ +/* + * Copyright 2019 The Starlark in Rust Authors. + * Copyright (c) Facebook, Inc. and its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +use std::fmt; +use std::fmt::Formatter; +use std::ops::Deref; + +use allocative::Allocative; +use dupe::Dupe; + +use crate::values::FrozenHeapRef; +use crate::values::FrozenRef; + +/// Same as a `FrozenRef`, but it keeps itself alive by storing a reference to the owning heap. +/// +/// Usually constructed from an `OwnedFrozenValueTyped`. +#[derive(Clone, Dupe, Allocative)] +pub struct OwnedFrozenRef { + owner: FrozenHeapRef, + // Invariant: this FrozenValue must be kept alive by the `owner` field. + value: FrozenRef<'static, T>, +} + +impl OwnedFrozenRef { + /// Creates a new `OwnedFrozenRef` pointing at the given value. + /// + /// ## Safety + /// + /// The reference must be kept alive by the owning heap + pub unsafe fn new_unchecked(value: &'static T, owner: FrozenHeapRef) -> OwnedFrozenRef { + OwnedFrozenRef { + owner, + value: FrozenRef::new(value), + } + } + + /// Returns a reference to the underlying value. + pub fn as_ref<'a>(&'a self) -> &'a T { + self.value.as_ref() + } + + /// Converts `self` into a new reference that points at something reachable from the previous. + /// + /// See the caveats on `[starlark::values::OwnedFrozenValue::map]` + pub fn map(self, f: F) -> OwnedFrozenRef + where + for<'v> F: FnOnce(&'v T) -> &'v U, + { + OwnedFrozenRef { + owner: self.owner, + value: self.value.map(f), + } + } + + /// Fallible map the reference to another one. + pub fn try_map_result(self, f: F) -> Result, E> + where + for<'v> F: FnOnce(&'v T) -> Result<&'v U, E>, + { + Ok(OwnedFrozenRef { + owner: self.owner, + value: self.value.try_map_result(f)?, + }) + } + + /// Optionally map the reference to another one. + pub fn try_map_option(self, f: F) -> Option> + where + for<'v> F: FnOnce(&'v T) -> Option<&'v U>, + { + Some(OwnedFrozenRef { + owner: self.owner, + value: self.value.try_map_option(f)?, + }) + } + + /// Get a reference to the owning frozen heap + pub fn owner(&self) -> &FrozenHeapRef { + &self.owner + } +} + +impl fmt::Debug for OwnedFrozenRef { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.value, f) + } +} + +impl fmt::Display for OwnedFrozenRef { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + fmt::Display::fmt(&self.value, f) + } +} + +impl Deref for OwnedFrozenRef { + type Target = T; + + fn deref(&self) -> &T { + self.as_ref() + } +}