Skip to content
Closed
15 changes: 15 additions & 0 deletions dag/gunbc/compile_clean_diagnostic_policy.dag
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,21 @@ data advisory_class_ceilings: List<AdvisoryClassCeilingRow> = [
field: WholeDeclaration
}
},
AdvisoryClassCeilingRow {
class_name: "TestCodeReferenceAdmitted" as NonEmptyStr,
ceiling: DeclaredAdmissionRoster {
roster: DeclarationRef {
module_path: "v1.compiler.compile",
decl_name: "test_reference_debt",
field: WholeDeclaration
}
},
census: DeclarationRef {
module_path: "gunbc.instrument_targets",
decl_name: "compile_clean_diagnostic_census_binding",
field: WholeDeclaration
}
},
AdvisoryClassCeilingRow {
class_name: "MethodExistenceFrontierAdmitted" as NonEmptyStr,
ceiling: DeclaredAdmissionRoster {
Expand Down
54 changes: 54 additions & 0 deletions dag/test/claim/test_reference_wall_witness_test.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module test.claim.test_reference_wall_witness

import gunbc.compile_census_probe { blocking_subject_count_for, any_class_count_for }
import std.types { String, Bool, Int }
import v2.std.live_tree { LiveTreeDisposition, ReadsLiveTree }

data live_tree_disposition: LiveTreeDisposition = ReadsLiveTree

// THE EXECUTING EVIDENCE for the v1 test-reference wall (v1.compiler.compile
// test_reference_diagnostics). Its first evidence was placed in compiler_tests, a #[cfg(test)]
// module no CI step runs (review 67224): the admitted arm was exercised by the real corpus, and the
// two BLOCKING arms -- the wall's whole claim -- executed nowhere. These rows ask the compiler
// through the source-string census the floor discovers, so the refusals run on every required run.
//
// The subject of a blocking test-reference diagnostic is the referrer, `module.declaration`, so
// each red names the exact declaration that must refuse rather than counting the class anywhere.

data rollup_source: String = "module wall.fixture.rollup\nimport std.types { Bool }\ntest fn leaf() -> Bool { true }\ntest fn rollup() -> Bool { leaf() }\nfn helper() -> Bool { leaf() }\n"

data function_value_source: String = "module wall.fixture.value\nimport std.types { Bool }\ntest fn leaf() -> Bool { true }\nfn pick() -> fn() -> Bool { leaf }\n"

data clean_source: String = "module wall.fixture.clean\nimport std.types { Bool }\nfn helper() -> Bool { true }\ntest fn uses_helper() -> Bool { helper() }\n"

// A module that carries a ledger row, compiled with none of its references: the paid-down
// direction of the equality budget. It names a real row, so it moves when that row is paid down,
// and it retires with the ledger's last row, when the mismatch arm has nothing left to count.
data paid_down_source: String = "module test.claim.host_build_cache_provision_design\nimport std.types { Bool }\nfn witness_red_control_widen_on_absent_rejected_by_gate() -> Bool { true }\n"

// DISCRIMINATING RED: a test that calls a test refuses, at the calling test.
test fn a_test_calling_a_test_is_refused() -> Bool {
blocking_subject_count_for(source: rollup_source, wanted_class: "TestCodeReferenced", wanted_subject: "wall.fixture.rollup.rollup") == 1
}

// DISCRIMINATING RED: serving code calling a test refuses too.
test fn serving_code_calling_a_test_is_refused() -> Bool {
blocking_subject_count_for(source: rollup_source, wanted_class: "TestCodeReferenced", wanted_subject: "wall.fixture.rollup.helper") == 1
}

// DISCRIMINATING RED: a test taken as a function value is a reference.
test fn a_test_used_as_a_value_is_refused() -> Bool {
blocking_subject_count_for(source: function_value_source, wanted_class: "TestCodeReferenced", wanted_subject: "wall.fixture.value.pick") == 1
}

// ACCEPTED POSITIVE CONTROL: a test calling an ordinary fn draws no test-reference diagnostic at
// any severity, so the reds above mean "a test was referenced" and not "a test was compiled".
test fn a_test_calling_an_ordinary_fn_is_admitted() -> Bool {
any_class_count_for(source: clean_source, wanted_class: "TestCodeReferenced") == 0
&& any_class_count_for(source: clean_source, wanted_class: "TestCodeReferenceAdmitted") == 0
}

// THE RATCHET: a ledger row whose references are gone refuses until the row is deleted.
test fn a_paid_down_ledger_row_is_refused() -> Bool {
any_class_count_for(source: paid_down_source, wanted_class: "TestCodeReferenceBudgetMismatch") == 1
}
89 changes: 56 additions & 33 deletions src/v1/00_core.dag

Large diffs are not rendered by default.

168 changes: 106 additions & 62 deletions src/v1/02_parse.dag

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions src/v1/04_env.dag
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module v1.compiler.infer_env

import std.occurrence_identity { OccurrenceSynthetic }

import v1.std.core { Node, NewlineIndex, InternTable, Resolved, qualified_last_segment, empty_intern_table, merge_intern_tables, intern, intern_find, intern_str, source_text_at, authored_name_at, find_child_named, Cardinality, Connective, ExprData, InferredNode, kernel_span, declaration_provenance_of, module_path_segments, param_node_name_at, param_node_type_expr, CompilerDiagnostic, AmbiguousReference, UnresolvedType }
import v1.std.core { Unmarked, Node, NewlineIndex, InternTable, Resolved, qualified_last_segment, empty_intern_table, merge_intern_tables, intern, intern_find, intern_str, source_text_at, authored_name_at, find_child_named, Cardinality, Connective, ExprData, InferredNode, kernel_span, declaration_provenance_of, module_path_segments, param_node_name_at, param_node_type_expr, CompilerDiagnostic, AmbiguousReference, UnresolvedType }
import v1.compiler.type_head_exposure { TypeHeadExposure }

import std.types { SourceSpan, is_kernel_type }
Expand Down Expand Up @@ -917,7 +917,7 @@ fn qualify_borrowed_type_names(n: Node, owner_module_path: String, env: TypeEnv,
body: n.body, transport: n.transport, properties: n.properties,
type_annotation: n.type_annotation, is_self_recursive: n.is_self_recursive,
has_non_tail_self_call: n.has_non_tail_self_call, match_pattern: n.match_pattern,
module_item_kind: n.module_item_kind, expr_data: n.expr_data
module_item_kind: n.module_item_kind, declaration_marker: n.declaration_marker, expr_data: n.expr_data
}
}
Absent => node_with_children(n: n, children: qualified_children)
Expand All @@ -932,7 +932,7 @@ fn node_with_children(n: Node, children: List<Node>) -> Node {
body: n.body, transport: n.transport, properties: n.properties,
type_annotation: n.type_annotation, is_self_recursive: n.is_self_recursive,
has_non_tail_self_call: n.has_non_tail_self_call, match_pattern: n.match_pattern,
module_item_kind: n.module_item_kind, expr_data: n.expr_data
module_item_kind: n.module_item_kind, declaration_marker: n.declaration_marker, expr_data: n.expr_data
}
}

Expand All @@ -944,7 +944,7 @@ fn node_with_inferred(n: Node, inferred: InferredNode?) -> Node {
body: n.body, transport: n.transport, properties: n.properties,
type_annotation: n.type_annotation, is_self_recursive: n.is_self_recursive,
has_non_tail_self_call: n.has_non_tail_self_call, match_pattern: n.match_pattern,
module_item_kind: n.module_item_kind, expr_data: n.expr_data
module_item_kind: n.module_item_kind, declaration_marker: n.declaration_marker, expr_data: n.expr_data
}
}

Expand Down Expand Up @@ -1312,7 +1312,7 @@ fn env_with_type_variable_bindings(env: TypeEnv, tp_names: List<String>) -> Type
fold(tp_names, init: env, f: (e, tp_name) =>
let tp_binding = TypeBinding {
name: tp_name,
resolved: Node { occurrence_identity: OccurrenceSynthetic, name: tp_name, span: kernel_span(name: tp_name), ident_span: Present { value: kernel_span(name: tp_name) }, children: [], connective: NoConnective, params: [], inferred: Present { value: TypeVariable { id: tp_name } }, return_cardinality: Required, uses: [], body: none, transport: none, properties: [], type_annotation: none, is_self_recursive: false, has_non_tail_self_call: false, match_pattern: none, module_item_kind: NotAModuleItem, expr_data: NoExprData },
resolved: Node { occurrence_identity: OccurrenceSynthetic, name: tp_name, span: kernel_span(name: tp_name), ident_span: Present { value: kernel_span(name: tp_name) }, children: [], connective: NoConnective, params: [], inferred: Present { value: TypeVariable { id: tp_name } }, return_cardinality: Required, uses: [], body: none, transport: none, properties: [], type_annotation: none, is_self_recursive: false, has_non_tail_self_call: false, match_pattern: none, module_item_kind: NotAModuleItem, declaration_marker: Unmarked, expr_data: NoExprData },
provenance: SubValueUnknown
}
let shadowed = effective_visible_binding(str_bindings: e.str_bindings, parents: e.parents, name: tp_name)
Expand Down
Loading
Loading