1
0
Fork 0

WIP fixing TraceAsString -- need to fix AssertValidityState::get_target_states

This commit is contained in:
Jacob Lifshay 2026-05-13 23:32:33 -07:00
parent ea183eac87
commit 8304e84584
Signed by: programmerjake
SSH key fingerprint: SHA256:HnFTLGpSm4Q4Fj502oCFisjZSoakwEuTsJJMSke63RQ
10 changed files with 692 additions and 194 deletions

View file

@ -1723,3 +1723,188 @@ impl<'a, T: Type> ToSimValueInner<'a> for &'a SimValue<T> {
Cow::Borrowed(&**this) Cow::Borrowed(&**this)
} }
} }
pub trait ToTraceAsString: ValueType {
type Output: ValueType<Type = TraceAsString<Self::Type>, ValueCategory = Self::ValueCategory>;
fn to_trace_as_string_with_ty(&self, ty: TraceAsString<Self::Type>) -> Self::Output;
fn into_trace_as_string_with_ty(self, ty: TraceAsString<Self::Type>) -> Self::Output
where
Self: Sized;
fn to_trace_as_string(&self) -> Self::Output;
fn into_trace_as_string(self) -> Self::Output
where
Self: Sized;
}
impl<
T: ?Sized
+ ValueType
+ ToTraceAsStringImpl<<Self as ValueType>::Type, <Self as ValueType>::ValueCategory>,
> ToTraceAsString for T
{
type Output = T::ImplOutput;
fn to_trace_as_string_with_ty(&self, ty: TraceAsString<Self::Type>) -> Self::Output {
Self::to_trace_as_string_with_ty_impl(self, ty)
}
fn into_trace_as_string_with_ty(self, ty: TraceAsString<Self::Type>) -> Self::Output
where
Self: Sized,
{
Self::into_trace_as_string_with_ty_impl(self, ty)
}
fn to_trace_as_string(&self) -> Self::Output {
Self::to_trace_as_string_impl(self)
}
fn into_trace_as_string(self) -> Self::Output
where
Self: Sized,
{
Self::into_trace_as_string_impl(self)
}
}
pub trait ToTraceAsStringImpl<Ty: Type, C: value_category::ValueCategory> {
type ImplOutput: ValueType<Type = TraceAsString<Ty>, ValueCategory = C>;
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput;
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
where
Self: Sized;
fn to_trace_as_string_with_ty_impl(this: &Self, ty: TraceAsString<Ty>) -> Self::ImplOutput;
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<Ty>) -> Self::ImplOutput
where
Self: Sized;
}
impl<T: ?Sized + crate::sim::value::ToSimValue>
ToTraceAsStringImpl<T::Type, value_category::ValueCategoryValue> for T
{
type ImplOutput = crate::ty::TraceAsStringSimValue<T::Type>;
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput {
crate::ty::TraceAsStringSimValue::new(this)
}
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
where
Self: Sized,
{
crate::ty::TraceAsStringSimValue::new(this)
}
fn to_trace_as_string_with_ty_impl(
this: &Self,
ty: TraceAsString<T::Type>,
) -> Self::ImplOutput {
crate::ty::TraceAsStringSimValue::new_with_ty(this, ty)
}
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<T::Type>) -> Self::ImplOutput
where
Self: Sized,
{
crate::ty::TraceAsStringSimValue::new_with_ty(this, ty)
}
}
impl<T: ?Sized + crate::sim::value::ToSimValue>
ToTraceAsStringImpl<T::Type, value_category::ValueCategorySimValue> for T
{
type ImplOutput = SimValue<TraceAsString<T::Type>>;
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput {
crate::ty::TraceAsStringSimValue::new(this).into_sim_value()
}
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
where
Self: Sized,
{
crate::ty::TraceAsStringSimValue::new(this).into_sim_value()
}
fn to_trace_as_string_with_ty_impl(
this: &Self,
ty: TraceAsString<T::Type>,
) -> Self::ImplOutput {
crate::ty::TraceAsStringSimValue::new_with_ty(this, ty).into_sim_value()
}
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<T::Type>) -> Self::ImplOutput
where
Self: Sized,
{
crate::ty::TraceAsStringSimValue::new_with_ty(this, ty).into_sim_value()
}
}
impl<T: ?Sized + ToExpr> ToTraceAsStringImpl<T::Type, value_category::ValueCategoryExpr> for T {
type ImplOutput = Expr<TraceAsString<T::Type>>;
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput {
let this = this.to_expr();
ops::AsTraceAsString::new(Expr::canonical(this), TraceAsString::new(this.ty())).to_expr()
}
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
where
Self: Sized,
{
let this = this.to_expr();
ops::AsTraceAsString::new(Expr::canonical(this), TraceAsString::new(this.ty())).to_expr()
}
fn to_trace_as_string_with_ty_impl(
this: &Self,
ty: TraceAsString<T::Type>,
) -> Self::ImplOutput {
let this = this.to_expr();
ops::AsTraceAsString::new(
Expr::canonical(this),
ty.with_new_inner_ty(this.ty().intern_sized()),
)
.to_expr()
}
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<T::Type>) -> Self::ImplOutput
where
Self: Sized,
{
let this = this.to_expr();
ops::AsTraceAsString::new(
Expr::canonical(this),
ty.with_new_inner_ty(this.ty().intern_sized()),
)
.to_expr()
}
}
impl<T: ?Sized + ValueType> ToTraceAsStringImpl<T::Type, value_category::ValueCategoryValueless>
for T
{
type ImplOutput = Valueless<TraceAsString<T::Type>>;
fn to_trace_as_string_impl(this: &Self) -> Self::ImplOutput {
Valueless::new(TraceAsString::new(this.ty()))
}
fn into_trace_as_string_impl(this: Self) -> Self::ImplOutput
where
Self: Sized,
{
Valueless::new(TraceAsString::new(this.ty()))
}
fn to_trace_as_string_with_ty_impl(
this: &Self,
ty: TraceAsString<T::Type>,
) -> Self::ImplOutput {
Valueless::new(ty.with_new_inner_ty(this.ty().intern_sized()))
}
fn into_trace_as_string_with_ty_impl(this: Self, ty: TraceAsString<T::Type>) -> Self::ImplOutput
where
Self: Sized,
{
Valueless::new(ty.with_new_inner_ty(this.ty().intern_sized()))
}
}

View file

@ -45,6 +45,9 @@ use std::{
}, },
}; };
#[cfg(test)]
mod test_ops_impls;
macro_rules! make_impls { macro_rules! make_impls {
( (
$([$($args:tt)*])? $([$($args:tt)*])?
@ -584,9 +587,6 @@ macro_rules! make_impls {
#[cfg(test)] #[cfg(test)]
pub(crate) use make_impls; pub(crate) use make_impls;
#[cfg(test)]
mod test_ops_impls;
macro_rules! impl_simple_binary_op_trait { macro_rules! impl_simple_binary_op_trait {
( (
[$($LLifetimes:tt)*][$($LBounds:tt)*] ($($L:tt)*), [$($LLifetimes:tt)*][$($LBounds:tt)*] ($($L:tt)*),

View file

@ -1454,6 +1454,9 @@ enum TargetStateInner {
Decomposed { Decomposed {
subtargets: HashMap<Interned<TargetPathElement>, TargetState>, subtargets: HashMap<Interned<TargetPathElement>, TargetState>,
}, },
Transparent {
subtarget: Box<TargetState>,
},
} }
#[derive(Debug)] #[derive(Debug)]
@ -1496,6 +1499,7 @@ impl TargetState {
subtarget.assert_written(); subtarget.assert_written();
} }
} }
TargetStateInner::Transparent { subtarget } => subtarget.assert_written(),
} }
} }
fn merge_conditional_sub_blocks_into_block( fn merge_conditional_sub_blocks_into_block(
@ -1535,6 +1539,9 @@ impl TargetState {
i.merge_conditional_sub_blocks_into_block(target_block, sub_blocks.clone()); i.merge_conditional_sub_blocks_into_block(target_block, sub_blocks.clone());
} }
} }
TargetStateInner::Transparent { subtarget } => {
subtarget.merge_conditional_sub_blocks_into_block(target_block, sub_blocks)
}
} }
} }
fn new(target: Interned<Target>, declared_in_block: usize) -> Self { fn new(target: Interned<Target>, declared_in_block: usize) -> Self {
@ -1589,14 +1596,15 @@ impl TargetState {
declared_in_block, declared_in_block,
written_in_blocks: RefCell::default(), written_in_blocks: RefCell::default(),
}, },
CanonicalType::TraceAsString(_) => { CanonicalType::TraceAsString(_) => TargetStateInner::Transparent {
return Self::new( subtarget: Box::new(Self::new(
Target::intern_sized(
target target
.join(Intern::intern_sized(TargetPathTraceAsStringInner {}.into())) .join(Intern::intern_sized(TargetPathTraceAsStringInner {}.into())),
.intern_sized(), ),
declared_in_block, declared_in_block,
); )),
} },
}, },
} }
} }
@ -1746,6 +1754,9 @@ impl AssertValidityState {
} }
} }
} }
TargetStateInner::Transparent { subtarget } => {
Self::set_connect_target_written(subtarget, is_lhs, block, exact_target_unknown);
}
} }
} }
#[track_caller] #[track_caller]

View file

@ -13,7 +13,7 @@ pub use crate::{
enum_::{Enum, HdlNone, HdlOption, HdlSome}, enum_::{Enum, HdlNone, HdlOption, HdlSome},
expr::{ expr::{
CastBitsTo, CastTo, CastToBits, Expr, HdlPartialEq, HdlPartialOrd, MakeUninitExpr, CastBitsTo, CastTo, CastToBits, Expr, HdlPartialEq, HdlPartialOrd, MakeUninitExpr,
ReduceBits, ToExpr, ValueType, repeat, ReduceBits, ToExpr, ToTraceAsString, ValueType, repeat,
}, },
formal::{ formal::{
MakeFormalExpr, all_const, all_seq, any_const, any_seq, formal_global_clock, formal_reset, MakeFormalExpr, all_const, all_seq, any_const, any_seq, formal_global_clock, formal_reset,
@ -38,7 +38,7 @@ pub use crate::{
}, },
source_location::SourceLocation, source_location::SourceLocation,
testing::{FormalMode, assert_formal}, testing::{FormalMode, assert_formal},
ty::{AsMask, CanonicalType, Type}, ty::{AsMask, CanonicalType, TraceAsString, Type},
util::{ConstUsize, GenericConstUsize}, util::{ConstUsize, GenericConstUsize},
wire::Wire, wire::Wire,
}; };

View file

@ -19,20 +19,19 @@ use crate::{
impl_match_variant_as_self, impl_match_variant_as_self,
}, },
util::{ util::{
ConstUsize, HashMap, ConstUsize,
alternating_cell::{AlternatingCell, AlternatingCellMethods}, alternating_cell::{AlternatingCell, AlternatingCellMethods},
serde_by_id::{SerdeById, SerdeByIdProperties, SerdeByIdTable, SerdeByIdTrait},
}, },
}; };
use bitvec::{slice::BitSlice, vec::BitVec}; use bitvec::{slice::BitSlice, vec::BitVec};
use hashbrown::hash_map::Entry;
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as _, ser::Error as _}; use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error as _, ser::Error as _};
use std::{ use std::{
borrow::{Borrow, BorrowMut, Cow}, borrow::{Borrow, BorrowMut, Cow},
fmt::{self, Write}, fmt,
hash::{BuildHasher, Hash, Hasher, RandomState},
num::NonZero, num::NonZero,
ops::{Deref, DerefMut, Index, IndexMut}, ops::{Deref, DerefMut, Index, IndexMut},
sync::{Arc, Mutex}, sync::Arc,
}; };
pub(crate) mod sim_only_value_unsafe; pub(crate) mod sim_only_value_unsafe;
@ -1228,80 +1227,17 @@ macro_rules! impl_to_sim_value_for_int_value {
impl_to_sim_value_for_int_value!(UIntValue, UInt, UIntType); impl_to_sim_value_for_int_value!(UIntValue, UInt, UIntType);
impl_to_sim_value_for_int_value!(SIntValue, SInt, SIntType); impl_to_sim_value_for_int_value!(SIntValue, SInt, SIntType);
#[derive(Default)] impl SerdeByIdTrait for DynSimOnly {
struct DynSimOnlySerdeTableRest { fn serde_by_id_properties(&self) -> SerdeByIdProperties<Self> {
from_serde: HashMap<DynSimOnlySerdeId, DynSimOnly>, self.serde_by_id_properties_inner()
serde_id_random_state: RandomState,
buffer: String,
}
impl DynSimOnlySerdeTableRest {
#[cold]
fn add_new(&mut self, ty: DynSimOnly) -> DynSimOnlySerdeId {
let mut try_number = 0u64;
let mut hasher = self.serde_id_random_state.build_hasher();
// extract more bits of randomness from TypeId -- its Hash impl only hashes 64-bits
write!(self.buffer, "{:?}", ty.type_id()).expect("shouldn't ever fail");
self.buffer.hash(&mut hasher);
loop {
let mut hasher = hasher.clone();
try_number.hash(&mut hasher);
try_number += 1;
let retval = DynSimOnlySerdeId(std::array::from_fn(|i| {
let mut hasher = hasher.clone();
i.hash(&mut hasher);
hasher.finish() as u32
}));
match self.from_serde.entry(retval) {
Entry::Occupied(_) => continue,
Entry::Vacant(e) => {
e.insert(ty);
return retval;
} }
}
}
}
}
#[derive(Default)] fn static_table() -> &'static SerdeByIdTable<Self> {
struct DynSimOnlySerdeTable { static TABLE: SerdeByIdTable<DynSimOnly> = SerdeByIdTable::new();
to_serde: HashMap<DynSimOnly, DynSimOnlySerdeId>, &TABLE
rest: DynSimOnlySerdeTableRest,
}
static DYN_SIM_ONLY_VALUE_TYPE_SERDE_TABLE: Mutex<Option<DynSimOnlySerdeTable>> = Mutex::new(None);
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
#[serde(transparent)]
struct DynSimOnlySerdeId([u32; 4]);
impl From<DynSimOnly> for DynSimOnlySerdeId {
fn from(ty: DynSimOnly) -> Self {
let mut locked = DYN_SIM_ONLY_VALUE_TYPE_SERDE_TABLE
.lock()
.expect("shouldn't be poison");
let DynSimOnlySerdeTable { to_serde, rest } = locked.get_or_insert_default();
match to_serde.entry(ty) {
Entry::Occupied(occupied_entry) => *occupied_entry.get(),
Entry::Vacant(vacant_entry) => *vacant_entry.insert(rest.add_new(ty)),
} }
}
}
impl DynSimOnlySerdeId { const NAME: &'static str = "DynSimOnly";
fn ty(self) -> Option<DynSimOnly> {
let locked = DYN_SIM_ONLY_VALUE_TYPE_SERDE_TABLE
.lock()
.expect("shouldn't be poison");
Some(*locked.as_ref()?.rest.from_serde.get(&self)?)
}
}
#[derive(Clone, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)]
struct DynSimOnlySerde<'a> {
random_id: DynSimOnlySerdeId,
#[serde(borrow)]
type_name: Cow<'a, str>,
} }
impl Serialize for DynSimOnly { impl Serialize for DynSimOnly {
@ -1309,11 +1245,7 @@ impl Serialize for DynSimOnly {
where where
S: Serializer, S: Serializer,
{ {
DynSimOnlySerde { SerdeById { inner: *self }.serialize(serializer)
random_id: (*self).into(),
type_name: Cow::Borrowed(self.type_name()),
}
.serialize(serializer)
} }
} }
@ -1322,16 +1254,7 @@ impl<'de> Deserialize<'de> for DynSimOnly {
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
let deserialized = DynSimOnlySerde::deserialize(deserializer)?; Ok(SerdeById::deserialize(deserializer)?.inner)
let retval = deserialized
.random_id
.ty()
.filter(|ty| ty.type_name() == deserialized.type_name);
retval.ok_or_else(|| {
D::Error::custom(
"doesn't match any DynSimOnly that was serialized this time this program was run",
)
})
} }
} }

View file

@ -3,7 +3,10 @@
//! `unsafe` parts of [`DynSimOnlyValue`] //! `unsafe` parts of [`DynSimOnlyValue`]
use crate::expr::{ValueType, value_category::ValueCategoryValue}; use crate::{
expr::{ValueType, value_category::ValueCategoryValue},
util::serde_by_id::SerdeByIdProperties,
};
use serde::{Serialize, de::DeserializeOwned}; use serde::{Serialize, de::DeserializeOwned};
use std::{ use std::{
any::{self, TypeId}, any::{self, TypeId},
@ -33,6 +36,7 @@ unsafe trait DynSimOnlyTrait: 'static + Send + Sync {
&self, &self,
json_str: &str, json_str: &str,
) -> serde_json::Result<Rc<dyn DynSimOnlyValueTrait>>; ) -> serde_json::Result<Rc<dyn DynSimOnlyValueTrait>>;
fn serde_by_id_properties_inner(&self) -> SerdeByIdProperties<DynSimOnly>;
} }
/// Safety: `type_id_dyn` is implemented correctly /// Safety: `type_id_dyn` is implemented correctly
@ -55,6 +59,9 @@ unsafe impl<T: SimOnlyValueTrait> DynSimOnlyTrait for SimOnly<T> {
) -> serde_json::Result<Rc<dyn DynSimOnlyValueTrait>> { ) -> serde_json::Result<Rc<dyn DynSimOnlyValueTrait>> {
Ok(Rc::<T>::new(serde_json::from_str(json_str)?)) Ok(Rc::<T>::new(serde_json::from_str(json_str)?))
} }
fn serde_by_id_properties_inner(&self) -> SerdeByIdProperties<DynSimOnly> {
SerdeByIdProperties::of::<T>()
}
} }
/// Safety: /// Safety:
@ -151,6 +158,9 @@ impl DynSimOnly {
pub fn default_value(self) -> DynSimOnlyValue { pub fn default_value(self) -> DynSimOnlyValue {
DynSimOnlyValue(self.ty.default_value()) DynSimOnlyValue(self.ty.default_value())
} }
pub(super) fn serde_by_id_properties_inner(self) -> SerdeByIdProperties<Self> {
self.ty.serde_by_id_properties_inner()
}
} }
impl PartialEq for DynSimOnly { impl PartialEq for DynSimOnly {

View file

@ -6,7 +6,7 @@ use crate::{
bundle::{Bundle, BundleField, BundleType}, bundle::{Bundle, BundleField, BundleType},
clock::Clock, clock::Clock,
enum_::{Enum, EnumType, EnumVariant}, enum_::{Enum, EnumType, EnumVariant},
expr::{Expr, ToExpr, ValueType, ops}, expr::{Expr, HdlPartialEqImpl, HdlPartialOrdImpl, ToExpr, ValueType, Valueless, ops},
int::{Bool, SInt, UInt, UIntValue}, int::{Bool, SInt, UInt, UIntValue},
intern::{Intern, Interned, LazyInterned, Memoize, SupportsPtrEqWithTypeId}, intern::{Intern, Interned, LazyInterned, Memoize, SupportsPtrEqWithTypeId},
module::transform::visit::{Fold, Folder, Visit, Visitor}, module::transform::visit::{Fold, Folder, Visit, Visitor},
@ -23,6 +23,7 @@ use crate::{
use bitvec::{slice::BitSlice, vec::BitVec}; use bitvec::{slice::BitSlice, vec::BitVec};
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::DeserializeOwned}; use serde::{Deserialize, Deserializer, Serialize, Serializer, de::DeserializeOwned};
use std::{ use std::{
borrow::Cow,
fmt::{self, Write}, fmt::{self, Write},
hash::Hash, hash::Hash,
iter::{FusedIterator, Sum}, iter::{FusedIterator, Sum},
@ -997,9 +998,6 @@ impl OpaqueSimValue {
pub fn sim_only_values(&self) -> &[DynSimOnlyValue] { pub fn sim_only_values(&self) -> &[DynSimOnlyValue] {
&self.sim_only_values &self.sim_only_values
} }
pub(crate) fn sim_only_values_vec(&self) -> &Vec<DynSimOnlyValue> {
&self.sim_only_values
}
pub fn sim_only_values_mut(&mut self) -> &mut Vec<DynSimOnlyValue> { pub fn sim_only_values_mut(&mut self) -> &mut Vec<DynSimOnlyValue> {
&mut self.sim_only_values &mut self.sim_only_values
} }
@ -1463,14 +1461,14 @@ impl<T: Type> SimValueDebug for TraceAsString<T> {
value: &<Self as Type>::SimValue, value: &<Self as Type>::SimValue,
f: &mut fmt::Formatter<'_>, f: &mut fmt::Formatter<'_>,
) -> fmt::Result { ) -> fmt::Result {
T::sim_value_debug(value, f) T::sim_value_debug(value.inner(), f)
} }
} }
impl<T: Type> Type for TraceAsString<T> { impl<T: Type> Type for TraceAsString<T> {
type BaseType = TraceAsString<CanonicalType>; type BaseType = TraceAsString<CanonicalType>;
type MaskType = T::MaskType; type MaskType = T::MaskType;
type SimValue = TraceAsStringSimValue<T::SimValue>; type SimValue = TraceAsStringSimValue<T>;
type MatchVariant = Expr<T>; type MatchVariant = Expr<T>;
type MatchActiveScope = (); type MatchActiveScope = ();
type MatchVariantAndInactiveScope = MatchVariantWithoutScope<Self::MatchVariant>; type MatchVariantAndInactiveScope = MatchVariantWithoutScope<Self::MatchVariant>;
@ -1507,7 +1505,8 @@ impl<T: Type> Type for TraceAsString<T> {
fn sim_value_from_opaque(&self, opaque: OpaqueSimValueSlice<'_>) -> Self::SimValue { fn sim_value_from_opaque(&self, opaque: OpaqueSimValueSlice<'_>) -> Self::SimValue {
TraceAsStringSimValue { TraceAsStringSimValue {
inner: self.inner_ty.sim_value_from_opaque(opaque), inner: SimValue::from_opaque(self.inner_ty(), opaque.to_owned()),
trace_as_string: self.trace_as_string.interned(),
} }
} }
@ -1594,101 +1593,217 @@ impl<T: Type> Index<T> for TraceAsStringWithoutGenerics {
} }
} }
#[derive(Copy, Clone, Eq, Ord, Hash, Default, Serialize, Deserialize)] #[derive(Clone)]
pub struct TraceAsStringSimValue<T> { pub struct TraceAsStringSimValue<T: Type> {
inner: SimValue<T>,
trace_as_string: Interned<dyn TraceAsStringTrait>,
}
#[derive(Serialize, Deserialize)]
#[serde(rename = "TraceAsStringSimValue")]
struct TraceAsStringSimValueSerde<T> {
inner: T, inner: T,
trace_as_string: crate::util::serde_by_id::SerdeById<Interned<dyn TraceAsStringTrait>>,
} }
impl<T> TraceAsStringSimValue<T> { impl<T: Type<SimValue: Serialize> + Serialize> Serialize for TraceAsStringSimValue<T> {
pub const fn new(inner: T) -> Self { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
Self { inner } where
S: Serializer,
{
let Self {
inner,
trace_as_string,
} = self;
TraceAsStringSimValueSerde {
inner,
trace_as_string: crate::util::serde_by_id::SerdeById {
inner: *trace_as_string,
},
} }
pub fn into_inner(this: Self) -> T { .serialize(serializer)
let Self { inner } = this;
inner
} }
} }
impl<T: ValueType> ValueType for TraceAsStringSimValue<T> { impl<'de, T: Type<SimValue: Deserialize<'de>> + Deserialize<'de>> Deserialize<'de>
type Type = TraceAsString<T::Type>;
type ValueCategory = T::ValueCategory;
fn ty(&self) -> Self::Type {
TraceAsString::new(self.inner.ty())
}
}
impl<T: ToExpr> ToExpr for TraceAsStringSimValue<T> {
fn to_expr(&self) -> Expr<Self::Type> {
let inner = self.inner.to_expr();
ops::AsTraceAsString::new(Expr::canonical(inner), TraceAsString::new(inner.ty())).to_expr()
}
}
impl<T: ToSimValueWithType<Ty>, Ty: Type> ToSimValueWithType<TraceAsString<Ty>>
for TraceAsStringSimValue<T> for TraceAsStringSimValue<T>
{ {
fn to_sim_value_with_type(&self, ty: TraceAsString<Ty>) -> SimValue<TraceAsString<Ty>> { fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
let inner = self.inner.to_sim_value_with_type(ty.inner_ty()); where
let inner = SimValue::into_value(inner); D: Deserializer<'de>,
SimValue::from_value(ty, TraceAsStringSimValue { inner }) {
} let TraceAsStringSimValueSerde {
fn into_sim_value_with_type(self, ty: TraceAsString<Ty>) -> SimValue<TraceAsString<Ty>> { inner,
let inner = self.inner.into_sim_value_with_type(ty.inner_ty()); trace_as_string:
let inner = SimValue::into_value(inner); crate::util::serde_by_id::SerdeById {
SimValue::from_value(ty, TraceAsStringSimValue { inner }) inner: trace_as_string,
},
} = Deserialize::deserialize(deserializer)?;
Ok(Self {
inner,
trace_as_string,
})
} }
} }
impl<T: ToSimValue> ToSimValue for TraceAsStringSimValue<T> { impl<T: Type> TraceAsStringSimValue<T> {
fn to_sim_value(&self) -> SimValue<Self::Type> { pub fn new_with_ty(inner: impl ToSimValueWithType<T>, ty: TraceAsString<T>) -> Self {
self.to_sim_value_with_type(self.ty()) Self {
inner: inner.into_sim_value_with_type(ty.inner_ty()),
trace_as_string: ty.trace_as_string.interned(),
} }
fn into_sim_value(self) -> SimValue<Self::Type> {
let ty = self.ty();
self.into_sim_value_with_type(ty)
} }
} pub fn new(inner: impl ToSimValue<Type = T>) -> Self {
let inner = inner.into_sim_value();
impl<T> std::ops::Deref for TraceAsStringSimValue<T> { Self {
type Target = T; trace_as_string: TraceAsString::new(inner.ty()).trace_as_string.interned(),
inner,
fn deref(&self) -> &Self::Target { }
}
pub fn into_inner(self) -> SimValue<T> {
self.inner
}
pub fn inner(&self) -> &SimValue<T> {
&self.inner &self.inner
} }
} pub fn inner_mut(&mut self) -> &mut SimValue<T> {
impl<T> std::ops::DerefMut for TraceAsStringSimValue<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner &mut self.inner
} }
} }
impl<T: fmt::Debug> fmt::Debug for TraceAsStringSimValue<T> { impl<T: Type> ValueType for TraceAsStringSimValue<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { type Type = TraceAsString<T>;
let Self { inner } = self; type ValueCategory = crate::expr::value_category::ValueCategoryValue;
fmt::Debug::fmt(inner, f)
fn ty(&self) -> Self::Type {
let inner_ty = self.inner.ty().intern_sized();
if self
.trace_as_string
.can_substitute_type(inner_ty.canonical())
{
TraceAsString {
inner_ty: LazyInterned::Interned(inner_ty),
trace_as_string: LazyInterned::Interned(self.trace_as_string),
}
} else {
TraceAsString::new_interned(inner_ty)
}
} }
} }
impl<T: fmt::Display> fmt::Display for TraceAsStringSimValue<T> { impl<T: Type> ToExpr for TraceAsStringSimValue<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { #[track_caller]
let Self { inner } = self; fn to_expr(&self) -> Expr<Self::Type> {
fmt::Display::fmt(inner, f) let inner = self.inner.to_expr();
let inner_canonical = Expr::canonical(inner);
let inner_ty = inner.ty().intern_sized();
let ty = if self
.trace_as_string
.can_substitute_type(inner_canonical.ty())
{
TraceAsString {
inner_ty: LazyInterned::Interned(inner_ty),
trace_as_string: LazyInterned::Interned(self.trace_as_string),
}
} else {
TraceAsString::new_interned(inner_ty)
};
ops::AsTraceAsString::new(inner_canonical, ty).to_expr()
} }
} }
impl<T: PartialOrd<U>, U> PartialOrd<TraceAsStringSimValue<U>> for TraceAsStringSimValue<T> { impl<T: Type> ToSimValueWithType<TraceAsString<T>> for TraceAsStringSimValue<T> {
fn to_sim_value_with_type(&self, ty: TraceAsString<T>) -> SimValue<TraceAsString<T>> {
let inner = self.inner.to_sim_value_with_type(ty.inner_ty());
SimValue::from_value(
ty,
TraceAsStringSimValue {
inner,
trace_as_string: ty.trace_as_string.interned(),
},
)
}
fn into_sim_value_with_type(self, ty: TraceAsString<T>) -> SimValue<TraceAsString<T>> {
let inner = self.inner.into_sim_value_with_type(ty.inner_ty());
SimValue::from_value(
ty,
TraceAsStringSimValue {
inner,
trace_as_string: ty.trace_as_string.interned(),
},
)
}
}
impl<T: Type> ToSimValue for TraceAsStringSimValue<T> {
fn to_sim_value(&self) -> SimValue<Self::Type> {
SimValue::from_value(self.ty(), self.clone())
}
fn into_sim_value(self) -> SimValue<Self::Type> {
SimValue::from_value(self.ty(), self)
}
}
impl<T: Type> fmt::Debug for TraceAsStringSimValue<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.inner, f)
}
}
impl<T: Type<SimValue: fmt::Display>> fmt::Display for TraceAsStringSimValue<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.inner, f)
}
}
impl<T: Type> Ord for TraceAsStringSimValue<T>
where
SimValue<T>: Ord,
{
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.inner.cmp(&other.inner)
}
}
impl<T: Type, U: Type> PartialOrd<TraceAsStringSimValue<U>> for TraceAsStringSimValue<T>
where
SimValue<T>: PartialOrd<SimValue<U>>,
{
fn partial_cmp(&self, other: &TraceAsStringSimValue<U>) -> Option<std::cmp::Ordering> { fn partial_cmp(&self, other: &TraceAsStringSimValue<U>) -> Option<std::cmp::Ordering> {
let Self { inner } = self; self.inner.partial_cmp(&other.inner)
inner.partial_cmp(&other.inner)
} }
} }
impl<T: PartialEq<U>, U> PartialEq<TraceAsStringSimValue<U>> for TraceAsStringSimValue<T> { impl<T: Type> Eq for TraceAsStringSimValue<T> where SimValue<T>: Eq {}
impl<T: Type> Hash for TraceAsStringSimValue<T>
where
SimValue<T>: Hash,
{
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.inner.hash(state);
}
}
impl<T: Type> Default for TraceAsStringSimValue<T>
where
SimValue<T>: Default,
{
fn default() -> Self {
let inner = SimValue::default();
Self {
trace_as_string: TraceAsString::new(inner.ty()).trace_as_string.interned(),
inner,
}
}
}
impl<T: Type, U: Type> PartialEq<TraceAsStringSimValue<U>> for TraceAsStringSimValue<T>
where
SimValue<T>: PartialEq<SimValue<U>>,
{
fn eq(&self, other: &TraceAsStringSimValue<U>) -> bool { fn eq(&self, other: &TraceAsStringSimValue<U>) -> bool {
let Self { inner } = self; self.inner == other.inner
*inner == other.inner
} }
} }
@ -1711,3 +1826,259 @@ impl<T: Type + Visit<State>, State: ?Sized + Visitor> Visit<State> for TraceAsSt
self.interned_inner_ty().visit(state) self.interned_inner_ty().visit(state)
} }
} }
fn trace_as_string_cow_into_inner<T: Type>(
this: Cow<'_, SimValue<TraceAsString<T>>>,
) -> Cow<'_, SimValue<T>> {
match this {
Cow::Borrowed(v) => Cow::Borrowed(&v.inner),
Cow::Owned(v) => Cow::Owned(SimValue::into_value(v).inner),
}
}
fn trace_as_string_cow_into_inner_value<T: Type>(
this: Cow<'_, TraceAsStringSimValue<T>>,
) -> Cow<'_, T::SimValue> {
match this {
Cow::Borrowed(v) => Cow::Borrowed(&v.inner),
Cow::Owned(v) => Cow::Owned(SimValue::into_value(v.inner)),
}
}
impl<T: HdlPartialEqImpl<U>, U: Type> HdlPartialEqImpl<TraceAsString<U>> for TraceAsString<T> {
#[track_caller]
fn cmp_value_eq(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: TraceAsString<U>,
rhs_value: Cow<'_, <TraceAsString<U> as Type>::SimValue>,
) -> bool {
HdlPartialEqImpl::cmp_value_eq(
lhs.inner_ty(),
trace_as_string_cow_into_inner_value(lhs_value),
rhs.inner_ty(),
trace_as_string_cow_into_inner_value(rhs_value),
)
}
#[track_caller]
fn cmp_value_ne(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: TraceAsString<U>,
rhs_value: Cow<'_, <TraceAsString<U> as Type>::SimValue>,
) -> bool {
HdlPartialEqImpl::cmp_value_ne(
lhs.inner_ty(),
trace_as_string_cow_into_inner_value(lhs_value),
rhs.inner_ty(),
trace_as_string_cow_into_inner_value(rhs_value),
)
}
#[track_caller]
fn cmp_sim_value_eq(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<TraceAsString<U>>>,
) -> SimValue<Bool> {
HdlPartialEqImpl::cmp_sim_value_eq(
trace_as_string_cow_into_inner(lhs),
trace_as_string_cow_into_inner(rhs),
)
}
#[track_caller]
fn cmp_sim_value_ne(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<TraceAsString<U>>>,
) -> SimValue<Bool> {
HdlPartialEqImpl::cmp_sim_value_ne(
trace_as_string_cow_into_inner(lhs),
trace_as_string_cow_into_inner(rhs),
)
}
#[track_caller]
fn cmp_expr_eq(lhs: Expr<Self>, rhs: Expr<TraceAsString<U>>) -> Expr<Bool> {
HdlPartialEqImpl::cmp_expr_eq(*lhs, *rhs)
}
#[track_caller]
fn cmp_expr_ne(lhs: Expr<Self>, rhs: Expr<TraceAsString<U>>) -> Expr<Bool> {
HdlPartialEqImpl::cmp_expr_ne(*lhs, *rhs)
}
#[track_caller]
fn cmp_valueless_eq(lhs: Valueless<Self>, rhs: Valueless<TraceAsString<U>>) -> Valueless<Bool> {
HdlPartialEqImpl::cmp_valueless_eq(
Valueless::new(lhs.ty().inner_ty()),
Valueless::new(rhs.ty().inner_ty()),
)
}
#[track_caller]
fn cmp_valueless_ne(lhs: Valueless<Self>, rhs: Valueless<TraceAsString<U>>) -> Valueless<Bool> {
HdlPartialEqImpl::cmp_valueless_ne(
Valueless::new(lhs.ty().inner_ty()),
Valueless::new(rhs.ty().inner_ty()),
)
}
}
impl<T: HdlPartialOrdImpl<U>, U: Type> HdlPartialOrdImpl<TraceAsString<U>> for TraceAsString<T> {
#[track_caller]
fn cmp_value_lt(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: TraceAsString<U>,
rhs_value: Cow<'_, <TraceAsString<U> as Type>::SimValue>,
) -> bool {
HdlPartialOrdImpl::cmp_value_lt(
lhs.inner_ty(),
trace_as_string_cow_into_inner_value(lhs_value),
rhs.inner_ty(),
trace_as_string_cow_into_inner_value(rhs_value),
)
}
#[track_caller]
fn cmp_value_le(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: TraceAsString<U>,
rhs_value: Cow<'_, <TraceAsString<U> as Type>::SimValue>,
) -> bool {
HdlPartialOrdImpl::cmp_value_le(
lhs.inner_ty(),
trace_as_string_cow_into_inner_value(lhs_value),
rhs.inner_ty(),
trace_as_string_cow_into_inner_value(rhs_value),
)
}
#[track_caller]
fn cmp_value_gt(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: TraceAsString<U>,
rhs_value: Cow<'_, <TraceAsString<U> as Type>::SimValue>,
) -> bool {
HdlPartialOrdImpl::cmp_value_gt(
lhs.inner_ty(),
trace_as_string_cow_into_inner_value(lhs_value),
rhs.inner_ty(),
trace_as_string_cow_into_inner_value(rhs_value),
)
}
#[track_caller]
fn cmp_value_ge(
lhs: Self,
lhs_value: Cow<'_, Self::SimValue>,
rhs: TraceAsString<U>,
rhs_value: Cow<'_, <TraceAsString<U> as Type>::SimValue>,
) -> bool {
HdlPartialOrdImpl::cmp_value_ge(
lhs.inner_ty(),
trace_as_string_cow_into_inner_value(lhs_value),
rhs.inner_ty(),
trace_as_string_cow_into_inner_value(rhs_value),
)
}
#[track_caller]
fn cmp_sim_value_lt(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<TraceAsString<U>>>,
) -> SimValue<Bool> {
HdlPartialOrdImpl::cmp_sim_value_lt(
trace_as_string_cow_into_inner(lhs),
trace_as_string_cow_into_inner(rhs),
)
}
#[track_caller]
fn cmp_sim_value_le(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<TraceAsString<U>>>,
) -> SimValue<Bool> {
HdlPartialOrdImpl::cmp_sim_value_le(
trace_as_string_cow_into_inner(lhs),
trace_as_string_cow_into_inner(rhs),
)
}
#[track_caller]
fn cmp_sim_value_gt(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<TraceAsString<U>>>,
) -> SimValue<Bool> {
HdlPartialOrdImpl::cmp_sim_value_gt(
trace_as_string_cow_into_inner(lhs),
trace_as_string_cow_into_inner(rhs),
)
}
#[track_caller]
fn cmp_sim_value_ge(
lhs: Cow<'_, SimValue<Self>>,
rhs: Cow<'_, SimValue<TraceAsString<U>>>,
) -> SimValue<Bool> {
HdlPartialOrdImpl::cmp_sim_value_ge(
trace_as_string_cow_into_inner(lhs),
trace_as_string_cow_into_inner(rhs),
)
}
#[track_caller]
fn cmp_expr_lt(lhs: Expr<Self>, rhs: Expr<TraceAsString<U>>) -> Expr<Bool> {
HdlPartialOrdImpl::cmp_expr_lt(*lhs, *rhs)
}
#[track_caller]
fn cmp_expr_le(lhs: Expr<Self>, rhs: Expr<TraceAsString<U>>) -> Expr<Bool> {
HdlPartialOrdImpl::cmp_expr_le(*lhs, *rhs)
}
#[track_caller]
fn cmp_expr_gt(lhs: Expr<Self>, rhs: Expr<TraceAsString<U>>) -> Expr<Bool> {
HdlPartialOrdImpl::cmp_expr_gt(*lhs, *rhs)
}
#[track_caller]
fn cmp_expr_ge(lhs: Expr<Self>, rhs: Expr<TraceAsString<U>>) -> Expr<Bool> {
HdlPartialOrdImpl::cmp_expr_ge(*lhs, *rhs)
}
#[track_caller]
fn cmp_valueless_lt(lhs: Valueless<Self>, rhs: Valueless<TraceAsString<U>>) -> Valueless<Bool> {
HdlPartialOrdImpl::cmp_valueless_lt(
Valueless::new(lhs.ty().inner_ty()),
Valueless::new(rhs.ty().inner_ty()),
)
}
#[track_caller]
fn cmp_valueless_le(lhs: Valueless<Self>, rhs: Valueless<TraceAsString<U>>) -> Valueless<Bool> {
HdlPartialOrdImpl::cmp_valueless_le(
Valueless::new(lhs.ty().inner_ty()),
Valueless::new(rhs.ty().inner_ty()),
)
}
#[track_caller]
fn cmp_valueless_gt(lhs: Valueless<Self>, rhs: Valueless<TraceAsString<U>>) -> Valueless<Bool> {
HdlPartialOrdImpl::cmp_valueless_gt(
Valueless::new(lhs.ty().inner_ty()),
Valueless::new(rhs.ty().inner_ty()),
)
}
#[track_caller]
fn cmp_valueless_ge(lhs: Valueless<Self>, rhs: Valueless<TraceAsString<U>>) -> Valueless<Bool> {
HdlPartialOrdImpl::cmp_valueless_ge(
Valueless::new(lhs.ty().inner_ty()),
Valueless::new(rhs.ty().inner_ty()),
)
}
}

View file

@ -39,6 +39,7 @@ impl<'de, T: ?Sized + PhantomConstValue> Deserialize<'de> for SerdePhantomConst<
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[serde(rename = "CanonicalType")] #[serde(rename = "CanonicalType")]
#[expect(private_interfaces)]
pub(crate) enum SerdeCanonicalType< pub(crate) enum SerdeCanonicalType<
ArrayElement = CanonicalType, ArrayElement = CanonicalType,
ThePhantomConst = SerdePhantomConst<Interned<PhantomConstCanonicalValue>>, ThePhantomConst = SerdePhantomConst<Interned<PhantomConstCanonicalValue>>,

View file

@ -13,7 +13,7 @@ use fayalite::{
prelude::*, prelude::*,
reset::ResetType, reset::ResetType,
sim::vcd::VcdWriterDecls, sim::vcd::VcdWriterDecls,
ty::{SimValueDebug, StaticType, TraceAsString, TraceAsStringSimValue}, ty::SimValueDebug,
util::{RcWriter, ready_valid::queue}, util::{RcWriter, ready_valid::queue},
}; };
use std::{collections::BTreeMap, num::NonZeroUsize, rc::Rc}; use std::{collections::BTreeMap, num::NonZeroUsize, rc::Rc};
@ -3061,10 +3061,7 @@ pub fn sim_trace_as_string() {
#[hdl] #[hdl]
let write: WriteStruct<Array<TraceAsString<HasCustomDebug>, 2>, ConstUsize<8>> = m.input(); let write: WriteStruct<Array<TraceAsString<HasCustomDebug>, 2>, ConstUsize<8>> = m.input();
#[hdl] #[hdl]
let mut mem = memory_with_init( let mut mem = memory_with_init([[HasCustomDebug::new_sim(Ok("")).to_trace_as_string(); 2]; 4]);
[[Expr::as_trace_as_string(HasCustomDebug::new_sim(Ok("")).to_expr(), StaticType::TYPE); 2];
4],
);
let read_port = mem.new_read_port(); let read_port = mem.new_read_port();
connect(read_port.clk, clk); connect(read_port.clk, clk);
connect_any(read_port.addr, read.addr); connect_any(read_port.addr, read.addr);
@ -3156,7 +3153,7 @@ fn test_sim_trace_as_string() {
sim.write(sim.io().write.en, write_addr.is_some()); sim.write(sim.io().write.en, write_addr.is_some());
sim.write( sim.write(
sim.io().write.data, sim.io().write.data,
write_data.map(|v| TraceAsStringSimValue::new(HasCustomDebug::new_sim(v))), write_data.map(|v| HasCustomDebug::new_sim(v).to_trace_as_string()),
); );
sim.write( sim.write(
sim.io().write.mask, sim.io().write.mask,
@ -3172,7 +3169,7 @@ fn test_sim_trace_as_string() {
.map(HasCustomDebug::new_sim) .map(HasCustomDebug::new_sim)
.into_sim_value(); .into_sim_value();
assert!( assert!(
**read_data == *expected_read_data, *read_data.inner() == expected_read_data,
"{read_data:#?}\n!= {expected_read_data:#?}", "{read_data:#?}\n!= {expected_read_data:#?}",
); );
} }

View file

@ -55,7 +55,7 @@ error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'sta
note: required because it appears within the type `DynSimOnlyValue` note: required because it appears within the type `DynSimOnlyValue`
--> src/sim/value/sim_only_value_unsafe.rs --> src/sim/value/sim_only_value_unsafe.rs
| |
271 | pub struct DynSimOnlyValue(Rc<dyn DynSimOnlyValueTrait>); 281 | pub struct DynSimOnlyValue(Rc<dyn DynSimOnlyValueTrait>);
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
note: required because it appears within the type `PhantomData<DynSimOnlyValue>` note: required because it appears within the type `PhantomData<DynSimOnlyValue>`
--> $RUST/core/src/marker.rs --> $RUST/core/src/marker.rs
@ -75,12 +75,12 @@ note: required because it appears within the type `Vec<DynSimOnlyValue>`
note: required because it appears within the type `OpaqueSimValue` note: required because it appears within the type `OpaqueSimValue`
--> src/ty.rs --> src/ty.rs
| |
895 | pub struct OpaqueSimValue { 896 | pub struct OpaqueSimValue {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
note: required because it appears within the type `value::SimValueInner<()>` note: required because it appears within the type `value::SimValueInner<()>`
--> src/sim/value.rs --> src/sim/value.rs
| |
52 | struct SimValueInner<T: Type> { 51 | struct SimValueInner<T: Type> {
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
note: required because it appears within the type `UnsafeCell<value::SimValueInner<()>>` note: required because it appears within the type `UnsafeCell<value::SimValueInner<()>>`
--> $RUST/core/src/cell.rs --> $RUST/core/src/cell.rs
@ -95,7 +95,7 @@ note: required because it appears within the type `util::alternating_cell::Alter
note: required because it appears within the type `fayalite::prelude::SimValue<()>` note: required because it appears within the type `fayalite::prelude::SimValue<()>`
--> src/sim/value.rs --> src/sim/value.rs
| |
161 | pub struct SimValue<T: Type> { 160 | pub struct SimValue<T: Type> {
| ^^^^^^^^ | ^^^^^^^^
note: required by a bound in `fayalite::intern::Interned` note: required by a bound in `fayalite::intern::Interned`
--> src/intern.rs --> src/intern.rs
@ -194,7 +194,7 @@ error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'sta
note: required because it appears within the type `DynSimOnlyValue` note: required because it appears within the type `DynSimOnlyValue`
--> src/sim/value/sim_only_value_unsafe.rs --> src/sim/value/sim_only_value_unsafe.rs
| |
271 | pub struct DynSimOnlyValue(Rc<dyn DynSimOnlyValueTrait>); 281 | pub struct DynSimOnlyValue(Rc<dyn DynSimOnlyValueTrait>);
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
note: required because it appears within the type `PhantomData<DynSimOnlyValue>` note: required because it appears within the type `PhantomData<DynSimOnlyValue>`
--> $RUST/core/src/marker.rs --> $RUST/core/src/marker.rs
@ -214,12 +214,12 @@ note: required because it appears within the type `Vec<DynSimOnlyValue>`
note: required because it appears within the type `OpaqueSimValue` note: required because it appears within the type `OpaqueSimValue`
--> src/ty.rs --> src/ty.rs
| |
895 | pub struct OpaqueSimValue { 896 | pub struct OpaqueSimValue {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
note: required because it appears within the type `value::SimValueInner<()>` note: required because it appears within the type `value::SimValueInner<()>`
--> src/sim/value.rs --> src/sim/value.rs
| |
52 | struct SimValueInner<T: Type> { 51 | struct SimValueInner<T: Type> {
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
note: required because it appears within the type `UnsafeCell<value::SimValueInner<()>>` note: required because it appears within the type `UnsafeCell<value::SimValueInner<()>>`
--> $RUST/core/src/cell.rs --> $RUST/core/src/cell.rs
@ -234,7 +234,7 @@ note: required because it appears within the type `util::alternating_cell::Alter
note: required because it appears within the type `fayalite::prelude::SimValue<()>` note: required because it appears within the type `fayalite::prelude::SimValue<()>`
--> src/sim/value.rs --> src/sim/value.rs
| |
161 | pub struct SimValue<T: Type> { 160 | pub struct SimValue<T: Type> {
| ^^^^^^^^ | ^^^^^^^^
note: required by a bound in `intern_sized` note: required by a bound in `intern_sized`
--> src/intern.rs --> src/intern.rs
@ -306,7 +306,7 @@ error[E0277]: `Rc<(dyn value::sim_only_value_unsafe::DynSimOnlyValueTrait + 'sta
note: required because it appears within the type `DynSimOnlyValue` note: required because it appears within the type `DynSimOnlyValue`
--> src/sim/value/sim_only_value_unsafe.rs --> src/sim/value/sim_only_value_unsafe.rs
| |
271 | pub struct DynSimOnlyValue(Rc<dyn DynSimOnlyValueTrait>); 281 | pub struct DynSimOnlyValue(Rc<dyn DynSimOnlyValueTrait>);
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
note: required because it appears within the type `PhantomData<DynSimOnlyValue>` note: required because it appears within the type `PhantomData<DynSimOnlyValue>`
--> $RUST/core/src/marker.rs --> $RUST/core/src/marker.rs
@ -326,12 +326,12 @@ note: required because it appears within the type `Vec<DynSimOnlyValue>`
note: required because it appears within the type `OpaqueSimValue` note: required because it appears within the type `OpaqueSimValue`
--> src/ty.rs --> src/ty.rs
| |
895 | pub struct OpaqueSimValue { 896 | pub struct OpaqueSimValue {
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
note: required because it appears within the type `value::SimValueInner<()>` note: required because it appears within the type `value::SimValueInner<()>`
--> src/sim/value.rs --> src/sim/value.rs
| |
52 | struct SimValueInner<T: Type> { 51 | struct SimValueInner<T: Type> {
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
note: required because it appears within the type `UnsafeCell<value::SimValueInner<()>>` note: required because it appears within the type `UnsafeCell<value::SimValueInner<()>>`
--> $RUST/core/src/cell.rs --> $RUST/core/src/cell.rs
@ -346,7 +346,7 @@ note: required because it appears within the type `util::alternating_cell::Alter
note: required because it appears within the type `fayalite::prelude::SimValue<()>` note: required because it appears within the type `fayalite::prelude::SimValue<()>`
--> src/sim/value.rs --> src/sim/value.rs
| |
161 | pub struct SimValue<T: Type> { 160 | pub struct SimValue<T: Type> {
| ^^^^^^^^ | ^^^^^^^^
note: required by a bound in `fayalite::intern::Interned` note: required by a bound in `fayalite::intern::Interned`
--> src/intern.rs --> src/intern.rs