M cmd/goast/main.go => cmd/goast/main.go +4 -2
@@ 10,9 10,11 @@ func main() {
src := `
package main
+type I interface {
+ foo(int) int
+}
+
func main() {
- s := map[string]bool{"a": true}
- _ = s
}
`
M pkg/ast/ast.go => pkg/ast/ast.go +30 -15
@@ 39,7 39,7 @@ type (
Name *Ident
GenericParams *GenericClause // possibly nil
Signature *FnSig
- Body *Block // possibly nil for external func declarations
+ Body *Block // possibly nil for external func declarations or methods in interface decls
}
// Block represents a block of statements, including the surrounding braces.
@@ 66,6 66,16 @@ type (
Rbrace token.Pos
}
+ // InterfaceDecl represents a InterfaceDecl production.
+ InterfaceDecl struct {
+ Interface token.Pos
+ Name *Ident
+ GenericParams *GenericClause // possibly nil
+ Lbrace token.Pos
+ Methods []*FnDecl
+ Rbrace token.Pos
+ }
+
// ReturnStmt represents a ReturnStmt production.
ReturnStmt struct {
Ret token.Pos
@@ 302,16 312,17 @@ type Stmt interface {
stmtNode()
}
-func (f *FnDecl) stmtNode() {}
-func (v *VarDecl) stmtNode() {}
-func (s *StructDecl) stmtNode() {}
-func (r *ReturnStmt) stmtNode() {}
-func (b *BadStmt) stmtNode() {}
-func (b *Block) stmtNode() {}
-func (a *AssignStmt) stmtNode() {}
-func (e *ExprStmt) stmtNode() {}
-func (i *IfStmt) stmtNode() {}
-func (g *GuardStmt) stmtNode() {}
+func (f *FnDecl) stmtNode() {}
+func (v *VarDecl) stmtNode() {}
+func (s *StructDecl) stmtNode() {}
+func (i *InterfaceDecl) stmtNode() {}
+func (r *ReturnStmt) stmtNode() {}
+func (b *BadStmt) stmtNode() {}
+func (b *Block) stmtNode() {}
+func (a *AssignStmt) stmtNode() {}
+func (e *ExprStmt) stmtNode() {}
+func (i *IfStmt) stmtNode() {}
+func (g *GuardStmt) stmtNode() {}
// Decl represents a symbol declaration statement in the AST.
type Decl interface {
@@ 319,10 330,11 @@ type Decl interface {
declNode()
}
-func (f *FnDecl) declNode() {}
-func (v *VarDecl) declNode() {}
-func (s *StructDecl) declNode() {}
-func (b *BadStmt) declNode() {}
+func (f *FnDecl) declNode() {}
+func (v *VarDecl) declNode() {}
+func (s *StructDecl) declNode() {}
+func (i *InterfaceDecl) declNode() {}
+func (b *BadStmt) declNode() {}
// The rest of the file implements the Pos and End methods on every node.
@@ 449,6 461,9 @@ func (v *VarDef) End() token.Pos {
func (s *StructDecl) Pos() token.Pos { return s.Struct }
func (s *StructDecl) End() token.Pos { return s.Rbrace + 1 }
+func (i *InterfaceDecl) Pos() token.Pos { return i.Interface }
+func (i *InterfaceDecl) End() token.Pos { return i.Rbrace + 1 }
+
func (r *ReturnStmt) Pos() token.Pos { return r.Ret }
func (r *ReturnStmt) End() token.Pos {
if r.Value != nil {
M pkg/ast/visitor.go => pkg/ast/visitor.go +11 -0
@@ 119,6 119,17 @@ func Walk(v Visitor, node Node) {
Walk(v, decl)
}
+ case *InterfaceDecl:
+ if n.Name != nil {
+ Walk(v, n.Name)
+ }
+ if n.GenericParams != nil {
+ Walk(v, n.GenericParams)
+ }
+ for _, meth := range n.Methods {
+ Walk(v, meth)
+ }
+
case *ReturnStmt:
if n.Value != nil {
Walk(v, n.Value)
M pkg/codegen/mangle.go => pkg/codegen/mangle.go +21 -1
@@ 89,6 89,10 @@ func mangle(unit *semantic.Unit) *nameResolver {
case *semantic.Struct:
b.withPrefixFor(decl)
names[decl] = b.get(decl.Ident())
+
+ case *semantic.Interface:
+ b.withPrefixFor(decl)
+ names[decl] = b.get(decl.Ident())
}
}
return true
@@ 121,6 125,13 @@ func (r *nameResolver) NameForStructType(st *semantic.StructType, resolve map[*s
return r.NameForGenericDeclAndTypes(st.Decl, st.Inst, resolve)
}
+func (r *nameResolver) NameForInterfaceType(it *semantic.InterfaceType, resolve map[*semantic.GenericType]semantic.Type) string {
+ if !it.Decl.IsGeneric() {
+ return r.NameForDecl(it.Decl)
+ }
+ return r.NameForGenericDeclAndTypes(it.Decl, it.Inst, resolve)
+}
+
func (r *nameResolver) NameForGenericInst(gi *semantic.GenericInst, resolve map[*semantic.GenericType]semantic.Type) string {
gd := gi.GenericDecl.Ref.(semantic.GenericDecl)
_, insts := gd.GenInsts()
@@ 196,7 207,9 @@ type fmtBuilder struct {
func (b *fmtBuilder) withPrefixFor(decl semantic.Decl) {
switch decl := decl.(type) {
case *semantic.Fn:
- if decl.Scope().IsTopLevel() || decl.MethodOf != nil {
+ if decl.Scope().IsTopLevel() || decl.MethodOf != nil || decl.AbstractMethodOf != nil {
+ // TODO: this will be an issue with pub/exported methods eventually: the mangling of
+ // an interface method might not match the one of an otherwise matching struct method.
b.withExport(false)
}
case *semantic.Var:
@@ 208,6 221,13 @@ func (b *fmtBuilder) withPrefixFor(decl semantic.Decl) {
if !decl.Scope().IsTopLevel() {
b.withScope(decl.Scope())
}
+ case *semantic.Interface:
+ b.withExport(false)
+ if !decl.Scope().IsTopLevel() {
+ b.withScope(decl.Scope())
+ }
+ default:
+ panic(fmt.Sprintf("invalid declaration type for mangler prefix: %T", decl))
}
}
M pkg/codegen/position.go => pkg/codegen/position.go +2 -0
@@ 130,6 130,8 @@ func (p *positioner) Visit(n goast.Node) goast.Visitor {
return nil
case *goast.IfStmt:
n.If = p.getIncByLen("if ")
+ case *goast.InterfaceType:
+ n.Interface = p.getIncByLen("interface ")
}
return p
}
A pkg/codegen/testdata/fn_assign_call_interface.snow => pkg/codegen/testdata/fn_assign_call_interface.snow +30 -0
@@ 0,0 1,30 @@
+interface I {
+ fn foo()
+}
+
+struct S {
+ let s: string
+
+ fn foo() {
+ println(s)
+ }
+
+ struct S2 {
+ fn foo() {
+ println("s2")
+ }
+ }
+}
+
+@extern(import: "fmt", symbol: "Println")
+fn println(s: string)
+
+fn main() {
+ var iface: I = S(s: "hello!")
+ iface.foo()
+ iface = S.S2()
+ iface.foo()
+}
+
+#=hello!
+#=s2
A pkg/codegen/testdata/fn_assign_call_interface.snow.err => pkg/codegen/testdata/fn_assign_call_interface.snow.err +0 -0
A pkg/codegen/testdata/fn_assign_call_interface.snow.want => pkg/codegen/testdata/fn_assign_call_interface.snow.want +58 -0
@@ 0,0 1,58 @@
+package main
+
+import "fmt"
+
+type _اS struct {
+ _اs string
+}
+
+func (
+ self _اS,
+) _اfoo() {
+ _اprintln(self._اs)
+}
+
+type _ا6اS2 struct {
+}
+
+func (
+ self _ا6اS2,
+) _اfoo() {
+ _اprintln("s2")
+}
+
+func _ا6اS2اnew(
+ s _ا6اS2,
+ m map[string]bool,
+) _ا6اS2 {
+ var r _ا6اS2
+ return r
+}
+
+func _اSاnew(
+ s _اS,
+ m map[string]bool,
+) _اS {
+ var r _اS
+ if m["s"] {
+ r._اs = s._اs
+ }
+ return r
+}
+
+func _اprintln(
+ s string,
+) {
+ fmt.Println(s)
+}
+
+func main() {
+ var iface _اI = _اSاnew(_اS{_اs: "hello!"}, map[string]bool{"s": true})
+ iface._اfoo()
+ iface = _ا6اS2اnew(_ا6اS2{}, map[string]bool{})
+ iface._اfoo()
+}
+
+type _اI interface {
+ _اfoo()
+}
A pkg/codegen/testdata/fn_interface_with_ref_method.snow.notyet => pkg/codegen/testdata/fn_interface_with_ref_method.snow.notyet +28 -0
@@ 0,0 1,28 @@
+interface I {
+ fn foo()
+}
+
+struct S {
+ var i: int
+ ref fn foo() {
+ i = i + 1
+ }
+}
+
+fn main() {
+ var s = S(i: 0)
+ let iface: I = s
+ iface.foo()
+ println(s.i)
+
+ # this should work, s is mutable
+ let tup: (int, I) = (1, s)
+ tup.1.foo()
+ println(s.i)
+}
+
+@extern(import: "fmt", symbol: "Println")
+fn println(v: int)
+
+#=1
+#=2
M pkg/codegen/translate.go => pkg/codegen/translate.go +84 -10
@@ 124,6 124,9 @@ func (t *translator) Visit(n semantic.Node) semantic.Visitor {
for _, fn := range n.Fns {
semantic.Walk(t, fn)
}
+ for _, iface := range n.Interfaces {
+ semantic.Walk(t, iface)
+ }
})
// ************** DECLARATIONS *****************
@@ 169,6 172,16 @@ func (t *translator) Visit(n semantic.Node) semantic.Visitor {
Specs: []goast.Spec{vs},
})
+ case *semantic.Interface:
+ if n.IsGeneric() {
+ // go nodes will be generated only on instantiation, create an empty container for now
+ m := &mark{list: t.topLevel, elem: t.topLevel.PushBack(newContainer(n))}
+ t.genDeclMarks[n] = m
+ break
+ }
+ name := t.resolver.NameForDecl(n)
+ t.createInterface(name, semantic.AsInterfaceType(n.Type()))
+
// ************** STATEMENTS *****************
case *semantic.Block:
@@ 408,21 421,22 @@ func (t *translator) createFn(nm string, fn *semantic.Fn) {
var body *goast.BlockStmt
t.withContainer(cont, func() {
- if fn.Body == nil {
- body = createExternalFnBody(ft, t.fnImports[fn])
- } else {
+ if fn.Body != nil {
semantic.Walk(t, fn.Body)
+ } else if fn.AbstractMethodOf == nil {
+ // this is an external function
+ body = createExternalFnBody(ft, t.fnImports[fn])
}
})
// the function declaration is a top-level func statement if it is top-level
// in snow or is a struct method.
+ fd := &goast.FuncDecl{
+ Name: &goast.Ident{Name: nm},
+ Type: ft,
+ Body: body,
+ }
if fn.Scope().IsTopLevel() || fn.MethodOf != nil {
- fd := &goast.FuncDecl{
- Name: &goast.Ident{Name: nm},
- Type: ft,
- Body: body,
- }
if str := fn.MethodOf; str != nil {
t.convertFuncToMethod(fd, str, fn.IsRef)
}
@@ 434,6 448,14 @@ func (t *translator) createFn(nm string, fn *semantic.Fn) {
t.topLevel.PushBack(cont)
}
return
+
+ }
+ if fn.AbstractMethodOf != nil {
+ // if it is an interface method, create the function declaration inside the
+ // interface's container. It cannot be a generic itself (only the interface can).
+ cont.nodes = []goast.Node{fd}
+ t.parentContainer.PushBack(cont)
+ return
}
cont.nodes = createFuncLit(nm, ft, body)
@@ 499,13 521,16 @@ func (t *translator) createStruct(nm string, strTyp *semantic.StructType) {
// generate struct initializer function
strInit := t.createStructInit(nm, strTyp, propInit)
- // generate methods and nested structs
+ // generate methods and nested structs and interfaces
for _, meth := range strTyp.Decl.Fns {
semantic.Walk(t, meth)
}
for _, str := range strTyp.Decl.Structs {
semantic.Walk(t, str)
}
+ for _, iface := range strTyp.Decl.Interfaces {
+ semantic.Walk(t, iface)
+ }
if mark := t.genDeclMarks[strTyp.Decl]; mark != nil {
mark.list.InsertBefore(strInit, mark.elem)
@@ 514,6 539,40 @@ func (t *translator) createStruct(nm string, strTyp *semantic.StructType) {
}
}
+func (t *translator) createInterface(nm string, ifaceTyp *semantic.InterfaceType) {
+ // all interface declarations are attached to the top-level scope of the file.
+ fields := &goast.FieldList{List: make([]*goast.Field, len(ifaceTyp.Decl.Methods))}
+
+ // create the container but don't set its Go node yet, it will be created
+ // only after looping over the methods.
+ cont := &container{snode: ifaceTyp.Decl, children: list.New()}
+
+ t.withContainer(cont, func() {
+ for i, m := range ifaceTyp.Decl.Methods {
+ semantic.Walk(t, m)
+ node := t.parentContainer.Back().Value
+ fnDecl := node.(*container).nodes[0].(*goast.FuncDecl)
+ fields.List[i] = &goast.Field{
+ Names: []*goast.Ident{fnDecl.Name},
+ Type: fnDecl.Type,
+ }
+ }
+ })
+
+ decl := &goast.GenDecl{
+ Tok: gotoken.TYPE,
+ Specs: []goast.Spec{
+ &goast.TypeSpec{Name: &goast.Ident{Name: nm}, Type: &goast.InterfaceType{Methods: fields}},
+ },
+ }
+ cont.nodes = []goast.Node{decl}
+ if mark := t.genDeclMarks[ifaceTyp.Decl]; mark != nil {
+ mark.list.InsertBefore(cont, mark.elem)
+ } else {
+ t.topLevel.PushBack(cont)
+ }
+}
+
func (t *translator) addFileImports(f *semantic.File, gof *goast.File) {
imports := t.fileImports[f]
set := make(map[string]bool, len(imports))
@@ 569,7 628,6 @@ func (t *translator) goTypeExprFor(T semantic.Type) goast.Expr {
}
for i, field := range T.Fields {
st.Fields.List[i] = &goast.Field{
- // TODO: for now, always unexported?
Names: []*goast.Ident{{Name: t.resolver.NameForTuple(i, false)}},
Type: t.goTypeExprFor(field),
}
@@ 580,6 638,10 @@ func (t *translator) goTypeExprFor(T semantic.Type) goast.Expr {
name := t.resolver.NameForStructType(T, t.curGenInst)
return &goast.Ident{Name: name}
+ case *semantic.InterfaceType:
+ name := t.resolver.NameForInterfaceType(T, t.curGenInst)
+ return &goast.Ident{Name: name}
+
default:
panic(fmt.Sprintf("invalid type: %T", T))
}
@@ 595,6 657,16 @@ func (t *translator) reconcileExprWith(LT, RT semantic.Type, expr goast.Expr) go
func (t *translator) convertExprFromTo(expr goast.Expr, fromT, toT semantic.Type) goast.Expr {
var convertCallExpr goast.Expr
+ // if toT is an interface, no explicit conversion needed, Go will be able to assign fromT
+ // to it (as the rules for assignability are the same). Only thing is if one of the methods
+ // is satisfied by a ref function, the address of expr must be returned instead.
+ if semantic.AsInterfaceType(toT) != nil {
+ if st := semantic.AsStructType(fromT); st != nil && st.Ctx == semantic.Mutable {
+ return &goast.UnaryExpr{Op: gotoken.AND, X: expr}
+ }
+ return expr
+ }
+
fromTupT, ok1 := fromT.(*semantic.TupleType)
toTupT, ok2 := toT.(*semantic.TupleType)
if ok1 && ok2 {
@@ 819,6 891,8 @@ func (t *translator) renderGenInst(gi *semantic.GenericInst, name string) {
t.createFn(name, decl)
case *semantic.Struct:
t.createStruct(name, semantic.AsStructType(gi.Type()))
+ case *semantic.Interface:
+ t.createInterface(name, semantic.AsInterfaceType(gi.Type()))
default:
panic(fmt.Sprintf("invalid generic type to render: %T", decl))
}
M pkg/codegen/treebuild.go => pkg/codegen/treebuild.go +3 -0
@@ 99,6 99,9 @@ func (tb *treebuilder) Visit(n semantic.Node) semantic.Visitor {
case *semantic.Struct:
// a struct container has a single Go node, the struct decl, and it is fully
// formed, no need to append children, so nothing to do.
+ case *semantic.Interface:
+ // an interface container has a single Go node, the interface decl, and it is fully
+ // formed, no need to append children, so nothing to do.
case *semantic.Block:
cont := tb.curContainer
M pkg/grammar/grammar.ebnf => pkg/grammar/grammar.ebnf +5 -1
@@ 20,7 20,7 @@ GenericArgClause = "[" TypeList [ "," ] "]" .
// => Statements
TopLevelStmt = Declaration .
Stmt = Declaration | SimpleStmt | Block | ReturnStmt | BranchStmt .
-Declaration = VarDecl | FuncDecl | StructDecl .
+Declaration = VarDecl | FuncDecl | StructDecl | InterfaceDecl .
SimpleStmt = ExprStmt | AssignStmt | EmptyStmt .
// => Variable declaration statement
@@ 46,6 46,10 @@ FuncTrailer = "->" Type .
StructDecl = "struct" ident [ GenericParamClause ] "{" StructDeclBody "}" .
StructDeclBody = { Declaration } .
+// => Interface type declaration statement
+InterfaceDecl = "interface" ident [ GenericParamClause ] "{" InterfaceBody "}" .
+InterfaceBody = { FuncDecl } . // the parser will make sure there is no attribute, generic clause and body
+
// => Assignment statement
AssignStmt = Expr "=" Expr .
M pkg/parser/parser.go => pkg/parser/parser.go +35 -0
@@ 109,6 109,8 @@ func (p *parser) parseDecl(errLabel string, syncSet map[token.Token]bool) ast.De
return p.parseFuncDecl()
case token.Struct:
return p.parseStructDecl()
+ case token.Interface:
+ return p.parseInterfaceDecl()
default:
pos := p.pos
p.errorExpected(pos, errLabel)
@@ 786,6 788,39 @@ func (p *parser) parseStructDecl() *ast.StructDecl {
return str
}
+func (p *parser) parseInterfaceDecl() *ast.InterfaceDecl {
+ id := &ast.InterfaceDecl{
+ Interface: p.expect(token.Interface),
+ }
+ id.Name = p.parseIdent()
+ if p.tok == token.Lbrack {
+ id.GenericParams = p.parseGenericClause(genericClauseParams)
+ }
+ id.Lbrace = p.expect(token.Lbrace)
+
+ var methods []*ast.FnDecl
+ for !tokenIn(p.tok, token.Rbrace, token.EOF) {
+ fn := p.parseFuncDecl()
+ if len(fn.Attrs) > 0 {
+ p.error(fn.Pos(), "interface method cannot have attributes")
+ }
+ if fn.Ref.IsValid() {
+ p.error(fn.Pos(), "interface method cannot be marked as ref")
+ }
+ if fn.GenericParams != nil {
+ p.error(fn.Pos(), "interface method cannot have a generic clause (the interface itself can)")
+ }
+ if fn.Body != nil {
+ p.error(fn.Pos(), "interface method cannot have a body")
+ }
+ methods = append(methods, fn)
+ }
+ id.Methods = methods
+ id.Rbrace = p.expect(token.Rbrace)
+ p.expectSemi()
+ return id
+}
+
type genericClauseMode int
const (
A pkg/parser/testdata/interface.snow => pkg/parser/testdata/interface.snow +6 -0
@@ 0,0 1,6 @@
+interface I {}
+
+interface J[$T, $U] {
+ ref fn foo(t: $T, u: $U)
+ fn bar() -> ($T, $U)
+}
A pkg/parser/testdata/interface.snow.err => pkg/parser/testdata/interface.snow.err +1 -0
@@ 0,0 1,1 @@
+testdata/interface.snow:4:3: interface method cannot be marked as ref
A pkg/parser/testdata/interface.snow.want => pkg/parser/testdata/interface.snow.want +27 -0
@@ 0,0 1,27 @@
+file [2, #0] [0:89]
+ interface [0] [0:14]
+ ident [I] [10:11]
+ interface [2] [16:89]
+ ident [J] [26:27]
+ generic [27:35]
+ param [28:31]
+ ident [$T] [28:30]
+ param [32:34]
+ ident [$U] [32:34]
+ ref fn [40:64]
+ ident [foo] [47:50]
+ sig [2->0] [50:64]
+ param [51:57]
+ ident [t] [51:52]
+ ident [$T] [54:56]
+ param [58:63]
+ ident [u] [58:59]
+ ident [$U] [61:63]
+ fn [67:87]
+ ident [bar] [70:73]
+ sig [0->1] [73:87]
+ tuple type [2] [79:87]
+ param [80:83]
+ ident [$T] [80:82]
+ param [84:86]
+ ident [$U] [84:86]
A pkg/parser/testdata/invalid_interface.snow => pkg/parser/testdata/invalid_interface.snow +10 -0
@@ 0,0 1,10 @@
+interface I {
+ @external(x: 1, y: "a")
+ fn foo()
+
+ fn bar() {
+ foo()
+ }
+
+ fn quz[$T](t: $T)
+}
A pkg/parser/testdata/invalid_interface.snow.err => pkg/parser/testdata/invalid_interface.snow.err +3 -0
@@ 0,0 1,3 @@
+testdata/invalid_interface.snow:2:3: interface method cannot have attributes
+testdata/invalid_interface.snow:5:3: interface method cannot have a body
+testdata/invalid_interface.snow:9:3: interface method cannot have a generic clause (the interface itself can)
A pkg/parser/testdata/invalid_interface.snow.want => pkg/parser/testdata/invalid_interface.snow.want +30 -0
@@ 0,0 1,30 @@
+file [1, #0] [0:101]
+ interface [3] [0:101]
+ ident [I] [10:11]
+ fn [16:50]
+ @ [2] [16:39]
+ ident [external] [17:25]
+ field [26:31]
+ ident [x] [26:27]
+ int [1] [29:30]
+ field [32:38]
+ ident [y] [32:33]
+ string ["a"] [35:38]
+ ident [foo] [45:48]
+ sig [0->0] [48:50]
+ fn [54:78]
+ ident [bar] [57:60]
+ sig [0->0] [60:62]
+ block [1] [63:78]
+ expr [69:74]
+ call [0] [69:74]
+ ident [foo] [69:72]
+ fn [82:99]
+ ident [quz] [85:88]
+ generic [88:92]
+ param [89:91]
+ ident [$T] [89:91]
+ sig [1->0] [92:99]
+ param [93:98]
+ ident [t] [93:94]
+ ident [$T] [96:98]
M pkg/parser/testdata/var_kw_as_ident.snow.err => pkg/parser/testdata/var_kw_as_ident.snow.err +1 -0
@@ 6,3 6,4 @@ testdata/var_kw_as_ident.snow:5:5: expected 'ident', found 'if'
testdata/var_kw_as_ident.snow:6:5: expected 'ident', found 'guard'
testdata/var_kw_as_ident.snow:7:5: expected 'ident', found 'else'
testdata/var_kw_as_ident.snow:8:5: expected 'ident', found 'struct'
+testdata/var_kw_as_ident.snow:23:5: expected 'ident', found 'interface'
M pkg/parser/testdata/var_kw_as_ident.snow.want => pkg/parser/testdata/var_kw_as_ident.snow.want +2 -2
@@ 84,8 84,8 @@ file [28, #0] [0:444]
ident [import] [314:320]
ident [f32] [322:325]
let [327:345]
- interface: [331:345]
- ident [interface] [331:340]
+ : [331:345]
+ ident [] [331:331]
ident [f64] [342:345]
let [347:362]
map: [351:362]
M pkg/printer/printer.go => pkg/printer/printer.go +15 -3
@@ 155,7 155,8 @@ func (p *semanticPrinter) Visit(n semantic.Node) semantic.Visitor {
switch n := n.(type) {
case *semantic.File:
- p.printMsg(fmt.Sprintf("file %s [%d, %d, %d]", p.file.Name(), len(n.Vars), len(n.Fns), len(n.Structs)), true)
+ p.printMsg(fmt.Sprintf("file %s [%d, %d, %d, %d]",
+ p.file.Name(), len(n.Vars), len(n.Fns), len(n.Structs), len(n.Interfaces)), true)
case *semantic.Fn:
format := "fn %s"
args := []interface{}{n.Ident()}
@@ 177,8 178,17 @@ func (p *semanticPrinter) Visit(n semantic.Node) semantic.Visitor {
}
p.printMsg(fmt.Sprintf("%s %s", lbl, n.Ident()), true)
case *semantic.Struct:
- format := "struct %s [%d, %d, %d"
- args := []interface{}{n.Ident(), len(n.Vars), len(n.Fns), len(n.Structs)}
+ format := "struct %s [%d, %d, %d, %d"
+ args := []interface{}{n.Ident(), len(n.Vars), len(n.Fns), len(n.Structs), len(n.Interfaces)}
+ if n.GenericParams != nil {
+ format += ", $%d"
+ args = append(args, len(n.GenericParams.Elems))
+ }
+ format += "]"
+ p.printMsg(fmt.Sprintf(format, args...), true)
+ case *semantic.Interface:
+ format := "interface %s [%d"
+ args := []interface{}{n.Ident(), len(n.Methods)}
if n.GenericParams != nil {
format += ", $%d"
args = append(args, len(n.GenericParams.Elems))
@@ 326,6 336,8 @@ func (p *astPrinter) Visit(n ast.Node) ast.Visitor {
p.printMsg(lbl, true)
case *ast.StructDecl:
p.printMsg(fmt.Sprintf("struct [%d]", len(n.Decls)), true)
+ case *ast.InterfaceDecl:
+ p.printMsg(fmt.Sprintf("interface [%d]", len(n.Methods)), true)
case *ast.ReturnStmt:
p.printMsg("return", true)
case *ast.BinaryExpr:
M pkg/scanner/scanner_test.go => pkg/scanner/scanner_test.go +7 -0
@@ 313,6 313,13 @@ func TestScanner(t *testing.T) {
},
1,
},
+ {
+ "interface",
+ []tokLit{
+ {token.Interface, "interface"},
+ },
+ 0,
+ },
}
for i, c := range cases {
t.Run(fmt.Sprintf("%d: %s", i, c.in), func(t *testing.T) {
M pkg/semantic/scope.go => pkg/semantic/scope.go +1 -1
@@ 101,7 101,7 @@ func newScope(owner Node, parent *Scope) *Scope {
}
orderInd = true
- case *Fn, *If, *Guard, *Block:
+ case *Fn, *If, *Guard, *Block, *Interface:
if parent == nil {
panic(fmt.Sprintf("universe scope created with invalid owner %T", owner))
}
M pkg/semantic/semantic.go => pkg/semantic/semantic.go +71 -9
@@ 55,6 55,7 @@ type Typed interface {
Node
Type() Type
TypeContext() TypeContext
+ setType(T Type)
}
type Expr interface {
@@ 71,6 72,7 @@ type commonExpr struct {
func (c commonExpr) Type() Type { return c.typ }
func (c commonExpr) TypeContext() TypeContext { return c.ctx }
func (c commonExpr) expr() {}
+func (c *commonExpr) setType(T Type) { c.typ = T }
type Decl interface {
Typed
@@ 93,6 95,11 @@ type GenericDecl interface {
// values. This is so that the caller can loop over the sorted slice and
// process the map in deterministic order.
GenInsts() ([]*GenericInst, map[*GenericInst][]Type)
+
+ // Instantiate returns the type of the GenericDecl on which it is called once
+ // instantiated by the GenericInst, with the specified Types and the map of
+ // generic type to resolved type.
+ Instantiate(*GenericInst, []Type, map[*GenericType]Type) Type
}
type commonDecl struct {
@@ 105,6 112,7 @@ func (c commonDecl) Ident() string { return c.ident }
func (c commonDecl) Type() Type { return c.typ }
func (c commonDecl) IsGeneric() bool { return false }
func (c commonDecl) decl() {}
+func (c *commonDecl) setType(T Type) { c.typ = T }
func AsFnDecl(n Node) *Fn {
if fn, ok := n.(*Fn); ok {
@@ 129,9 137,10 @@ type Unit struct {
}
type File struct {
- Vars []*Var
- Fns []*Fn
- Structs []*Struct
+ Vars []*Var
+ Fns []*Fn
+ Structs []*Struct
+ Interfaces []*Interface
commonNode
}
@@ 146,14 155,16 @@ type Fn struct {
ReturnExpr Expr // possibly nil, not a resolved Type, but the Expr of the return
Body *Block // possibly nil
- MethodOf *Struct // set during translation pass
- IsRef bool // set during translation pass
+ MethodOf *Struct // set during translation pass
+ AbstractMethodOf *Interface // set during translation pass
+ IsRef bool // set during translation pass
commonDecl
}
func (fn *Fn) TypeContext() TypeContext { return Immutable }
func (fn *Fn) IsGeneric() bool { return fn.GenericParams != nil }
func (fn *Fn) GenClause() *GenericClause { return fn.GenericParams }
+
func (fn *Fn) GenInsts() ([]*GenericInst, map[*GenericInst][]Type) {
gis := make([]*GenericInst, 0, len(fn.GenericInsts))
for gi := range fn.GenericInsts {
@@ 166,6 177,14 @@ func (fn *Fn) GenInsts() ([]*GenericInst, map[*GenericInst][]Type) {
return gis, fn.GenericInsts
}
+func (fn *Fn) Instantiate(gi *GenericInst, types []Type, resolve map[*GenericType]Type) Type {
+ if fn.GenericInsts == nil {
+ fn.GenericInsts = make(map[*GenericInst][]Type)
+ }
+ fn.GenericInsts[gi] = types
+ return fn.Type().ResolveGeneric(resolve)
+}
+
type Var struct {
Ctx TypeContext // only mutable or immutable for Var, set during translation pass
TypeExpr Expr // possibly nil, not a resolved Type, but the Expr assigned to var in `var x: int`
@@ 180,14 199,16 @@ func (v *Var) TypeContext() TypeContext { return v.Ctx }
// Struct is also used to declare the pre-defined attributes (currently just
// @extern), even though just Vars can be declared on those. This is TBD if
// it stays this way, but the current thinking is that attributes will be
-// structs with a special trait.
+// structs with some compiler magic.
type Struct struct {
GenericParams *GenericClause // set during translation pass
GenericInsts map[*GenericInst][]Type // set during type-assign pass, each distinct instantiation is recorded here
- Vars []*Var
- Fns []*Fn
- Structs []*Struct
+ Vars []*Var
+ Fns []*Fn
+ Structs []*Struct
+ Interfaces []*Interface
+
// BodyScope is the scope for the content of the struct (unlike Struct.Scope
// which is the scope where the struct is defined).
BodyScope *Scope
@@ 197,6 218,7 @@ type Struct struct {
func (s *Struct) TypeContext() TypeContext { return Typ }
func (s *Struct) IsGeneric() bool { return s.GenericParams != nil }
func (s *Struct) GenClause() *GenericClause { return s.GenericParams }
+
func (s *Struct) GenInsts() ([]*GenericInst, map[*GenericInst][]Type) {
gis := make([]*GenericInst, 0, len(s.GenericInsts))
for gi := range s.GenericInsts {
@@ 209,6 231,46 @@ func (s *Struct) GenInsts() ([]*GenericInst, map[*GenericInst][]Type) {
return gis, s.GenericInsts
}
+func (s *Struct) Instantiate(gi *GenericInst, types []Type, resolve map[*GenericType]Type) Type {
+ if s.GenericInsts == nil {
+ s.GenericInsts = make(map[*GenericInst][]Type)
+ }
+ s.GenericInsts[gi] = types
+ return &StructType{Decl: s, Inst: types}
+}
+
+type Interface struct {
+ GenericParams *GenericClause // set during translation pass
+ GenericInsts map[*GenericInst][]Type // set during type-assign pass, each distinct instantiation is recorded here
+
+ Methods []*Fn
+ commonDecl
+}
+
+func (i *Interface) TypeContext() TypeContext { return Typ }
+func (i *Interface) IsGeneric() bool { return i.GenericParams != nil }
+func (i *Interface) GenClause() *GenericClause { return i.GenericParams }
+
+func (i *Interface) GenInsts() ([]*GenericInst, map[*GenericInst][]Type) {
+ gis := make([]*GenericInst, 0, len(i.GenericInsts))
+ for gi := range i.GenericInsts {
+ gis = append(gis, gi)
+ }
+ sort.Slice(gis, func(i, j int) bool {
+ l, r := gis[i], gis[j]
+ return l.Pos() < r.Pos()
+ })
+ return gis, i.GenericInsts
+}
+
+func (i *Interface) Instantiate(gi *GenericInst, types []Type, resolve map[*GenericType]Type) Type {
+ if i.GenericInsts == nil {
+ i.GenericInsts = make(map[*GenericInst][]Type)
+ }
+ i.GenericInsts[gi] = types
+ return &InterfaceType{Decl: i, Inst: types}
+}
+
type GenericElem struct {
commonDecl
}
M pkg/semantic/testdata/check/cycle.snow.want => pkg/semantic/testdata/check/cycle.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/cycle.snow [3, 0, 0]
+file testdata/cycle.snow [3, 0, 0, 0]
var= A [var: unresolved]
ident B [var: unresolved]
var= B [var: unresolved]
M pkg/semantic/testdata/check/empty.snow.want => pkg/semantic/testdata/check/empty.snow.want +1 -1
@@ 1,1 1,1 @@
-file testdata/empty.snow [0, 0, 0]
+file testdata/empty.snow [0, 0, 0, 0]
M pkg/semantic/testdata/check/fn.snow.want => pkg/semantic/testdata/check/fn.snow.want +1 -1
@@ 1,3 1,3 @@
-file testdata/fn.snow [0, 1, 0]
+file testdata/fn.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [0]
M pkg/semantic/testdata/check/fn_access_invalid_struct_field.snow.want => pkg/semantic/testdata/check/fn_access_invalid_struct_field.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_access_invalid_struct_field.snow [0, 1, 1]
+file testdata/fn_access_invalid_struct_field.snow [0, 1, 1, 0]
fn test [let: () -> void]
block [4]
var: s [var: struct S]
@@ 16,6 16,6 @@ file testdata/fn_access_invalid_struct_field.snow [0, 1, 1]
select [invalid: unresolved]
ident s [var: struct S]
ident z [invalid: unresolved]
- struct S [1, 0, 0] [type: struct S]
+ struct S [1, 0, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_access_struct_type_field.snow.want => pkg/semantic/testdata/check/fn_access_struct_type_field.snow.want +2 -2
@@ 1,10 1,10 @@
-file testdata/fn_access_struct_type_field.snow [0, 1, 1]
+file testdata/fn_access_struct_type_field.snow [0, 1, 1, 0]
fn test [let: () -> void]
block [1]
var= y [var: int]
select [invalid: int]
ident Point [type: struct Point]
ident x [var: int]
- struct Point [1, 0, 0] [type: struct Point]
+ struct Point [1, 0, 0, 0] [type: struct Point]
var: x [var: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_access_var_outside_struct.snow.want => pkg/semantic/testdata/check/fn_access_var_outside_struct.snow.want +3 -3
@@ 1,9 1,9 @@
-file testdata/fn_access_var_outside_struct.snow [0, 1, 0]
+file testdata/fn_access_var_outside_struct.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [2]
var: x [var: int]
ident int [type: int]
- struct S [1, 1, 1] [type: struct S]
+ struct S [1, 1, 1, 0] [type: struct S]
var: y [var: string]
ident string [type: string]
fn get [let: () -> int]
@@ 11,7 11,7 @@ file testdata/fn_access_var_outside_struct.snow [0, 1, 0]
block [1]
return
ident x [var: int]
- struct T [0, 1, 0] [type: struct T]
+ struct T [0, 1, 0, 0] [type: struct T]
fn get [let: () -> string]
ident string [type: string]
block [1]
A pkg/semantic/testdata/check/fn_assign_call_interface.snow.err => pkg/semantic/testdata/check/fn_assign_call_interface.snow.err +0 -0
A pkg/semantic/testdata/check/fn_assign_call_interface.snow.want => pkg/semantic/testdata/check/fn_assign_call_interface.snow.want +32 -0
@@ 0,0 1,32 @@
+file testdata/fn_assign_call_interface.snow [0, 2, 1, 1]
+ fn println [let: (string) -> void]
+ @ [import, symbol] [2] [value: struct extern]
+ ident extern [type: struct extern]
+ string ["fmt"] [const: string]
+ string ["Println"] [const: string]
+ let: s [let: string]
+ ident string [type: string]
+ fn main [let: () -> void]
+ block [2]
+ let:= iface [let: interface I]
+ ident I [type: interface I]
+ implicit conv [value: interface I]
+ call [s] [1] [value: struct S]
+ ident S [type: struct S]
+ string ["hello!"] [const: string]
+ expr
+ call [0] [value: void]
+ select [let: () -> void]
+ ident iface [let: interface I]
+ ident foo [let: () -> void]
+ struct S [1, 1, 0, 0] [type: struct S]
+ let: s [let: string]
+ ident string [type: string]
+ fn foo [let: () -> void]
+ block [1]
+ expr
+ call [1] [value: void]
+ ident println [let: (string) -> void]
+ ident s [let: string]
+ interface I [1] [type: interface I]
+ fn foo [let: () -> void]
M pkg/semantic/testdata/check/fn_assign_invalid.snow.want => pkg/semantic/testdata/check/fn_assign_invalid.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_assign_invalid.snow [0, 1, 0]
+file testdata/fn_assign_invalid.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [2]
var: x [var: f64]
M pkg/semantic/testdata/check/fn_assign_let.snow.want => pkg/semantic/testdata/check/fn_assign_let.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_assign_let.snow [0, 1, 0]
+file testdata/fn_assign_let.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [2]
let= x [let: int]
M pkg/semantic/testdata/check/fn_assign_struct_fields.snow.want => pkg/semantic/testdata/check/fn_assign_struct_fields.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_assign_struct_fields.snow [0, 1, 1]
+file testdata/fn_assign_struct_fields.snow [0, 1, 1, 0]
fn test [let: () -> void]
block [8]
var: vs [var: struct S]
@@ 35,7 35,7 @@ file testdata/fn_assign_struct_fields.snow [0, 1, 1]
ident ls [let: struct S]
ident z [let: () -> void]
ident test [let: () -> void]
- struct S [2, 1, 0] [type: struct S]
+ struct S [2, 1, 0, 0] [type: struct S]
let: x [let: int]
ident int [type: int]
var: y [var: int]
M pkg/semantic/testdata/check/fn_assign_struct_method_to_var.snow.want => pkg/semantic/testdata/check/fn_assign_struct_method_to_var.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_assign_struct_method_to_var.snow [0, 1, 1]
+file testdata/fn_assign_struct_method_to_var.snow [0, 1, 1, 0]
fn main [let: () -> void]
block [6]
var: s [var: struct S]
@@ 28,7 28,7 @@ file testdata/fn_assign_struct_method_to_var.snow [0, 1, 1]
select [let: (int) -> void]
ident s2 [let: struct S]
ident set [let: (int) -> void]
- struct S [1, 2, 0] [type: struct S]
+ struct S [1, 2, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
fn get [let: () -> int]
M pkg/semantic/testdata/check/fn_assign_type.snow.want => pkg/semantic/testdata/check/fn_assign_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_assign_type.snow [0, 1, 0]
+file testdata/fn_assign_type.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [1]
assign
M pkg/semantic/testdata/check/fn_assign_unifying_type.snow.want => pkg/semantic/testdata/check/fn_assign_unifying_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_assign_unifying_type.snow [0, 1, 0]
+file testdata/fn_assign_unifying_type.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [3]
var: x [var: u8]
M pkg/semantic/testdata/check/fn_call_fn_value_with_labels.snow.want => pkg/semantic/testdata/check/fn_call_fn_value_with_labels.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_call_fn_value_with_labels.snow [0, 2, 0]
+file testdata/fn_call_fn_value_with_labels.snow [0, 2, 0, 0]
fn add [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_call_struct_init.snow.want => pkg/semantic/testdata/check/fn_call_struct_init.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_call_struct_init.snow [0, 1, 1]
+file testdata/fn_call_struct_init.snow [0, 1, 1, 0]
fn main [let: () -> void]
block [1]
var= s [var: struct S]
@@ 6,7 6,7 @@ file testdata/fn_call_struct_init.snow [0, 1, 1]
ident S [type: struct S]
int [1] [const: int]
string ["a"] [const: string]
- struct S [2, 0, 0] [type: struct S]
+ struct S [2, 0, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
let: y [let: string]
M pkg/semantic/testdata/check/fn_call_struct_init_no_label.snow.want => pkg/semantic/testdata/check/fn_call_struct_init_no_label.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_call_struct_init_no_label.snow [0, 1, 1]
+file testdata/fn_call_struct_init_no_label.snow [0, 1, 1, 0]
fn main [let: () -> void]
block [1]
var= s [var: struct S]
@@ 6,7 6,7 @@ file testdata/fn_call_struct_init_no_label.snow [0, 1, 1]
ident S [type: struct S]
int [1] [const: int]
string ["a"] [const: string]
- struct S [2, 0, 0] [type: struct S]
+ struct S [2, 0, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
let: y [let: string]
M pkg/semantic/testdata/check/fn_call_struct_init_only_required_no_order.snow.want => pkg/semantic/testdata/check/fn_call_struct_init_only_required_no_order.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_call_struct_init_only_required_no_order.snow [0, 1, 1]
+file testdata/fn_call_struct_init_only_required_no_order.snow [0, 1, 1, 0]
fn main [let: () -> void]
block [2]
var= s [var: struct S]
@@ 10,7 10,7 @@ file testdata/fn_call_struct_init_only_required_no_order.snow [0, 1, 1]
call [b] [1] [value: struct S]
ident S [type: struct S]
string ["b"] [const: string]
- struct S [3, 0, 0] [type: struct S]
+ struct S [3, 0, 0, 0] [type: struct S]
var: a [var: int]
ident int [type: int]
let: b [let: string]
M pkg/semantic/testdata/check/fn_call_struct_method.snow.want => pkg/semantic/testdata/check/fn_call_struct_method.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_call_struct_method.snow [0, 1, 1]
+file testdata/fn_call_struct_method.snow [0, 1, 1, 0]
fn test [let: () -> void]
block [2]
var: p [var: struct Point]
@@ 9,7 9,7 @@ file testdata/fn_call_struct_method.snow [0, 1, 1]
ident p [var: struct Point]
ident add [let: (int) -> void]
int [1] [const: int]
- struct Point [1, 1, 0] [type: struct Point]
+ struct Point [1, 1, 0, 0] [type: struct Point]
var: x [var: int]
ident int [type: int]
fn add [let: (int) -> void]
M pkg/semantic/testdata/check/fn_call_unifying_type.snow.want => pkg/semantic/testdata/check/fn_call_unifying_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_call_unifying_type.snow [0, 2, 0]
+file testdata/fn_call_unifying_type.snow [0, 2, 0, 0]
fn add [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_call_with_invalid_labels.snow.want => pkg/semantic/testdata/check/fn_call_with_invalid_labels.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_call_with_invalid_labels.snow [0, 2, 0]
+file testdata/fn_call_with_invalid_labels.snow [0, 2, 0, 0]
fn add [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_call_with_labels.snow.want => pkg/semantic/testdata/check/fn_call_with_labels.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_call_with_labels.snow [0, 2, 1]
+file testdata/fn_call_with_labels.snow [0, 2, 1, 0]
fn add [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
@@ 45,7 45,7 @@ file testdata/fn_call_with_labels.snow [0, 2, 1]
ident s [var: struct S]
ident do [let: (int) -> void]
int [6] [const: int]
- struct S [0, 1, 0] [type: struct S]
+ struct S [0, 1, 0, 0] [type: struct S]
fn do [let: (int) -> void]
let: z [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_call_wrong_arity.snow.want => pkg/semantic/testdata/check/fn_call_wrong_arity.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_call_wrong_arity.snow [0, 2, 0]
+file testdata/fn_call_wrong_arity.snow [0, 2, 0, 0]
fn add [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_compare.snow.want => pkg/semantic/testdata/check/fn_compare.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_compare.snow [0, 1, 0]
+file testdata/fn_compare.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [2]
var= x [var: int]
M pkg/semantic/testdata/check/fn_complex_selectors.snow.want => pkg/semantic/testdata/check/fn_complex_selectors.snow.want +3 -3
@@ 1,4 1,4 @@
-file testdata/fn_complex_selectors.snow [0, 2, 1]
+file testdata/fn_complex_selectors.snow [0, 2, 1, 0]
fn create [let: () -> struct S]
ident S [type: struct S]
block [2]
@@ 36,12 36,12 @@ file testdata/fn_complex_selectors.snow [0, 2, 1]
ident s2 [var: struct T]
ident do [let: () -> (int, () -> int)]
ident 1 [value: () -> int]
- struct S [2, 0, 1] [type: struct S]
+ struct S [2, 0, 1, 0] [type: struct S]
var: s1 [var: int]
ident int [type: int]
var: s2 [var: struct T]
ident T [type: struct T]
- struct T [1, 1, 0] [type: struct T]
+ struct T [1, 1, 0, 0] [type: struct T]
var: t1 [var: string]
ident string [type: string]
fn do [let: () -> (int, () -> int)]
M pkg/semantic/testdata/check/fn_duplicate_param_name.snow.want => pkg/semantic/testdata/check/fn_duplicate_param_name.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_duplicate_param_name.snow [0, 1, 0]
+file testdata/fn_duplicate_param_name.snow [0, 1, 0, 0]
fn dup [let: (int, string) -> void]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_explicit_void.snow.want => pkg/semantic/testdata/check/fn_explicit_void.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_explicit_void.snow [0, 3, 0]
+file testdata/fn_explicit_void.snow [0, 3, 0, 0]
fn do_nothing [let: () -> void]
ident void [type: void]
block [1]
M pkg/semantic/testdata/check/fn_extern_pkg_before_conflict_name.snow.want => pkg/semantic/testdata/check/fn_extern_pkg_before_conflict_name.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_extern_pkg_before_conflict_name.snow [0, 1, 0]
+file testdata/fn_extern_pkg_before_conflict_name.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [4]
fn print [let: (int) -> void]
M pkg/semantic/testdata/check/fn_extern_pkg_conflict_name.snow.want => pkg/semantic/testdata/check/fn_extern_pkg_conflict_name.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_extern_pkg_conflict_name.snow [0, 1, 0]
+file testdata/fn_extern_pkg_conflict_name.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [4]
var: fmt [var: int]
M pkg/semantic/testdata/check/fn_extern_ref_method.snow.want => pkg/semantic/testdata/check/fn_extern_ref_method.snow.want +2 -2
@@ 1,7 1,7 @@
-file testdata/fn_extern_ref_method.snow [0, 1, 0]
+file testdata/fn_extern_ref_method.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [1]
- struct S [0, 1, 0] [type: struct S]
+ struct S [0, 1, 0, 0] [type: struct S]
ref fn f [let: () -> void]
@ [import, symbol] [2] [value: struct extern]
ident extern [type: struct extern]
M pkg/semantic/testdata/check/fn_extern_with_body.snow.want => pkg/semantic/testdata/check/fn_extern_with_body.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_extern_with_body.snow [0, 1, 0]
+file testdata/fn_extern_with_body.snow [0, 1, 0, 0]
fn test [let: () -> void]
@ [import, symbol] [2] [value: struct extern]
ident extern [type: struct extern]
M pkg/semantic/testdata/check/fn_fn_arg.snow.want => pkg/semantic/testdata/check/fn_fn_arg.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_fn_arg.snow [0, 3, 0]
+file testdata/fn_fn_arg.snow [0, 3, 0, 0]
fn do [let: (int, (int) -> int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_generic_decl_after_inst.snow.want => pkg/semantic/testdata/check/fn_generic_decl_after_inst.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_generic_decl_after_inst.snow [0, 2, 0]
+file testdata/fn_generic_decl_after_inst.snow [0, 2, 0, 0]
fn main [let: () -> void]
block [1]
let= a [let: int]
M pkg/semantic/testdata/check/fn_generic_fn_uses_generic_fn.snow.want => pkg/semantic/testdata/check/fn_generic_fn_uses_generic_fn.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_generic_fn_uses_generic_fn.snow [0, 3, 0]
+file testdata/fn_generic_fn_uses_generic_fn.snow [0, 3, 0, 0]
fn A [$1] [let: ($T) -> $T]
generic type $T [type: $T]
let: v [let: $T]
M pkg/semantic/testdata/check/fn_generic_identity.snow.want => pkg/semantic/testdata/check/fn_generic_identity.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_generic_identity.snow [0, 5, 0]
+file testdata/fn_generic_identity.snow [0, 5, 0, 0]
fn id [$1] [let: ($T) -> $T]
generic type $T [type: $T]
let: v [let: $T]
A pkg/semantic/testdata/check/fn_generic_interface.snow.err => pkg/semantic/testdata/check/fn_generic_interface.snow.err +1 -0
@@ 0,0 1,1 @@
+testdata/fn_generic_interface.snow:23:14: cannot assign type struct G[bool] to variable of type interface I[int]
A pkg/semantic/testdata/check/fn_generic_interface.snow.want => pkg/semantic/testdata/check/fn_generic_interface.snow.want +82 -0
@@ 0,0 1,82 @@
+file testdata/fn_generic_interface.snow [0, 1, 2, 1]
+ fn main [let: () -> void]
+ block [10]
+ var:= ifaceInt [var: interface I[int]]
+ generic inst [1] [type: interface I[int]]
+ ident I [type: interface I]
+ ident int [type: int]
+ implicit conv [value: interface I[int]]
+ call [0] [value: struct S]
+ ident S [type: struct S]
+ var= res [var: int]
+ call [1] [value: int]
+ select [let: (int) -> int]
+ ident ifaceInt [var: interface I[int]]
+ ident foo [let: (int) -> int]
+ int [1] [const: int]
+ var: gInt [var: struct G[int]]
+ generic inst [1] [type: struct G[int]]
+ ident G [type: struct G]
+ ident int [type: int]
+ var= gres [var: int]
+ call [1] [value: int]
+ select [let: (int) -> int]
+ ident gInt [var: struct G[int]]
+ ident foo [let: (int) -> int]
+ int [1] [const: int]
+ assign
+ ident ifaceInt [var: interface I[int]]
+ implicit conv [value: interface I[int]]
+ call [0] [value: struct G[int]]
+ generic inst [1] [type: struct G[int]]
+ ident G [type: struct G]
+ ident int [type: int]
+ assign
+ ident res [var: int]
+ call [1] [value: int]
+ select [let: (int) -> int]
+ ident ifaceInt [var: interface I[int]]
+ ident foo [let: (int) -> int]
+ int [2] [const: int]
+ assign
+ ident ifaceInt [var: interface I[int]]
+ call [0] [value: struct G[bool]]
+ generic inst [1] [type: struct G[bool]]
+ ident G [type: struct G]
+ ident bool [type: bool]
+ var: ifaceString [var: interface I[string]]
+ generic inst [1] [type: interface I[string]]
+ ident I [type: interface I]
+ ident string [type: string]
+ assign
+ ident ifaceString [var: interface I[string]]
+ implicit conv [value: interface I[string]]
+ call [0] [value: struct G[string]]
+ generic inst [1] [type: struct G[string]]
+ ident G [type: struct G]
+ ident string [type: string]
+ expr
+ call [1] [value: string]
+ select [let: (string) -> string]
+ ident ifaceString [var: interface I[string]]
+ ident foo [let: (string) -> string]
+ string ["a"] [const: string]
+ struct S [0, 1, 0, 0] [type: struct S]
+ fn foo [let: (int) -> int]
+ let: i [let: int]
+ ident int [type: int]
+ ident int [type: int]
+ block [0]
+ struct G [0, 1, 0, 0, $1] [type: struct G]
+ generic type $T [type: $T]
+ fn foo [let: ($T) -> $T]
+ let: t [let: $T]
+ ident $T [type: $T]
+ ident $T [type: $T]
+ block [0]
+ interface I [1, $1] [type: interface I]
+ generic type $T [type: $T]
+ fn foo [let: ($T) -> $T]
+ let: t [let: $T]
+ ident $T [type: $T]
+ ident $T [type: $T]
M pkg/semantic/testdata/check/fn_generic_unused_in_signature.snow.want => pkg/semantic/testdata/check/fn_generic_unused_in_signature.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_generic_unused_in_signature.snow [0, 6, 0]
+file testdata/fn_generic_unused_in_signature.snow [0, 6, 0, 0]
fn g1 [$2] [let: (int) -> int]
generic type $T [type: $T]
generic type $U [type: $U]
M pkg/semantic/testdata/check/fn_guard_fallthrough.snow.want => pkg/semantic/testdata/check/fn_guard_fallthrough.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_guard_fallthrough.snow [0, 1, 0]
+file testdata/fn_guard_fallthrough.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [3]
var: x [var: bool]
M pkg/semantic/testdata/check/fn_ident_as_type.snow.want => pkg/semantic/testdata/check/fn_ident_as_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_ident_as_type.snow [1, 1, 0]
+file testdata/fn_ident_as_type.snow [1, 1, 0, 0]
var: x [var: () -> void]
ident test [let: () -> void]
fn test [let: () -> void]
M pkg/semantic/testdata/check/fn_init_order.snow.want => pkg/semantic/testdata/check/fn_init_order.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_init_order.snow [0, 1, 0]
+file testdata/fn_init_order.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [2]
var= A [var: unresolved]
M pkg/semantic/testdata/check/fn_invalid_attr.snow.want => pkg/semantic/testdata/check/fn_invalid_attr.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_invalid_attr.snow [0, 1, 0]
+file testdata/fn_invalid_attr.snow [0, 1, 0, 0]
fn test [let: () -> void]
@ [x] [1] [value: unresolved]
ident invalid [invalid: unresolved]
M pkg/semantic/testdata/check/fn_invalid_extern_fields.snow.want => pkg/semantic/testdata/check/fn_invalid_extern_fields.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_invalid_extern_fields.snow [0, 3, 0]
+file testdata/fn_invalid_extern_fields.snow [0, 3, 0, 0]
fn test1 [let: () -> void]
@ [badField] [1] [value: struct extern]
ident extern [type: struct extern]
M pkg/semantic/testdata/check/fn_invalid_generic_use_in_fn.snow.want => pkg/semantic/testdata/check/fn_invalid_generic_use_in_fn.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_invalid_generic_use_in_fn.snow [0, 1, 0]
+file testdata/fn_invalid_generic_use_in_fn.snow [0, 1, 0, 0]
fn g [$2] [let: ($T, $U) -> void]
generic type $T [type: $T]
generic type $U [type: $U]
M pkg/semantic/testdata/check/fn_invalid_main.snow.want => pkg/semantic/testdata/check/fn_invalid_main.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_invalid_main.snow [0, 1, 0]
+file testdata/fn_invalid_main.snow [0, 1, 0, 0]
fn main [let: (int) -> string]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_invalid_ref.snow.want => pkg/semantic/testdata/check/fn_invalid_ref.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_invalid_ref.snow [0, 1, 0]
+file testdata/fn_invalid_ref.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [1]
ref fn test [let: () -> void]
M pkg/semantic/testdata/check/fn_invalid_ref_call.snow.want => pkg/semantic/testdata/check/fn_invalid_ref_call.snow.want +2 -2
@@ 1,7 1,7 @@
-file testdata/fn_invalid_ref_call.snow [0, 1, 0]
+file testdata/fn_invalid_ref_call.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [3]
- struct S [1, 1, 0] [type: struct S]
+ struct S [1, 1, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
ref fn set [let: (int) -> void]
M pkg/semantic/testdata/check/fn_invalid_ref_call_via_value.snow.want => pkg/semantic/testdata/check/fn_invalid_ref_call_via_value.snow.want +2 -2
@@ 1,7 1,7 @@
-file testdata/fn_invalid_ref_call_via_value.snow [0, 1, 0]
+file testdata/fn_invalid_ref_call_via_value.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [3]
- struct S [1, 1, 0] [type: struct S]
+ struct S [1, 1, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
ref fn set [let: (int) -> void]
M pkg/semantic/testdata/check/fn_invalid_return.snow.want => pkg/semantic/testdata/check/fn_invalid_return.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_invalid_return.snow [0, 1, 0]
+file testdata/fn_invalid_return.snow [0, 1, 0, 0]
fn test [let: () -> uint]
ident uint [type: uint]
block [1]
M pkg/semantic/testdata/check/fn_invalid_tuple_access.snow.want => pkg/semantic/testdata/check/fn_invalid_tuple_access.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_invalid_tuple_access.snow [0, 1, 0]
+file testdata/fn_invalid_tuple_access.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [3]
var: x [var: (int, string, (bool, uint))]
M pkg/semantic/testdata/check/fn_main_extern.snow.want => pkg/semantic/testdata/check/fn_main_extern.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_main_extern.snow [0, 1, 0]
+file testdata/fn_main_extern.snow [0, 1, 0, 0]
fn main [let: () -> void]
@ [import, symbol] [2] [value: struct extern]
ident extern [type: struct extern]
M pkg/semantic/testdata/check/fn_many_extern.snow.want => pkg/semantic/testdata/check/fn_many_extern.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_many_extern.snow [0, 1, 0]
+file testdata/fn_many_extern.snow [0, 1, 0, 0]
fn test [let: () -> void]
@ [import, symbol] [2] [value: struct extern]
ident extern [type: struct extern]
M pkg/semantic/testdata/check/fn_method_explicit_self.snow.want => pkg/semantic/testdata/check/fn_method_explicit_self.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_method_explicit_self.snow [0, 1, 1]
+file testdata/fn_method_explicit_self.snow [0, 1, 1, 0]
fn main [let: () -> void]
block [2]
var: s [var: struct S]
@@ 8,7 8,7 @@ file testdata/fn_method_explicit_self.snow [0, 1, 1]
select [let: () -> int]
ident s [var: struct S]
ident getX [let: () -> int]
- struct S [1, 1, 0] [type: struct S]
+ struct S [1, 1, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
fn getX [let: () -> int]
M pkg/semantic/testdata/check/fn_multi_vars_per_decl.snow.want => pkg/semantic/testdata/check/fn_multi_vars_per_decl.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_multi_vars_per_decl.snow [0, 1, 0]
+file testdata/fn_multi_vars_per_decl.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [3]
var:= x [var: int]
M pkg/semantic/testdata/check/fn_nested_block.snow.want => pkg/semantic/testdata/check/fn_nested_block.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_nested_block.snow [0, 1, 0]
+file testdata/fn_nested_block.snow [0, 1, 0, 0]
fn test [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_nested_fn.snow.want => pkg/semantic/testdata/check/fn_nested_fn.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_nested_fn.snow [0, 1, 0]
+file testdata/fn_nested_fn.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [4]
fn add [let: (int, int) -> int]
M pkg/semantic/testdata/check/fn_nested_fn_init_order.snow.want => pkg/semantic/testdata/check/fn_nested_fn_init_order.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_nested_fn_init_order.snow [0, 1, 0]
+file testdata/fn_nested_fn_init_order.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [3]
fn A [let: () -> void]
M pkg/semantic/testdata/check/fn_nested_generic_fn.snow.want => pkg/semantic/testdata/check/fn_nested_generic_fn.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_nested_generic_fn.snow [0, 3, 0]
+file testdata/fn_nested_generic_fn.snow [0, 3, 0, 0]
fn call [let: ((bool) -> bool) -> bool]
let: f [let: (bool) -> bool]
sig [1->1] [type: (bool) -> bool]
M pkg/semantic/testdata/check/fn_nested_struct_method.snow.want => pkg/semantic/testdata/check/fn_nested_struct_method.snow.want +3 -3
@@ 1,7 1,7 @@
-file testdata/fn_nested_struct_method.snow [0, 1, 0]
+file testdata/fn_nested_struct_method.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [6]
- struct S [1, 1, 1] [type: struct S]
+ struct S [1, 1, 1, 0] [type: struct S]
var: x [var: string]
ident string [type: string]
ref fn init [let: () -> void]
@@ 9,7 9,7 @@ file testdata/fn_nested_struct_method.snow [0, 1, 0]
assign
ident x [var: string]
string ["hello"] [const: string]
- struct T [1, 1, 0] [type: struct T]
+ struct T [1, 1, 0, 0] [type: struct T]
var: y [var: string]
ident string [type: string]
ref fn append [let: (string) -> void]
M pkg/semantic/testdata/check/fn_nested_struct_self.snow.want => pkg/semantic/testdata/check/fn_nested_struct_self.snow.want +3 -3
@@ 1,8 1,8 @@
-file testdata/fn_nested_struct_self.snow [0, 0, 1]
- struct S [1, 0, 1] [type: struct S]
+file testdata/fn_nested_struct_self.snow [0, 0, 1, 0]
+ struct S [1, 0, 1, 0] [type: struct S]
var: x [var: string]
ident string [type: string]
- struct T [1, 1, 0] [type: struct T]
+ struct T [1, 1, 0, 0] [type: struct T]
var: x [var: int]
ident int [type: int]
fn negate [let: () -> int]
M pkg/semantic/testdata/check/fn_nested_structs.snow.want => pkg/semantic/testdata/check/fn_nested_structs.snow.want +3 -3
@@ 1,10 1,10 @@
-file testdata/fn_nested_structs.snow [0, 1, 0]
+file testdata/fn_nested_structs.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [3]
- struct Outer [1, 0, 1] [type: struct Outer]
+ struct Outer [1, 0, 1, 0] [type: struct Outer]
let: x [let: struct Inner]
ident Inner [type: struct Inner]
- struct Inner [1, 0, 0] [type: struct Inner]
+ struct Inner [1, 0, 0, 0] [type: struct Inner]
let: y [let: int]
ident int [type: int]
var: o [var: struct Outer]
M pkg/semantic/testdata/check/fn_nested_tuple_type.snow.want => pkg/semantic/testdata/check/fn_nested_tuple_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_nested_tuple_type.snow [0, 1, 0]
+file testdata/fn_nested_tuple_type.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [1]
var: x [var: (int, (bool, string))]
M pkg/semantic/testdata/check/fn_non_type_selectors.snow.want => pkg/semantic/testdata/check/fn_non_type_selectors.snow.want +3 -3
@@ 1,4 1,4 @@
-file testdata/fn_non_type_selectors.snow [2, 1, 1]
+file testdata/fn_non_type_selectors.snow [2, 1, 1, 0]
var: x [var: int]
ident int [type: int]
let: y [let: string]
@@ 40,9 40,9 @@ file testdata/fn_non_type_selectors.snow [2, 1, 1]
ident S [type: struct S]
ident T [type: struct T]
ident tt [var: int]
- struct S [1, 0, 1] [type: struct S]
+ struct S [1, 0, 1, 0] [type: struct S]
var: ss [var: int]
ident int [type: int]
- struct T [1, 0, 0] [type: struct T]
+ struct T [1, 0, 0, 0] [type: struct T]
var: tt [var: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_param_type_is_var_in_body.snow.want => pkg/semantic/testdata/check/fn_param_type_is_var_in_body.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_param_type_is_var_in_body.snow [0, 1, 0]
+file testdata/fn_param_type_is_var_in_body.snow [0, 1, 0, 0]
fn test [let: (int) -> void]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_params.snow.want => pkg/semantic/testdata/check/fn_params.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_params.snow [0, 1, 0]
+file testdata/fn_params.snow [0, 1, 0, 0]
fn test [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_params_locals.snow.want => pkg/semantic/testdata/check/fn_params_locals.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_params_locals.snow [0, 1, 0]
+file testdata/fn_params_locals.snow [0, 1, 0, 0]
fn test [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_recursion.snow.want => pkg/semantic/testdata/check/fn_recursion.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_recursion.snow [0, 1, 0]
+file testdata/fn_recursion.snow [0, 1, 0, 0]
fn test [let: (int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_ref_on_fn_nested_in_method.snow.want => pkg/semantic/testdata/check/fn_ref_on_fn_nested_in_method.snow.want +2 -2
@@ 1,5 1,5 @@
-file testdata/fn_ref_on_fn_nested_in_method.snow [0, 0, 1]
- struct S [1, 1, 0] [type: struct S]
+file testdata/fn_ref_on_fn_nested_in_method.snow [0, 0, 1, 0]
+ struct S [1, 1, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
ref fn rf [let: () -> void]
M pkg/semantic/testdata/check/fn_return_internal_struct.snow.want => pkg/semantic/testdata/check/fn_return_internal_struct.snow.want +2 -2
@@ 1,8 1,8 @@
-file testdata/fn_return_internal_struct.snow [0, 1, 0]
+file testdata/fn_return_internal_struct.snow [0, 1, 0, 0]
fn test [let: () -> unresolved]
ident S [invalid: unresolved]
block [3]
- struct S [0, 0, 0] [type: struct S]
+ struct S [0, 0, 0, 0] [type: struct S]
var: s [var: struct S]
ident S [type: struct S]
return
M pkg/semantic/testdata/check/fn_return_missing_value.snow.want => pkg/semantic/testdata/check/fn_return_missing_value.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_return_missing_value.snow [0, 1, 0]
+file testdata/fn_return_missing_value.snow [0, 1, 0, 0]
fn test [let: () -> int]
ident int [type: int]
block [1]
M pkg/semantic/testdata/check/fn_return_struct.snow.want => pkg/semantic/testdata/check/fn_return_struct.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_return_struct.snow [0, 2, 1]
+file testdata/fn_return_struct.snow [0, 2, 1, 0]
fn newS [let: () -> struct S]
ident S [type: struct S]
block [2]
@@ 42,7 42,7 @@ file testdata/fn_return_struct.snow [0, 2, 1]
ident newS [let: () -> struct S]
ident z [let: () -> void]
ident test [let: () -> void]
- struct S [2, 1, 0] [type: struct S]
+ struct S [2, 1, 0, 0] [type: struct S]
let: x [let: int]
ident int [type: int]
var: y [var: int]
M pkg/semantic/testdata/check/fn_return_unifying_type.snow.want => pkg/semantic/testdata/check/fn_return_unifying_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_return_unifying_type.snow [0, 1, 0]
+file testdata/fn_return_unifying_type.snow [0, 1, 0, 0]
fn test [let: () -> i16]
ident i16 [type: i16]
block [2]
M pkg/semantic/testdata/check/fn_struct_main_method.snow.want => pkg/semantic/testdata/check/fn_struct_main_method.snow.want +2 -2
@@ 1,7 1,7 @@
-file testdata/fn_struct_main_method.snow [0, 1, 1]
+file testdata/fn_struct_main_method.snow [0, 1, 1, 0]
fn main [let: () -> void]
block [0]
- struct S [0, 1, 0] [type: struct S]
+ struct S [0, 1, 0, 0] [type: struct S]
fn main [let: (int) -> void]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_struct_method_access_top_level.snow.want => pkg/semantic/testdata/check/fn_struct_method_access_top_level.snow.want +2 -2
@@ 1,9 1,9 @@
-file testdata/fn_struct_method_access_top_level.snow [1, 1, 1]
+file testdata/fn_struct_method_access_top_level.snow [1, 1, 1, 0]
var: x [var: int]
ident int [type: int]
fn main [let: () -> void]
block [0]
- struct S [0, 1, 0] [type: struct S]
+ struct S [0, 1, 0, 0] [type: struct S]
fn get [let: () -> int]
ident int [type: int]
block [1]
M pkg/semantic/testdata/check/fn_struct_order_independent.snow.want => pkg/semantic/testdata/check/fn_struct_order_independent.snow.want +2 -2
@@ 1,5 1,5 @@
-file testdata/fn_struct_order_independent.snow [0, 0, 1]
- struct S [2, 1, 0] [type: struct S]
+file testdata/fn_struct_order_independent.snow [0, 0, 1, 0]
+ struct S [2, 1, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
let: y [let: int]
M pkg/semantic/testdata/check/fn_struct_same_name_diff_scope.snow.want => pkg/semantic/testdata/check/fn_struct_same_name_diff_scope.snow.want +3 -3
@@ 1,11 1,11 @@
-file testdata/fn_struct_same_name_diff_scope.snow [0, 1, 0]
+file testdata/fn_struct_same_name_diff_scope.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [3]
- struct A [0, 0, 0] [type: struct A]
+ struct A [0, 0, 0, 0] [type: struct A]
var: a [var: struct A]
ident A [type: struct A]
block [3]
- struct A [0, 0, 0] [type: struct A]
+ struct A [0, 0, 0, 0] [type: struct A]
var: b [var: struct A]
ident A [type: struct A]
assign
M pkg/semantic/testdata/check/fn_struct_selector.snow.want => pkg/semantic/testdata/check/fn_struct_selector.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_struct_selector.snow [0, 1, 1]
+file testdata/fn_struct_selector.snow [0, 1, 1, 0]
fn test [let: () -> void]
block [2]
var: p [var: struct Point]
@@ 7,6 7,6 @@ file testdata/fn_struct_selector.snow [0, 1, 1]
select [let: int]
ident p [var: struct Point]
ident x [let: int]
- struct Point [1, 0, 0] [type: struct Point]
+ struct Point [1, 0, 0, 0] [type: struct Point]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/check/fn_struct_self_shadow.snow.want => pkg/semantic/testdata/check/fn_struct_self_shadow.snow.want +2 -2
@@ 1,5 1,5 @@
-file testdata/fn_struct_self_shadow.snow [0, 0, 1]
- struct S [1, 1, 0] [type: struct S]
+file testdata/fn_struct_self_shadow.snow [0, 0, 1, 0]
+ struct S [1, 1, 0, 0] [type: struct S]
var: self [var: int]
ident int [type: int]
fn get [let: () -> int]
M pkg/semantic/testdata/check/fn_struct_self_uses.snow.want => pkg/semantic/testdata/check/fn_struct_self_uses.snow.want +2 -2
@@ 1,5 1,5 @@
-file testdata/fn_struct_self_uses.snow [0, 0, 1]
- struct S [0, 1, 0] [type: struct S]
+file testdata/fn_struct_self_uses.snow [0, 0, 1, 0]
+ struct S [0, 1, 0, 0] [type: struct S]
fn set [let: () -> void]
block [1]
var: self [var: int]
M pkg/semantic/testdata/check/fn_tuple_assign_compatible_types.snow.want => pkg/semantic/testdata/check/fn_tuple_assign_compatible_types.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_tuple_assign_compatible_types.snow [0, 1, 0]
+file testdata/fn_tuple_assign_compatible_types.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [4]
var: i [var: i16]
M pkg/semantic/testdata/check/fn_tuple_assign_incompatible_types.snow.want => pkg/semantic/testdata/check/fn_tuple_assign_incompatible_types.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_tuple_assign_incompatible_types.snow [0, 1, 0]
+file testdata/fn_tuple_assign_incompatible_types.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [4]
var: t [var: (i32, u16, bool)]
M pkg/semantic/testdata/check/fn_tuple_expr_select_field.snow.want => pkg/semantic/testdata/check/fn_tuple_expr_select_field.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_tuple_expr_select_field.snow [0, 1, 0]
+file testdata/fn_tuple_expr_select_field.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [4]
var= t1 [var: (int, int, int)]
M pkg/semantic/testdata/check/fn_type_as_value.snow.want => pkg/semantic/testdata/check/fn_type_as_value.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_type_as_value.snow [0, 1, 0]
+file testdata/fn_type_as_value.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [1]
let= res [let: int]
M pkg/semantic/testdata/check/fn_unknown_symbol.snow.want => pkg/semantic/testdata/check/fn_unknown_symbol.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_unknown_symbol.snow [0, 1, 0]
+file testdata/fn_unknown_symbol.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [1]
expr
M pkg/semantic/testdata/check/fn_var_as_param_type.snow.want => pkg/semantic/testdata/check/fn_var_as_param_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_var_as_param_type.snow [3, 1, 0]
+file testdata/fn_var_as_param_type.snow [3, 1, 0, 0]
var: x [var: int]
ident int [type: int]
var: f [var: (int) -> void]
M pkg/semantic/testdata/check/fn_without_body.snow.want => pkg/semantic/testdata/check/fn_without_body.snow.want +1 -1
@@ 1,2 1,2 @@
-file testdata/fn_without_body.snow [0, 1, 0]
+file testdata/fn_without_body.snow [0, 1, 0, 0]
fn test [let: () -> void]
M pkg/semantic/testdata/check/fns.snow.want => pkg/semantic/testdata/check/fns.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fns.snow [0, 3, 0]
+file testdata/fns.snow [0, 3, 0, 0]
fn add [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
A pkg/semantic/testdata/check/generic_interface.snow.err => pkg/semantic/testdata/check/generic_interface.snow.err +1 -0
@@ 0,0 1,1 @@
+main function missing
A pkg/semantic/testdata/check/generic_interface.snow.want => pkg/semantic/testdata/check/generic_interface.snow.want +9 -0
@@ 0,0 1,9 @@
+file testdata/generic_interface.snow [0, 0, 0, 1]
+ interface I [2, $2] [type: interface I]
+ generic type $T [type: $T]
+ generic type $U [type: $U]
+ fn get_t [let: () -> $T]
+ ident $T [type: $T]
+ fn set_u [let: ($U) -> void]
+ let: u [let: $U]
+ ident $U [type: $U]
M pkg/semantic/testdata/check/generic_struct_instantiation.snow.want => pkg/semantic/testdata/check/generic_struct_instantiation.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/generic_struct_instantiation.snow [0, 1, 1]
+file testdata/generic_struct_instantiation.snow [0, 1, 1, 0]
fn main [let: () -> void]
block [2]
let= g1 [let: struct G[int]]
@@ 11,7 11,7 @@ file testdata/generic_struct_instantiation.snow [0, 1, 1]
generic inst [1] [type: struct G[string]]
ident G [type: struct G]
ident string [type: string]
- struct G [1, 0, 0, $1] [type: struct G]
+ struct G [1, 0, 0, 0, $1] [type: struct G]
generic type $T [type: $T]
var: x [var: $T]
ident $T [type: $T]
M pkg/semantic/testdata/check/guard_else.snow.want => pkg/semantic/testdata/check/guard_else.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/guard_else.snow [0, 1, 0]
+file testdata/guard_else.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [3]
var= x [var: bool]
M pkg/semantic/testdata/check/if_else_if.snow.want => pkg/semantic/testdata/check/if_else_if.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/if_else_if.snow [0, 1, 0]
+file testdata/if_else_if.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [3]
var= x [var: bool]
M pkg/semantic/testdata/check/if_non_bool.snow.want => pkg/semantic/testdata/check/if_non_bool.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/if_non_bool.snow [0, 1, 0]
+file testdata/if_non_bool.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [2]
var= x [var: int]
A pkg/semantic/testdata/check/interface.snow.err => pkg/semantic/testdata/check/interface.snow.err +1 -0
@@ 0,0 1,1 @@
+main function missing
A pkg/semantic/testdata/check/interface.snow.want => pkg/semantic/testdata/check/interface.snow.want +3 -0
@@ 0,0 1,3 @@
+file testdata/interface.snow [0, 0, 0, 1]
+ interface I [1] [type: interface I]
+ fn foo [let: () -> void]
A pkg/semantic/testdata/check/interface_satisfied.snow.err => pkg/semantic/testdata/check/interface_satisfied.snow.err +7 -0
@@ 0,0 1,7 @@
+testdata/interface_satisfied.snow:39:11: cannot assign type int to variable of type interface Empty
+testdata/interface_satisfied.snow:42:7: cannot assign type struct S2 to variable of type interface Foo
+testdata/interface_satisfied.snow:43:7: cannot assign type struct S3 to variable of type interface Foo
+testdata/interface_satisfied.snow:51:7: cannot assign type struct S4 to variable of type interface Foo
+testdata/interface_satisfied.snow:53:7: cannot assign type struct S4 to variable of type interface Foo
+testdata/interface_satisfied.snow:59:9: cannot assign type (int, struct S4) to variable of type (int, interface Foo)
+testdata/interface_satisfied.snow:63:10: cannot assign type (int, struct S4, (bool, struct S4)) to variable of type (int, interface Foo, (bool, interface Foo))
A pkg/semantic/testdata/check/interface_satisfied.snow.want => pkg/semantic/testdata/check/interface_satisfied.snow.want +164 -0
@@ 0,0 1,164 @@
+file testdata/interface_satisfied.snow [0, 2, 4, 2]
+ fn get_s4 [let: () -> struct S4]
+ ident S4 [type: struct S4]
+ block [1]
+ return
+ call [0] [value: struct S4]
+ ident S4 [type: struct S4]
+ fn main [let: () -> void]
+ block [25]
+ var: empty [var: interface Empty]
+ ident Empty [type: interface Empty]
+ var: f [var: interface Foo]
+ ident Foo [type: interface Foo]
+ var: integer [var: int]
+ ident int [type: int]
+ var: s1 [var: struct S1]
+ ident S1 [type: struct S1]
+ assign
+ ident empty [var: interface Empty]
+ ident empty [var: interface Empty]
+ assign
+ ident empty [var: interface Empty]
+ implicit conv [value: interface Empty]
+ ident f [var: interface Foo]
+ assign
+ ident empty [var: interface Empty]
+ implicit conv [value: interface Empty]
+ ident s1 [var: struct S1]
+ assign
+ ident empty [var: interface Empty]
+ ident integer [var: int]
+ assign
+ ident f [var: interface Foo]
+ implicit conv [value: interface Foo]
+ call [0] [value: struct S1]
+ ident S1 [type: struct S1]
+ assign
+ ident f [var: interface Foo]
+ call [0] [value: struct S2]
+ ident S2 [type: struct S2]
+ assign
+ ident f [var: interface Foo]
+ call [0] [value: struct S3]
+ ident S3 [type: struct S3]
+ var= vs4 [var: struct S4]
+ call [0] [value: struct S4]
+ ident S4 [type: struct S4]
+ let= ls4 [let: struct S4]
+ call [0] [value: struct S4]
+ ident S4 [type: struct S4]
+ assign
+ ident f [var: interface Foo]
+ implicit conv [value: interface Foo]
+ ident vs4 [var: struct S4]
+ assign
+ ident f [var: interface Foo]
+ ident ls4 [let: struct S4]
+ assign
+ ident f [var: interface Foo]
+ call [0] [value: struct S4]
+ ident S4 [type: struct S4]
+ var: tup [var: (int, interface Foo)]
+ tuple type [2] [type: (int, interface Foo)]
+ ident int [type: int]
+ ident Foo [type: interface Foo]
+ assign
+ ident tup [var: (int, interface Foo)]
+ implicit conv [value: (int, interface Foo)]
+ tuple value [2] [value: (int, struct S4)]
+ int [1] [const: int]
+ ident vs4 [var: struct S4]
+ assign
+ ident tup [var: (int, interface Foo)]
+ tuple value [2] [value: (int, struct S4)]
+ int [1] [const: int]
+ ident ls4 [let: struct S4]
+ var: tup2 [var: (int, interface Foo, (bool, interface Foo))]
+ tuple type [3] [type: (int, interface Foo, (bool, interface Foo))]
+ ident int [type: int]
+ ident Foo [type: interface Foo]
+ tuple type [2] [type: (bool, interface Foo)]
+ ident bool [type: bool]
+ ident Foo [type: interface Foo]
+ assign
+ ident tup2 [var: (int, interface Foo, (bool, interface Foo))]
+ implicit conv [value: (int, interface Foo, (bool, interface Foo))]
+ tuple value [3] [value: (int, struct S4, (bool, struct S4))]
+ int [1] [const: int]
+ ident vs4 [var: struct S4]
+ tuple value [2] [value: (bool, struct S4)]
+ ident true [let: bool]
+ ident vs4 [var: struct S4]
+ assign
+ ident tup2 [var: (int, interface Foo, (bool, interface Foo))]
+ tuple value [3] [value: (int, struct S4, (bool, struct S4))]
+ int [1] [const: int]
+ ident ls4 [let: struct S4]
+ tuple value [2] [value: (bool, struct S4)]
+ ident true [let: bool]
+ call [0] [value: struct S4]
+ ident get_s4 [let: () -> struct S4]
+ var: tup3 [var: (int, (interface Foo, interface Empty))]
+ tuple type [2] [type: (int, (interface Foo, interface Empty))]
+ ident int [type: int]
+ tuple type [2] [type: (interface Foo, interface Empty)]
+ ident Foo [type: interface Foo]
+ paren [type: interface Empty]
+ ident Empty [type: interface Empty]
+ assign
+ ident tup3 [var: (int, (interface Foo, interface Empty))]
+ implicit conv [value: (int, (interface Foo, interface Empty))]
+ tuple value [2] [value: (int, (struct S4, struct S4))]
+ int [3] [const: int]
+ tuple value [2] [value: (struct S4, struct S4)]
+ ident vs4 [var: struct S4]
+ paren [let: struct S4]
+ ident ls4 [let: struct S4]
+ assign
+ ident tup3 [var: (int, (interface Foo, interface Empty))]
+ implicit conv [value: (int, (interface Foo, interface Empty))]
+ tuple value [2] [value: (int, (struct S4, struct S4))]
+ int [3] [const: int]
+ tuple value [2] [value: (struct S4, struct S4)]
+ ident vs4 [var: struct S4]
+ paren [value: struct S4]
+ call [0] [value: struct S4]
+ ident get_s4 [let: () -> struct S4]
+ struct S1 [0, 2, 0, 0] [type: struct S1]
+ fn foo [let: (int) -> int]
+ let: x [let: int]
+ ident int [type: int]
+ ident int [type: int]
+ block [0]
+ fn bar [let: (string) -> void]
+ let: s [let: string]
+ ident string [type: string]
+ block [0]
+ struct S2 [0, 2, 0, 0] [type: struct S2]
+ fn bar [let: (string) -> void]
+ let: s [let: string]
+ ident string [type: string]
+ block [0]
+ fn quz [let: (bool) -> void]
+ let: b [let: bool]
+ ident bool [type: bool]
+ block [0]
+ struct S3 [0, 1, 0, 0] [type: struct S3]
+ fn foo [let: (uint) -> int]
+ let: u [let: uint]
+ ident uint [type: uint]
+ ident int [type: int]
+ block [0]
+ struct S4 [0, 1, 0, 0] [type: struct S4]
+ ref fn foo [let: (int) -> int]
+ let: i [let: int]
+ ident int [type: int]
+ ident int [type: int]
+ block [0]
+ interface Empty [0] [type: interface Empty]
+ interface Foo [1] [type: interface Foo]
+ fn foo [let: (int) -> int]
+ let: i [let: int]
+ ident int [type: int]
+ ident int [type: int]
M pkg/semantic/testdata/check/invalid_binary_op.snow.want => pkg/semantic/testdata/check/invalid_binary_op.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/invalid_binary_op.snow [3, 0, 0]
+file testdata/invalid_binary_op.snow [3, 0, 0, 0]
var= x [var: int]
int [3] [const: int]
var= y [var: string]
A pkg/semantic/testdata/check/invalid_ref_fn_assign.snow.err => pkg/semantic/testdata/check/invalid_ref_fn_assign.snow.err +2 -0
@@ 0,0 1,2 @@
+testdata/invalid_ref_fn_assign.snow:14:16: cannot access ref fn foo; left-hand side must be var, is let
+testdata/invalid_ref_fn_assign.snow:15:21: cannot access ref fn foo; left-hand side must be var, is value
A pkg/semantic/testdata/check/invalid_ref_fn_assign.snow.want => pkg/semantic/testdata/check/invalid_ref_fn_assign.snow.want +45 -0
@@ 0,0 1,45 @@
+file testdata/invalid_ref_fn_assign.snow [0, 2, 1, 0]
+ fn get_s [let: () -> struct S]
+ ident S [type: struct S]
+ block [1]
+ return
+ call [0] [value: struct S]
+ ident S [type: struct S]
+ fn main [let: () -> void]
+ block [6]
+ var: tup [var: (int, () -> void)]
+ tuple type [2] [type: (int, () -> void)]
+ ident int [type: int]
+ sig [0->1] [type: () -> void]
+ ident void [type: void]
+ var= s1 [var: struct S]
+ call [0] [value: struct S]
+ ident S [type: struct S]
+ let= s2 [let: struct S]
+ call [0] [value: struct S]
+ ident S [type: struct S]
+ assign
+ ident tup [var: (int, () -> void)]
+ tuple value [2] [value: (int, () -> void)]
+ int [1] [const: int]
+ select [let: () -> void]
+ ident s1 [var: struct S]
+ ident foo [let: () -> void]
+ assign
+ ident tup [var: (int, () -> void)]
+ tuple value [2] [value: (int, () -> void)]
+ int [2] [const: int]
+ select [let: () -> void]
+ ident s2 [let: struct S]
+ ident foo [let: () -> void]
+ assign
+ ident tup [var: (int, () -> void)]
+ tuple value [2] [value: (int, () -> void)]
+ int [3] [const: int]
+ select [value: () -> void]
+ call [0] [value: struct S]
+ ident get_s [let: () -> struct S]
+ ident foo [let: () -> void]
+ struct S [0, 1, 0, 0] [type: struct S]
+ ref fn foo [let: () -> void]
+ block [0]
M pkg/semantic/testdata/check/let.snow.want => pkg/semantic/testdata/check/let.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/let.snow [1, 0, 0]
+file testdata/let.snow [1, 0, 0, 0]
let:= y [let: string]
ident string [type: string]
string ["abc"] [const: string]
M pkg/semantic/testdata/check/let_invalid_tuple_type.snow.want => pkg/semantic/testdata/check/let_invalid_tuple_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/let_invalid_tuple_type.snow [1, 0, 0]
+file testdata/let_invalid_tuple_type.snow [1, 0, 0, 0]
let: x [let: (int, bool)]
tuple type [2] [type: (int, bool)]
ident int [type: int]
M pkg/semantic/testdata/check/let_invalid_unary.snow.want => pkg/semantic/testdata/check/let_invalid_unary.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/let_invalid_unary.snow [1, 0, 0]
+file testdata/let_invalid_unary.snow [1, 0, 0, 0]
let= x [let: unresolved]
unary [!] [value: unresolved]
string ["a"] [const: string]
M pkg/semantic/testdata/check/let_unary.snow.want => pkg/semantic/testdata/check/let_unary.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/let_unary.snow [1, 0, 0]
+file testdata/let_unary.snow [1, 0, 0, 0]
let= x [let: int]
unary [-] [value: int]
int [1] [const: int]
M pkg/semantic/testdata/check/paren_type.snow.want => pkg/semantic/testdata/check/paren_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/paren_type.snow [1, 0, 0]
+file testdata/paren_type.snow [1, 0, 0, 0]
var:= x [var: int]
paren [type: int]
ident int [type: int]
M pkg/semantic/testdata/check/struct_complex_generic.snow.want => pkg/semantic/testdata/check/struct_complex_generic.snow.want +3 -3
@@ 1,4 1,4 @@
-file testdata/struct_complex_generic.snow [0, 3, 1]
+file testdata/struct_complex_generic.snow [0, 3, 1, 0]
fn str [let: (string) -> string]
let: s [let: string]
ident string [type: string]
@@ 29,7 29,7 @@ file testdata/struct_complex_generic.snow [0, 3, 1]
ident string [type: string]
ident str [let: (string) -> string]
ident integer [let: (int) -> int]
- struct A [2, 0, 1, $2] [type: struct A]
+ struct A [2, 0, 1, 0, $2] [type: struct A]
generic type $T [type: $T]
generic type $U [type: $U]
var: bb [var: struct B[$U]]
@@ 40,7 40,7 @@ file testdata/struct_complex_generic.snow [0, 3, 1]
sig [1->1] [type: ($T) -> $T]
ident $T [type: $T]
ident $T [type: $T]
- struct B [1, 0, 0, $1] [type: struct B]
+ struct B [1, 0, 0, 0, $1] [type: struct B]
generic type $V [type: $V]
var: ffb [var: ($V) -> $V]
sig [1->1] [type: ($V) -> $V]
M pkg/semantic/testdata/check/struct_generic.snow.want => pkg/semantic/testdata/check/struct_generic.snow.want +5 -5
@@ 1,5 1,5 @@
-file testdata/struct_generic.snow [0, 0, 4]
- struct A [2, 1, 0] [type: struct A]
+file testdata/struct_generic.snow [0, 0, 4, 0]
+ struct A [2, 1, 0, 0] [type: struct A]
var: x [var: unresolved]
ident $T [invalid: unresolved]
let: y [let: unresolved]
@@ 14,7 14,7 @@ file testdata/struct_generic.snow [0, 0, 4]
block [1]
let: c [let: unresolved]
ident $W [invalid: unresolved]
- struct B [1, 1, 0, $3] [type: struct B]
+ struct B [1, 1, 0, 0, $3] [type: struct B]
generic type $T [type: $T]
generic type $U [type: $U]
generic type $V [type: $V]
@@ 26,7 26,7 @@ file testdata/struct_generic.snow [0, 0, 4]
block [1]
var: z [var: $U]
ident $U [type: $U]
- struct C [2, 0, 0, $3] [type: struct C]
+ struct C [2, 0, 0, 0, $3] [type: struct C]
generic type $T [type: $T]
generic type $U [type: $U]
generic type $T [type: $T]
@@ 34,7 34,7 @@ file testdata/struct_generic.snow [0, 0, 4]
ident $T [type: $T]
let: y [let: $U]
ident $U [type: $U]
- struct D [3, 0, 0, $2] [type: struct D]
+ struct D [3, 0, 0, 0, $2] [type: struct D]
generic type $T [type: $T]
generic type $U [type: $U]
var: v [var: $T]
M pkg/semantic/testdata/check/struct_simple_generic.snow.want => pkg/semantic/testdata/check/struct_simple_generic.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/struct_simple_generic.snow [0, 2, 1]
+file testdata/struct_simple_generic.snow [0, 2, 1, 0]
fn main [let: () -> void]
block [2]
let= a [let: struct A[int]]
@@ 20,7 20,7 @@ file testdata/struct_simple_generic.snow [0, 2, 1]
string ["Println"] [const: string]
let: i [let: int]
ident int [type: int]
- struct A [1, 0, 0, $1] [type: struct A]
+ struct A [1, 0, 0, 0, $1] [type: struct A]
generic type $T [type: $T]
var: x [var: $T]
ident $T [type: $T]
M pkg/semantic/testdata/check/struct_var_expr_call_method.snow.want => pkg/semantic/testdata/check/struct_var_expr_call_method.snow.want +2 -2
@@ 1,7 1,7 @@
-file testdata/struct_var_expr_call_method.snow [0, 1, 1]
+file testdata/struct_var_expr_call_method.snow [0, 1, 1, 0]
fn main [let: () -> void]
block [0]
- struct S [3, 2, 0] [type: struct S]
+ struct S [3, 2, 0, 0] [type: struct S]
var:= x [var: int]
ident int [type: int]
call [0] [value: int]
M pkg/semantic/testdata/check/top_level_fn_init_order.snow.want => pkg/semantic/testdata/check/top_level_fn_init_order.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/top_level_fn_init_order.snow [0, 2, 0]
+file testdata/top_level_fn_init_order.snow [0, 2, 0, 0]
fn A [let: () -> void]
block [1]
expr
M pkg/semantic/testdata/check/top_level_init_order.snow.want => pkg/semantic/testdata/check/top_level_init_order.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/top_level_init_order.snow [2, 0, 0]
+file testdata/top_level_init_order.snow [2, 0, 0, 0]
var= A [var: int]
ident B [let: int]
let= B [let: int]
M pkg/semantic/testdata/check/tuple_as_struct_generic.snow.want => pkg/semantic/testdata/check/tuple_as_struct_generic.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/tuple_as_struct_generic.snow [0, 2, 1]
+file testdata/tuple_as_struct_generic.snow [0, 2, 1, 0]
fn main [let: () -> void]
block [2]
let:= s [let: struct S[(int, bool, string)]]
@@ 34,7 34,7 @@ file testdata/tuple_as_struct_generic.snow [0, 2, 1]
string ["Println"] [const: string]
let: v [let: string]
ident string [type: string]
- struct S [1, 0, 0, $1] [type: struct S]
+ struct S [1, 0, 0, 0, $1] [type: struct S]
generic type $T [type: $T]
let: t [let: $T]
ident $T [type: $T]
M pkg/semantic/testdata/check/var.snow.want => pkg/semantic/testdata/check/var.snow.want +1 -1
@@ 1,3 1,3 @@
-file testdata/var.snow [1, 0, 0]
+file testdata/var.snow [1, 0, 0, 0]
var: x [var: int]
ident int [type: int]
M pkg/semantic/testdata/check/var_auto_ref.snow.want => pkg/semantic/testdata/check/var_auto_ref.snow.want +1 -1
@@ 1,3 1,3 @@
-file testdata/var_auto_ref.snow [1, 0, 0]
+file testdata/var_auto_ref.snow [1, 0, 0, 0]
var= x [var: unresolved]
ident x [var: unresolved]
M pkg/semantic/testdata/check/var_bool.snow.want => pkg/semantic/testdata/check/var_bool.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/var_bool.snow [2, 0, 0]
+file testdata/var_bool.snow [2, 0, 0, 0]
var= t [var: bool]
ident true [let: bool]
var= f [var: bool]
M pkg/semantic/testdata/check/var_duplicate_symbol.snow.want => pkg/semantic/testdata/check/var_duplicate_symbol.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/var_duplicate_symbol.snow [2, 0, 0]
+file testdata/var_duplicate_symbol.snow [2, 0, 0, 0]
var: x [var: int]
ident int [type: int]
var: x [var: string]
M pkg/semantic/testdata/check/var_tuple_type.snow.want => pkg/semantic/testdata/check/var_tuple_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/var_tuple_type.snow [1, 0, 0]
+file testdata/var_tuple_type.snow [1, 0, 0, 0]
var: x [var: (int, string, bool)]
tuple type [3] [type: (int, string, bool)]
ident int [type: int]
A pkg/semantic/testdata/fn_assign_call_interface.snow => pkg/semantic/testdata/fn_assign_call_interface.snow +19 -0
@@ 0,0 1,19 @@
+interface I {
+ fn foo()
+}
+
+struct S {
+ let s: string
+
+ fn foo() {
+ println(s)
+ }
+}
+
+@extern(import: "fmt", symbol: "Println")
+fn println(s: string)
+
+fn main() {
+ let iface: I = S(s: "hello!")
+ iface.foo()
+}
A pkg/semantic/testdata/fn_generic_interface.snow => pkg/semantic/testdata/fn_generic_interface.snow +29 -0
@@ 0,0 1,29 @@
+interface I[$T] {
+ fn foo(t: $T) -> $T
+}
+
+struct S {
+ fn foo(i: int) -> int {}
+}
+
+struct G[$T] {
+ fn foo(t: $T) -> $T {}
+}
+
+fn main() {
+ var ifaceInt: I[int] = S()
+ var res = ifaceInt.foo(1)
+ var gInt: G[int]
+ var gres = gInt.foo(1)
+
+ ifaceInt = G[int]()
+ res = ifaceInt.foo(2)
+
+ # this should fail
+ ifaceInt = G[bool]()
+
+ # this should work
+ var ifaceString: I[string]
+ ifaceString = G[string]()
+ ifaceString.foo("a")
+}
A pkg/semantic/testdata/generic_interface.snow => pkg/semantic/testdata/generic_interface.snow +4 -0
@@ 0,0 1,4 @@
+interface I[$T, $U] {
+ fn get_t() -> $T
+ fn set_u(u: $U)
+}
A pkg/semantic/testdata/interface.snow => pkg/semantic/testdata/interface.snow +3 -0
@@ 0,0 1,3 @@
+interface I {
+ fn foo()
+}
A pkg/semantic/testdata/interface_satisfied.snow => pkg/semantic/testdata/interface_satisfied.snow +70 -0
@@ 0,0 1,70 @@
+interface Empty {
+}
+
+interface Foo {
+ fn foo(i: int) -> int
+}
+
+struct S1 {
+ fn foo(x: int) -> int {}
+ fn bar(s: string) {}
+}
+
+struct S2 {
+ fn bar(s: string) {}
+ fn quz(b: bool) {}
+}
+
+struct S3 {
+ fn foo(u: uint) -> int {}
+}
+
+struct S4 {
+ ref fn foo(i: int) -> int {}
+}
+
+fn get_s4() -> S4 {
+ return S4()
+}
+
+fn main() {
+ var empty: Empty
+ var f: Foo
+ var integer: int
+ var s1: S1
+
+ empty = empty # self assignment should work
+ empty = f # ok, everything satisfies empty
+ empty = s1 # yep
+ empty = integer # well no, not quite everything!
+
+ f = S1() # all good, S1.foo exists and same types
+ f = S2() # nope
+ f = S3() # types don't match
+
+ var vs4 = S4()
+ let ls4 = S4()
+
+ # this works, vs4 is a var
+ f = vs4
+ # not this, ls4 is immutable
+ f = ls4
+ # not this either, rhs is a value
+ f = S4()
+
+ var tup: (int, Foo)
+ # this is fine
+ tup = (1, vs4)
+ # this is not, should fail because ls4 is immutable
+ tup = (1, ls4)
+
+ var tup2: (int, Foo, (bool, Foo))
+ tup2 = (1, vs4, (true, vs4)) # works, var s4 in both Foo places
+ tup2 = (1, ls4, (true, get_s4())) # fails, immutable S4 and value S4
+
+ # those all work (var S4 for Foo, and whatever for Empty)
+ var tup3: (int, (Foo, (Empty)))
+ tup3 = (3, (vs4, (ls4)))
+ tup3 = (3, (vs4, (get_s4())))
+}
+
A pkg/semantic/testdata/invalid_ref_fn_assign.snow => pkg/semantic/testdata/invalid_ref_fn_assign.snow +16 -0
@@ 0,0 1,16 @@
+struct S {
+ ref fn foo() {}
+}
+
+fn get_s() -> S {
+ return S()
+}
+
+fn main() {
+ var tup: (int, () -> void)
+ var s1 = S()
+ let s2 = S()
+ tup = (1, s1.foo)
+ tup = (2, s2.foo)
+ tup = (3, get_s().foo)
+}
A pkg/semantic/testdata/scopes/fn_assign_call_interface.snow.err => pkg/semantic/testdata/scopes/fn_assign_call_interface.snow.err +0 -0
A pkg/semantic/testdata/scopes/fn_assign_call_interface.snow.want => pkg/semantic/testdata/scopes/fn_assign_call_interface.snow.want +50 -0
@@ 0,0 1,50 @@
+1 *semantic.Unit {
+. bool
+. extern
+. f32
+. f64
+. false
+. float
+. i16
+. i32
+. i64
+. i8
+. int
+. string
+. true
+. u16
+. u32
+. u64
+. u8
+. uint
+. void
+. 2 *semantic.Struct {
+. . import
+. . pkg
+. . symbol
+. }
+. 3 *semantic.File {
+. . I
+. . S
+. . main
+. . println
+. . 4 *semantic.Interface {
+. . . foo
+. . . 5 *semantic.Fn {
+. . . }
+. . }
+. . 6 *semantic.Struct {
+. . . foo
+. . . s
+. . . 7 *semantic.Fn {
+. . . . self
+. . . }
+. . }
+. . 8 *semantic.Fn {
+. . . s
+. . }
+. . 9 *semantic.Fn {
+. . . iface
+. . }
+. }
+}
A pkg/semantic/testdata/scopes/fn_generic_interface.snow.err => pkg/semantic/testdata/scopes/fn_generic_interface.snow.err +0 -0
A pkg/semantic/testdata/scopes/fn_generic_interface.snow.want => pkg/semantic/testdata/scopes/fn_generic_interface.snow.want +61 -0
@@ 0,0 1,61 @@
+1 *semantic.Unit {
+. bool
+. extern
+. f32
+. f64
+. false
+. float
+. i16
+. i32
+. i64
+. i8
+. int
+. string
+. true
+. u16
+. u32
+. u64
+. u8
+. uint
+. void
+. 2 *semantic.Struct {
+. . import
+. . pkg
+. . symbol
+. }
+. 3 *semantic.File {
+. . G
+. . I
+. . S
+. . main
+. . 4 *semantic.Interface {
+. . . $T
+. . . foo
+. . . 5 *semantic.Fn {
+. . . . t
+. . . }
+. . }
+. . 6 *semantic.Struct {
+. . . foo
+. . . 7 *semantic.Fn {
+. . . . i
+. . . . self
+. . . }
+. . }
+. . 8 *semantic.Struct {
+. . . $T
+. . . foo
+. . . 9 *semantic.Fn {
+. . . . self
+. . . . t
+. . . }
+. . }
+. . 10 *semantic.Fn {
+. . . gInt
+. . . gres
+. . . ifaceInt
+. . . ifaceString
+. . . res
+. . }
+. }
+}
A pkg/semantic/testdata/scopes/generic_interface.snow.err => pkg/semantic/testdata/scopes/generic_interface.snow.err +0 -0
A pkg/semantic/testdata/scopes/generic_interface.snow.want => pkg/semantic/testdata/scopes/generic_interface.snow.want +40 -0
@@ 0,0 1,40 @@
+1 *semantic.Unit {
+. bool
+. extern
+. f32
+. f64
+. false
+. float
+. i16
+. i32
+. i64
+. i8
+. int
+. string
+. true
+. u16
+. u32
+. u64
+. u8
+. uint
+. void
+. 2 *semantic.Struct {
+. . import
+. . pkg
+. . symbol
+. }
+. 3 *semantic.File {
+. . I
+. . 4 *semantic.Interface {
+. . . $T
+. . . $U
+. . . get_t
+. . . set_u
+. . . 5 *semantic.Fn {
+. . . }
+. . . 6 *semantic.Fn {
+. . . . u
+. . . }
+. . }
+. }
+}
A pkg/semantic/testdata/scopes/interface.snow.err => pkg/semantic/testdata/scopes/interface.snow.err +0 -0
A pkg/semantic/testdata/scopes/interface.snow.want => pkg/semantic/testdata/scopes/interface.snow.want +34 -0
@@ 0,0 1,34 @@
+1 *semantic.Unit {
+. bool
+. extern
+. f32
+. f64
+. false
+. float
+. i16
+. i32
+. i64
+. i8
+. int
+. string
+. true
+. u16
+. u32
+. u64
+. u8
+. uint
+. void
+. 2 *semantic.Struct {
+. . import
+. . pkg
+. . symbol
+. }
+. 3 *semantic.File {
+. . I
+. . 4 *semantic.Interface {
+. . . foo
+. . . 5 *semantic.Fn {
+. . . }
+. . }
+. }
+}
A pkg/semantic/testdata/scopes/interface_satisfied.snow.err => pkg/semantic/testdata/scopes/interface_satisfied.snow.err +0 -0
A pkg/semantic/testdata/scopes/interface_satisfied.snow.want => pkg/semantic/testdata/scopes/interface_satisfied.snow.want +95 -0
@@ 0,0 1,95 @@
+1 *semantic.Unit {
+. bool
+. extern
+. f32
+. f64
+. false
+. float
+. i16
+. i32
+. i64
+. i8
+. int
+. string
+. true
+. u16
+. u32
+. u64
+. u8
+. uint
+. void
+. 2 *semantic.Struct {
+. . import
+. . pkg
+. . symbol
+. }
+. 3 *semantic.File {
+. . Empty
+. . Foo
+. . S1
+. . S2
+. . S3
+. . S4
+. . get_s4
+. . main
+. . 4 *semantic.Interface {
+. . }
+. . 5 *semantic.Interface {
+. . . foo
+. . . 6 *semantic.Fn {
+. . . . i
+. . . }
+. . }
+. . 7 *semantic.Struct {
+. . . bar
+. . . foo
+. . . 8 *semantic.Fn {
+. . . . self
+. . . . x
+. . . }
+. . . 9 *semantic.Fn {
+. . . . s
+. . . . self
+. . . }
+. . }
+. . 10 *semantic.Struct {
+. . . bar
+. . . quz
+. . . 11 *semantic.Fn {
+. . . . s
+. . . . self
+. . . }
+. . . 12 *semantic.Fn {
+. . . . b
+. . . . self
+. . . }
+. . }
+. . 13 *semantic.Struct {
+. . . foo
+. . . 14 *semantic.Fn {
+. . . . self
+. . . . u
+. . . }
+. . }
+. . 15 *semantic.Struct {
+. . . foo
+. . . 16 *semantic.Fn {
+. . . . i
+. . . . self
+. . . }
+. . }
+. . 17 *semantic.Fn {
+. . }
+. . 18 *semantic.Fn {
+. . . empty
+. . . f
+. . . integer
+. . . ls4
+. . . s1
+. . . tup
+. . . tup2
+. . . tup3
+. . . vs4
+. . }
+. }
+}
A pkg/semantic/testdata/scopes/invalid_ref_fn_assign.snow.err => pkg/semantic/testdata/scopes/invalid_ref_fn_assign.snow.err +0 -0
A pkg/semantic/testdata/scopes/invalid_ref_fn_assign.snow.want => pkg/semantic/testdata/scopes/invalid_ref_fn_assign.snow.want +44 -0
@@ 0,0 1,44 @@
+1 *semantic.Unit {
+. bool
+. extern
+. f32
+. f64
+. false
+. float
+. i16
+. i32
+. i64
+. i8
+. int
+. string
+. true
+. u16
+. u32
+. u64
+. u8
+. uint
+. void
+. 2 *semantic.Struct {
+. . import
+. . pkg
+. . symbol
+. }
+. 3 *semantic.File {
+. . S
+. . get_s
+. . main
+. . 4 *semantic.Struct {
+. . . foo
+. . . 5 *semantic.Fn {
+. . . . self
+. . . }
+. . }
+. . 6 *semantic.Fn {
+. . }
+. . 7 *semantic.Fn {
+. . . s1
+. . . s2
+. . . tup
+. . }
+. }
+}
A pkg/semantic/testdata/static/fn_assign_call_interface.snow.err => pkg/semantic/testdata/static/fn_assign_call_interface.snow.err +0 -0
A pkg/semantic/testdata/static/fn_assign_call_interface.snow.want => pkg/semantic/testdata/static/fn_assign_call_interface.snow.want +5 -0
@@ 0,0 1,5 @@
+testdata/fn_assign_call_interface.snow:9:5: println
+testdata/fn_assign_call_interface.snow:9:13: s
+testdata/fn_assign_call_interface.snow:17:18: S
+testdata/fn_assign_call_interface.snow:18:3: iface
+testdata/fn_assign_call_interface.snow:18:9: foo
A pkg/semantic/testdata/static/fn_generic_interface.snow.err => pkg/semantic/testdata/static/fn_generic_interface.snow.err +1 -0
@@ 0,0 1,1 @@
+testdata/fn_generic_interface.snow:23:14: cannot assign type struct G[bool] to variable of type interface I[int]
A pkg/semantic/testdata/static/fn_generic_interface.snow.want => pkg/semantic/testdata/static/fn_generic_interface.snow.want +15 -0
@@ 0,0 1,15 @@
+testdata/fn_generic_interface.snow:14:26: S
+testdata/fn_generic_interface.snow:15:13: ifaceInt
+testdata/fn_generic_interface.snow:15:22: foo
+testdata/fn_generic_interface.snow:17:14: gInt
+testdata/fn_generic_interface.snow:17:19: foo
+testdata/fn_generic_interface.snow:19:14: G
+testdata/fn_generic_interface.snow:19:16: int
+testdata/fn_generic_interface.snow:20:9: ifaceInt
+testdata/fn_generic_interface.snow:20:18: foo
+testdata/fn_generic_interface.snow:23:14: G
+testdata/fn_generic_interface.snow:23:16: bool
+testdata/fn_generic_interface.snow:27:17: G
+testdata/fn_generic_interface.snow:27:19: string
+testdata/fn_generic_interface.snow:28:3: ifaceString
+testdata/fn_generic_interface.snow:28:15: foo
A pkg/semantic/testdata/static/generic_interface.snow.err => pkg/semantic/testdata/static/generic_interface.snow.err +1 -0
@@ 0,0 1,1 @@
+main function missing
A pkg/semantic/testdata/static/generic_interface.snow.want => pkg/semantic/testdata/static/generic_interface.snow.want +0 -0
A pkg/semantic/testdata/static/interface.snow.err => pkg/semantic/testdata/static/interface.snow.err +1 -0
@@ 0,0 1,1 @@
+main function missing
A pkg/semantic/testdata/static/interface.snow.want => pkg/semantic/testdata/static/interface.snow.want +0 -0
A pkg/semantic/testdata/static/interface_satisfied.snow.err => pkg/semantic/testdata/static/interface_satisfied.snow.err +7 -0
@@ 0,0 1,7 @@
+testdata/interface_satisfied.snow:39:11: cannot assign type int to variable of type interface Empty
+testdata/interface_satisfied.snow:42:7: cannot assign type struct S2 to variable of type interface Foo
+testdata/interface_satisfied.snow:43:7: cannot assign type struct S3 to variable of type interface Foo
+testdata/interface_satisfied.snow:51:7: cannot assign type struct S4 to variable of type interface Foo
+testdata/interface_satisfied.snow:53:7: cannot assign type struct S4 to variable of type interface Foo
+testdata/interface_satisfied.snow:59:9: cannot assign type (int, struct S4) to variable of type (int, interface Foo)
+testdata/interface_satisfied.snow:63:10: cannot assign type (int, struct S4, (bool, struct S4)) to variable of type (int, interface Foo, (bool, interface Foo))
A pkg/semantic/testdata/static/interface_satisfied.snow.want => pkg/semantic/testdata/static/interface_satisfied.snow.want +25 -0
@@ 0,0 1,25 @@
+testdata/interface_satisfied.snow:27:10: S4
+testdata/interface_satisfied.snow:36:11: empty
+testdata/interface_satisfied.snow:37:11: f
+testdata/interface_satisfied.snow:38:11: s1
+testdata/interface_satisfied.snow:39:11: integer
+testdata/interface_satisfied.snow:41:7: S1
+testdata/interface_satisfied.snow:42:7: S2
+testdata/interface_satisfied.snow:43:7: S3
+testdata/interface_satisfied.snow:45:13: S4
+testdata/interface_satisfied.snow:46:13: S4
+testdata/interface_satisfied.snow:49:7: vs4
+testdata/interface_satisfied.snow:51:7: ls4
+testdata/interface_satisfied.snow:53:7: S4
+testdata/interface_satisfied.snow:57:13: vs4
+testdata/interface_satisfied.snow:59:13: ls4
+testdata/interface_satisfied.snow:62:14: vs4
+testdata/interface_satisfied.snow:62:20: true
+testdata/interface_satisfied.snow:62:26: vs4
+testdata/interface_satisfied.snow:63:14: ls4
+testdata/interface_satisfied.snow:63:20: true
+testdata/interface_satisfied.snow:63:26: get_s4
+testdata/interface_satisfied.snow:67:15: vs4
+testdata/interface_satisfied.snow:67:21: ls4
+testdata/interface_satisfied.snow:68:15: vs4
+testdata/interface_satisfied.snow:68:21: get_s4
A pkg/semantic/testdata/static/invalid_ref_fn_assign.snow.err => pkg/semantic/testdata/static/invalid_ref_fn_assign.snow.err +2 -0
@@ 0,0 1,2 @@
+testdata/invalid_ref_fn_assign.snow:14:16: cannot access ref fn foo; left-hand side must be var, is let
+testdata/invalid_ref_fn_assign.snow:15:21: cannot access ref fn foo; left-hand side must be var, is value
A pkg/semantic/testdata/static/invalid_ref_fn_assign.snow.want => pkg/semantic/testdata/static/invalid_ref_fn_assign.snow.want +9 -0
@@ 0,0 1,9 @@
+testdata/invalid_ref_fn_assign.snow:6:10: S
+testdata/invalid_ref_fn_assign.snow:11:12: S
+testdata/invalid_ref_fn_assign.snow:12:12: S
+testdata/invalid_ref_fn_assign.snow:13:13: s1
+testdata/invalid_ref_fn_assign.snow:13:16: foo
+testdata/invalid_ref_fn_assign.snow:14:13: s2
+testdata/invalid_ref_fn_assign.snow:14:16: foo
+testdata/invalid_ref_fn_assign.snow:15:13: get_s
+testdata/invalid_ref_fn_assign.snow:15:21: foo
M pkg/semantic/testdata/types/cycle.snow.want => pkg/semantic/testdata/types/cycle.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/cycle.snow [3, 0, 0]
+file testdata/cycle.snow [3, 0, 0, 0]
var= A [var: unresolved]
ident B [var: unresolved]
var= B [var: unresolved]
M pkg/semantic/testdata/types/empty.snow.want => pkg/semantic/testdata/types/empty.snow.want +1 -1
@@ 1,1 1,1 @@
-file testdata/empty.snow [0, 0, 0]
+file testdata/empty.snow [0, 0, 0, 0]
M pkg/semantic/testdata/types/fn.snow.want => pkg/semantic/testdata/types/fn.snow.want +1 -1
@@ 1,3 1,3 @@
-file testdata/fn.snow [0, 1, 0]
+file testdata/fn.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [0]
M pkg/semantic/testdata/types/fn_access_invalid_struct_field.snow.want => pkg/semantic/testdata/types/fn_access_invalid_struct_field.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_access_invalid_struct_field.snow [0, 1, 1]
+file testdata/fn_access_invalid_struct_field.snow [0, 1, 1, 0]
fn test [let: () -> void]
block [4]
var: s [var: struct S]
@@ 16,6 16,6 @@ file testdata/fn_access_invalid_struct_field.snow [0, 1, 1]
select [invalid: unresolved]
ident s [var: struct S]
ident z [invalid: unresolved]
- struct S [1, 0, 0] [type: struct S]
+ struct S [1, 0, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
M pkg/semantic/testdata/types/fn_access_struct_type_field.snow.want => pkg/semantic/testdata/types/fn_access_struct_type_field.snow.want +2 -2
@@ 1,10 1,10 @@
-file testdata/fn_access_struct_type_field.snow [0, 1, 1]
+file testdata/fn_access_struct_type_field.snow [0, 1, 1, 0]
fn test [let: () -> void]
block [1]
var= y [var: int]
select [invalid: int]
ident Point [type: struct Point]
ident x [var: int]
- struct Point [1, 0, 0] [type: struct Point]
+ struct Point [1, 0, 0, 0] [type: struct Point]
var: x [var: int]
ident int [type: int]
M pkg/semantic/testdata/types/fn_access_var_outside_struct.snow.want => pkg/semantic/testdata/types/fn_access_var_outside_struct.snow.want +3 -3
@@ 1,9 1,9 @@
-file testdata/fn_access_var_outside_struct.snow [0, 1, 0]
+file testdata/fn_access_var_outside_struct.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [2]
var: x [var: int]
ident int [type: int]
- struct S [1, 1, 1] [type: struct S]
+ struct S [1, 1, 1, 0] [type: struct S]
var: y [var: string]
ident string [type: string]
fn get [let: () -> int]
@@ 11,7 11,7 @@ file testdata/fn_access_var_outside_struct.snow [0, 1, 0]
block [1]
return
ident x [var: int]
- struct T [0, 1, 0] [type: struct T]
+ struct T [0, 1, 0, 0] [type: struct T]
fn get [let: () -> string]
ident string [type: string]
block [1]
A pkg/semantic/testdata/types/fn_assign_call_interface.snow.err => pkg/semantic/testdata/types/fn_assign_call_interface.snow.err +0 -0
A pkg/semantic/testdata/types/fn_assign_call_interface.snow.want => pkg/semantic/testdata/types/fn_assign_call_interface.snow.want +31 -0
@@ 0,0 1,31 @@
+file testdata/fn_assign_call_interface.snow [0, 2, 1, 1]
+ fn println [let: (string) -> void]
+ @ [import, symbol] [2] [value: struct extern]
+ ident extern [type: struct extern]
+ string ["fmt"] [const: string]
+ string ["Println"] [const: string]
+ let: s [let: string]
+ ident string [type: string]
+ fn main [let: () -> void]
+ block [2]
+ let:= iface [let: interface I]
+ ident I [type: interface I]
+ call [s] [1] [value: struct S]
+ ident S [type: struct S]
+ string ["hello!"] [const: string]
+ expr
+ call [0] [value: void]
+ select [let: () -> void]
+ ident iface [let: interface I]
+ ident foo [let: () -> void]
+ struct S [1, 1, 0, 0] [type: struct S]
+ let: s [let: string]
+ ident string [type: string]
+ fn foo [let: () -> void]
+ block [1]
+ expr
+ call [1] [value: void]
+ ident println [let: (string) -> void]
+ ident s [let: string]
+ interface I [1] [type: interface I]
+ fn foo [let: () -> void]
M pkg/semantic/testdata/types/fn_assign_invalid.snow.want => pkg/semantic/testdata/types/fn_assign_invalid.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_assign_invalid.snow [0, 1, 0]
+file testdata/fn_assign_invalid.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [2]
var: x [var: f64]
M pkg/semantic/testdata/types/fn_assign_let.snow.want => pkg/semantic/testdata/types/fn_assign_let.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_assign_let.snow [0, 1, 0]
+file testdata/fn_assign_let.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [2]
let= x [let: int]
M pkg/semantic/testdata/types/fn_assign_struct_fields.snow.want => pkg/semantic/testdata/types/fn_assign_struct_fields.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_assign_struct_fields.snow [0, 1, 1]
+file testdata/fn_assign_struct_fields.snow [0, 1, 1, 0]
fn test [let: () -> void]
block [8]
var: vs [var: struct S]
@@ 35,7 35,7 @@ file testdata/fn_assign_struct_fields.snow [0, 1, 1]
ident ls [let: struct S]
ident z [let: () -> void]
ident test [let: () -> void]
- struct S [2, 1, 0] [type: struct S]
+ struct S [2, 1, 0, 0] [type: struct S]
let: x [let: int]
ident int [type: int]
var: y [var: int]
M pkg/semantic/testdata/types/fn_assign_struct_method_to_var.snow.want => pkg/semantic/testdata/types/fn_assign_struct_method_to_var.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_assign_struct_method_to_var.snow [0, 1, 1]
+file testdata/fn_assign_struct_method_to_var.snow [0, 1, 1, 0]
fn main [let: () -> void]
block [6]
var: s [var: struct S]
@@ 28,7 28,7 @@ file testdata/fn_assign_struct_method_to_var.snow [0, 1, 1]
select [let: (int) -> void]
ident s2 [let: struct S]
ident set [let: (int) -> void]
- struct S [1, 2, 0] [type: struct S]
+ struct S [1, 2, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
fn get [let: () -> int]
M pkg/semantic/testdata/types/fn_assign_type.snow.want => pkg/semantic/testdata/types/fn_assign_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_assign_type.snow [0, 1, 0]
+file testdata/fn_assign_type.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [1]
assign
M pkg/semantic/testdata/types/fn_assign_unifying_type.snow.want => pkg/semantic/testdata/types/fn_assign_unifying_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_assign_unifying_type.snow [0, 1, 0]
+file testdata/fn_assign_unifying_type.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [3]
var: x [var: u8]
M pkg/semantic/testdata/types/fn_call_fn_value_with_labels.snow.want => pkg/semantic/testdata/types/fn_call_fn_value_with_labels.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_call_fn_value_with_labels.snow [0, 2, 0]
+file testdata/fn_call_fn_value_with_labels.snow [0, 2, 0, 0]
fn add [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/types/fn_call_struct_init.snow.want => pkg/semantic/testdata/types/fn_call_struct_init.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_call_struct_init.snow [0, 1, 1]
+file testdata/fn_call_struct_init.snow [0, 1, 1, 0]
fn main [let: () -> void]
block [1]
var= s [var: struct S]
@@ 6,7 6,7 @@ file testdata/fn_call_struct_init.snow [0, 1, 1]
ident S [type: struct S]
int [1] [const: int]
string ["a"] [const: string]
- struct S [2, 0, 0] [type: struct S]
+ struct S [2, 0, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
let: y [let: string]
M pkg/semantic/testdata/types/fn_call_struct_init_no_label.snow.want => pkg/semantic/testdata/types/fn_call_struct_init_no_label.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_call_struct_init_no_label.snow [0, 1, 1]
+file testdata/fn_call_struct_init_no_label.snow [0, 1, 1, 0]
fn main [let: () -> void]
block [1]
var= s [var: struct S]
@@ 6,7 6,7 @@ file testdata/fn_call_struct_init_no_label.snow [0, 1, 1]
ident S [type: struct S]
int [1] [const: int]
string ["a"] [const: string]
- struct S [2, 0, 0] [type: struct S]
+ struct S [2, 0, 0, 0] [type: struct S]
var: x [var: int]
ident int [type: int]
let: y [let: string]
M pkg/semantic/testdata/types/fn_call_struct_init_only_required_no_order.snow.want => pkg/semantic/testdata/types/fn_call_struct_init_only_required_no_order.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_call_struct_init_only_required_no_order.snow [0, 1, 1]
+file testdata/fn_call_struct_init_only_required_no_order.snow [0, 1, 1, 0]
fn main [let: () -> void]
block [2]
var= s [var: struct S]
@@ 10,7 10,7 @@ file testdata/fn_call_struct_init_only_required_no_order.snow [0, 1, 1]
call [b] [1] [value: struct S]
ident S [type: struct S]
string ["b"] [const: string]
- struct S [3, 0, 0] [type: struct S]
+ struct S [3, 0, 0, 0] [type: struct S]
var: a [var: int]
ident int [type: int]
let: b [let: string]
M pkg/semantic/testdata/types/fn_call_struct_method.snow.want => pkg/semantic/testdata/types/fn_call_struct_method.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_call_struct_method.snow [0, 1, 1]
+file testdata/fn_call_struct_method.snow [0, 1, 1, 0]
fn test [let: () -> void]
block [2]
var: p [var: struct Point]
@@ 9,7 9,7 @@ file testdata/fn_call_struct_method.snow [0, 1, 1]
ident p [var: struct Point]
ident add [let: (int) -> void]
int [1] [const: int]
- struct Point [1, 1, 0] [type: struct Point]
+ struct Point [1, 1, 0, 0] [type: struct Point]
var: x [var: int]
ident int [type: int]
fn add [let: (int) -> void]
M pkg/semantic/testdata/types/fn_call_unifying_type.snow.want => pkg/semantic/testdata/types/fn_call_unifying_type.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_call_unifying_type.snow [0, 2, 0]
+file testdata/fn_call_unifying_type.snow [0, 2, 0, 0]
fn add [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/types/fn_call_with_invalid_labels.snow.want => pkg/semantic/testdata/types/fn_call_with_invalid_labels.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_call_with_invalid_labels.snow [0, 2, 0]
+file testdata/fn_call_with_invalid_labels.snow [0, 2, 0, 0]
fn add [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/types/fn_call_with_labels.snow.want => pkg/semantic/testdata/types/fn_call_with_labels.snow.want +2 -2
@@ 1,4 1,4 @@
-file testdata/fn_call_with_labels.snow [0, 2, 1]
+file testdata/fn_call_with_labels.snow [0, 2, 1, 0]
fn add [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
@@ 45,7 45,7 @@ file testdata/fn_call_with_labels.snow [0, 2, 1]
ident s [var: struct S]
ident do [let: (int) -> void]
int [6] [const: int]
- struct S [0, 1, 0] [type: struct S]
+ struct S [0, 1, 0, 0] [type: struct S]
fn do [let: (int) -> void]
let: z [let: int]
ident int [type: int]
M pkg/semantic/testdata/types/fn_call_wrong_arity.snow.want => pkg/semantic/testdata/types/fn_call_wrong_arity.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_call_wrong_arity.snow [0, 2, 0]
+file testdata/fn_call_wrong_arity.snow [0, 2, 0, 0]
fn add [let: (int, int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/types/fn_compare.snow.want => pkg/semantic/testdata/types/fn_compare.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_compare.snow [0, 1, 0]
+file testdata/fn_compare.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [2]
var= x [var: int]
M pkg/semantic/testdata/types/fn_complex_selectors.snow.want => pkg/semantic/testdata/types/fn_complex_selectors.snow.want +3 -3
@@ 1,4 1,4 @@
-file testdata/fn_complex_selectors.snow [0, 2, 1]
+file testdata/fn_complex_selectors.snow [0, 2, 1, 0]
fn create [let: () -> struct S]
ident S [type: struct S]
block [2]
@@ 36,12 36,12 @@ file testdata/fn_complex_selectors.snow [0, 2, 1]
ident s2 [var: struct T]
ident do [let: () -> (int, () -> int)]
ident 1 [value: () -> int]
- struct S [2, 0, 1] [type: struct S]
+ struct S [2, 0, 1, 0] [type: struct S]
var: s1 [var: int]
ident int [type: int]
var: s2 [var: struct T]
ident T [type: struct T]
- struct T [1, 1, 0] [type: struct T]
+ struct T [1, 1, 0, 0] [type: struct T]
var: t1 [var: string]
ident string [type: string]
fn do [let: () -> (int, () -> int)]
M pkg/semantic/testdata/types/fn_duplicate_param_name.snow.want => pkg/semantic/testdata/types/fn_duplicate_param_name.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_duplicate_param_name.snow [0, 1, 0]
+file testdata/fn_duplicate_param_name.snow [0, 1, 0, 0]
fn dup [let: (int, string) -> void]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/types/fn_explicit_void.snow.want => pkg/semantic/testdata/types/fn_explicit_void.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_explicit_void.snow [0, 3, 0]
+file testdata/fn_explicit_void.snow [0, 3, 0, 0]
fn do_nothing [let: () -> void]
ident void [type: void]
block [1]
M pkg/semantic/testdata/types/fn_extern_pkg_before_conflict_name.snow.want => pkg/semantic/testdata/types/fn_extern_pkg_before_conflict_name.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_extern_pkg_before_conflict_name.snow [0, 1, 0]
+file testdata/fn_extern_pkg_before_conflict_name.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [4]
fn print [let: (int) -> void]
M pkg/semantic/testdata/types/fn_extern_pkg_conflict_name.snow.want => pkg/semantic/testdata/types/fn_extern_pkg_conflict_name.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_extern_pkg_conflict_name.snow [0, 1, 0]
+file testdata/fn_extern_pkg_conflict_name.snow [0, 1, 0, 0]
fn test [let: () -> void]
block [4]
var: fmt [var: int]
M pkg/semantic/testdata/types/fn_extern_ref_method.snow.want => pkg/semantic/testdata/types/fn_extern_ref_method.snow.want +2 -2
@@ 1,7 1,7 @@
-file testdata/fn_extern_ref_method.snow [0, 1, 0]
+file testdata/fn_extern_ref_method.snow [0, 1, 0, 0]
fn main [let: () -> void]
block [1]
- struct S [0, 1, 0] [type: struct S]
+ struct S [0, 1, 0, 0] [type: struct S]
ref fn f [let: () -> void]
@ [import, symbol] [2] [value: struct extern]
ident extern [type: struct extern]
M pkg/semantic/testdata/types/fn_extern_with_body.snow.want => pkg/semantic/testdata/types/fn_extern_with_body.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_extern_with_body.snow [0, 1, 0]
+file testdata/fn_extern_with_body.snow [0, 1, 0, 0]
fn test [let: () -> void]
@ [import, symbol] [2] [value: struct extern]
ident extern [type: struct extern]
M pkg/semantic/testdata/types/fn_fn_arg.snow.want => pkg/semantic/testdata/types/fn_fn_arg.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_fn_arg.snow [0, 3, 0]
+file testdata/fn_fn_arg.snow [0, 3, 0, 0]
fn do [let: (int, (int) -> int) -> int]
let: x [let: int]
ident int [type: int]
M pkg/semantic/testdata/types/fn_generic_decl_after_inst.snow.want => pkg/semantic/testdata/types/fn_generic_decl_after_inst.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_generic_decl_after_inst.snow [0, 2, 0]
+file testdata/fn_generic_decl_after_inst.snow [0, 2, 0, 0]
fn main [let: () -> void]
block [1]
let= a [let: int]
M pkg/semantic/testdata/types/fn_generic_fn_uses_generic_fn.snow.want => pkg/semantic/testdata/types/fn_generic_fn_uses_generic_fn.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_generic_fn_uses_generic_fn.snow [0, 3, 0]
+file testdata/fn_generic_fn_uses_generic_fn.snow [0, 3, 0, 0]
fn A [$1] [let: ($T) -> $T]
generic type $T [type: $T]
let: v [let: $T]
M pkg/semantic/testdata/types/fn_generic_identity.snow.want => pkg/semantic/testdata/types/fn_generic_identity.snow.want +1 -1
@@ 1,4 1,4 @@
-file testdata/fn_generic_identity.snow [0, 5, 0]
+file testdata/fn_generic_identity.snow [0, 5, 0, 0]
fn id [$1] [let: ($T) -> $T]