~mna/snow unlisted

9192873ba99a797d553d354f6bd7ee1f66627ed8 — Martin Angers 9 months ago 6ca7099
pkg/semantic: more tests around ref struct fns and interfaces deep in tuples
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)