fix(gnovm): reject make(chan T) at preprocess time#5238
fix(gnovm): reject make(chan T) at preprocess time#5238davd-gzl wants to merge 17 commits intognolang:masterfrom
make(chan T) at preprocess time#5238Conversation
make(chan T) previously passed deployment but panicked with 'not yet implemented' at runtime, leaving a permanent landmine on-chain. Reject it during preprocessing instead, producing a clean deployment error. Closes gnolang#5233
🛠 PR Checks SummaryAll Automated Checks passed. ✅ 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
|
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
gnovm/pkg/gnolang/preprocess.go
Outdated
| } else if fv.PkgPath == uversePkgPath && fv.Name == "attach" { | ||
| // reserve attach() so we can support it later. | ||
| panic("attach() not yet supported") | ||
| } else if fv.PkgPath == uversePkgPath && fv.Name == "make" { |
There was a problem hiding this comment.
If we're going to reject channels at preprocess time, I think the scope should be broader than just make(chan T). Any reference to a channel type could be caught early, for example:
package main
func ch1() chan int {
return nil
}
func main() {
var ch chan int
_ = ch1()
println(ch)
}
This deploys fine today even though channels aren't supported. IMO if we want a preprocess-time error, it should trigger when the chan type itself is encountered, not only on make. That way var ch chan int, func() chan int, type C chan int, etc. would all be rejected consistently, rather than only catching the one specific case of constructing a channel via make.
Reject ChanTypeExpr during preprocessing so all channel type usage (variable declarations, named types, function signatures, struct fields, make calls) is caught at deployment time with a clear error instead of panicking at runtime. Alternative to gnolang#5238 with broader scope — rejects the channel type itself rather than only make(chan T). Fixes gnolang#5233
Reject ChanTypeExpr during preprocessing so all channel type usage (variable declarations, named types, function signatures, struct fields, make calls) is caught at deployment time with a clear error instead of panicking at runtime. Alternative to gnolang#5238 with broader scope — rejects the channel type itself rather than only make(chan T). Fixes gnolang#5233
|
I suggest we change this PR so that at preprocess time, whenever we process a type expression and it is a chan, we just panic, so we also reject files of this kind: package main
func main() {
type T chan int
var ch chan int
_ = ch
_ = T(nil)
println("ok")
} |
Reject ChanTypeExpr during preprocessing so all channel type usage (variable declarations, named types, function signatures, struct fields, make calls) is caught at deployment time with a clear error instead of panicking at runtime. Broadens the previous make(chan T)-only check per reviewer feedback from omarsy and thehowl.
The addpkg_private and addpkg_public integration tests declared a var savedChannel chan *avl.Tree that is now rejected at preprocess time after rejecting all channel type expressions.
ltzmaxwell
left a comment
There was a problem hiding this comment.
Currently, the preprocess stage disallows the chan type, but there are still some occurrences at runtime, which looks inconsistent. It's acceptable as is, but need a proper comment somewhere maybe in preprocess.go to document the current situation and future plan.
Co-authored-by: ltzmaxwell <ltz.maxwell@gmail.com>
Address review feedback from ltzmaxwell: document the current situation
where ChanTypeExpr is rejected at preprocess time but still has cases
in other functions. Added explanatory comments and consistent panic
messages ('channel type is not yet supported') in:
- preprocess.go: findUndefinedT and tryPredefine functions
- transcribe.go: transcribe function
- uverse.go: make builtin
Also updated all channel-related filetests to match the new error message.
There was a problem hiding this comment.
Pull request overview
This PR addresses gnovm issue #5233 by rejecting channel types (e.g. make(chan T) and chan T in declarations/signatures) during preprocessing, preventing “not yet implemented” runtime panics from being deployed on-chain.
Changes:
- Add preprocess-time rejection for
ChanTypeExpr, aligning runtime behavior with a clean deployment/preprocess error. - Update runtime
make()handling to emit a consistent “channel type is not yet supported” message as a backstop. - Adjust/add filetests and integration fixtures to avoid/cover channel-type usage.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
gnovm/pkg/gnolang/preprocess.go |
Rejects ChanTypeExpr during preprocessing; adds/adjusts related handling paths. |
gnovm/pkg/gnolang/uverse.go |
Updates make() chan-type runtime backstop panic message. |
gnovm/pkg/gnolang/transcribe.go |
Adds ChanTypeExpr handling, but currently panics inside traversal (see comments). |
gnovm/tests/files/chan_make0.gno |
New filetest covering make(chan int) rejection. |
gnovm/tests/files/chan_type{0,1,2,3}.gno |
New filetests covering chan usage in var/type/sig/struct-field contexts. |
gnovm/tests/files/recurse0.gno |
Removes channel fields from a recursion/type-printing test and updates golden output. |
gnovm/tests/files/extern/net/http/http.gno |
Removes CloseNotifier interface due to <-chan return type. |
gnovm/tests/files/assign_unnamed_type/unnamedtype7_filetest.gno |
Reworks test away from channels to a pointer-based unnamed-type case. |
gnovm/pkg/benchops/gno/opcodes/opcode.gno |
Updates benchmark/opcode expectations and example struct away from chan types. |
gno.land/pkg/integration/testdata/addpkg_{public,private}.txtar |
Removes saved channel fields from integration test fixtures. |
fix #5233
make(chan T)previously passed deployment but panicked with 'not yet implemented' at runtime, leaving a implicit panic on-chain. Reject it during preprocessing instead, producing a clean deployment error.