Skip to content

Commit

Permalink
eval,typecheck: implement naked returns
Browse files Browse the repository at this point in the history
Fixes #188.
  • Loading branch information
sbinet committed Jan 6, 2018
1 parent 6fff279 commit a51db59
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 6 deletions.
44 changes: 44 additions & 0 deletions eval/testdata/func10.ng
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
func f1() (i, j int) { return }

if v1, v2 := f1(); v1 != 0 || v2 != 0 {
panic("ERROR 1")
}

func f2() (i, j int) {
i = 1
j = 2
return
}

if v1, v2 := f2(); v1 != 1 || v2 != 2 {
panic("ERROR 2")
}

func f3(i int) (v int) {
if i == 0 {
return
}
if i == 1 {
v = 1
return
}
if i == 2 {
v = 2
return v
}
return
}

if v := f3(0); v != 0 {
panic("ERROR 3.1")
}

if v := f3(1); v != 1 {
panic("ERROR 3.2")
}

if v := f3(2); v != 2 {
panic("ERROR 3.3")
}

print("OK")
1 change: 1 addition & 0 deletions eval/testdata/func11_error.ng
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
func f() (i, j, k int) { return 1, 2 } // ERROR: not enough arguments to return
24 changes: 18 additions & 6 deletions typecheck/typecheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,13 +453,23 @@ func (c *Checker) stmt(s stmt.Stmt, retType *tipe.Tuple, retNames []string) tipe
c.errorfmt("too many arguments to return")
return nil
case len(s.Exprs) < len(retType.Elems):
c.errorfmt("not enough arguments to return")
return nil
if !(len(s.Exprs) == 0 && len(retNames) == len(retType.Elems)) {
c.errorfmt("not enough arguments to return")
return nil
}
}
var partials []partial
for i, e := range s.Exprs {
partials = append(partials, c.expr(e))
c.constrainUntyped(&partials[i], retType.Elems[i])
switch len(s.Exprs) {
case 0:
partials = make([]partial, len(retType.Elems))
for i, t := range retType.Elems {
c.constrainUntyped(&partials[i], t)
}
default:
for i, e := range s.Exprs {
partials = append(partials, c.expr(e))
c.constrainUntyped(&partials[i], retType.Elems[i])
}
}
for _, p := range partials {
if p.mode == modeInvalid {
Expand Down Expand Up @@ -2086,12 +2096,14 @@ func (c *Checker) exprPartial(e expr.Expr, hint typeHint) (p partial) {
}
}
}
var retNames []string
if e.Type.Results != nil {
for i, t := range e.Type.Results.Elems {
e.Type.Results.Elems[i], _ = c.resolve(t)
}
for i, rname := range e.ResultNames {
if rname != "" {
retNames = append(retNames, rname)
t := e.Type.Results.Elems[i]
c.addObj(&Obj{
Name: rname,
Expand All @@ -2102,7 +2114,7 @@ func (c *Checker) exprPartial(e expr.Expr, hint typeHint) (p partial) {
}
}
}
c.stmt(e.Body.(*stmt.Block), e.Type.Results, e.ResultNames)
c.stmt(e.Body.(*stmt.Block), e.Type.Results, retNames)
for _, pname := range e.ParamNames {
delete(c.cur.foundInParent, pname)
}
Expand Down

0 comments on commit a51db59

Please sign in to comment.