forked from libre-chip/fayalite
		
	Compare commits
	
		
			10 commits
		
	
	
		
			36f1b9bbb6
			...
			668e714dc9
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 668e714dc9 | |||
| 88323a8c16 | |||
| 91e1b619e8 | |||
| e2d2d4110b | |||
| b1f9706e4e | |||
| 4eda4366c8 | |||
| 122c08d3cf | |||
| b08a747e20 | |||
| e0c9939147 | |||
| 07725ab489 | 
					 23 changed files with 567 additions and 111 deletions
				
			
		| 
						 | 
					@ -59,3 +59,4 @@ jobs:
 | 
				
			||||||
      - run: cargo build --tests --features=unstable-doc
 | 
					      - run: cargo build --tests --features=unstable-doc
 | 
				
			||||||
      - run: cargo test --doc --features=unstable-doc
 | 
					      - run: cargo test --doc --features=unstable-doc
 | 
				
			||||||
      - run: cargo doc --features=unstable-doc
 | 
					      - run: cargo doc --features=unstable-doc
 | 
				
			||||||
 | 
					      - run: FAYALITE_TEST_HASHER=always_zero cargo test --test=module --features=unstable-doc,unstable-test-hasher
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										56
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										56
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							| 
						 | 
					@ -2,18 +2,6 @@
 | 
				
			||||||
# It is not intended for manual editing.
 | 
					# It is not intended for manual editing.
 | 
				
			||||||
version = 3
 | 
					version = 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "ahash"
 | 
					 | 
				
			||||||
version = "0.8.7"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "cfg-if",
 | 
					 | 
				
			||||||
 "once_cell",
 | 
					 | 
				
			||||||
 "version_check",
 | 
					 | 
				
			||||||
 "zerocopy",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "allocator-api2"
 | 
					name = "allocator-api2"
 | 
				
			||||||
version = "0.2.16"
 | 
					version = "0.2.16"
 | 
				
			||||||
| 
						 | 
					@ -365,6 +353,12 @@ version = "0.5.7"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
 | 
					checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "foldhash"
 | 
				
			||||||
 | 
					version = "0.1.5"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "funty"
 | 
					name = "funty"
 | 
				
			||||||
version = "2.0.0"
 | 
					version = "2.0.0"
 | 
				
			||||||
| 
						 | 
					@ -400,12 +394,13 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "hashbrown"
 | 
					name = "hashbrown"
 | 
				
			||||||
version = "0.14.3"
 | 
					version = "0.15.2"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
 | 
					checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "ahash",
 | 
					 | 
				
			||||||
 "allocator-api2",
 | 
					 "allocator-api2",
 | 
				
			||||||
 | 
					 "equivalent",
 | 
				
			||||||
 | 
					 "foldhash",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
| 
						 | 
					@ -431,9 +426,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "indexmap"
 | 
					name = "indexmap"
 | 
				
			||||||
version = "2.5.0"
 | 
					version = "2.9.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5"
 | 
					checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "equivalent",
 | 
					 "equivalent",
 | 
				
			||||||
 "hashbrown",
 | 
					 "hashbrown",
 | 
				
			||||||
| 
						 | 
					@ -524,11 +519,14 @@ dependencies = [
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "petgraph"
 | 
					name = "petgraph"
 | 
				
			||||||
version = "0.6.5"
 | 
					version = "0.8.1"
 | 
				
			||||||
source = "git+https://github.com/programmerjake/petgraph.git?rev=258ea8071209a924b73fe96f9f87a3b7b45cbc9f#258ea8071209a924b73fe96f9f87a3b7b45cbc9f"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "7a98c6720655620a521dcc722d0ad66cd8afd5d86e34a89ef691c50b7b24de06"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "fixedbitset",
 | 
					 "fixedbitset",
 | 
				
			||||||
 | 
					 "hashbrown",
 | 
				
			||||||
 "indexmap",
 | 
					 "indexmap",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
| 
						 | 
					@ -893,23 +891,3 @@ checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "tap",
 | 
					 "tap",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "zerocopy"
 | 
					 | 
				
			||||||
version = "0.7.32"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "zerocopy-derive",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[package]]
 | 
					 | 
				
			||||||
name = "zerocopy-derive"
 | 
					 | 
				
			||||||
version = "0.7.32"
 | 
					 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					 | 
				
			||||||
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
 | 
					 | 
				
			||||||
dependencies = [
 | 
					 | 
				
			||||||
 "proc-macro2",
 | 
					 | 
				
			||||||
 "quote",
 | 
					 | 
				
			||||||
 "syn",
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,14 +23,13 @@ blake3 = { version = "1.5.4", features = ["serde"] }
 | 
				
			||||||
clap = { version = "4.5.9", features = ["derive", "env", "string"] }
 | 
					clap = { version = "4.5.9", features = ["derive", "env", "string"] }
 | 
				
			||||||
ctor = "0.2.8"
 | 
					ctor = "0.2.8"
 | 
				
			||||||
eyre = "0.6.12"
 | 
					eyre = "0.6.12"
 | 
				
			||||||
hashbrown = "0.14.3"
 | 
					hashbrown = "0.15.2"
 | 
				
			||||||
indexmap = { version = "2.5.0", features = ["serde"] }
 | 
					indexmap = { version = "2.5.0", features = ["serde"] }
 | 
				
			||||||
jobslot = "0.2.19"
 | 
					jobslot = "0.2.19"
 | 
				
			||||||
num-bigint = "0.4.6"
 | 
					num-bigint = "0.4.6"
 | 
				
			||||||
num-traits = "0.2.16"
 | 
					num-traits = "0.2.16"
 | 
				
			||||||
os_pipe = "1.2.1"
 | 
					os_pipe = "1.2.1"
 | 
				
			||||||
# TODO: switch back to crates.io once petgraph accepts PR #684 and releases a new version
 | 
					petgraph = "0.8.1"
 | 
				
			||||||
petgraph = { git = "https://github.com/programmerjake/petgraph.git", rev = "258ea8071209a924b73fe96f9f87a3b7b45cbc9f" }
 | 
					 | 
				
			||||||
prettyplease = "0.2.20"
 | 
					prettyplease = "0.2.20"
 | 
				
			||||||
proc-macro2 = "1.0.83"
 | 
					proc-macro2 = "1.0.83"
 | 
				
			||||||
quote = "1.0.36"
 | 
					quote = "1.0.36"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,6 +40,7 @@ fayalite-visit-gen.workspace = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[features]
 | 
					[features]
 | 
				
			||||||
unstable-doc = []
 | 
					unstable-doc = []
 | 
				
			||||||
 | 
					unstable-test-hasher = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[package.metadata.docs.rs]
 | 
					[package.metadata.docs.rs]
 | 
				
			||||||
features = ["unstable-doc"]
 | 
					features = ["unstable-doc"]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,9 +14,9 @@ use crate::{
 | 
				
			||||||
        impl_match_variant_as_self, CanonicalType, MatchVariantWithoutScope, OpaqueSimValue,
 | 
					        impl_match_variant_as_self, CanonicalType, MatchVariantWithoutScope, OpaqueSimValue,
 | 
				
			||||||
        StaticType, Type, TypeProperties, TypeWithDeref,
 | 
					        StaticType, Type, TypeProperties, TypeWithDeref,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    util::HashMap,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bitvec::{slice::BitSlice, vec::BitVec};
 | 
					use bitvec::{slice::BitSlice, vec::BitVec};
 | 
				
			||||||
use hashbrown::HashMap;
 | 
					 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
use std::{fmt, marker::PhantomData};
 | 
					use std::{fmt, marker::PhantomData};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -160,7 +160,7 @@ impl Default for BundleTypePropertiesBuilder {
 | 
				
			||||||
impl Bundle {
 | 
					impl Bundle {
 | 
				
			||||||
    #[track_caller]
 | 
					    #[track_caller]
 | 
				
			||||||
    pub fn new(fields: Interned<[BundleField]>) -> Self {
 | 
					    pub fn new(fields: Interned<[BundleField]>) -> Self {
 | 
				
			||||||
        let mut name_indexes = HashMap::with_capacity(fields.len());
 | 
					        let mut name_indexes = HashMap::with_capacity_and_hasher(fields.len(), Default::default());
 | 
				
			||||||
        let mut field_offsets = Vec::with_capacity(fields.len());
 | 
					        let mut field_offsets = Vec::with_capacity(fields.len());
 | 
				
			||||||
        let mut type_props_builder = BundleTypePropertiesBuilder::new();
 | 
					        let mut type_props_builder = BundleTypePropertiesBuilder::new();
 | 
				
			||||||
        for (index, &BundleField { name, flipped, ty }) in fields.iter().enumerate() {
 | 
					        for (index, &BundleField { name, flipped, ty }) in fields.iter().enumerate() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -258,7 +258,7 @@ pub struct VerilogArgs {
 | 
				
			||||||
        default_value = "firtool",
 | 
					        default_value = "firtool",
 | 
				
			||||||
        env = "FIRTOOL",
 | 
					        env = "FIRTOOL",
 | 
				
			||||||
        value_hint = ValueHint::CommandName,
 | 
					        value_hint = ValueHint::CommandName,
 | 
				
			||||||
        value_parser = OsStringValueParser::new().try_map(which::which)
 | 
					        value_parser = OsStringValueParser::new().try_map(which)
 | 
				
			||||||
    )]
 | 
					    )]
 | 
				
			||||||
    pub firtool: PathBuf,
 | 
					    pub firtool: PathBuf,
 | 
				
			||||||
    #[arg(long)]
 | 
					    #[arg(long)]
 | 
				
			||||||
| 
						 | 
					@ -428,6 +428,13 @@ impl clap::Args for FormalAdjustArgs {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn which(v: std::ffi::OsString) -> which::Result<PathBuf> {
 | 
				
			||||||
 | 
					    #[cfg(not(miri))]
 | 
				
			||||||
 | 
					    return which::which(v);
 | 
				
			||||||
 | 
					    #[cfg(miri)]
 | 
				
			||||||
 | 
					    return Ok(Path::new("/").join(v));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Parser, Clone)]
 | 
					#[derive(Parser, Clone)]
 | 
				
			||||||
#[non_exhaustive]
 | 
					#[non_exhaustive]
 | 
				
			||||||
pub struct FormalArgs {
 | 
					pub struct FormalArgs {
 | 
				
			||||||
| 
						 | 
					@ -438,7 +445,7 @@ pub struct FormalArgs {
 | 
				
			||||||
        default_value = "sby",
 | 
					        default_value = "sby",
 | 
				
			||||||
        env = "SBY",
 | 
					        env = "SBY",
 | 
				
			||||||
        value_hint = ValueHint::CommandName,
 | 
					        value_hint = ValueHint::CommandName,
 | 
				
			||||||
        value_parser = OsStringValueParser::new().try_map(which::which)
 | 
					        value_parser = OsStringValueParser::new().try_map(which)
 | 
				
			||||||
    )]
 | 
					    )]
 | 
				
			||||||
    pub sby: PathBuf,
 | 
					    pub sby: PathBuf,
 | 
				
			||||||
    #[arg(long)]
 | 
					    #[arg(long)]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,9 +19,9 @@ use crate::{
 | 
				
			||||||
        CanonicalType, MatchVariantAndInactiveScope, OpaqueSimValue, StaticType, Type,
 | 
					        CanonicalType, MatchVariantAndInactiveScope, OpaqueSimValue, StaticType, Type,
 | 
				
			||||||
        TypeProperties,
 | 
					        TypeProperties,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    util::HashMap,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bitvec::{order::Lsb0, slice::BitSlice, view::BitView};
 | 
					use bitvec::{order::Lsb0, slice::BitSlice, view::BitView};
 | 
				
			||||||
use hashbrown::HashMap;
 | 
					 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
use std::{convert::Infallible, fmt, iter::FusedIterator, sync::Arc};
 | 
					use std::{convert::Infallible, fmt, iter::FusedIterator, sync::Arc};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -193,7 +193,8 @@ impl Default for EnumTypePropertiesBuilder {
 | 
				
			||||||
impl Enum {
 | 
					impl Enum {
 | 
				
			||||||
    #[track_caller]
 | 
					    #[track_caller]
 | 
				
			||||||
    pub fn new(variants: Interned<[EnumVariant]>) -> Self {
 | 
					    pub fn new(variants: Interned<[EnumVariant]>) -> Self {
 | 
				
			||||||
        let mut name_indexes = HashMap::with_capacity(variants.len());
 | 
					        let mut name_indexes =
 | 
				
			||||||
 | 
					            HashMap::with_capacity_and_hasher(variants.len(), Default::default());
 | 
				
			||||||
        let mut type_props_builder = EnumTypePropertiesBuilder::new();
 | 
					        let mut type_props_builder = EnumTypePropertiesBuilder::new();
 | 
				
			||||||
        for (index, EnumVariant { name, ty }) in variants.iter().enumerate() {
 | 
					        for (index, EnumVariant { name, ty }) in variants.iter().enumerate() {
 | 
				
			||||||
            if let Some(old_index) = name_indexes.insert(*name, index) {
 | 
					            if let Some(old_index) = name_indexes.insert(*name, index) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -274,6 +274,17 @@ pub struct Expr<T: Type> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T: Type + fmt::Debug> fmt::Debug for Expr<T> {
 | 
					impl<T: Type + fmt::Debug> fmt::Debug for Expr<T> {
 | 
				
			||||||
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
					    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | 
				
			||||||
 | 
					        #[cfg(debug_assertions)]
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            let Self {
 | 
				
			||||||
 | 
					                __enum,
 | 
				
			||||||
 | 
					                __ty,
 | 
				
			||||||
 | 
					                __flow,
 | 
				
			||||||
 | 
					            } = self;
 | 
				
			||||||
 | 
					            let expr_ty = __ty.canonical();
 | 
				
			||||||
 | 
					            let enum_ty = __enum.to_expr().__ty;
 | 
				
			||||||
 | 
					            assert_eq!(expr_ty, enum_ty, "expr ty mismatch:\nExpr {{\n__enum: {__enum:?},\n__ty: {__ty:?},\n__flow: {__flow:?}\n}}");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        self.__enum.fmt(f)
 | 
					        self.__enum.fmt(f)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,12 +36,11 @@ use crate::{
 | 
				
			||||||
    ty::{CanonicalType, Type},
 | 
					    ty::{CanonicalType, Type},
 | 
				
			||||||
    util::{
 | 
					    util::{
 | 
				
			||||||
        const_str_array_is_strictly_ascending, BitSliceWriteWithBase, DebugAsRawString,
 | 
					        const_str_array_is_strictly_ascending, BitSliceWriteWithBase, DebugAsRawString,
 | 
				
			||||||
        GenericConstBool,
 | 
					        GenericConstBool, HashMap, HashSet,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bitvec::slice::BitSlice;
 | 
					use bitvec::slice::BitSlice;
 | 
				
			||||||
use clap::value_parser;
 | 
					use clap::value_parser;
 | 
				
			||||||
use hashbrown::{HashMap, HashSet};
 | 
					 | 
				
			||||||
use num_traits::Signed;
 | 
					use num_traits::Signed;
 | 
				
			||||||
use serde::Serialize;
 | 
					use serde::Serialize;
 | 
				
			||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
| 
						 | 
					@ -2622,7 +2621,7 @@ fn export_impl(
 | 
				
			||||||
            indent_depth: &indent_depth,
 | 
					            indent_depth: &indent_depth,
 | 
				
			||||||
            indent: "    ",
 | 
					            indent: "    ",
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        seen_modules: HashSet::new(),
 | 
					        seen_modules: HashSet::default(),
 | 
				
			||||||
        unwritten_modules: VecDeque::new(),
 | 
					        unwritten_modules: VecDeque::new(),
 | 
				
			||||||
        global_ns,
 | 
					        global_ns,
 | 
				
			||||||
        module: ModuleState::default(),
 | 
					        module: ModuleState::default(),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,9 @@
 | 
				
			||||||
// SPDX-License-Identifier: LGPL-3.0-or-later
 | 
					// SPDX-License-Identifier: LGPL-3.0-or-later
 | 
				
			||||||
// See Notices.txt for copyright information
 | 
					// See Notices.txt for copyright information
 | 
				
			||||||
#![allow(clippy::type_complexity)]
 | 
					#![allow(clippy::type_complexity)]
 | 
				
			||||||
use crate::intern::type_map::TypeIdMap;
 | 
					use crate::{intern::type_map::TypeIdMap, util::DefaultBuildHasher};
 | 
				
			||||||
use bitvec::{ptr::BitPtr, slice::BitSlice, vec::BitVec};
 | 
					use bitvec::{ptr::BitPtr, slice::BitSlice, vec::BitVec};
 | 
				
			||||||
use hashbrown::{hash_map::RawEntryMut, HashMap, HashTable};
 | 
					use hashbrown::HashTable;
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
    any::{Any, TypeId},
 | 
					    any::{Any, TypeId},
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ use std::{
 | 
				
			||||||
    sync::{Mutex, RwLock},
 | 
					    sync::{Mutex, RwLock},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub mod type_map;
 | 
					mod type_map;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub trait LazyInternedTrait<T: ?Sized + Send + Sync + 'static>: Send + Sync + Any {
 | 
					pub trait LazyInternedTrait<T: ?Sized + Send + Sync + 'static>: Send + Sync + Any {
 | 
				
			||||||
    fn get(&self) -> Interned<T>;
 | 
					    fn get(&self) -> Interned<T>;
 | 
				
			||||||
| 
						 | 
					@ -316,8 +316,13 @@ pub trait Intern: Any + Send + Sync {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct InternerState<T: ?Sized + 'static + Send + Sync> {
 | 
				
			||||||
 | 
					    table: HashTable<&'static T>,
 | 
				
			||||||
 | 
					    hasher: DefaultBuildHasher,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Interner<T: ?Sized + 'static + Send + Sync> {
 | 
					pub struct Interner<T: ?Sized + 'static + Send + Sync> {
 | 
				
			||||||
    map: Mutex<HashMap<&'static T, ()>>,
 | 
					    state: Mutex<InternerState<T>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T: ?Sized + 'static + Send + Sync> Interner<T> {
 | 
					impl<T: ?Sized + 'static + Send + Sync> Interner<T> {
 | 
				
			||||||
| 
						 | 
					@ -330,7 +335,10 @@ impl<T: ?Sized + 'static + Send + Sync> Interner<T> {
 | 
				
			||||||
impl<T: ?Sized + 'static + Send + Sync> Default for Interner<T> {
 | 
					impl<T: ?Sized + 'static + Send + Sync> Default for Interner<T> {
 | 
				
			||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            map: Default::default(),
 | 
					            state: Mutex::new(InternerState {
 | 
				
			||||||
 | 
					                table: HashTable::new(),
 | 
				
			||||||
 | 
					                hasher: Default::default(),
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -341,17 +349,16 @@ impl<T: ?Sized + 'static + Send + Sync + Hash + Eq + ToOwned> Interner<T> {
 | 
				
			||||||
        alloc: F,
 | 
					        alloc: F,
 | 
				
			||||||
        value: Cow<'_, T>,
 | 
					        value: Cow<'_, T>,
 | 
				
			||||||
    ) -> Interned<T> {
 | 
					    ) -> Interned<T> {
 | 
				
			||||||
        let mut map = self.map.lock().unwrap();
 | 
					        let mut state = self.state.lock().unwrap();
 | 
				
			||||||
        let hasher = map.hasher().clone();
 | 
					        let InternerState { table, hasher } = &mut *state;
 | 
				
			||||||
        let hash = hasher.hash_one(&*value);
 | 
					        let inner = *table
 | 
				
			||||||
        let inner = match map.raw_entry_mut().from_hash(hash, |k| **k == *value) {
 | 
					            .entry(
 | 
				
			||||||
            RawEntryMut::Occupied(entry) => *entry.key(),
 | 
					                hasher.hash_one(&*value),
 | 
				
			||||||
            RawEntryMut::Vacant(entry) => {
 | 
					                |k| **k == *value,
 | 
				
			||||||
                *entry
 | 
					                |k| hasher.hash_one(&**k),
 | 
				
			||||||
                    .insert_with_hasher(hash, alloc(value), (), |k| hasher.hash_one(&**k))
 | 
					            )
 | 
				
			||||||
                    .0
 | 
					            .or_insert_with(|| alloc(value))
 | 
				
			||||||
            }
 | 
					            .get();
 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        Interned { inner }
 | 
					        Interned { inner }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -742,7 +749,7 @@ pub trait MemoizeGeneric: 'static + Send + Sync + Hash + Eq + Copy {
 | 
				
			||||||
    fn get_cow(self, input: Self::InputCow<'_>) -> Self::Output {
 | 
					    fn get_cow(self, input: Self::InputCow<'_>) -> Self::Output {
 | 
				
			||||||
        static TYPE_ID_MAP: TypeIdMap = TypeIdMap::new();
 | 
					        static TYPE_ID_MAP: TypeIdMap = TypeIdMap::new();
 | 
				
			||||||
        let map: &RwLock<(
 | 
					        let map: &RwLock<(
 | 
				
			||||||
            hashbrown::hash_map::DefaultHashBuilder,
 | 
					            DefaultBuildHasher,
 | 
				
			||||||
            HashTable<(Self, Self::InputOwned, Self::Output)>,
 | 
					            HashTable<(Self, Self::InputOwned, Self::Output)>,
 | 
				
			||||||
        )> = TYPE_ID_MAP.get_or_insert_default();
 | 
					        )> = TYPE_ID_MAP.get_or_insert_default();
 | 
				
			||||||
        fn hash_eq_key<'a, 'b, T: MemoizeGeneric>(
 | 
					        fn hash_eq_key<'a, 'b, T: MemoizeGeneric>(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,10 +24,10 @@ use crate::{
 | 
				
			||||||
    sim::{ExternModuleSimGenerator, ExternModuleSimulation},
 | 
					    sim::{ExternModuleSimGenerator, ExternModuleSimulation},
 | 
				
			||||||
    source_location::SourceLocation,
 | 
					    source_location::SourceLocation,
 | 
				
			||||||
    ty::{CanonicalType, Type},
 | 
					    ty::{CanonicalType, Type},
 | 
				
			||||||
    util::ScopedRef,
 | 
					    util::{HashMap, HashSet, ScopedRef},
 | 
				
			||||||
    wire::{IncompleteWire, Wire},
 | 
					    wire::{IncompleteWire, Wire},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use hashbrown::{hash_map::Entry, HashMap, HashSet};
 | 
					use hashbrown::hash_map::Entry;
 | 
				
			||||||
use num_bigint::BigInt;
 | 
					use num_bigint::BigInt;
 | 
				
			||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
    cell::RefCell,
 | 
					    cell::RefCell,
 | 
				
			||||||
| 
						 | 
					@ -1498,7 +1498,7 @@ impl TargetState {
 | 
				
			||||||
                        .collect(),
 | 
					                        .collect(),
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                CanonicalType::PhantomConst(_) => TargetStateInner::Decomposed {
 | 
					                CanonicalType::PhantomConst(_) => TargetStateInner::Decomposed {
 | 
				
			||||||
                    subtargets: HashMap::new(),
 | 
					                    subtargets: HashMap::default(),
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                CanonicalType::Array(ty) => TargetStateInner::Decomposed {
 | 
					                CanonicalType::Array(ty) => TargetStateInner::Decomposed {
 | 
				
			||||||
                    subtargets: (0..ty.len())
 | 
					                    subtargets: (0..ty.len())
 | 
				
			||||||
| 
						 | 
					@ -1864,7 +1864,7 @@ impl<T: BundleType> Module<T> {
 | 
				
			||||||
        AssertValidityState {
 | 
					        AssertValidityState {
 | 
				
			||||||
            module: self.canonical(),
 | 
					            module: self.canonical(),
 | 
				
			||||||
            blocks: vec![],
 | 
					            blocks: vec![],
 | 
				
			||||||
            target_states: HashMap::with_capacity(64),
 | 
					            target_states: HashMap::with_capacity_and_hasher(64, Default::default()),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        .assert_validity();
 | 
					        .assert_validity();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -2125,8 +2125,8 @@ impl ModuleBuilder {
 | 
				
			||||||
                        incomplete_declarations: vec![],
 | 
					                        incomplete_declarations: vec![],
 | 
				
			||||||
                        stmts: vec![],
 | 
					                        stmts: vec![],
 | 
				
			||||||
                    }],
 | 
					                    }],
 | 
				
			||||||
                    annotations_map: HashMap::new(),
 | 
					                    annotations_map: HashMap::default(),
 | 
				
			||||||
                    memory_map: HashMap::new(),
 | 
					                    memory_map: HashMap::default(),
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
| 
						 | 
					@ -2136,7 +2136,7 @@ impl ModuleBuilder {
 | 
				
			||||||
            impl_: RefCell::new(ModuleBuilderImpl {
 | 
					            impl_: RefCell::new(ModuleBuilderImpl {
 | 
				
			||||||
                body,
 | 
					                body,
 | 
				
			||||||
                io: vec![],
 | 
					                io: vec![],
 | 
				
			||||||
                io_indexes: HashMap::new(),
 | 
					                io_indexes: HashMap::default(),
 | 
				
			||||||
                module_annotations: vec![],
 | 
					                module_annotations: vec![],
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,8 +24,9 @@ use crate::{
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    prelude::*,
 | 
					    prelude::*,
 | 
				
			||||||
    reset::{ResetType, ResetTypeDispatch},
 | 
					    reset::{ResetType, ResetTypeDispatch},
 | 
				
			||||||
 | 
					    util::{HashMap, HashSet},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use hashbrown::{hash_map::Entry, HashMap, HashSet};
 | 
					use hashbrown::hash_map::Entry;
 | 
				
			||||||
use num_bigint::BigInt;
 | 
					use num_bigint::BigInt;
 | 
				
			||||||
use petgraph::unionfind::UnionFind;
 | 
					use petgraph::unionfind::UnionFind;
 | 
				
			||||||
use std::{fmt, marker::PhantomData};
 | 
					use std::{fmt, marker::PhantomData};
 | 
				
			||||||
| 
						 | 
					@ -2251,9 +2252,9 @@ pub fn deduce_resets(
 | 
				
			||||||
    fallback_to_sync_reset: bool,
 | 
					    fallback_to_sync_reset: bool,
 | 
				
			||||||
) -> Result<Interned<Module<Bundle>>, DeduceResetsError> {
 | 
					) -> Result<Interned<Module<Bundle>>, DeduceResetsError> {
 | 
				
			||||||
    let mut state = State {
 | 
					    let mut state = State {
 | 
				
			||||||
        modules_added_to_graph: HashSet::new(),
 | 
					        modules_added_to_graph: HashSet::default(),
 | 
				
			||||||
        substituted_modules: HashMap::new(),
 | 
					        substituted_modules: HashMap::default(),
 | 
				
			||||||
        expr_resets: HashMap::new(),
 | 
					        expr_resets: HashMap::default(),
 | 
				
			||||||
        reset_graph: ResetGraph::default(),
 | 
					        reset_graph: ResetGraph::default(),
 | 
				
			||||||
        fallback_to_sync_reset,
 | 
					        fallback_to_sync_reset,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,10 +18,10 @@ use crate::{
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    source_location::SourceLocation,
 | 
					    source_location::SourceLocation,
 | 
				
			||||||
    ty::{CanonicalType, Type},
 | 
					    ty::{CanonicalType, Type},
 | 
				
			||||||
 | 
					    util::HashMap,
 | 
				
			||||||
    wire::Wire,
 | 
					    wire::Wire,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use core::fmt;
 | 
					use core::fmt;
 | 
				
			||||||
use hashbrown::HashMap;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub enum SimplifyEnumsError {
 | 
					pub enum SimplifyEnumsError {
 | 
				
			||||||
| 
						 | 
					@ -965,8 +965,8 @@ pub fn simplify_enums(
 | 
				
			||||||
    kind: SimplifyEnumsKind,
 | 
					    kind: SimplifyEnumsKind,
 | 
				
			||||||
) -> Result<Interned<Module<Bundle>>, SimplifyEnumsError> {
 | 
					) -> Result<Interned<Module<Bundle>>, SimplifyEnumsError> {
 | 
				
			||||||
    module.fold(&mut State {
 | 
					    module.fold(&mut State {
 | 
				
			||||||
        enum_types: HashMap::new(),
 | 
					        enum_types: HashMap::default(),
 | 
				
			||||||
        replacement_mem_ports: HashMap::new(),
 | 
					        replacement_mem_ports: HashMap::default(),
 | 
				
			||||||
        kind,
 | 
					        kind,
 | 
				
			||||||
        module_state_stack: vec![],
 | 
					        module_state_stack: vec![],
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,11 +14,10 @@ use crate::{
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    source_location::SourceLocation,
 | 
					    source_location::SourceLocation,
 | 
				
			||||||
    ty::{CanonicalType, Type},
 | 
					    ty::{CanonicalType, Type},
 | 
				
			||||||
    util::MakeMutSlice,
 | 
					    util::{HashMap, MakeMutSlice},
 | 
				
			||||||
    wire::Wire,
 | 
					    wire::Wire,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bitvec::{slice::BitSlice, vec::BitVec};
 | 
					use bitvec::{slice::BitSlice, vec::BitVec};
 | 
				
			||||||
use hashbrown::HashMap;
 | 
					 | 
				
			||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
    convert::Infallible,
 | 
					    convert::Infallible,
 | 
				
			||||||
    fmt::Write,
 | 
					    fmt::Write,
 | 
				
			||||||
| 
						 | 
					@ -897,7 +896,7 @@ impl Folder for State {
 | 
				
			||||||
            module,
 | 
					            module,
 | 
				
			||||||
            ModuleState {
 | 
					            ModuleState {
 | 
				
			||||||
                output_module: None,
 | 
					                output_module: None,
 | 
				
			||||||
                memories: HashMap::new(),
 | 
					                memories: HashMap::default(),
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        let mut this = PushedState::push_module(self, module);
 | 
					        let mut this = PushedState::push_module(self, module);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,10 +41,9 @@ use crate::{
 | 
				
			||||||
        value::SimValue,
 | 
					        value::SimValue,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    ty::StaticType,
 | 
					    ty::StaticType,
 | 
				
			||||||
    util::{BitSliceWriteWithBase, DebugAsDisplay},
 | 
					    util::{BitSliceWriteWithBase, DebugAsDisplay, HashMap, HashSet},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bitvec::{bits, order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView};
 | 
					use bitvec::{bits, order::Lsb0, slice::BitSlice, vec::BitVec, view::BitView};
 | 
				
			||||||
use hashbrown::{HashMap, HashSet};
 | 
					 | 
				
			||||||
use num_bigint::BigInt;
 | 
					use num_bigint::BigInt;
 | 
				
			||||||
use num_traits::{Signed, Zero};
 | 
					use num_traits::{Signed, Zero};
 | 
				
			||||||
use petgraph::{
 | 
					use petgraph::{
 | 
				
			||||||
| 
						 | 
					@ -580,8 +579,9 @@ impl Assignments {
 | 
				
			||||||
            big_slots,
 | 
					            big_slots,
 | 
				
			||||||
        }) = self.slot_readers();
 | 
					        }) = self.slot_readers();
 | 
				
			||||||
        AssignmentsElements {
 | 
					        AssignmentsElements {
 | 
				
			||||||
            node_indexes: HashMap::with_capacity(
 | 
					            node_indexes: HashMap::with_capacity_and_hasher(
 | 
				
			||||||
                self.assignments().len() + small_slots.len() + big_slots.len(),
 | 
					                self.assignments().len() + small_slots.len() + big_slots.len(),
 | 
				
			||||||
 | 
					                Default::default(),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            nodes: self.node_references(),
 | 
					            nodes: self.node_references(),
 | 
				
			||||||
            edges: self.edge_references(),
 | 
					            edges: self.edge_references(),
 | 
				
			||||||
| 
						 | 
					@ -1022,6 +1022,16 @@ impl VisitMap<AssignmentOrSlotIndex> for AssignmentsVisitMap {
 | 
				
			||||||
            AssignmentOrSlotIndex::BigSlot(slot) => self.slots.contains(slot),
 | 
					            AssignmentOrSlotIndex::BigSlot(slot) => self.slots.contains(slot),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn unvisit(&mut self, n: AssignmentOrSlotIndex) -> bool {
 | 
				
			||||||
 | 
					        match n {
 | 
				
			||||||
 | 
					            AssignmentOrSlotIndex::AssignmentIndex(assignment_index) => {
 | 
				
			||||||
 | 
					                mem::replace(&mut self.assignments[assignment_index], false)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            AssignmentOrSlotIndex::SmallSlot(slot) => self.slots.remove(slot),
 | 
				
			||||||
 | 
					            AssignmentOrSlotIndex::BigSlot(slot) => self.slots.remove(slot),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Visitable for Assignments {
 | 
					impl Visitable for Assignments {
 | 
				
			||||||
| 
						 | 
					@ -1676,18 +1686,18 @@ impl Compiler {
 | 
				
			||||||
            insns: Insns::new(),
 | 
					            insns: Insns::new(),
 | 
				
			||||||
            original_base_module,
 | 
					            original_base_module,
 | 
				
			||||||
            base_module,
 | 
					            base_module,
 | 
				
			||||||
            modules: HashMap::new(),
 | 
					            modules: HashMap::default(),
 | 
				
			||||||
            extern_modules: Vec::new(),
 | 
					            extern_modules: Vec::new(),
 | 
				
			||||||
            compiled_values: HashMap::new(),
 | 
					            compiled_values: HashMap::default(),
 | 
				
			||||||
            compiled_exprs: HashMap::new(),
 | 
					            compiled_exprs: HashMap::default(),
 | 
				
			||||||
            compiled_exprs_to_values: HashMap::new(),
 | 
					            compiled_exprs_to_values: HashMap::default(),
 | 
				
			||||||
            decl_conditions: HashMap::new(),
 | 
					            decl_conditions: HashMap::default(),
 | 
				
			||||||
            compiled_values_to_dyn_array_indexes: HashMap::new(),
 | 
					            compiled_values_to_dyn_array_indexes: HashMap::default(),
 | 
				
			||||||
            compiled_value_bool_dest_is_small_map: HashMap::new(),
 | 
					            compiled_value_bool_dest_is_small_map: HashMap::default(),
 | 
				
			||||||
            assignments: Assignments::default(),
 | 
					            assignments: Assignments::default(),
 | 
				
			||||||
            clock_triggers: Vec::new(),
 | 
					            clock_triggers: Vec::new(),
 | 
				
			||||||
            compiled_value_to_clock_trigger_map: HashMap::new(),
 | 
					            compiled_value_to_clock_trigger_map: HashMap::default(),
 | 
				
			||||||
            enum_discriminants: HashMap::new(),
 | 
					            enum_discriminants: HashMap::default(),
 | 
				
			||||||
            registers: Vec::new(),
 | 
					            registers: Vec::new(),
 | 
				
			||||||
            traces: SimTraces(Vec::new()),
 | 
					            traces: SimTraces(Vec::new()),
 | 
				
			||||||
            memories: Vec::new(),
 | 
					            memories: Vec::new(),
 | 
				
			||||||
| 
						 | 
					@ -5976,8 +5986,8 @@ impl SimulationModuleState {
 | 
				
			||||||
    fn new(base_targets: impl IntoIterator<Item = (Target, CompiledValue<CanonicalType>)>) -> Self {
 | 
					    fn new(base_targets: impl IntoIterator<Item = (Target, CompiledValue<CanonicalType>)>) -> Self {
 | 
				
			||||||
        let mut retval = Self {
 | 
					        let mut retval = Self {
 | 
				
			||||||
            base_targets: Vec::new(),
 | 
					            base_targets: Vec::new(),
 | 
				
			||||||
            uninitialized_ios: HashMap::new(),
 | 
					            uninitialized_ios: HashMap::default(),
 | 
				
			||||||
            io_targets: HashMap::new(),
 | 
					            io_targets: HashMap::default(),
 | 
				
			||||||
            did_initial_settle: false,
 | 
					            did_initial_settle: false,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        for (base_target, value) in base_targets {
 | 
					        for (base_target, value) in base_targets {
 | 
				
			||||||
| 
						 | 
					@ -6207,7 +6217,7 @@ impl Default for EarliestWaitTargets {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            settle: false,
 | 
					            settle: false,
 | 
				
			||||||
            instant: None,
 | 
					            instant: None,
 | 
				
			||||||
            changes: HashMap::new(),
 | 
					            changes: HashMap::default(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -6217,14 +6227,14 @@ impl EarliestWaitTargets {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            settle: true,
 | 
					            settle: true,
 | 
				
			||||||
            instant: None,
 | 
					            instant: None,
 | 
				
			||||||
            changes: HashMap::new(),
 | 
					            changes: HashMap::default(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn instant(instant: SimInstant) -> Self {
 | 
					    fn instant(instant: SimInstant) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            settle: false,
 | 
					            settle: false,
 | 
				
			||||||
            instant: Some(instant),
 | 
					            instant: Some(instant),
 | 
				
			||||||
            changes: HashMap::new(),
 | 
					            changes: HashMap::default(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn len(&self) -> usize {
 | 
					    fn len(&self) -> usize {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,10 +7,9 @@ use crate::{
 | 
				
			||||||
    intern::{Intern, Interned, Memoize},
 | 
					    intern::{Intern, Interned, Memoize},
 | 
				
			||||||
    source_location::SourceLocation,
 | 
					    source_location::SourceLocation,
 | 
				
			||||||
    ty::CanonicalType,
 | 
					    ty::CanonicalType,
 | 
				
			||||||
    util::get_many_mut,
 | 
					    util::{get_many_mut, HashMap, HashSet},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bitvec::{boxed::BitBox, slice::BitSlice};
 | 
					use bitvec::{boxed::BitBox, slice::BitSlice};
 | 
				
			||||||
use hashbrown::{HashMap, HashSet};
 | 
					 | 
				
			||||||
use num_bigint::BigInt;
 | 
					use num_bigint::BigInt;
 | 
				
			||||||
use num_traits::{One, Signed, ToPrimitive, Zero};
 | 
					use num_traits::{One, Signed, ToPrimitive, Zero};
 | 
				
			||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,9 +14,10 @@ use crate::{
 | 
				
			||||||
        TraceModuleIO, TraceReg, TraceSInt, TraceScalar, TraceScalarId, TraceScope, TraceSyncReset,
 | 
					        TraceModuleIO, TraceReg, TraceSInt, TraceScalar, TraceScalarId, TraceScope, TraceSyncReset,
 | 
				
			||||||
        TraceUInt, TraceWire, TraceWriter, TraceWriterDecls,
 | 
					        TraceUInt, TraceWire, TraceWriter, TraceWriterDecls,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    util::HashMap,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use bitvec::{order::Lsb0, slice::BitSlice};
 | 
					use bitvec::{order::Lsb0, slice::BitSlice};
 | 
				
			||||||
use hashbrown::{hash_map::Entry, HashMap};
 | 
					use hashbrown::hash_map::Entry;
 | 
				
			||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
    fmt::{self, Write as _},
 | 
					    fmt::{self, Write as _},
 | 
				
			||||||
    io, mem,
 | 
					    io, mem,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,9 +2,8 @@
 | 
				
			||||||
// See Notices.txt for copyright information
 | 
					// See Notices.txt for copyright information
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    intern::{Intern, Interned},
 | 
					    intern::{Intern, Interned},
 | 
				
			||||||
    util::DebugAsDisplay,
 | 
					    util::{DebugAsDisplay, HashMap},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use hashbrown::HashMap;
 | 
					 | 
				
			||||||
use std::{cell::RefCell, fmt, num::NonZeroUsize, panic, path::Path};
 | 
					use std::{cell::RefCell, fmt, num::NonZeroUsize, panic, path::Path};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 | 
					#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 | 
				
			||||||
| 
						 | 
					@ -97,7 +96,7 @@ impl NormalizeFilesForTestsState {
 | 
				
			||||||
    fn new() -> Self {
 | 
					    fn new() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            test_position: panic::Location::caller(),
 | 
					            test_position: panic::Location::caller(),
 | 
				
			||||||
            file_pattern_matches: HashMap::new(),
 | 
					            file_pattern_matches: HashMap::default(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -143,7 +142,7 @@ impl From<&'_ panic::Location<'_>> for SourceLocation {
 | 
				
			||||||
                        map.entry_ref(file)
 | 
					                        map.entry_ref(file)
 | 
				
			||||||
                            .or_insert_with(|| NormalizedFileForTestState {
 | 
					                            .or_insert_with(|| NormalizedFileForTestState {
 | 
				
			||||||
                                file_name_id: NonZeroUsize::new(len + 1).unwrap(),
 | 
					                                file_name_id: NonZeroUsize::new(len + 1).unwrap(),
 | 
				
			||||||
                                positions_map: HashMap::new(),
 | 
					                                positions_map: HashMap::default(),
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
                    file_str = m.generate_file_name(file_state.file_name_id);
 | 
					                    file_str = m.generate_file_name(file_state.file_name_id);
 | 
				
			||||||
                    file = &file_str;
 | 
					                    file = &file_str;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,9 +3,9 @@
 | 
				
			||||||
use crate::{
 | 
					use crate::{
 | 
				
			||||||
    cli::{FormalArgs, FormalMode, FormalOutput, RunPhase},
 | 
					    cli::{FormalArgs, FormalMode, FormalOutput, RunPhase},
 | 
				
			||||||
    firrtl::ExportOptions,
 | 
					    firrtl::ExportOptions,
 | 
				
			||||||
 | 
					    util::HashMap,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use clap::Parser;
 | 
					use clap::Parser;
 | 
				
			||||||
use hashbrown::HashMap;
 | 
					 | 
				
			||||||
use serde::Deserialize;
 | 
					use serde::Deserialize;
 | 
				
			||||||
use std::{
 | 
					use std::{
 | 
				
			||||||
    fmt::Write,
 | 
					    fmt::Write,
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ fn get_assert_formal_target_path(test_name: &dyn std::fmt::Display) -> PathBuf {
 | 
				
			||||||
    let index = *DIRS
 | 
					    let index = *DIRS
 | 
				
			||||||
        .lock()
 | 
					        .lock()
 | 
				
			||||||
        .unwrap()
 | 
					        .unwrap()
 | 
				
			||||||
        .get_or_insert_with(HashMap::new)
 | 
					        .get_or_insert_with(HashMap::default)
 | 
				
			||||||
        .entry_ref(&dir)
 | 
					        .entry_ref(&dir)
 | 
				
			||||||
        .and_modify(|v| *v += 1)
 | 
					        .and_modify(|v| *v += 1)
 | 
				
			||||||
        .or_insert(0);
 | 
					        .or_insert(0);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,16 @@ mod const_usize;
 | 
				
			||||||
mod misc;
 | 
					mod misc;
 | 
				
			||||||
mod scoped_ref;
 | 
					mod scoped_ref;
 | 
				
			||||||
pub(crate) mod streaming_read_utf8;
 | 
					pub(crate) mod streaming_read_utf8;
 | 
				
			||||||
 | 
					mod test_hasher;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// allow easily switching the hasher crate-wide for testing
 | 
				
			||||||
 | 
					#[cfg(feature = "unstable-test-hasher")]
 | 
				
			||||||
 | 
					pub type DefaultBuildHasher = test_hasher::DefaultBuildHasher;
 | 
				
			||||||
 | 
					#[cfg(not(feature = "unstable-test-hasher"))]
 | 
				
			||||||
 | 
					pub(crate) type DefaultBuildHasher = hashbrown::DefaultHashBuilder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub(crate) type HashMap<K, V> = hashbrown::HashMap<K, V, DefaultBuildHasher>;
 | 
				
			||||||
 | 
					pub(crate) type HashSet<T> = hashbrown::HashSet<T, DefaultBuildHasher>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[doc(inline)]
 | 
					#[doc(inline)]
 | 
				
			||||||
pub use const_bool::{ConstBool, ConstBoolDispatch, ConstBoolDispatchTag, GenericConstBool};
 | 
					pub use const_bool::{ConstBool, ConstBoolDispatch, ConstBoolDispatchTag, GenericConstBool};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										240
									
								
								crates/fayalite/src/util/test_hasher.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								crates/fayalite/src/util/test_hasher.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,240 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: LGPL-3.0-or-later
 | 
				
			||||||
 | 
					// See Notices.txt for copyright information
 | 
				
			||||||
 | 
					#![cfg(feature = "unstable-test-hasher")]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use std::{
 | 
				
			||||||
 | 
					    fmt::Write as _,
 | 
				
			||||||
 | 
					    hash::{BuildHasher, Hash, Hasher},
 | 
				
			||||||
 | 
					    io::Write as _,
 | 
				
			||||||
 | 
					    marker::PhantomData,
 | 
				
			||||||
 | 
					    sync::LazyLock,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BoxDynHasher = Box<dyn Hasher + Send + Sync>;
 | 
				
			||||||
 | 
					type BoxDynBuildHasher = Box<dyn DynBuildHasherTrait + Send + Sync>;
 | 
				
			||||||
 | 
					type BoxDynMakeBuildHasher = Box<dyn Fn() -> BoxDynBuildHasher + Send + Sync>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					trait TryGetDynBuildHasher: Copy {
 | 
				
			||||||
 | 
					    type Type;
 | 
				
			||||||
 | 
					    fn try_get_make_build_hasher(self) -> Option<BoxDynMakeBuildHasher>;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<T> TryGetDynBuildHasher for PhantomData<T> {
 | 
				
			||||||
 | 
					    type Type = T;
 | 
				
			||||||
 | 
					    fn try_get_make_build_hasher(self) -> Option<BoxDynMakeBuildHasher> {
 | 
				
			||||||
 | 
					        None
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<T: Default + BuildHasher<Hasher: Send + Sync + 'static> + Send + Sync + 'static + Clone>
 | 
				
			||||||
 | 
					    TryGetDynBuildHasher for &'_ PhantomData<T>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    type Type = T;
 | 
				
			||||||
 | 
					    fn try_get_make_build_hasher(self) -> Option<BoxDynMakeBuildHasher> {
 | 
				
			||||||
 | 
					        Some(Box::new(|| Box::<DynBuildHasher<T>>::default()))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Default, Clone)]
 | 
				
			||||||
 | 
					struct DynBuildHasher<T>(T);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					trait DynBuildHasherTrait: BuildHasher<Hasher = BoxDynHasher> {
 | 
				
			||||||
 | 
					    fn clone_dyn_build_hasher(&self) -> BoxDynBuildHasher;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<BH: BuildHasher<Hasher: Send + Sync + 'static>> BuildHasher for DynBuildHasher<BH> {
 | 
				
			||||||
 | 
					    type Hasher = BoxDynHasher;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn build_hasher(&self) -> Self::Hasher {
 | 
				
			||||||
 | 
					        Box::new(self.0.build_hasher())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn hash_one<T: Hash>(&self, x: T) -> u64 {
 | 
				
			||||||
 | 
					        self.0.hash_one(x)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<BH> DynBuildHasherTrait for DynBuildHasher<BH>
 | 
				
			||||||
 | 
					where
 | 
				
			||||||
 | 
					    Self: Clone + BuildHasher<Hasher = BoxDynHasher> + Send + Sync + 'static,
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    fn clone_dyn_build_hasher(&self) -> BoxDynBuildHasher {
 | 
				
			||||||
 | 
					        Box::new(self.clone())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct DefaultBuildHasher(BoxDynBuildHasher);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Clone for DefaultBuildHasher {
 | 
				
			||||||
 | 
					    fn clone(&self) -> Self {
 | 
				
			||||||
 | 
					        DefaultBuildHasher(self.0.clone_dyn_build_hasher())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ENV_VAR_NAME: &'static str = "FAYALITE_TEST_HASHER";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct EnvVarValue {
 | 
				
			||||||
 | 
					    key: &'static str,
 | 
				
			||||||
 | 
					    try_get_make_build_hasher: fn() -> Option<BoxDynMakeBuildHasher>,
 | 
				
			||||||
 | 
					    description: &'static str,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					macro_rules! env_var_value {
 | 
				
			||||||
 | 
					    (
 | 
				
			||||||
 | 
					        key: $key:literal,
 | 
				
			||||||
 | 
					        build_hasher: $build_hasher:ty,
 | 
				
			||||||
 | 
					        description: $description:literal,
 | 
				
			||||||
 | 
					    ) => {
 | 
				
			||||||
 | 
					        EnvVarValue {
 | 
				
			||||||
 | 
					            key: $key,
 | 
				
			||||||
 | 
					            try_get_make_build_hasher: || {
 | 
				
			||||||
 | 
					                // use rust method resolution to detect if $build_hasher is usable
 | 
				
			||||||
 | 
					                // (e.g. hashbrown's hasher won't be usable without the right feature enabled)
 | 
				
			||||||
 | 
					                (&PhantomData::<DynBuildHasher<$build_hasher>>).try_get_make_build_hasher()
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            description: $description,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Default)]
 | 
				
			||||||
 | 
					struct AlwaysZeroHasher;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Hasher for AlwaysZeroHasher {
 | 
				
			||||||
 | 
					    fn write(&mut self, _bytes: &[u8]) {}
 | 
				
			||||||
 | 
					    fn finish(&self) -> u64 {
 | 
				
			||||||
 | 
					        0
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const ENV_VAR_VALUES: &'static [EnvVarValue] = &[
 | 
				
			||||||
 | 
					    env_var_value! {
 | 
				
			||||||
 | 
					        key: "std",
 | 
				
			||||||
 | 
					        build_hasher: std::hash::RandomState,
 | 
				
			||||||
 | 
					        description: "use std::hash::RandomState",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    env_var_value! {
 | 
				
			||||||
 | 
					        key: "hashbrown",
 | 
				
			||||||
 | 
					        build_hasher: hashbrown::DefaultHashBuilder,
 | 
				
			||||||
 | 
					        description: "use hashbrown's DefaultHashBuilder",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    env_var_value! {
 | 
				
			||||||
 | 
					        key: "always_zero",
 | 
				
			||||||
 | 
					        build_hasher: std::hash::BuildHasherDefault<AlwaysZeroHasher>,
 | 
				
			||||||
 | 
					        description: "use a hasher that always returns 0 for all hashes,\n    \
 | 
				
			||||||
 | 
					        this is useful for checking that PartialEq impls are correct",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn report_bad_env_var(msg: impl std::fmt::Display) -> ! {
 | 
				
			||||||
 | 
					    let mut msg = format!("{ENV_VAR_NAME}: {msg}\n");
 | 
				
			||||||
 | 
					    for &EnvVarValue {
 | 
				
			||||||
 | 
					        key,
 | 
				
			||||||
 | 
					        try_get_make_build_hasher,
 | 
				
			||||||
 | 
					        description,
 | 
				
			||||||
 | 
					    } in ENV_VAR_VALUES
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        let availability = match try_get_make_build_hasher() {
 | 
				
			||||||
 | 
					            Some(_) => "available",
 | 
				
			||||||
 | 
					            None => "unavailable",
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        writeln!(msg, "{key}: ({availability})\n    {description}").expect("can't fail");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    std::io::stderr()
 | 
				
			||||||
 | 
					        .write_all(msg.as_bytes())
 | 
				
			||||||
 | 
					        .expect("should be able to write to stderr");
 | 
				
			||||||
 | 
					    std::process::abort();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Default for DefaultBuildHasher {
 | 
				
			||||||
 | 
					    fn default() -> Self {
 | 
				
			||||||
 | 
					        static DEFAULT_FN: LazyLock<BoxDynMakeBuildHasher> = LazyLock::new(|| {
 | 
				
			||||||
 | 
					            let var = std::env::var_os(ENV_VAR_NAME);
 | 
				
			||||||
 | 
					            let var = var.as_deref().unwrap_or("std".as_ref());
 | 
				
			||||||
 | 
					            for &EnvVarValue {
 | 
				
			||||||
 | 
					                key,
 | 
				
			||||||
 | 
					                try_get_make_build_hasher,
 | 
				
			||||||
 | 
					                description: _,
 | 
				
			||||||
 | 
					            } in ENV_VAR_VALUES
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if var.as_encoded_bytes().eq_ignore_ascii_case(key.as_bytes()) {
 | 
				
			||||||
 | 
					                    return try_get_make_build_hasher().unwrap_or_else(|| {
 | 
				
			||||||
 | 
					                        report_bad_env_var(format_args!(
 | 
				
			||||||
 | 
					                            "unavailable hasher: {key} (is the appropriate feature enabled?)"
 | 
				
			||||||
 | 
					                        ));
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            report_bad_env_var(format_args!("unrecognized hasher: {var:?}"));
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        Self(DEFAULT_FN())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct DefaultHasher(BoxDynHasher);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl BuildHasher for DefaultBuildHasher {
 | 
				
			||||||
 | 
					    type Hasher = DefaultHasher;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn build_hasher(&self) -> Self::Hasher {
 | 
				
			||||||
 | 
					        DefaultHasher(self.0.build_hasher())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Hasher for DefaultHasher {
 | 
				
			||||||
 | 
					    fn finish(&self) -> u64 {
 | 
				
			||||||
 | 
					        self.0.finish()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write(&mut self, bytes: &[u8]) {
 | 
				
			||||||
 | 
					        self.0.write(bytes)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_u8(&mut self, i: u8) {
 | 
				
			||||||
 | 
					        self.0.write_u8(i)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_u16(&mut self, i: u16) {
 | 
				
			||||||
 | 
					        self.0.write_u16(i)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_u32(&mut self, i: u32) {
 | 
				
			||||||
 | 
					        self.0.write_u32(i)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_u64(&mut self, i: u64) {
 | 
				
			||||||
 | 
					        self.0.write_u64(i)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_u128(&mut self, i: u128) {
 | 
				
			||||||
 | 
					        self.0.write_u128(i)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_usize(&mut self, i: usize) {
 | 
				
			||||||
 | 
					        self.0.write_usize(i)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_i8(&mut self, i: i8) {
 | 
				
			||||||
 | 
					        self.0.write_i8(i)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_i16(&mut self, i: i16) {
 | 
				
			||||||
 | 
					        self.0.write_i16(i)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_i32(&mut self, i: i32) {
 | 
				
			||||||
 | 
					        self.0.write_i32(i)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_i64(&mut self, i: i64) {
 | 
				
			||||||
 | 
					        self.0.write_i64(i)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_i128(&mut self, i: i128) {
 | 
				
			||||||
 | 
					        self.0.write_i128(i)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_isize(&mut self, i: isize) {
 | 
				
			||||||
 | 
					        self.0.write_isize(i)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								crates/fayalite/tests/ui/simvalue_is_not_internable.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								crates/fayalite/tests/ui/simvalue_is_not_internable.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: LGPL-3.0-or-later
 | 
				
			||||||
 | 
					// See Notices.txt for copyright information
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//! check that SimValue can't be interned, since equality may ignore types
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use fayalite::{
 | 
				
			||||||
 | 
					    intern::{Intern, Interned},
 | 
				
			||||||
 | 
					    sim::value::SimValue,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn f(v: SimValue<()>) -> Interned<SimValue<()>> {
 | 
				
			||||||
 | 
					    Intern::intern_sized(v)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {}
 | 
				
			||||||
							
								
								
									
										178
									
								
								crates/fayalite/tests/ui/simvalue_is_not_internable.stderr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										178
									
								
								crates/fayalite/tests/ui/simvalue_is_not_internable.stderr
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,178 @@
 | 
				
			||||||
 | 
					error[E0277]: `Cell<util::alternating_cell::State>` cannot be shared between threads safely
 | 
				
			||||||
 | 
					  --> tests/ui/simvalue_is_not_internable.rs:11:26
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					11 | fn f(v: SimValue<()>) -> Interned<SimValue<()>> {
 | 
				
			||||||
 | 
					   |                          ^^^^^^^^^^^^^^^^^^^^^^ `Cell<util::alternating_cell::State>` cannot be shared between threads safely
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell<util::alternating_cell::State>`, which is required by `SimValue<()>: Sync`
 | 
				
			||||||
 | 
					   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`
 | 
				
			||||||
 | 
					note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>`
 | 
				
			||||||
 | 
					  --> src/util/alternating_cell.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub(crate) struct AlternatingCell<T: ?Sized> {
 | 
				
			||||||
 | 
					   |                   ^^^^^^^^^^^^^^^
 | 
				
			||||||
 | 
					note: required because it appears within the type `SimValue<()>`
 | 
				
			||||||
 | 
					  --> src/sim/value.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub struct SimValue<T: Type> {
 | 
				
			||||||
 | 
					   |            ^^^^^^^^
 | 
				
			||||||
 | 
					note: required by a bound in `fayalite::intern::Interned`
 | 
				
			||||||
 | 
					  --> src/intern.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub struct Interned<T: ?Sized + 'static + Send + Sync> {
 | 
				
			||||||
 | 
					   |                                                  ^^^^ required by this bound in `Interned`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error[E0277]: `UnsafeCell<value::SimValueInner<()>>` cannot be shared between threads safely
 | 
				
			||||||
 | 
					  --> tests/ui/simvalue_is_not_internable.rs:11:26
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					11 | fn f(v: SimValue<()>) -> Interned<SimValue<()>> {
 | 
				
			||||||
 | 
					   |                          ^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<value::SimValueInner<()>>` cannot be shared between threads safely
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell<value::SimValueInner<()>>`, which is required by `SimValue<()>: Sync`
 | 
				
			||||||
 | 
					note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>`
 | 
				
			||||||
 | 
					  --> src/util/alternating_cell.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub(crate) struct AlternatingCell<T: ?Sized> {
 | 
				
			||||||
 | 
					   |                   ^^^^^^^^^^^^^^^
 | 
				
			||||||
 | 
					note: required because it appears within the type `SimValue<()>`
 | 
				
			||||||
 | 
					  --> src/sim/value.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub struct SimValue<T: Type> {
 | 
				
			||||||
 | 
					   |            ^^^^^^^^
 | 
				
			||||||
 | 
					note: required by a bound in `fayalite::intern::Interned`
 | 
				
			||||||
 | 
					  --> src/intern.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub struct Interned<T: ?Sized + 'static + Send + Sync> {
 | 
				
			||||||
 | 
					   |                                                  ^^^^ required by this bound in `Interned`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error[E0277]: the trait bound `SimValue<()>: Intern` is not satisfied
 | 
				
			||||||
 | 
					  --> tests/ui/simvalue_is_not_internable.rs:12:26
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					12 |     Intern::intern_sized(v)
 | 
				
			||||||
 | 
					   |     -------------------- ^ the trait `Hash` is not implemented for `SimValue<()>`, which is required by `SimValue<()>: Intern`
 | 
				
			||||||
 | 
					   |     |
 | 
				
			||||||
 | 
					   |     required by a bound introduced by this call
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   = help: the following other types implement trait `Intern`:
 | 
				
			||||||
 | 
					             BitSlice
 | 
				
			||||||
 | 
					             [T]
 | 
				
			||||||
 | 
					             str
 | 
				
			||||||
 | 
					   = note: required for `SimValue<()>` to implement `Intern`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error[E0277]: the trait bound `SimValue<()>: Intern` is not satisfied
 | 
				
			||||||
 | 
					  --> tests/ui/simvalue_is_not_internable.rs:12:26
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					12 |     Intern::intern_sized(v)
 | 
				
			||||||
 | 
					   |     -------------------- ^ the trait `std::cmp::Eq` is not implemented for `SimValue<()>`, which is required by `SimValue<()>: Intern`
 | 
				
			||||||
 | 
					   |     |
 | 
				
			||||||
 | 
					   |     required by a bound introduced by this call
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   = help: the following other types implement trait `Intern`:
 | 
				
			||||||
 | 
					             BitSlice
 | 
				
			||||||
 | 
					             [T]
 | 
				
			||||||
 | 
					             str
 | 
				
			||||||
 | 
					   = note: required for `SimValue<()>` to implement `Intern`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error[E0277]: `Cell<util::alternating_cell::State>` cannot be shared between threads safely
 | 
				
			||||||
 | 
					  --> tests/ui/simvalue_is_not_internable.rs:12:26
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					12 |     Intern::intern_sized(v)
 | 
				
			||||||
 | 
					   |     -------------------- ^ `Cell<util::alternating_cell::State>` cannot be shared between threads safely
 | 
				
			||||||
 | 
					   |     |
 | 
				
			||||||
 | 
					   |     required by a bound introduced by this call
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell<util::alternating_cell::State>`, which is required by `SimValue<()>: Sync`
 | 
				
			||||||
 | 
					   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`
 | 
				
			||||||
 | 
					note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>`
 | 
				
			||||||
 | 
					  --> src/util/alternating_cell.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub(crate) struct AlternatingCell<T: ?Sized> {
 | 
				
			||||||
 | 
					   |                   ^^^^^^^^^^^^^^^
 | 
				
			||||||
 | 
					note: required because it appears within the type `SimValue<()>`
 | 
				
			||||||
 | 
					  --> src/sim/value.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub struct SimValue<T: Type> {
 | 
				
			||||||
 | 
					   |            ^^^^^^^^
 | 
				
			||||||
 | 
					note: required by a bound in `intern_sized`
 | 
				
			||||||
 | 
					  --> src/intern.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub trait Intern: Any + Send + Sync {
 | 
				
			||||||
 | 
					   |                                ^^^^ required by this bound in `Intern::intern_sized`
 | 
				
			||||||
 | 
					   |     fn intern(&self) -> Interned<Self>;
 | 
				
			||||||
 | 
					   |     fn intern_sized(self) -> Interned<Self>
 | 
				
			||||||
 | 
					   |        ------------ required by a bound in this associated function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error[E0277]: `UnsafeCell<value::SimValueInner<()>>` cannot be shared between threads safely
 | 
				
			||||||
 | 
					  --> tests/ui/simvalue_is_not_internable.rs:12:26
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					12 |     Intern::intern_sized(v)
 | 
				
			||||||
 | 
					   |     -------------------- ^ `UnsafeCell<value::SimValueInner<()>>` cannot be shared between threads safely
 | 
				
			||||||
 | 
					   |     |
 | 
				
			||||||
 | 
					   |     required by a bound introduced by this call
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell<value::SimValueInner<()>>`, which is required by `SimValue<()>: Sync`
 | 
				
			||||||
 | 
					note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>`
 | 
				
			||||||
 | 
					  --> src/util/alternating_cell.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub(crate) struct AlternatingCell<T: ?Sized> {
 | 
				
			||||||
 | 
					   |                   ^^^^^^^^^^^^^^^
 | 
				
			||||||
 | 
					note: required because it appears within the type `SimValue<()>`
 | 
				
			||||||
 | 
					  --> src/sim/value.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub struct SimValue<T: Type> {
 | 
				
			||||||
 | 
					   |            ^^^^^^^^
 | 
				
			||||||
 | 
					note: required by a bound in `intern_sized`
 | 
				
			||||||
 | 
					  --> src/intern.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub trait Intern: Any + Send + Sync {
 | 
				
			||||||
 | 
					   |                                ^^^^ required by this bound in `Intern::intern_sized`
 | 
				
			||||||
 | 
					   |     fn intern(&self) -> Interned<Self>;
 | 
				
			||||||
 | 
					   |     fn intern_sized(self) -> Interned<Self>
 | 
				
			||||||
 | 
					   |        ------------ required by a bound in this associated function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error[E0277]: `Cell<util::alternating_cell::State>` cannot be shared between threads safely
 | 
				
			||||||
 | 
					  --> tests/ui/simvalue_is_not_internable.rs:12:5
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					12 |     Intern::intern_sized(v)
 | 
				
			||||||
 | 
					   |     ^^^^^^^^^^^^^^^^^^^^^^^ `Cell<util::alternating_cell::State>` cannot be shared between threads safely
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   = help: within `SimValue<()>`, the trait `Sync` is not implemented for `Cell<util::alternating_cell::State>`, which is required by `SimValue<()>: Sync`
 | 
				
			||||||
 | 
					   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock`
 | 
				
			||||||
 | 
					note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>`
 | 
				
			||||||
 | 
					  --> src/util/alternating_cell.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub(crate) struct AlternatingCell<T: ?Sized> {
 | 
				
			||||||
 | 
					   |                   ^^^^^^^^^^^^^^^
 | 
				
			||||||
 | 
					note: required because it appears within the type `SimValue<()>`
 | 
				
			||||||
 | 
					  --> src/sim/value.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub struct SimValue<T: Type> {
 | 
				
			||||||
 | 
					   |            ^^^^^^^^
 | 
				
			||||||
 | 
					note: required by a bound in `fayalite::intern::Interned`
 | 
				
			||||||
 | 
					  --> src/intern.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub struct Interned<T: ?Sized + 'static + Send + Sync> {
 | 
				
			||||||
 | 
					   |                                                  ^^^^ required by this bound in `Interned`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error[E0277]: `UnsafeCell<value::SimValueInner<()>>` cannot be shared between threads safely
 | 
				
			||||||
 | 
					  --> tests/ui/simvalue_is_not_internable.rs:12:5
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					12 |     Intern::intern_sized(v)
 | 
				
			||||||
 | 
					   |     ^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<value::SimValueInner<()>>` cannot be shared between threads safely
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   = help: within `SimValue<()>`, the trait `Sync` is not implemented for `UnsafeCell<value::SimValueInner<()>>`, which is required by `SimValue<()>: Sync`
 | 
				
			||||||
 | 
					note: required because it appears within the type `util::alternating_cell::AlternatingCell<value::SimValueInner<()>>`
 | 
				
			||||||
 | 
					  --> src/util/alternating_cell.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub(crate) struct AlternatingCell<T: ?Sized> {
 | 
				
			||||||
 | 
					   |                   ^^^^^^^^^^^^^^^
 | 
				
			||||||
 | 
					note: required because it appears within the type `SimValue<()>`
 | 
				
			||||||
 | 
					  --> src/sim/value.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub struct SimValue<T: Type> {
 | 
				
			||||||
 | 
					   |            ^^^^^^^^
 | 
				
			||||||
 | 
					note: required by a bound in `fayalite::intern::Interned`
 | 
				
			||||||
 | 
					  --> src/intern.rs
 | 
				
			||||||
 | 
					   |
 | 
				
			||||||
 | 
					   | pub struct Interned<T: ?Sized + 'static + Send + Sync> {
 | 
				
			||||||
 | 
					   |                                                  ^^^^ required by this bound in `Interned`
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue