Add a nothing built-in literal
diff --git a/cmd/wuffs-c/internal/cgen/statement.go b/cmd/wuffs-c/internal/cgen/statement.go
index aaaad05..64f65ea 100644
--- a/cmd/wuffs-c/internal/cgen/statement.go
+++ b/cmd/wuffs-c/internal/cgen/statement.go
@@ -446,7 +446,7 @@
b.writes("return ")
if g.currFunk.astFunc.Out() == nil {
- return fmt.Errorf("TODO: allow empty return type (when not suspendible)")
+ b.writes("((wuffs_base__empty_struct){})")
} else if err := g.writeExpr(b, retExpr, depth); err != nil {
return err
}
diff --git a/lang/check/bounds.go b/lang/check/bounds.go
index 615dfc7..9acb3f3 100644
--- a/lang/check/bounds.go
+++ b/lang/check/bounds.go
@@ -308,7 +308,7 @@
if q.astFunc.Effect().Coroutine() {
lTyp = typeExprStatus
} else if lTyp == nil {
- return fmt.Errorf("TODO: allow returning nothing")
+ lTyp = typeExprEmptyStruct
}
if _, err := q.bcheckAssignment1(nil, lTyp, t.IDEq, n.Value()); err != nil {
return err
diff --git a/lang/check/type.go b/lang/check/type.go
index eedc54e..668e94b 100644
--- a/lang/check/type.go
+++ b/lang/check/type.go
@@ -173,7 +173,7 @@
if q.astFunc.Effect().Coroutine() {
lTyp = typeExprStatus
} else if lTyp == nil {
- return fmt.Errorf("TODO: allow returning nothing")
+ lTyp = typeExprEmptyStruct
}
value := n.Value()
if err := q.tcheckExpr(value, 0); err != nil {
@@ -391,6 +391,11 @@
n.SetMType(typeExprBool)
return nil
+ case t.IDNothing:
+ n.SetConstValue(zero)
+ n.SetMType(typeExprEmptyStruct)
+ return nil
+
case t.IDNullptr:
n.SetConstValue(zero)
n.SetMType(typeExprNullptr)
diff --git a/lang/token/list.go b/lang/token/list.go
index 0dd118c..254a026 100644
--- a/lang/token/list.go
+++ b/lang/token/list.go
@@ -382,8 +382,9 @@
IDFalse = ID(0xB0)
IDTrue = ID(0xB1)
- IDNullptr = ID(0xB2)
- IDOk = ID(0xB3)
+ IDNothing = ID(0xB2)
+ IDNullptr = ID(0xB3)
+ IDOk = ID(0xB4)
ID0 = ID(0xC0)
ID1 = ID(0xC1)
@@ -702,6 +703,7 @@
IDFalse: "false",
IDTrue: "true",
+ IDNothing: "nothing",
IDNullptr: "nullptr",
IDOk: "ok",