@@ -30,6 +30,8 @@ using namespace std::string_view_literals;
3030template <typename Ctx>
3131Result<typename Ctx::HeapTypeT> absheaptype (Ctx&, Shareability);
3232template <typename Ctx> Result<typename Ctx::HeapTypeT> heaptype (Ctx&);
33+ template <typename Ctx>
34+ MaybeResult<typename Ctx::TypeT> maybeReftypeAbbrev (Ctx&);
3335template <typename Ctx> MaybeResult<typename Ctx::RefTypeT> maybeReftype (Ctx&);
3436template <typename Ctx> Result<typename Ctx::RefTypeT> reftype (Ctx&);
3537template <typename Ctx> MaybeResult<typename Ctx::TypeT> tupletype (Ctx&);
@@ -456,68 +458,85 @@ template<typename Ctx> Result<typename Ctx::HeapTypeT> heaptype(Ctx& ctx) {
456458// | 'i31ref' => i31ref
457459// | 'structref' => structref
458460// | 'arrayref' => arrayref
459- // | '(' ref null? t:heaptype ')' => ref null? t
460- template <typename Ctx> MaybeResult<typename Ctx::TypeT> maybeReftype (Ctx& ctx) {
461+ // | ...
462+ template <typename Ctx>
463+ MaybeResult<typename Ctx::TypeT> maybeReftypeAbbrev (Ctx& ctx) {
461464 if (ctx.in .takeKeyword (" funcref" sv)) {
462- return ctx.makeRefType (ctx.makeFuncType (Unshared), Nullable);
465+ return ctx.makeRefType (ctx.makeFuncType (Unshared), Nullable, Inexact );
463466 }
464467 if (ctx.in .takeKeyword (" externref" sv)) {
465- return ctx.makeRefType (ctx.makeExternType (Unshared), Nullable);
468+ return ctx.makeRefType (ctx.makeExternType (Unshared), Nullable, Inexact );
466469 }
467470 if (ctx.in .takeKeyword (" anyref" sv)) {
468- return ctx.makeRefType (ctx.makeAnyType (Unshared), Nullable);
471+ return ctx.makeRefType (ctx.makeAnyType (Unshared), Nullable, Inexact );
469472 }
470473 if (ctx.in .takeKeyword (" eqref" sv)) {
471- return ctx.makeRefType (ctx.makeEqType (Unshared), Nullable);
474+ return ctx.makeRefType (ctx.makeEqType (Unshared), Nullable, Inexact );
472475 }
473476 if (ctx.in .takeKeyword (" i31ref" sv)) {
474- return ctx.makeRefType (ctx.makeI31Type (Unshared), Nullable);
477+ return ctx.makeRefType (ctx.makeI31Type (Unshared), Nullable, Inexact );
475478 }
476479 if (ctx.in .takeKeyword (" structref" sv)) {
477- return ctx.makeRefType (ctx.makeStructType (Unshared), Nullable);
480+ return ctx.makeRefType (ctx.makeStructType (Unshared), Nullable, Inexact );
478481 }
479482 if (ctx.in .takeKeyword (" arrayref" sv)) {
480- return ctx.makeRefType (ctx.makeArrayType (Unshared), Nullable);
483+ return ctx.makeRefType (ctx.makeArrayType (Unshared), Nullable, Inexact );
481484 }
482485 if (ctx.in .takeKeyword (" exnref" sv)) {
483- return ctx.makeRefType (ctx.makeExnType (Unshared), Nullable);
486+ return ctx.makeRefType (ctx.makeExnType (Unshared), Nullable, Inexact );
484487 }
485488 if (ctx.in .takeKeyword (" stringref" sv)) {
486- return ctx.makeRefType (ctx.makeStringType (Unshared), Nullable);
489+ return ctx.makeRefType (ctx.makeStringType (Unshared), Nullable, Inexact );
487490 }
488491 if (ctx.in .takeKeyword (" contref" sv)) {
489- return ctx.makeRefType (ctx.makeContType (Unshared), Nullable);
492+ return ctx.makeRefType (ctx.makeContType (Unshared), Nullable, Inexact );
490493 }
491494 if (ctx.in .takeKeyword (" nullref" sv)) {
492- return ctx.makeRefType (ctx.makeNoneType (Unshared), Nullable);
495+ return ctx.makeRefType (ctx.makeNoneType (Unshared), Nullable, Inexact );
493496 }
494497 if (ctx.in .takeKeyword (" nullexternref" sv)) {
495- return ctx.makeRefType (ctx.makeNoextType (Unshared), Nullable);
498+ return ctx.makeRefType (ctx.makeNoextType (Unshared), Nullable, Inexact );
496499 }
497500 if (ctx.in .takeKeyword (" nullfuncref" sv)) {
498- return ctx.makeRefType (ctx.makeNofuncType (Unshared), Nullable);
501+ return ctx.makeRefType (ctx.makeNofuncType (Unshared), Nullable, Inexact );
499502 }
500503 if (ctx.in .takeKeyword (" nullexnref" sv)) {
501- return ctx.makeRefType (ctx.makeNoexnType (Unshared), Nullable);
504+ return ctx.makeRefType (ctx.makeNoexnType (Unshared), Nullable, Inexact );
502505 }
503506 if (ctx.in .takeKeyword (" nullcontref" sv)) {
504- return ctx.makeRefType (ctx.makeNocontType (Unshared), Nullable);
507+ return ctx.makeRefType (ctx.makeNocontType (Unshared), Nullable, Inexact );
505508 }
509+ return {};
510+ }
506511
507- if (!ctx.in .takeSExprStart (" ref" sv)) {
508- return {};
512+ // reftype ::= ...
513+ // | '(' 'exact' (ref null ht):shorthand ')' => ref null exact ht
514+ // | '(' ref null? exact? ht:heaptype ')' => ref null? t
515+ template <typename Ctx> MaybeResult<typename Ctx::TypeT> maybeReftype (Ctx& ctx) {
516+ if (ctx.in .takeSExprStart (" exact" sv)) {
517+ auto rt = maybeReftypeAbbrev (ctx);
518+ CHECK_ERR (rt);
519+ if (!rt) {
520+ return ctx.in .err (" expected reftype shorthand" );
521+ }
522+ if (!ctx.in .takeRParen ()) {
523+ return ctx.in .err (" expected end of reftype" );
524+ }
525+ return ctx.makeRefType (ctx.getHeapTypeFromRefType (*rt), Nullable, Exact);
509526 }
510527
511- auto nullability = ctx.in .takeKeyword (" null" sv) ? Nullable : NonNullable;
512-
513- auto type = heaptype (ctx);
514- CHECK_ERR (type);
515-
516- if (!ctx.in .takeRParen ()) {
517- return ctx.in .err (" expected end of reftype" );
528+ if (ctx.in .takeSExprStart (" ref" sv)) {
529+ auto nullability = ctx.in .takeKeyword (" null" sv) ? Nullable : NonNullable;
530+ auto exactness = ctx.in .takeKeyword (" exact" sv) ? Exact : Inexact;
531+ auto type = heaptype (ctx);
532+ CHECK_ERR (type);
533+ if (!ctx.in .takeRParen ()) {
534+ return ctx.in .err (" expected end of reftype" );
535+ }
536+ return ctx.makeRefType (*type, nullability, exactness);
518537 }
519538
520- return ctx. makeRefType (*type, nullability );
539+ return maybeReftypeAbbrev (ctx );
521540}
522541
523542template <typename Ctx> Result<typename Ctx::TypeT> reftype (Ctx& ctx) {
0 commit comments