use std::fs;
use std::path::Path;
macro_rules! assert_public_type_core_traits {
($($ty:ty),* $(,)?) => {
$(
static_assertions::assert_impl_all!($ty: Send, Sync, Clone, std::fmt::Debug, PartialEq);
)*
};
}
#[cfg(feature = "serde")]
macro_rules! assert_public_type_serde_traits {
($($ty:ty),* $(,)?) => {
$(
static_assertions::assert_impl_all!($ty: serde::Serialize, serde::de::DeserializeOwned);
)*
};
}
assert_public_type_core_traits! {
weir::DataflowEvidence<u32>,
weir::callgraph::Callgraph,
weir::callgraph::CallgraphBuildScratch,
weir::control_dependence::ControlDependence,
weir::cross_language::CrossLanguage,
weir::def_use::DefUse,
weir::dominators::Dominators,
weir::escape::Escape,
weir::escapes::Escapes,
weir::fixed_point_batch::CsrGraph<'static>,
weir::fixed_point_execution_plan::FixedPointExecutionPlan,
weir::fixed_point_execution_plan_cache::FixedPointExecutionPlanCache,
weir::fixed_point_execution_plan_cache::FixedPointExecutionPlanCacheStats,
weir::fixed_point_graph::FixedPointAnalysisKind,
weir::fixed_point_graph::FixedPointAnalysisPlan,
weir::fixed_point_graph::FixedPointForwardGraph,
weir::fixed_point_resident::FixedPointResidentGraph,
weir::fixed_point_resident::FixedPointResidentBatch,
weir::fixed_point_resident::FixedPointResidentBatchStats,
weir::fixed_point_resident::FixedPointResidentFrontierScratch,
weir::fixed_point_resident::FixedPointResidentGraphCache,
weir::fixed_point_resident::FixedPointResidentPlan,
weir::fixed_point_resident::FixedPointBorrowedResidentPlan<'static>,
weir::fixed_point_resident_batch::FixedPointResidentBatch,
weir::fixed_point_resident_batch::FixedPointResidentBatchStats,
weir::fixed_point_resident_cache::FixedPointResidentGraphCache,
weir::fixed_point_resident_cache::FixedPointResidentGraphCacheStats,
weir::fixed_point_resident_frontier::FixedPointResidentFrontierScratch,
weir::fixed_point_resident_plan::FixedPointResidentPlan,
weir::fixed_point_resident_plan::FixedPointBorrowedResidentPlan<'static>,
weir::fixed_point_scratch::FixedPointScratch,
weir::fixed_point_scratch::FrontierDensityTelemetry,
weir::fixed_point_scratch::FrontierExecutionMode,
weir::fixed_point_scratch::ScratchPool<u32>,
weir::graph_layout::CsrGraph<'static>,
weir::graph_layout::CsrGraphNormalizationScratch,
weir::graph_layout::LinearDomain,
weir::graph_layout::NormalizedCsrGraph,
weir::ifds::Ifds,
weir::ifds_gpu::IfdsGpu,
weir::ifds_gpu::IfdsShape,
weir::ifds_gpu::IfdsPrepareScratch,
weir::ifds_gpu::IfdsSolveScratch,
weir::ifds_gpu::IfdsBorrowedSolveScratch,
weir::ifds_gpu::PreparedIfdsCsr,
weir::ifds_gpu::ResidentIfdsHostScratch,
weir::ifds_gpu::ResidentIfdsParallelHostScratch,
weir::ifds_resident_batch::ResidentIfdsBatchStats,
weir::ifds_resident_cache::ResidentIfdsCsrCacheStats,
weir::ifds_resident_direct_batch::DirectResidentIfdsBatchStats,
weir::ifds_resident_direct_batch::DirectResidentIfdsGraph<'static>,
weir::ifds_resident_direct_batch::DirectResidentIfdsGraphKey,
weir::ifds_resident_direct_prepare_scratch::DirectResidentIfdsPrepareScratch,
weir::live::Liveness,
weir::live::LiveFamily,
weir::live_at::LiveAt,
weir::loop_sum::LoopSum,
weir::loop_sum::LoopSummarizeScratch,
weir::may_alias::MayAlias,
weir::must_init::MustInit,
weir::points_to::PointsTo,
weir::points_to::PointsToFamily,
weir::post_dominates::PostDominates,
weir::range::Range,
weir::range::RangePropagateScratch,
weir::range_check::RangeCheck,
weir::reachability_witness::PathSeed,
weir::reachability_witness::ExtractedStatement,
weir::reachability_witness::ExtractedPath,
weir::reachability_witness::NodeAttr,
weir::reachability_witness::PreparedWitnessGraph<'static>,
weir::reachability_witness::PrepareWitnessGraphError,
weir::reachability_witness::PathError,
weir::reachability_witness::ExplodedDecodeError,
weir::reaching::ReachingDefs,
weir::reaching::ReachingFamily,
weir::reaching_def::ReachingDef,
weir::scc_query::SccQuery,
weir::slice::BackwardSlice,
weir::slice::SliceFamily,
weir::soundness::DataflowEvidence<u32>,
weir::ssa::Ssa,
weir::ssa::SsaForm,
weir::ssa::Block,
weir::ssa::Cfg,
weir::summary::Summary,
weir::summary::SummarizeFunctionScratch,
weir::value_set::ValueSet,
}
assert_public_type_core_traits! {
weir::fixed_point_batch::FixedPointBatch<'static, ()>,
weir::fixed_point_resident_plan::PlanBuilder<weir::fixed_point_resident::FixedPointResidentGraph>,
}
#[cfg(feature = "serde")]
assert_public_type_serde_traits! {
weir::DataflowEvidence<u32>,
weir::reachability_witness::PathSeed,
weir::reachability_witness::ExtractedStatement,
weir::reachability_witness::ExtractedPath,
weir::reachability_witness::PrepareWitnessGraphError,
weir::reachability_witness::PathError,
weir::reachability_witness::ExplodedDecodeError,
weir::soundness::DataflowEvidence<u32>,
}
#[test]
fn readme_release_token_matches_package_version() {
let root = Path::new(env!("CARGO_MANIFEST_DIR"));
let manifest = fs::read_to_string(root.join("Cargo.toml"))
.expect("Cargo.toml should be readable for release-surface contract");
let readme = fs::read_to_string(root.join("README.md"))
.expect("README.md should be readable for release-surface contract");
let version = package_version(&manifest).expect("package.version should be declared");
let release_token = format!("weir@{version}");
let version_sentence = format!("Weir `{version}` is the standalone dataflow crate");
assert!(
readme.contains(&version_sentence),
"README must name the exact package version `{version}` in the release surface"
);
assert!(
readme.contains(&release_token),
"README must expose the exact release package token `{release_token}`"
);
assert!(
!readme.contains("weir@0.0.1") && !readme.contains("Weir `0.0.1`"),
"README must not advertise stale Weir 0.0.1 release tokens"
);
}
#[test]
fn readme_keeps_cpu_helpers_oracle_only() {
let root = Path::new(env!("CARGO_MANIFEST_DIR"));
let readme = fs::read_to_string(root.join("README.md"))
.expect("README.md should be readable for release-surface contract");
assert!(
readme.contains("CPU reference routines live under `weir::oracle`"),
"README must route CPU references through the oracle namespace"
);
assert!(
readme.contains("not part of the production surface"),
"README must say direct CPU helpers are not production APIs"
);
assert!(
!readme.contains("deprecated compatibility paths"),
"README must not describe CPU helpers as a compatibility execution path"
);
}
#[test]
fn internal_gpu_abi_helpers_are_not_public_modules() {
let root = Path::new(env!("CARGO_MANIFEST_DIR"));
let source = fs::read_to_string(root.join("src/lib.rs"))
.expect("src/lib.rs should be readable for release-surface contract");
for internal_module in [
"output_scratch",
"dispatch_input_cache",
"staging_reserve",
] {
assert!(
source.contains(&format!("mod {internal_module};")),
"internal module `{internal_module}` must be declared"
);
assert!(
!source.contains(&format!("pub mod {internal_module};")),
"internal GPU ABI helper `{internal_module}` must not be exposed as public Weir API"
);
}
}
#[test]
fn reaching_def_summary_checked_fold_rejects_truncated_triples() {
let root = Path::new(env!("CARGO_MANIFEST_DIR"));
let source = fs::read_to_string(root.join("src/reaching_def_summary.rs"))
.expect("reaching_def_summary source should be readable for release-surface contract");
let fold_body = function_body(&source, "try_fold_summary_partials");
assert!(
fold_body.contains("partials.len() % 3 != 0")
&& fold_body.contains("not divisible by 3")
&& fold_body.contains("chunks_exact(3)"),
"try_fold_summary_partials must reject non-triple-aligned GPU summary output before chunks_exact folding"
);
}
fn package_version(manifest: &str) -> Option<&str> {
manifest.lines().find_map(|line| {
let trimmed = line.trim();
let value = trimmed.strip_prefix("version = ")?;
value.trim_matches('"').split('"').next()
})
}
fn function_body<'a>(source: &'a str, name: &str) -> &'a str {
let start = source
.find(&format!("fn {name}"))
.unwrap_or_else(|| panic!("{name} must exist in source"));
let after_start = &source[start..];
let open = after_start
.find('{')
.unwrap_or_else(|| panic!("{name} must have a body"));
let mut depth = 0usize;
for (offset, byte) in after_start[open..].bytes().enumerate() {
match byte {
b'{' => depth += 1,
b'}' => {
depth -= 1;
if depth == 0 {
return &after_start[open..=open + offset];
}
}
_ => {}
}
}
panic!("{name} body must close");
}