Skip to content

Commit

Permalink
fix: default untyped to uint when necessary (gnolang#2024)
Browse files Browse the repository at this point in the history
Closes gnolang#2004. This change allows for passing a value to `defaultTypeOf`.
In the case where we are looking for the default value of an untyped
int, it can use the value, if it exists, in order to determine whether
the default type should be a signed or unsigned int.
<!-- please provide a detailed description of the changes made in this
pull request. -->

<details><summary>Contributors' checklist...</summary>

- [x] Added new tests, or not needed, or not feasible
- [x] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [x] Updated the official documentation or not needed
- [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [x] Added references to related issues and PRs
- [x] Provided any useful hints for running manual tests
- [x] Added new benchmarks to [generated
graphs](https://gnoland.github.io/benchmarks), if any. More info
[here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
</details>

---------

Co-authored-by: Miloš Živković <[email protected]>
  • Loading branch information
deelawn and zivkovicmilos authored Jun 14, 2024
1 parent b42d0f0 commit e7e47d2
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 8 deletions.
2 changes: 1 addition & 1 deletion gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -2477,7 +2477,7 @@ func checkOrConvertType(store Store, last BlockNode, x *Expr, t Type, autoNative
// convert type
if isUntyped(xt) { // convert if x is untyped literal
if t == nil {
t = defaultTypeOf(xt)
t = defaultTypeOf(xt, nil)
}
// Push type into expr if qualifying binary expr.
if bx, ok := (*x).(*BinaryExpr); ok {
Expand Down
19 changes: 14 additions & 5 deletions gnovm/pkg/gnolang/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1203,8 +1203,8 @@ func (ft *FuncType) Specify(store Store, argTVs []TypedValue, isVarg bool) *Func
continue
} else if vargt == nil {
vargt = varg.T
} else if isUntyped(varg.T) && vargt.TypeID() == defaultTypeOf(varg.T).TypeID() {
vargt = defaultTypeOf(varg.T)
} else if isUntyped(varg.T) && vargt.TypeID() == defaultTypeOf(varg.T, varg.V).TypeID() {
vargt = defaultTypeOf(varg.T, varg.V)
} else if vargt.TypeID() != varg.T.TypeID() {
panic(fmt.Sprintf(
"incompatible varg types: expected %v, got %s",
Expand Down Expand Up @@ -2281,14 +2281,23 @@ func isDataByte(t Type) bool {

// TODO move untyped const stuff to preprocess.go.
// TODO associate with ConvertTo() in documentation.
func defaultTypeOf(t Type) Type {
func defaultTypeOf(t Type, v Value) Type {
switch t {
case UntypedBoolType:
return BoolType
case UntypedRuneType:
return Int32Type
case UntypedBigintType:
return IntType
typeVal := IntType
if bigintValue, ok := v.(BigintValue); ok {
if bigintValue.V != nil && bigintValue.V.Sign() == 1 && !bigintValue.V.IsInt64() {
// Use an unsigned type if the value is positive and we know
// it won't fit in an int64.
typeVal = Uint64Type
}
}

return typeVal
case UntypedBigdecType:
return Float64Type
case UntypedStringType:
Expand Down Expand Up @@ -2514,7 +2523,7 @@ func specifyType(store Store, lookup map[Name]Type, tmpl Type, spec Type, specTy
return // ok
} else {
if isUntyped(spec) {
spec = defaultTypeOf(spec)
spec = defaultTypeOf(spec, nil)
}
lookup[ct.Generic] = spec
return // ok
Expand Down
2 changes: 1 addition & 1 deletion gnovm/pkg/gnolang/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -1594,7 +1594,7 @@ func (tv *TypedValue) Assign(alloc *Allocator, tv2 TypedValue, cu bool) {
}
*tv = tv2.Copy(alloc)
if cu && isUntyped(tv.T) {
ConvertUntypedTo(tv, defaultTypeOf(tv.T))
ConvertUntypedTo(tv, defaultTypeOf(tv.T, tv.V))
}
}

Expand Down
2 changes: 1 addition & 1 deletion gnovm/pkg/gnolang/values_conversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -926,7 +926,7 @@ func ConvertUntypedTo(tv *TypedValue, t Type) {
}
// general case
if t == nil {
t = defaultTypeOf(tv.T)
t = defaultTypeOf(tv.T, tv.V)
}
switch tv.T {
case UntypedBoolType:
Expand Down
14 changes: 14 additions & 0 deletions gnovm/tests/files/bigint1.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

import (
"math"
)

func main() {
println(float64(math.MaxUint32))
println(float64(math.MaxUint64))
}

// Output:
// 4.294967295e+09
// 1.8446744073709552e+19

0 comments on commit e7e47d2

Please sign in to comment.