Skip to content

Commit

Permalink
fix: correct typed-nil handling (#1891)
Browse files Browse the repository at this point in the history
update: ready for review.

====================================
the dependency relationship: #1890 <- this one.

---------

Co-authored-by: Morgan Bazalgette <[email protected]>
  • Loading branch information
ltzmaxwell and thehowl authored Feb 18, 2025
1 parent 0a3df04 commit 64ea826
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 2 deletions.
13 changes: 13 additions & 0 deletions gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,19 @@ func preprocess1(store Store, ctx BlockNode, n Node) Node {
if !constConverted {
convertConst(store, last, n, arg0, nil)
}

// check legal type for nil
if arg0.IsUndefined() {
switch ct.Kind() { // special case for nil conversion check.
case SliceKind, PointerKind, FuncKind, MapKind, InterfaceKind, ChanKind:
convertConst(store, last, n, arg0, ct)
default:
panic(fmt.Sprintf(
"cannot convert %v to %v",
arg0, ct.Kind()))
}
}

// evaluate the new expression.
cx := evalConst(store, last, n)
// Though cx may be undefined if ct is interface,
Expand Down
5 changes: 5 additions & 0 deletions gnovm/pkg/gnolang/values_conversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ func ConvertTo(alloc *Allocator, store Store, tv *TypedValue, t Type, isConst bo
GNO_CASE:
// special case for interface target
if t.Kind() == InterfaceKind {
if tv.IsUndefined() && tv.T == nil {
if _, ok := t.(*NativeType); !ok { // no support for native now
tv.T = t
}
}
return
}
// special case for undefined/nil source
Expand Down
2 changes: 1 addition & 1 deletion gnovm/tests/files/convert4.gno
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ func main() {
}

// Error:
// main/files/convert4.gno:4:10: cannot convert (undefined) to int
// main/files/convert4.gno:4:10: cannot convert (const (undefined)) to IntKind
2 changes: 1 addition & 1 deletion gnovm/tests/files/convert5.gno
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ func main() {
}

// Error:
// main/files/convert5.gno:3:1: cannot convert (undefined) to int
// main/files/convert5.gno:3:1: cannot convert (const (undefined)) to IntKind
27 changes: 27 additions & 0 deletions gnovm/tests/files/types/cmp_iface_0_stdlibs.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"errors"
"strconv"
)

type Error int64

func (e Error) Error() string {
return "error: " + strconv.Itoa(int(e))
}

var errCmp = errors.New("XXXX")

// special case:
// one is interface
func main() {
if Error(0) == errCmp {
println("what the firetruck?")
} else {
println("something else")
}
}

// Output:
// something else
27 changes: 27 additions & 0 deletions gnovm/tests/files/types/cmp_iface_3_stdlibs.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"errors"
"strconv"
)

type Error int64

func (e Error) Error() string {
return "error: " + strconv.Itoa(int(e))
}

var errCmp = errors.New("XXXX")

// special case:
// one is interface
func main() {
if Error(1) == errCmp {
println("what the firetruck?")
} else {
println("something else")
}
}

// Output:
// something else
27 changes: 27 additions & 0 deletions gnovm/tests/files/types/cmp_iface_5_stdlibs.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"errors"
"strconv"
)

type Error int64

func (e Error) Error() string {
return "error: " + strconv.Itoa(int(e))
}

var errCmp = errors.New("XXXX")

// special case:
// one is interface
func main() {
if errCmp == int64(1) {
println("what the firetruck?")
} else {
println("something else")
}
}

// Error:
// main/files/types/cmp_iface_5_stdlibs.gno:19:5: int64 does not implement .uverse.error (missing method Error)
18 changes: 18 additions & 0 deletions gnovm/tests/files/types/typed_nil_a.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

import "fmt"

type integer int

func main() {
// illegal conversion
// should not work
if integer(nil) == nil {
fmt.Println("integer is nil")
} else {
fmt.Println("integer is not nil")
}
}

// Error:
// main/files/types/typed_nil_a.gno:10:5: cannot convert (const (undefined)) to IntKind
16 changes: 16 additions & 0 deletions gnovm/tests/files/types/typed_nil_b.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package main

import "fmt"

type integer *int

func main() {
println(integer(nil))
fmt.Println(integer(nil))
fmt.Printf("%T\n", integer(nil))
}

// Output:
// (nil main.integer)
// <nil>
// *int
12 changes: 12 additions & 0 deletions gnovm/tests/files/types/typed_nil_c.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

import "fmt"

func main() {
println(interface{}(nil) == (*int)(nil))
fmt.Printf("%T\n", interface{}(nil))
}

// Output:
// false
// <nil>

0 comments on commit 64ea826

Please sign in to comment.