The fn-body `#foreign [LIB] ["csym"]` marker now builds the SAME shape postfix `extern` produces — extern_export = .extern_ + extern_lib/extern_name + an empty-block body — instead of a `foreign_expr` body. With all four prereqs landed (visibility, variadic, plain-free classification, lib-ref validation), every downstream reader coalesces is_foreign with extern_export, so the IR and runtime behavior are byte-identical (full corpus + the A->B gate stay green). The surface keyword is no longer on the AST, so a `#foreign`-spelled decl now yields `extern`-worded diagnostics — the single accepted churn (Decision 7): example 1620's lib-ref error flips '#foreign library' -> 'extern library'. Parser-surface diagnostics (conflict/expected-token) fire on the literal keyword and are unaffected. c_import auto-synthesis still emits foreign_expr bodies (not this step), so both shapes still coexist. Parser unit test updated to assert the extern shape. 647 corpus / 444 unit, 0 failed. The const-with-type (dead) + runtime-class (already coalesced) paths need no flip — Phase 5.0 parser routing is complete.
6 lines
300 B
Plaintext
6 lines
300 B
Plaintext
error: extern library 'nosuchunit' is not declared; expected a #library constant or a named '#import c' unit
|
|
--> examples/1620-cimport-foreign-ref-unvalidated.sx:12:1
|
|
|
|
|
12 | ref_answer :: () -> i32 #foreign nosuchunit "ref_answer";
|
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|