roc/test/snapshots/static_dispatch/Adv.md
Richard Feldman 641f4db0b0
Update snapshots for nominal pattern bound variable fix
The fix correctly identifies that variables bound inside nominal
patterns (like `s` in `Container.Box(s)`) are bound in the pattern
scope and don't need to be captured. This results in cleaner
canonical IR where functions that use nominal pattern matching
are now represented as pure lambdas instead of closures with
unnecessary captures.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 07:55:22 -05:00

13 KiB

META

description=
type=file

SOURCE

Adv := [Val(U64, Str)].{
  to_str : Adv -> Str
  to_str = |Adv.Val(_, s)| s

  to_u64 : Adv -> U64
  to_u64 = |Adv.Val(u, _)| u

  update_str : Adv, Str -> Adv
  update_str = |Adv.Val(u64, _), next_str| Adv.Val(u64, next_str)

  update_u64 : Adv, U64 -> Adv
  update_u64 = |Adv.Val(_, str), next_u64| Adv.Val(next_u64, str)
}

mismatch = {
	val = Adv.Val(10, "hello")
	next_val = val.update_str(100)
	next_val
}

mismatch2 = {
	val = Adv.Val(10, "hello")
	next_val = val.update_strr(100)
	next_val
}

mismatch3 = {
	next_val = "Hello".update(100)
	next_val
}

main : (Str, U64)
main = {
	val = Adv.Val(10, "hello")
	next_val = val.update_str("world").update_u64(20)
	(next_val.to_str(), next_val.to_u64())
}

EXPECTED

MISSING METHOD - Adv.md:17:28:17:31 MISSING METHOD - Adv.md:23:17:23:28 MISSING METHOD - Adv.md:28:21:28:27

PROBLEMS

MISSING METHOD This from_numeral method is being called on a value whose type doesn't have that method: Adv.md:17:28:17:31:

	next_val = val.update_str(100)
                          ^^^

The value's type, which does not have a method named from_numeral, is:

_Str_

Hint: For this to work, the type would need to have a method named from_numeral associated with it in the type's declaration.

MISSING METHOD This update_strr method is being called on a value whose type doesn't have that method: Adv.md:23:17:23:28:

	next_val = val.update_strr(100)
               ^^^^^^^^^^^

The value's type, which does not have a method named update_strr, is:

_Adv_

Hint: For this to work, the type would need to have a method named update_strr associated with it in the type's declaration.

MISSING METHOD This update method is being called on a value whose type doesn't have that method: Adv.md:28:21:28:27:

	next_val = "Hello".update(100)
                   ^^^^^^

The value's type, which does not have a method named update, is:

_Str_

Hint: For this to work, the type would need to have a method named update associated with it in the type's declaration.

TOKENS

UpperIdent,OpColonEqual,OpenSquare,UpperIdent,NoSpaceOpenRound,UpperIdent,Comma,UpperIdent,CloseRound,CloseSquare,Dot,OpenCurly,
LowerIdent,OpColon,UpperIdent,OpArrow,UpperIdent,
LowerIdent,OpAssign,OpBar,UpperIdent,NoSpaceDotUpperIdent,NoSpaceOpenRound,Underscore,Comma,LowerIdent,CloseRound,OpBar,LowerIdent,
LowerIdent,OpColon,UpperIdent,OpArrow,UpperIdent,
LowerIdent,OpAssign,OpBar,UpperIdent,NoSpaceDotUpperIdent,NoSpaceOpenRound,LowerIdent,Comma,Underscore,CloseRound,OpBar,LowerIdent,
LowerIdent,OpColon,UpperIdent,Comma,UpperIdent,OpArrow,UpperIdent,
LowerIdent,OpAssign,OpBar,UpperIdent,NoSpaceDotUpperIdent,NoSpaceOpenRound,LowerIdent,Comma,Underscore,CloseRound,Comma,LowerIdent,OpBar,UpperIdent,NoSpaceDotUpperIdent,NoSpaceOpenRound,LowerIdent,Comma,LowerIdent,CloseRound,
LowerIdent,OpColon,UpperIdent,Comma,UpperIdent,OpArrow,UpperIdent,
LowerIdent,OpAssign,OpBar,UpperIdent,NoSpaceDotUpperIdent,NoSpaceOpenRound,Underscore,Comma,LowerIdent,CloseRound,Comma,LowerIdent,OpBar,UpperIdent,NoSpaceDotUpperIdent,NoSpaceOpenRound,LowerIdent,Comma,LowerIdent,CloseRound,
CloseCurly,
LowerIdent,OpAssign,OpenCurly,
LowerIdent,OpAssign,UpperIdent,NoSpaceDotUpperIdent,NoSpaceOpenRound,Int,Comma,StringStart,StringPart,StringEnd,CloseRound,
LowerIdent,OpAssign,LowerIdent,NoSpaceDotLowerIdent,NoSpaceOpenRound,Int,CloseRound,
LowerIdent,
CloseCurly,
LowerIdent,OpAssign,OpenCurly,
LowerIdent,OpAssign,UpperIdent,NoSpaceDotUpperIdent,NoSpaceOpenRound,Int,Comma,StringStart,StringPart,StringEnd,CloseRound,
LowerIdent,OpAssign,LowerIdent,NoSpaceDotLowerIdent,NoSpaceOpenRound,Int,CloseRound,
LowerIdent,
CloseCurly,
LowerIdent,OpAssign,OpenCurly,
LowerIdent,OpAssign,StringStart,StringPart,StringEnd,NoSpaceDotLowerIdent,NoSpaceOpenRound,Int,CloseRound,
LowerIdent,
CloseCurly,
LowerIdent,OpColon,OpenRound,UpperIdent,Comma,UpperIdent,CloseRound,
LowerIdent,OpAssign,OpenCurly,
LowerIdent,OpAssign,UpperIdent,NoSpaceDotUpperIdent,NoSpaceOpenRound,Int,Comma,StringStart,StringPart,StringEnd,CloseRound,
LowerIdent,OpAssign,LowerIdent,NoSpaceDotLowerIdent,NoSpaceOpenRound,StringStart,StringPart,StringEnd,CloseRound,NoSpaceDotLowerIdent,NoSpaceOpenRound,Int,CloseRound,
OpenRound,LowerIdent,NoSpaceDotLowerIdent,NoSpaceOpenRound,CloseRound,Comma,LowerIdent,NoSpaceDotLowerIdent,NoSpaceOpenRound,CloseRound,CloseRound,
CloseCurly,
EndOfFile,

PARSE

(file
	(type-module)
	(statements
		(s-type-decl
			(header (name "Adv")
				(args))
			(ty-tag-union
				(tags
					(ty-apply
						(ty (name "Val"))
						(ty (name "U64"))
						(ty (name "Str")))))
			(associated
				(s-type-anno (name "to_str")
					(ty-fn
						(ty (name "Adv"))
						(ty (name "Str"))))
				(s-decl
					(p-ident (raw "to_str"))
					(e-lambda
						(args
							(p-tag (raw ".Val")
								(p-underscore)
								(p-ident (raw "s"))))
						(e-ident (raw "s"))))
				(s-type-anno (name "to_u64")
					(ty-fn
						(ty (name "Adv"))
						(ty (name "U64"))))
				(s-decl
					(p-ident (raw "to_u64"))
					(e-lambda
						(args
							(p-tag (raw ".Val")
								(p-ident (raw "u"))
								(p-underscore)))
						(e-ident (raw "u"))))
				(s-type-anno (name "update_str")
					(ty-fn
						(ty (name "Adv"))
						(ty (name "Str"))
						(ty (name "Adv"))))
				(s-decl
					(p-ident (raw "update_str"))
					(e-lambda
						(args
							(p-tag (raw ".Val")
								(p-ident (raw "u64"))
								(p-underscore))
							(p-ident (raw "next_str")))
						(e-apply
							(e-tag (raw "Adv.Val"))
							(e-ident (raw "u64"))
							(e-ident (raw "next_str")))))
				(s-type-anno (name "update_u64")
					(ty-fn
						(ty (name "Adv"))
						(ty (name "U64"))
						(ty (name "Adv"))))
				(s-decl
					(p-ident (raw "update_u64"))
					(e-lambda
						(args
							(p-tag (raw ".Val")
								(p-underscore)
								(p-ident (raw "str")))
							(p-ident (raw "next_u64")))
						(e-apply
							(e-tag (raw "Adv.Val"))
							(e-ident (raw "next_u64"))
							(e-ident (raw "str")))))))
		(s-decl
			(p-ident (raw "mismatch"))
			(e-block
				(statements
					(s-decl
						(p-ident (raw "val"))
						(e-apply
							(e-tag (raw "Adv.Val"))
							(e-int (raw "10"))
							(e-string
								(e-string-part (raw "hello")))))
					(s-decl
						(p-ident (raw "next_val"))
						(e-field-access
							(e-ident (raw "val"))
							(e-apply
								(e-ident (raw "update_str"))
								(e-int (raw "100")))))
					(e-ident (raw "next_val")))))
		(s-decl
			(p-ident (raw "mismatch2"))
			(e-block
				(statements
					(s-decl
						(p-ident (raw "val"))
						(e-apply
							(e-tag (raw "Adv.Val"))
							(e-int (raw "10"))
							(e-string
								(e-string-part (raw "hello")))))
					(s-decl
						(p-ident (raw "next_val"))
						(e-field-access
							(e-ident (raw "val"))
							(e-apply
								(e-ident (raw "update_strr"))
								(e-int (raw "100")))))
					(e-ident (raw "next_val")))))
		(s-decl
			(p-ident (raw "mismatch3"))
			(e-block
				(statements
					(s-decl
						(p-ident (raw "next_val"))
						(e-field-access
							(e-string
								(e-string-part (raw "Hello")))
							(e-apply
								(e-ident (raw "update"))
								(e-int (raw "100")))))
					(e-ident (raw "next_val")))))
		(s-type-anno (name "main")
			(ty-tuple
				(ty (name "Str"))
				(ty (name "U64"))))
		(s-decl
			(p-ident (raw "main"))
			(e-block
				(statements
					(s-decl
						(p-ident (raw "val"))
						(e-apply
							(e-tag (raw "Adv.Val"))
							(e-int (raw "10"))
							(e-string
								(e-string-part (raw "hello")))))
					(s-decl
						(p-ident (raw "next_val"))
						(e-field-access
							(e-field-access
								(e-ident (raw "val"))
								(e-apply
									(e-ident (raw "update_str"))
									(e-string
										(e-string-part (raw "world")))))
							(e-apply
								(e-ident (raw "update_u64"))
								(e-int (raw "20")))))
					(e-tuple
						(e-field-access
							(e-ident (raw "next_val"))
							(e-apply
								(e-ident (raw "to_str"))))
						(e-field-access
							(e-ident (raw "next_val"))
							(e-apply
								(e-ident (raw "to_u64"))))))))))

FORMATTED

Adv := [Val(U64, Str)].{
	to_str : Adv -> Str
	to_str = |Adv.Val(_, s)| s

	to_u64 : Adv -> U64
	to_u64 = |Adv.Val(u, _)| u

	update_str : Adv, Str -> Adv
	update_str = |Adv.Val(u64, _), next_str| Adv.Val(u64, next_str)

	update_u64 : Adv, U64 -> Adv
	update_u64 = |Adv.Val(_, str), next_u64| Adv.Val(next_u64, str)
}

mismatch = {
	val = Adv.Val(10, "hello")
	next_val = val.update_str(100)
	next_val
}

mismatch2 = {
	val = Adv.Val(10, "hello")
	next_val = val.update_strr(100)
	next_val
}

mismatch3 = {
	next_val = "Hello".update(100)
	next_val
}

main : (Str, U64)
main = {
	val = Adv.Val(10, "hello")
	next_val = val.update_str("world").update_u64(20)
	(next_val.to_str(), next_val.to_u64())
}

CANONICALIZE

(can-ir
	(d-let
		(p-assign (ident "Adv.to_str"))
		(e-lambda
			(args
				(p-nominal
					(p-applied-tag)))
			(e-lookup-local
				(p-assign (ident "s"))))
		(annotation
			(ty-fn (effectful false)
				(ty-lookup (name "Adv") (local))
				(ty-lookup (name "Str") (builtin)))))
	(d-let
		(p-assign (ident "Adv.to_u64"))
		(e-lambda
			(args
				(p-nominal
					(p-applied-tag)))
			(e-lookup-local
				(p-assign (ident "u"))))
		(annotation
			(ty-fn (effectful false)
				(ty-lookup (name "Adv") (local))
				(ty-lookup (name "U64") (builtin)))))
	(d-let
		(p-assign (ident "Adv.update_str"))
		(e-lambda
			(args
				(p-nominal
					(p-applied-tag))
				(p-assign (ident "next_str")))
			(e-nominal (nominal "Adv")
				(e-tag (name "Val")
					(args
						(e-lookup-local
							(p-assign (ident "u64")))
						(e-lookup-local
							(p-assign (ident "next_str")))))))
		(annotation
			(ty-fn (effectful false)
				(ty-lookup (name "Adv") (local))
				(ty-lookup (name "Str") (builtin))
				(ty-lookup (name "Adv") (local)))))
	(d-let
		(p-assign (ident "Adv.update_u64"))
		(e-lambda
			(args
				(p-nominal
					(p-applied-tag))
				(p-assign (ident "next_u64")))
			(e-nominal (nominal "Adv")
				(e-tag (name "Val")
					(args
						(e-lookup-local
							(p-assign (ident "next_u64")))
						(e-lookup-local
							(p-assign (ident "str")))))))
		(annotation
			(ty-fn (effectful false)
				(ty-lookup (name "Adv") (local))
				(ty-lookup (name "U64") (builtin))
				(ty-lookup (name "Adv") (local)))))
	(d-let
		(p-assign (ident "mismatch"))
		(e-block
			(s-let
				(p-assign (ident "val"))
				(e-nominal (nominal "Adv")
					(e-tag (name "Val")
						(args
							(e-num (value "10"))
							(e-string
								(e-literal (string "hello")))))))
			(s-let
				(p-assign (ident "next_val"))
				(e-dot-access (field "update_str")
					(receiver
						(e-lookup-local
							(p-assign (ident "val"))))
					(args
						(e-num (value "100")))))
			(e-lookup-local
				(p-assign (ident "next_val")))))
	(d-let
		(p-assign (ident "mismatch2"))
		(e-block
			(s-let
				(p-assign (ident "val"))
				(e-nominal (nominal "Adv")
					(e-tag (name "Val")
						(args
							(e-num (value "10"))
							(e-string
								(e-literal (string "hello")))))))
			(s-let
				(p-assign (ident "next_val"))
				(e-dot-access (field "update_strr")
					(receiver
						(e-lookup-local
							(p-assign (ident "val"))))
					(args
						(e-num (value "100")))))
			(e-lookup-local
				(p-assign (ident "next_val")))))
	(d-let
		(p-assign (ident "mismatch3"))
		(e-block
			(s-let
				(p-assign (ident "next_val"))
				(e-dot-access (field "update")
					(receiver
						(e-string
							(e-literal (string "Hello"))))
					(args
						(e-num (value "100")))))
			(e-lookup-local
				(p-assign (ident "next_val")))))
	(d-let
		(p-assign (ident "main"))
		(e-block
			(s-let
				(p-assign (ident "val"))
				(e-nominal (nominal "Adv")
					(e-tag (name "Val")
						(args
							(e-num (value "10"))
							(e-string
								(e-literal (string "hello")))))))
			(s-let
				(p-assign (ident "next_val"))
				(e-dot-access (field "update_u64")
					(receiver
						(e-dot-access (field "update_str")
							(receiver
								(e-lookup-local
									(p-assign (ident "val"))))
							(args
								(e-string
									(e-literal (string "world"))))))
					(args
						(e-num (value "20")))))
			(e-tuple
				(elems
					(e-dot-access (field "to_str")
						(receiver
							(e-lookup-local
								(p-assign (ident "next_val"))))
						(args))
					(e-dot-access (field "to_u64")
						(receiver
							(e-lookup-local
								(p-assign (ident "next_val"))))
						(args)))))
		(annotation
			(ty-tuple
				(ty-lookup (name "Str") (builtin))
				(ty-lookup (name "U64") (builtin)))))
	(s-nominal-decl
		(ty-header (name "Adv"))
		(ty-tag-union
			(ty-tag-name (name "Val")
				(ty-lookup (name "U64") (builtin))
				(ty-lookup (name "Str") (builtin))))))

TYPES

(inferred-types
	(defs
		(patt (type "Adv -> Str"))
		(patt (type "Adv -> U64"))
		(patt (type "Adv, Str -> Adv"))
		(patt (type "Adv, U64 -> Adv"))
		(patt (type "Adv"))
		(patt (type "Error"))
		(patt (type "Error"))
		(patt (type "(Str, U64)")))
	(type_decls
		(nominal (type "Adv")
			(ty-header (name "Adv"))))
	(expressions
		(expr (type "Adv -> Str"))
		(expr (type "Adv -> U64"))
		(expr (type "Adv, Str -> Adv"))
		(expr (type "Adv, U64 -> Adv"))
		(expr (type "Adv"))
		(expr (type "Error"))
		(expr (type "Error"))
		(expr (type "(Str, U64)"))))