@@ -3882,6 +3882,80 @@ let qualified_value_tests = [
38823882 Alcotest. test_case " use Mod as M; M::fn(x) resolves (#178 follow-up)" `Quick test_qualval_coloncolon_alias_call;
38833883]
38843884
3885+ (* ---- Inline `extern fn` / `extern type` shape-coverage fixtures ----
3886+ Class-level coverage for the "first user of an inline extern shape
3887+ feeds it to every downstream consumer" surface that produced the
3888+ PR #346 FnExtern interp bug (eval_decl missing match arm — survived
3889+ since the interpreter was written, fired the moment STDLIB-04a's
3890+ tests became the first to hand an inline extern fn to
3891+ Interp.eval_program).
3892+
3893+ See .claude/CLAUDE.md §"Test-fixture hygiene for latent bug
3894+ surfaces" for the rationale. Each fixture is fed through
3895+ parse → resolve → typecheck → interp; the assertion is that ALL
3896+ four return Ok. A regression that re-introduces the silent
3897+ pattern-match-failure path of the kind that broke main between
3898+ #334 and #346 would fail loudly here. *)
3899+
3900+ let inline_extern_pipeline_ok path : bool =
3901+ let loader = Module_loader. create {
3902+ Module_loader. stdlib_path = " stdlib" ;
3903+ search_paths = [] ;
3904+ current_dir = fixture_dir;
3905+ } in
3906+ match parse_fixture path with
3907+ | Error _ -> false
3908+ | Ok raw ->
3909+ let prog = Resolve. lower_qualified_value_paths raw in
3910+ (match Resolve. resolve_program_with_loader prog loader with
3911+ | Error _ -> false
3912+ | Ok (resolve_ctx , import_type_ctx ) ->
3913+ (match Typecheck. check_program
3914+ ~import_types: import_type_ctx.Typecheck. name_types
3915+ resolve_ctx.symbols prog with
3916+ | Error _ -> false
3917+ | Ok _ ->
3918+ (* The PR #346 root cause was here: Interp.eval_decl's TopFn
3919+ arm didn't match FnExtern, raising Match_failure. The
3920+ fixtures don't *call* the extern at runtime (the host
3921+ impl isn't registered), but eval_program walks every
3922+ TopFn through eval_decl as part of building the initial
3923+ env — that's the path that fired the missing arm. *)
3924+ (match Interp. eval_program prog with
3925+ | Ok _ -> true
3926+ | Error _ -> false )))
3927+
3928+ let test_inline_extern_pure () =
3929+ Alcotest. (check bool )
3930+ " inline `extern fn host_pure_identity(x: Int) -> Int;` passes the pipeline"
3931+ true
3932+ (inline_extern_pipeline_ok (fixture " inline_extern_pure.affine" ))
3933+
3934+ let test_inline_extern_effectful () =
3935+ Alcotest. (check bool )
3936+ " inline `extern fn host_log(msg) -> Unit / IO;` passes the pipeline"
3937+ true
3938+ (inline_extern_pipeline_ok (fixture " inline_extern_effectful.affine" ))
3939+
3940+ let test_inline_extern_polymorphic () =
3941+ Alcotest. (check bool )
3942+ " inline `extern fn host_identity[T](x: T) -> T;` passes the pipeline"
3943+ true
3944+ (inline_extern_pipeline_ok (fixture " inline_extern_polymorphic.affine" ))
3945+
3946+ let test_inline_extern_type_consumed () =
3947+ Alcotest. (check bool )
3948+ " inline `extern type Handle; extern fn host_use(h: Handle) -> Int;` passes the pipeline"
3949+ true
3950+ (inline_extern_pipeline_ok (fixture " inline_extern_type_consumed.affine" ))
3951+
3952+ let inline_extern_shape_tests = [
3953+ Alcotest. test_case " pure (no effects)" `Quick test_inline_extern_pure;
3954+ Alcotest. test_case " effectful (effect row)" `Quick test_inline_extern_effectful;
3955+ Alcotest. test_case " polymorphic (type params)" `Quick test_inline_extern_polymorphic;
3956+ Alcotest. test_case " extern type + consuming fn" `Quick test_inline_extern_type_consumed;
3957+ ]
3958+
38853959(* ---- Type-syntax sugars: fn(...) -> T, Option<T>, (A, B) -> C ---- *)
38863960
38873961let parse_check_passes src : bool =
@@ -4352,6 +4426,7 @@ let tests =
43524426 (" E2E Array Type Sugar" , array_type_tests);
43534427 (" E2E Qualified Paths #228" , qualified_path_tests);
43544428 (" E2E Qualified Value #178" , qualified_value_tests);
4429+ (" E2E Inline Extern Shapes (Refs #346)" , inline_extern_shape_tests);
43554430 (" E2E WasmGC PatCon Destructure" , wasm_gc_patcon_tests);
43564431 (" E2E Type Syntax Sugar" , type_syntax_sugar_tests);
43574432 ]
0 commit comments