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/interface_satisfied.snow => pkg/semantic/testdata/interface_satisfied.snow +13 -1
@@ 23,6 23,10 @@ struct S4 {
ref fn foo(i: int) -> int {}
}
+fn get_s4() -> S4 {
+ return S4()
+}
+
fn main() {
var empty: Empty
var f: Foo
@@ 48,10 52,18 @@ fn main() {
# not this either, rhs is a value
f = S4()
- var tup = (int, Foo)
+ 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))
+ tup2 = (1, ls4, (true, get_s4()))
+
+ 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)
+}
M pkg/semantic/testdata/scopes/interface_satisfied.snow.want => pkg/semantic/testdata/scopes/interface_satisfied.snow.want +5 -0
@@ 30,6 30,7 @@
. . S2
. . S3
. . S4
+. . get_s4
. . main
. . 4 *semantic.Interface {
. . }
@@ 78,11 79,15 @@
. . . }
. . }
. . 17 *semantic.Fn {
+. . }
+. . 18 *semantic.Fn {
. . . empty
. . . f
. . . integer
. . . ls4
. . . s1
+. . . tup
+. . . tup2
. . . 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/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
A pkg/semantic/testdata/types/invalid_ref_fn_assign.snow.err => pkg/semantic/testdata/types/invalid_ref_fn_assign.snow.err +0 -0
A pkg/semantic/testdata/types/invalid_ref_fn_assign.snow.want => pkg/semantic/testdata/types/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/typeassign_pass.go => pkg/semantic/typeassign_pass.go +2 -1
@@ 97,7 97,8 @@ func (t *typeassignVisitor) Visit(n Node) Visitor {
n.typ = sigt
case *Var:
- // type of var is either its explicit type or the type of its initialization
+ // type of var is either its explicit type or the type of its initialization.
+ // Its ctx (type context) is set during translation pass, based on var or let keyword.
var typ Type = unresolvedType{}
if n.TypeExpr != nil {
Walk(t, n.TypeExpr)