Skip to content

Commit

Permalink
feat: implement shadowing rules (#1793)
Browse files Browse the repository at this point in the history
implements [this](#1779)

Most of the changes are fixing stdlib code where we get errors because
of the new shadowing rules.
  • Loading branch information
petar-dambovaliev authored Mar 23, 2024
1 parent 728f3f2 commit 52485ce
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 55 deletions.
6 changes: 3 additions & 3 deletions examples/gno.land/r/x/manfred_outfmt/outfmt.gno
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ func genResult() Result {
Number: r.Intn(1000),
}

len := r.Intn(8) + 2
res.Numbers = make([]int, len)
for i := 0; i < len; i++ {
length := r.Intn(8) + 2
res.Numbers = make([]int, length)
for i := 0; i < length; i++ {
res.Numbers[i] = r.Intn(100)
}

Expand Down
87 changes: 87 additions & 0 deletions gnovm/pkg/gnolang/gno_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,93 @@ import (
"github.com/jaekwon/testify/require"
)

func TestBuiltinIdentifiersShadowing(t *testing.T) {
t.Parallel()
tests := map[string]string{}

uverseNames := []string{
"iota",
"append",
"cap",
"close",
"complex",
"copy",
"delete",
"len",
"make",
"new",
"panic",
"print",
"println",
"recover",
"nil",
"bigint",
"bool",
"byte",
"float32",
"float64",
"int",
"int8",
"int16",
"int32",
"int64",
"rune",
"string",
"uint",
"uint8",
"uint16",
"uint32",
"uint64",
"typeval",
"error",
"true",
"false",
}

for _, name := range uverseNames {
tests[("struct builtin " + name)] = fmt.Sprintf(`
package test
type %v struct {}
func main() {}
`, name)

tests[("var builtin " + name)] = fmt.Sprintf(`
package test
func main() {
%v := 1
}
`, name)

tests[("var declr builtin " + name)] = fmt.Sprintf(`
package test
func main() {
var %v int
}
`, name)
}

for n, s := range tests {
t.Run(n, func(t *testing.T) {
t.Parallel()

defer func() {
if r := recover(); r == nil {
t.Fatalf("shadowing test: `%s` should have failed but didn't\n", n)
}
}()

m := NewMachine("test", nil)
nn := MustParseFile("main.go", s)
m.RunFiles(nn)
m.RunMain()
})
}
}

// run empty main().
func TestRunEmptyMain(t *testing.T) {
t.Parallel()
Expand Down
8 changes: 8 additions & 0 deletions gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -2912,6 +2912,10 @@ func predefineNow2(store Store, last BlockNode, d Decl, m map[Name]struct{}) (De
pkg := packageOf(last)
// pre-register d.GetName() to detect circular definition.
for _, dn := range d.GetDeclNames() {
if isUverseName(dn) {
panic(fmt.Sprintf(
"builtin identifiers cannot be shadowed: %s", dn))
}
m[dn] = struct{}{}
}
// recursively predefine dependencies.
Expand Down Expand Up @@ -3249,6 +3253,7 @@ func fillNameExprPath(last BlockNode, nx *NameExpr, isDefineLHS bool) {
// Blank name has no path; caller error.
panic("should not happen")
}

// If not DEFINE_LHS, yet is statically undefined, set path from parent.

// NOTE: ValueDecl names don't need this distinction, as
Expand Down Expand Up @@ -3291,6 +3296,9 @@ func fillNameExprPath(last BlockNode, nx *NameExpr, isDefineLHS bool) {
nx.Path = path
return
}
} else if isUverseName(nx.Name) {
panic(fmt.Sprintf(
"builtin identifiers cannot be shadowed: %s", nx.Name))
}
// Otherwise, set path for name.
// Uverse name paths get set here as well.
Expand Down
60 changes: 30 additions & 30 deletions gnovm/stdlibs/math/all_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -2235,9 +2235,9 @@ func tolerance(a, b, e float64) bool {
}
return d < e
}
func close(a, b float64) bool { return tolerance(a, b, 1e-14) }
func veryclose(a, b float64) bool { return tolerance(a, b, 4e-16) }
func soclose(a, b, e float64) bool { return tolerance(a, b, e) }
func closeFloat64(a, b float64) bool { return tolerance(a, b, 1e-14) }
func veryclose(a, b float64) bool { return tolerance(a, b, 4e-16) }
func soclose(a, b, e float64) bool { return tolerance(a, b, e) }
func alike(a, b float64) bool {
switch {
case math.IsNaN(a) && math.IsNaN(b):
Expand All @@ -2262,7 +2262,7 @@ func TestNaN(t *testing.T) {
func TestAcos(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := vf[i] / 10
if f := math.Acos(a); !close(acos[i], f) {
if f := math.Acos(a); !closeFloat64(acos[i], f) {
t.Errorf("math.Acos(%g) = %g, want %g", a, f, acos[i])
}
}
Expand Down Expand Up @@ -2413,7 +2413,7 @@ func TestCos(t *testing.T) {

func TestCosh(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := math.Cosh(vf[i]); !close(cosh[i], f) {
if f := math.Cosh(vf[i]); !closeFloat64(cosh[i], f) {
t.Errorf("math.Cosh(%g) = %g, want %g", vf[i], f, cosh[i])
}
}
Expand Down Expand Up @@ -2465,12 +2465,12 @@ func TestErfinv(t *testing.T) {
}
}
for x := -0.9; x <= 0.90; x += 1e-2 {
if f := math.Erf(math.Erfinv(x)); !close(x, f) {
if f := math.Erf(math.Erfinv(x)); !closeFloat64(x, f) {
t.Errorf("math.Erf(math.Erfinv(%g)) = %g, want %g", x, f, x)
}
}
for x := -0.9; x <= 0.90; x += 1e-2 {
if f := math.Erfinv(math.Erf(x)); !close(x, f) {
if f := math.Erfinv(math.Erf(x)); !closeFloat64(x, f) {
t.Errorf("math.Erfinv(math.Erf(%g)) = %g, want %g", x, f, x)
}
}
Expand All @@ -2489,12 +2489,12 @@ func TestErfcinv(t *testing.T) {
}
}
for x := 0.1; x <= 1.9; x += 1e-2 {
if f := math.Erfc(math.Erfcinv(x)); !close(x, f) {
if f := math.Erfc(math.Erfcinv(x)); !closeFloat64(x, f) {
t.Errorf("math.Erfc(math.Erfcinv(%g)) = %g, want %g", x, f, x)
}
}
for x := 0.1; x <= 1.9; x += 1e-2 {
if f := math.Erfcinv(math.Erfc(x)); !close(x, f) {
if f := math.Erfcinv(math.Erfc(x)); !closeFloat64(x, f) {
t.Errorf("math.Erfcinv(math.Erfc(%g)) = %g, want %g", x, f, x)
}
}
Expand Down Expand Up @@ -2527,7 +2527,7 @@ func TestExpm1(t *testing.T) {
}
for i := 0; i < len(vf); i++ {
a := vf[i] * 10
if f := math.Expm1(a); !close(expm1Large[i], f) {
if f := math.Expm1(a); !closeFloat64(expm1Large[i], f) {
t.Errorf("math.Expm1(%g) = %g, want %g", a, f, expm1Large[i])
}
}
Expand All @@ -2545,7 +2545,7 @@ func TestExp2(t *testing.T) {

func testExp2(t *testing.T, Exp2 func(float64) float64, name string) {
for i := 0; i < len(vf); i++ {
if f := math.Exp2(vf[i]); !close(exp2[i], f) {
if f := math.Exp2(vf[i]); !closeFloat64(exp2[i], f) {
t.Errorf("%s(%g) = %g, want %g", name, vf[i], f, exp2[i])
}
}
Expand Down Expand Up @@ -2680,7 +2680,7 @@ func TestFrexp(t *testing.T) {

func TestGamma(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := math.Gamma(vf[i]); !close(gamma[i], f) {
if f := math.Gamma(vf[i]); !closeFloat64(gamma[i], f) {
t.Errorf("math.Gamma(%g) = %g, want %g", vf[i], f, gamma[i])
}
}
Expand All @@ -2692,7 +2692,7 @@ func TestGamma(t *testing.T) {
} else if g[0] > -50 && g[0] <= 171 {
ok = veryclose(g[1], f)
} else {
ok = close(g[1], f)
ok = closeFloat64(g[1], f)
}
if !ok {
t.Errorf("math.Gamma(%g) = %g, want %g", g[0], f, g[1])
Expand Down Expand Up @@ -2762,7 +2762,7 @@ func TestJ0(t *testing.T) {

func TestJ1(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := math.J1(vf[i]); !close(j1[i], f) {
if f := math.J1(vf[i]); !closeFloat64(j1[i], f) {
t.Errorf("math.J1(%g) = %g, want %g", vf[i], f, j1[i])
}
}
Expand All @@ -2775,10 +2775,10 @@ func TestJ1(t *testing.T) {

func TestJn(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := math.Jn(2, vf[i]); !close(j2[i], f) {
if f := math.Jn(2, vf[i]); !closeFloat64(j2[i], f) {
t.Errorf("math.Jn(2, %g) = %g, want %g", vf[i], f, j2[i])
}
if f := math.Jn(-3, vf[i]); !close(jM3[i], f) {
if f := math.Jn(-3, vf[i]); !closeFloat64(jM3[i], f) {
t.Errorf("math.Jn(-3, %g) = %g, want %g", vf[i], f, jM3[i])
}
}
Expand Down Expand Up @@ -2822,7 +2822,7 @@ func TestLdexp(t *testing.T) {

func TestLgamma(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f, s := math.Lgamma(vf[i]); !close(lgamma[i].f, f) || lgamma[i].i != s {
if f, s := math.Lgamma(vf[i]); !closeFloat64(lgamma[i].f, f) || lgamma[i].i != s {
t.Errorf("math.Lgamma(%g) = %g, %d, want %g, %d", vf[i], f, s, lgamma[i].f, lgamma[i].i)
}
}
Expand Down Expand Up @@ -2969,7 +2969,7 @@ func TestNextafter64(t *testing.T) {

func TestPow(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := math.Pow(10, vf[i]); !close(pow[i], f) {
if f := math.Pow(10, vf[i]); !closeFloat64(pow[i], f) {
t.Errorf("math.Pow(10, %g) = %g, want %g", vf[i], f, pow[i])
}
}
Expand Down Expand Up @@ -3081,7 +3081,7 @@ func TestSincos(t *testing.T) {

func TestSinh(t *testing.T) {
for i := 0; i < len(vf); i++ {
if f := math.Sinh(vf[i]); !close(sinh[i], f) {
if f := math.Sinh(vf[i]); !closeFloat64(sinh[i], f) {
t.Errorf("math.Sinh(%g) = %g, want %g", vf[i], f, sinh[i])
}
}
Expand Down Expand Up @@ -3156,7 +3156,7 @@ func TestTrunc(t *testing.T) {
func TestY0(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := math.Abs(vf[i])
if f := math.Y0(a); !close(y0[i], f) {
if f := math.Y0(a); !closeFloat64(y0[i], f) {
t.Errorf("math.Y0(%g) = %g, want %g", a, f, y0[i])
}
}
Expand Down Expand Up @@ -3184,10 +3184,10 @@ func TestY1(t *testing.T) {
func TestYn(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := math.Abs(vf[i])
if f := math.Yn(2, a); !close(y2[i], f) {
if f := math.Yn(2, a); !closeFloat64(y2[i], f) {
t.Errorf("math.Yn(2, %g) = %g, want %g", a, f, y2[i])
}
if f := math.Yn(-3, a); !close(yM3[i], f) {
if f := math.Yn(-3, a); !closeFloat64(yM3[i], f) {
t.Errorf("math.Yn(-3, %g) = %g, want %g", a, f, yM3[i])
}
}
Expand Down Expand Up @@ -3267,7 +3267,7 @@ func TestLargeCos(t *testing.T) {
for i := 0; i < len(vf); i++ {
f1 := cosLarge[i]
f2 := math.Cos(vf[i] + large)
if !close(f1, f2) {
if !closeFloat64(f1, f2) {
t.Errorf("math.Cos(%g) = %g, want %g", vf[i]+large, f2, f1)
}
}
Expand All @@ -3278,7 +3278,7 @@ func TestLargeSin(t *testing.T) {
for i := 0; i < len(vf); i++ {
f1 := sinLarge[i]
f2 := math.Sin(vf[i] + large)
if !close(f1, f2) {
if !closeFloat64(f1, f2) {
t.Errorf("math.Sin(%g) = %g, want %g", vf[i]+large, f2, f1)
}
}
Expand All @@ -3289,7 +3289,7 @@ func TestLargeSincos(t *testing.T) {
for i := 0; i < len(vf); i++ {
f1, g1 := sinLarge[i], cosLarge[i]
f2, g2 := math.Sincos(vf[i] + large)
if !close(f1, f2) || !close(g1, g2) {
if !closeFloat64(f1, f2) || !closeFloat64(g1, g2) {
t.Errorf("math.Sincos(%g) = %g, %g, want %g, %g", vf[i]+large, f2, g2, f1, g1)
}
}
Expand All @@ -3300,7 +3300,7 @@ func TestLargeTan(t *testing.T) {
for i := 0; i < len(vf); i++ {
f1 := tanLarge[i]
f2 := math.Tan(vf[i] + large)
if !close(f1, f2) {
if !closeFloat64(f1, f2) {
t.Errorf("math.Tan(%g) = %g, want %g", vf[i]+large, f2, f1)
}
}
Expand All @@ -3325,18 +3325,18 @@ func TestTrigReduce(t *testing.T) {
j, z := math.TrigReduce(x)
xred := float64(j)*(math.Pi/4) + z

if f, fred := math.Sin(x), math.Sin(xred); !close(f, fred) {
if f, fred := math.Sin(x), math.Sin(xred); !closeFloat64(f, fred) {
t.Errorf("math.Sin(trigmath.Reduce(%g)) != math.Sin(%g), got %g, want %g", x, x, fred, f)
}
if f, fred := math.Cos(x), math.Cos(xred); !close(f, fred) {
if f, fred := math.Cos(x), math.Cos(xred); !closeFloat64(f, fred) {
t.Errorf("math.Cos(trigmath.Reduce(%g)) != math.Cos(%g), got %g, want %g", x, x, fred, f)
}
if f, fred := math.Tan(x), math.Tan(xred); !close(f, fred) {
if f, fred := math.Tan(x), math.Tan(xred); !closeFloat64(f, fred) {
t.Errorf(" math.Tan(trigmath.Reduce(%g)) != math.Tan(%g), got %g, want %g", x, x, fred, f)
}
f, g := math.Sincos(x)
fred, gred := math.Sincos(xred)
if !close(f, fred) || !close(g, gred) {
if !closeFloat64(f, fred) || !closeFloat64(g, gred) {
t.Errorf(" math.Sincos(trigmath.Reduce(%g)) != math.Sincos(%g), got %g, %g, want %g, %g", x, x, fred, gred, f, g)
}
}
Expand Down
4 changes: 2 additions & 2 deletions gnovm/stdlibs/math/bits/bits_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -646,12 +646,12 @@ func BenchmarkReverseBytes64(b *testing.B) {

func TestLen(t *testing.T) {
for i := 0; i < 256; i++ {
len := 8 - tab[i].nlz
length := 8 - tab[i].nlz
for k := 0; k < 64-8; k++ {
x := uint64(i) << uint(k)
want := 0
if x != 0 {
want = len + k
want = length + k
}
if x <= 1<<8-1 {
got := Len8(uint8(x))
Expand Down
4 changes: 2 additions & 2 deletions gnovm/stdlibs/regexp/regexp.gno
Original file line number Diff line number Diff line change
Expand Up @@ -983,8 +983,8 @@ func extract(str string) (name string, num int, rest string, ok bool) {
}
i := 0
for i < len(str) {
rune, size := utf8.DecodeRuneInString(str[i:])
if !unicode.IsLetter(rune) && !unicode.IsDigit(rune) && rune != '_' {
r, size := utf8.DecodeRuneInString(str[i:])
if !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != '_' {
break
}
i += size
Expand Down
Loading

0 comments on commit 52485ce

Please sign in to comment.