diff --git a/examples/gno.land/r/x/manfred_outfmt/outfmt.gno b/examples/gno.land/r/x/manfred_outfmt/outfmt.gno index b01485e16dc..5468a65c06f 100644 --- a/examples/gno.land/r/x/manfred_outfmt/outfmt.gno +++ b/examples/gno.land/r/x/manfred_outfmt/outfmt.gno @@ -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) } diff --git a/gnovm/pkg/gnolang/gno_test.go b/gnovm/pkg/gnolang/gno_test.go index d8bdcdfd4a0..e67d4a7024d 100644 --- a/gnovm/pkg/gnolang/gno_test.go +++ b/gnovm/pkg/gnolang/gno_test.go @@ -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() diff --git a/gnovm/pkg/gnolang/preprocess.go b/gnovm/pkg/gnolang/preprocess.go index 3d139f412d6..dcb1b0856ca 100644 --- a/gnovm/pkg/gnolang/preprocess.go +++ b/gnovm/pkg/gnolang/preprocess.go @@ -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. @@ -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 @@ -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. diff --git a/gnovm/stdlibs/math/all_test.gno b/gnovm/stdlibs/math/all_test.gno index 3d2a018b118..a138123b5ab 100644 --- a/gnovm/stdlibs/math/all_test.gno +++ b/gnovm/stdlibs/math/all_test.gno @@ -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): @@ -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]) } } @@ -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]) } } @@ -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) } } @@ -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) } } @@ -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]) } } @@ -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]) } } @@ -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]) } } @@ -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]) @@ -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]) } } @@ -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]) } } @@ -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) } } @@ -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]) } } @@ -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]) } } @@ -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]) } } @@ -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]) } } @@ -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) } } @@ -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) } } @@ -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) } } @@ -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) } } @@ -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) } } diff --git a/gnovm/stdlibs/math/bits/bits_test.gno b/gnovm/stdlibs/math/bits/bits_test.gno index 55b0e3c117b..e2834cacf7c 100644 --- a/gnovm/stdlibs/math/bits/bits_test.gno +++ b/gnovm/stdlibs/math/bits/bits_test.gno @@ -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)) diff --git a/gnovm/stdlibs/regexp/regexp.gno b/gnovm/stdlibs/regexp/regexp.gno index 2d61b8506b7..462d0616a85 100644 --- a/gnovm/stdlibs/regexp/regexp.gno +++ b/gnovm/stdlibs/regexp/regexp.gno @@ -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 diff --git a/gnovm/stdlibs/regexp/syntax/prog.gno b/gnovm/stdlibs/regexp/syntax/prog.gno index ef18f042f6c..ae50f390944 100644 --- a/gnovm/stdlibs/regexp/syntax/prog.gno +++ b/gnovm/stdlibs/regexp/syntax/prog.gno @@ -199,15 +199,15 @@ func (i *Inst) MatchRune(r rune) bool { // If not, MatchRunePos returns -1. // MatchRunePos should only be called when i.Op == InstRune. func (i *Inst) MatchRunePos(r rune) int { - rune := i.Rune + rr := i.Rune - switch len(rune) { + switch len(rr) { case 0: return noMatch case 1: // Special case: single-rune slice is from literal string, not char class. - r0 := rune[0] + r0 := rr[0] if r == r0 { return 0 } @@ -221,7 +221,7 @@ func (i *Inst) MatchRunePos(r rune) int { return noMatch case 2: - if r >= rune[0] && r <= rune[1] { + if r >= rr[0] && r <= rr[1] { return 0 } return noMatch @@ -229,11 +229,11 @@ func (i *Inst) MatchRunePos(r rune) int { case 4, 6, 8: // Linear search for a few pairs. // Should handle ASCII well. - for j := 0; j < len(rune); j += 2 { - if r < rune[j] { + for j := 0; j < len(rr); j += 2 { + if r < rr[j] { return noMatch } - if r <= rune[j+1] { + if r <= rr[j+1] { return j / 2 } } @@ -242,11 +242,11 @@ func (i *Inst) MatchRunePos(r rune) int { // Otherwise binary search. lo := 0 - hi := len(rune) / 2 + hi := len(rr) / 2 for lo < hi { m := lo + (hi-lo)/2 - if c := rune[2*m]; c <= r { - if r <= rune[2*m+1] { + if c := rr[2*m]; c <= r { + if r <= rr[2*m+1] { return m } lo = m + 1 diff --git a/gnovm/stdlibs/time/time.gno b/gnovm/stdlibs/time/time.gno index ceed70452f6..521679e48d5 100644 --- a/gnovm/stdlibs/time/time.gno +++ b/gnovm/stdlibs/time/time.gno @@ -700,17 +700,17 @@ func (d Duration) String() string { func fmtFrac(buf []byte, v uint64, prec int) (nw int, nv uint64) { // Omit trailing zeros up to and including decimal point. w := len(buf) - print := false + isprint := false for i := 0; i < prec; i++ { digit := v % 10 - print = print || digit != 0 - if print { + isprint = isprint || digit != 0 + if isprint { w-- buf[w] = byte(digit) + '0' } v /= 10 } - if print { + if isprint { w-- buf[w] = '.' } diff --git a/gnovm/tests/files/define3.gno b/gnovm/tests/files/define3.gno index 54de3249aa3..0c71e3d76f6 100644 --- a/gnovm/tests/files/define3.gno +++ b/gnovm/tests/files/define3.gno @@ -1,10 +1,10 @@ package main func main() { - println(int) + println(i) } -var int string = "foobar" +var i string = "foobar" // Output: // foobar diff --git a/gnovm/tests/files/define4.gno b/gnovm/tests/files/define4.gno index 8fcf8ace277..8744cfd7d38 100644 --- a/gnovm/tests/files/define4.gno +++ b/gnovm/tests/files/define4.gno @@ -2,8 +2,8 @@ package main func main() { func() { - var int string = "foobar" - println(int) + var i string = "foobar" + println(i) }() }