Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,775 changes: 1,389 additions & 1,386 deletions src/v3/compiler/src/bootstrap_generated.rs

Large diffs are not rendered by default.

2,609 changes: 1,306 additions & 1,303 deletions src/v3/compiler/src/bootstrap_generated_without_parse_surface.rs

Large diffs are not rendered by default.

78 changes: 60 additions & 18 deletions src/v3/compiler/src/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,8 @@ struct RealizationIndexes {
patterns: HashMap<DeclarationId, PatternRealizationBinding>,
syntax: GoLanguageSyntax,
execution_model: TargetExecutionModelBinding,
/// Source exclusion policy loaded from
/// `data go_source_filtering: ShapeATargetSourceFiltering`.
source_filtering: SourceFilteringBinding,
/// The Go clean-emission contract loaded from `data
/// go_clean_emission: CleanEmissionContract` (E-5 / Lane 1 Stage
Expand Down Expand Up @@ -2870,33 +2872,73 @@ fn require_scope_model(
})
}

impl SourceFilteringBinding {
pub(crate) fn build(dag: &Dag, declaration: DeclarationId) -> Result<Self, EmitError> {
let fields = structural_fields_for_decl(dag, declaration)?;
let value = fields
.iter()
.find(|(label, _)| label == "excluded_prefixes")
.map(|(_, value)| value)
.ok_or(EmitError::MalformedTargetSyntax {
declaration,
detail: "SourceFiltering is missing required `excluded_prefixes` field",
})?;
let FieldValue::List(entries) = value else {
/// Reads `excluded_prefixes` from a `data …: SourceFiltering` value body.
fn parse_source_filtering_excluded_prefixes(
dag: &Dag,
declaration: DeclarationId,
) -> Result<Vec<String>, EmitError> {
let fields = structural_fields_for_decl(dag, declaration)?;
let value = fields
.iter()
.find(|(label, _)| label == "excluded_prefixes")
.map(|(_, value)| value)
.ok_or(EmitError::MalformedTargetSyntax {
declaration,
detail: "SourceFiltering is missing required `excluded_prefixes` field",
})?;
let FieldValue::List(entries) = value else {
return Err(EmitError::MalformedTargetSyntax {
declaration,
detail: "SourceFiltering.excluded_prefixes must be a list",
});
};
let mut excluded_prefixes = Vec::with_capacity(entries.len());
for entry in entries {
let FieldValue::Literal(LiteralBits::String(prefix)) = entry else {
return Err(EmitError::MalformedTargetSyntax {
declaration,
detail: "SourceFiltering.excluded_prefixes must be a list",
detail: "SourceFiltering.excluded_prefixes entries must be string literals",
});
};
let mut excluded_prefixes = Vec::with_capacity(entries.len());
for entry in entries {
let FieldValue::Literal(LiteralBits::String(prefix)) = entry else {
excluded_prefixes.push(prefix.clone());
}
Ok(excluded_prefixes)
}

impl SourceFilteringBinding {
pub(crate) fn build(dag: &Dag, declaration: DeclarationId) -> Result<Self, EmitError> {
let fields = structural_fields_for_decl(dag, declaration)?;
if fields.iter().any(|(label, _)| label == "internal") {
let internal = require_field_decl_ref(fields, "internal", declaration)?;
let mut excluded_prefixes = parse_source_filtering_excluded_prefixes(dag, internal)?;
let additional = fields
.iter()
.find(|(label, _)| label == "additional_excluded_prefixes")
.map(|(_, value)| value)
.ok_or(EmitError::MalformedTargetSyntax {
declaration,
detail: "ShapeATargetSourceFiltering is missing required `additional_excluded_prefixes` field",
})?;
let FieldValue::List(extra_entries) = additional else {
return Err(EmitError::MalformedTargetSyntax {
declaration,
detail: "SourceFiltering.excluded_prefixes entries must be string literals",
detail:
"ShapeATargetSourceFiltering.additional_excluded_prefixes must be a list",
});
};
excluded_prefixes.push(prefix.clone());
for entry in extra_entries {
let FieldValue::Literal(LiteralBits::String(prefix)) = entry else {
return Err(EmitError::MalformedTargetSyntax {
declaration,
detail: "ShapeATargetSourceFiltering.additional_excluded_prefixes entries must be string literals",
});
};
excluded_prefixes.push(prefix.clone());
}
return Ok(Self { excluded_prefixes });
}

let excluded_prefixes = parse_source_filtering_excluded_prefixes(dag, declaration)?;
Ok(Self { excluded_prefixes })
}

Expand Down
2 changes: 2 additions & 0 deletions src/v3/compiler/src/emit/python_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ struct PythonIndexes {
patterns: HashMap<DeclarationId, PatternRealizationBinding>,
syntax: PythonSyntax,
target: PythonTarget,
/// Source exclusion policy loaded from
/// `data python_source_filtering: ShapeATargetSourceFiltering`.
source_filtering: SourceFilteringBinding,
/// The Python clean-emission contract loaded from `data
/// python_clean_emission: CleanEmissionContract` (E-5 / Lane 1
Expand Down
2 changes: 1 addition & 1 deletion src/v3/compiler/src/emit/rust_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ struct RealizationIndexes {
/// `data rust_execution_model: TargetExecutionModel`.
execution: TargetExecutionModelBinding,
/// Source exclusion policy loaded from
/// `data rust_source_filtering: SourceFiltering`.
/// `data rust_source_filtering: ShapeATargetSourceFiltering`.
source_filtering: SourceFilteringBinding,
/// The Rust clean-emission contract loaded from
/// `data rust_clean_emission: CleanEmissionContract` (E-5 /
Expand Down
2 changes: 2 additions & 0 deletions src/v3/compiler/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ mod sg3_surface_reflection_consumer_test;
mod sg6_hand_authored_census_test;
#[path = "integration/sg7_prep_variant_payload_freshness_test.rs"]
mod sg7_prep_variant_payload_freshness_test;
#[path = "integration/shape_a_target_source_filtering_authority_test.rs"]
mod shape_a_target_source_filtering_authority_test;
Comment on lines +144 to +145

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update SG-0 census allowlist for the new integration test

Adding shape_a_target_source_filtering_authority_test introduces a new hand-authored .rs file under src/v3/compiler/tests/integration/, but EXPECTED_HAND_AUTHORED_TEST in sg0_census_test.rs was not updated, so the ratchet now fails (cargo test -p v3-compiler sg0_v3_hand_authored_census panics with census drift and reports this exact path as unexpected). This breaks the integration test suite until the new file is added to the census list (or otherwise moved behind a generator path).

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified — already fixed on branch

The finding was correct for the pre-fix tip (e.g. be441ddd): shape_a_target_source_filtering_authority_test.rs was missing from EXPECTED_HAND_AUTHORED_TEST.

Current session/sleek-wren-716 includes 478768063, which adds that path to EXPECTED_HAND_AUTHORED_TEST in sg0_census_test.rs (sorted with the other integration/*.rs entries). sg0_v3_hand_authored_census / sg0_v3_test_hand_authored_subratchet pass on that head.

If the connector was pinned to an earlier SHA, refresh to 478768063 or later.

#[path = "integration/t_impossiblebugs_unenumerated_effects_test.rs"]
mod t_impossiblebugs_unenumerated_effects_test;
#[path = "integration/t_pb_b_1_dag_runner_test.rs"]
Expand Down
8 changes: 4 additions & 4 deletions src/v3/compiler/tests/integration/parse_corpus_manifest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ src/v3/compiler/tests/four_fixture_pressure/id.v3 2 2452 ec8b40edc3d3c017
src/v3/compiler/tests/four_fixture_pressure/is_empty.v3 3 6755 00117f14eb43dd20
src/v3/compiler/tests/four_fixture_pressure/wrap.v3 4 5189 ac633b042c944480
src/v3/compiler/tokenize.dag 29 59946 0a087425b90a125a
src/v3/spec/go.dag 122 1126317 82d4ec71acfdd80e
src/v3/spec/python.dag 88 579466 4d7f9bb14b85da04
src/v3/spec/rust.dag 140 1199314 5bd6bf1bf8a928b5
src/v3/spec/go.dag 122 1125002 82784b9fd7c75c11
src/v3/spec/python.dag 88 578107 68a9c621ec56df82
src/v3/spec/rust.dag 140 1197991 6d29fcfdbcde00f7
src/v3/spec/v3_l1.dag 8 2238 1f55d782265c3bfe
src/v3/std/algebra.dag 39 291807 4d45a732a553142a
src/v3/std/clean_emission.dag 15 23867 e7bc1e6145f4781e
src/v3/std/computation.dag 18 36754 0d38639c1f631609
src/v3/std/computation_model.dag 12 17291 30cd3a0f7cc08eae
src/v3/std/computation_model.dag 14 22953 20e458fe097d175a
src/v3/std/diagnostics.dag 6 7982 6dc35615cc265b02
src/v3/std/dimensions.dag 21 36211 8632c598dcf35274
src/v3/std/effects.dag 53 97984 1acdbeaa68acfd2e
Expand Down
1 change: 1 addition & 0 deletions src/v3/compiler/tests/integration/sg0_census_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ const EXPECTED_HAND_AUTHORED_TEST: &[&str] = &[
"src/v3/compiler/tests/integration/sg3_surface_reflection_consumer_test.rs",
"src/v3/compiler/tests/integration/sg6_hand_authored_census_test.rs",
"src/v3/compiler/tests/integration/sg7_prep_variant_payload_freshness_test.rs",
"src/v3/compiler/tests/integration/shape_a_target_source_filtering_authority_test.rs",
"src/v3/compiler/tests/integration/t_impossiblebugs_unenumerated_effects_test.rs",
"src/v3/compiler/tests/integration/t_pb_b_1_dag_runner_test.rs",
"src/v3/compiler/tests/integration/t_pb_b_brief_d_fixture_smoke_test.rs",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//! **Layer:** integration
//!
//! Regen-clean ratchet: Shape-A Rust/Go/Python target specs must bind
//! `*_source_filtering.internal` to the single canonical
//! `data internal_source_filtering` in `computation_model.dag`, not fork
//! independent `excluded_prefixes` lists (internal/bootstrap declaration
//! prefix drift across targets).

const COMPUTATION_MODEL: &str = include_str!("../../../std/computation_model.dag");
const RUST_SPEC: &str = include_str!("../../../spec/rust.dag");
const GO_SPEC: &str = include_str!("../../../spec/go.dag");
const PYTHON_SPEC: &str = include_str!("../../../spec/python.dag");

const CANONICAL_BINDING: &str = "internal: internal_source_filtering";

/// Returns the `{ ... }` value block for a `data <name>: <Ty> = {` row starting
/// at `row_prefix` (must be unique in `spec`). Used so the canonical `internal`
/// binding is asserted inside the specific declaration, not anywhere in the file.
fn struct_value_block<'a>(spec: &'a str, row_prefix: &str) -> &'a str {
let pos = spec.find(row_prefix).unwrap_or_else(|| {
panic!("expected `{row_prefix}` in spec");
});
let tail = &spec[pos..];
let open = tail
.find('{')
.unwrap_or_else(|| panic!("expected `{{` after `{row_prefix}`"));
let from_brace = &tail[open..];
let mut depth: i32 = 0;
let mut end_byte = 0usize;
for (i, c) in from_brace.char_indices() {
match c {
'{' => depth += 1,
'}' => {
depth -= 1;
if depth == 0 {
end_byte = i + c.len_utf8();
break;
}
}
_ => {}
}
}
assert!(end_byte > 0, "unclosed `{{` for `{row_prefix}`");
&from_brace[..end_byte]
}

#[test]
fn computation_model_declares_internal_source_filtering() {
assert!(
COMPUTATION_MODEL.contains("data internal_source_filtering: SourceFiltering"),
"expected `data internal_source_filtering: SourceFiltering` in computation_model.dag"
);
}

#[test]
fn shape_a_target_specs_reference_canonical_internal_source_filtering() {
for (label, row, spec) in [
(
"rust.dag",
"data rust_source_filtering: ShapeATargetSourceFiltering",
RUST_SPEC,
),
(
"go.dag",
"data go_source_filtering: ShapeATargetSourceFiltering",
GO_SPEC,
),
(
"python.dag",
"data python_source_filtering: ShapeATargetSourceFiltering",
PYTHON_SPEC,
),
] {
assert!(spec.contains(row), "{label}: expected `{row}`");
let block = struct_value_block(spec, row);
assert!(
block.contains(CANONICAL_BINDING),
"{label}: `{row}` value must bind `{CANONICAL_BINDING}` (got block: {block:?})"
);
}
}
14 changes: 5 additions & 9 deletions src/v3/spec/go.dag
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import v3.std.emit_model {
}
import v3.std.computation_model {
TargetExecutionModel, GarbageCollected, LexicalScoping,
SourceFiltering, ExecutionModelRequirement
ShapeATargetSourceFiltering, ExecutionModelRequirement,
internal_source_filtering
}
import v3.std.clean_emission {
CleanEmissionContract,
Expand All @@ -41,14 +42,9 @@ data go_execution_model: TargetExecutionModel = {
scope: LexicalScoping
}

data go_source_filtering: SourceFiltering = {
excluded_prefixes: [
"dsl/std/",
"dsl/extdeps/",
"src/v3/std/",
"src/v3/spec/",
"src/v3/compiler/",
]
data go_source_filtering: ShapeATargetSourceFiltering = {
internal: internal_source_filtering
additional_excluded_prefixes: ["src/v3/compiler/"]
}

data go_execution_requirement: ExecutionModelRequirement = GarbageCollected
Expand Down
13 changes: 5 additions & 8 deletions src/v3/spec/python.dag
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import std.algebra { BooleanAlgebra, OrderedRing }
import v3.std.computation_model {
TargetExecutionModel, MemoryModel,
GarbageCollected, LexicalScoping,
SourceFiltering, ExecutionModelRequirement
ShapeATargetSourceFiltering, ExecutionModelRequirement,
internal_source_filtering
}
import v3.std.emit_model {
TypeRealization, OperatorRealization, CallableRealization,
Expand Down Expand Up @@ -152,13 +153,9 @@ data python_target: TargetExecutionModel = {
scope: LexicalScoping
}

data python_source_filtering: SourceFiltering = {
excluded_prefixes: [
"dsl/std/",
"dsl/extdeps/",
"src/v3/std/",
"src/v3/spec/",
]
data python_source_filtering: ShapeATargetSourceFiltering = {
internal: internal_source_filtering
additional_excluded_prefixes: []
}

data python_execution_requirement: ExecutionModelRequirement = GarbageCollected
Expand Down
16 changes: 7 additions & 9 deletions src/v3/spec/rust.dag
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ module v3.spec.rust

import v3.spec.v3_l1 { Bind, Branch, Main }
import v3.std.computation_model { TargetExecutionModel, OwnershipBased, LexicalScoping }
import v3.std.computation_model { SourceFiltering, ExecutionModelRequirement }
import v3.std.computation_model {
ShapeATargetSourceFiltering, ExecutionModelRequirement,
internal_source_filtering
}
import v3.std.emit_model {
TypeRealization, FieldBinding, FieldAccess,
OperatorRealization, BehaviorRealization, CallableRealization,
Expand Down Expand Up @@ -92,14 +95,9 @@ data rust_execution_model: TargetExecutionModel = {
scope: LexicalScoping
}

data rust_source_filtering: SourceFiltering = {
excluded_prefixes: [
"dsl/std/",
"dsl/extdeps/",
"src/v3/std/",
"src/v3/spec/",
"src/v3/compiler/",
]
data rust_source_filtering: ShapeATargetSourceFiltering = {
internal: internal_source_filtering
additional_excluded_prefixes: ["src/v3/compiler/"]
}

data rust_execution_requirement: ExecutionModelRequirement = OwnershipBased
Expand Down
18 changes: 18 additions & 0 deletions src/v3/std/computation_model.dag
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,24 @@ type SourceFiltering {
excluded_prefixes: List<String>
}

// Shape-A emit targets share `internal_source_filtering` for the
// invariant internal/bootstrap prefix set; target-only prefixes (e.g.
// `src/v3/compiler/` for Rust/Go declaration walks) append here so the
// base list is not forked across `rust.dag` / `go.dag` / `python.dag`.
type ShapeATargetSourceFiltering {
internal: SourceFiltering
additional_excluded_prefixes: List<String>
}

data internal_source_filtering: SourceFiltering = {
excluded_prefixes: [
"dsl/std/",
"dsl/extdeps/",
"src/v3/std/",
"src/v3/spec/",
]
}

// 🟡 PHASE 2 PREP. Coarser-than-MemoryModel summary of whether a
// target takes the ownership-sensitive render path or the GC/value
// path. Added for Lane 1e PR-2.1; the current emitters still read the
Expand Down
Loading