fix(preprocess): avoid shadowing of iota - #5981
Conversation
🛠 PR Checks Summary🔴 Pending initial approval by a review team member, or review from tech-staff Manual Checks (for Reviewers):
Read More🤖 This bot helps streamline PR reviews by verifying automated checks and providing guidance for contributors and reviewers. ✅ Automated Checks (for Contributors):🟢 Maintainers must be able to edit this pull request (more info) ☑️ Contributor Actions:
☑️ Reviewer Actions:
📚 Resources:Debug
|
davd-gzl
left a comment
There was a problem hiding this comment.
[AI bot]
Verified on af3accb: gno lint rejects a package whose exported function takes an iota parameter, as gnoPreprocessError, matching the VM even though go/types accepts the source. Nested const groups still evaluate iota exactly as the Go compiler does.
main / build is red only on formatting: four of the new filetests end with a trailing blank line. docs is red on an unreachable link in gnoland-networks.md, which this branch does not touch.
| // iota is a non-shadowable builtin; reject binding it as a receiver, | ||
| // parameter, named result, type-switch guard, short-var-define, or | ||
| // range key/value name. (uverse's own "iota" registration goes through | ||
| // Define2 directly, bypassing Reserve, so it is unaffected.) |
There was a problem hiding this comment.
A three-clause for init never reaches this check. initStaticBlocks1 renames those names, and their body references, to <name>.loopvar, and it runs before Reserve sees them. So for iota := 0; iota < 2; iota++ { println(iota) } prints 0 and 1, while for iota := range s is rejected.
repro
# from a local clone of gnolang/gno:
gh pr checkout 5981 -R gnolang/gno
cat > gnovm/tests/files/iota_forinit.gno <<'EOF'
package main
func main() {
for iota := 0; iota < 2; iota++ {
println(iota)
}
}
// Error:
// main/iota_forinit.gno:4:6-14: builtin identifiers cannot be shadowed: iota
EOF
go test -run 'TestFiles/iota_forinit.gno$' ./gnovm/pkg/gnolang/
rm gnovm/tests/files/iota_forinit.gno--- FAIL: TestFiles (0.03s)
--- FAIL: TestFiles/iota_forinit.gno (0.00s)
files_test.go:135: unexpected output:
0
1
FAIL
FAIL github.com/gnolang/gno/gnovm/pkg/gnolang 0.044s
| // parameter, named result, type-switch guard, short-var-define, or | ||
| // range key/value name. (uverse's own "iota" registration goes through | ||
| // Define2 directly, bypassing Reserve, so it is unaffected.) | ||
| if nx.Name == iotaIdentifier { |
There was a problem hiding this comment.
func f(iota int) { println("hi") }, func f() (iota int) and func (iota T) M() all run on master, because the name is bound but never referenced. Node startup re-preprocesses every stored package at VMKeeper.Initialize, with no per-package recover. A package already on chain that uses one of those forms would fail at boot rather than at its next call.
repro
# from a local clone of gnolang/gno:
gh pr checkout 5981 -R gnolang/gno
cat > iota_param.gno <<'EOF'
package main
func f(iota int) { println("hi") }
func main() { f(3) }
EOF
echo "== at PR head:"; go run ./gnovm/cmd/gno run iota_param.gno
git checkout $(git merge-base origin/master HEAD) -- gnovm/pkg/gnolang/nodes.go
echo "== with the check removed:"; go run ./gnovm/cmd/gno run iota_param.gno
git checkout HEAD -- gnovm/pkg/gnolang/nodes.go
rm iota_param.gno== at PR head:
panic: builtin identifiers cannot be shadowed: iota [recovered]
panic: main/iota_param.gno:3:1-35: builtin identifiers cannot be shadowed: iota:
--- preprocess stack ---
== with the check removed:
hi
| // range key/value name. (uverse's own "iota" registration goes through | ||
| // Define2 directly, bypassing Reserve, so it is unaffected.) | ||
| if nx.Name == iotaIdentifier { | ||
| panic(fmt.Sprintf("builtin identifiers cannot be shadowed: %s", nx.Name)) |
There was a problem hiding this comment.
Nit: func f(len int) int { return len } compiles here, and so does every uverse name but iota in that position. The message says builtin identifiers cannot be shadowed, so an author who hits it on a parameter reads a rule the compiler does not enforce.
closes #5876