-
Notifications
You must be signed in to change notification settings - Fork 381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pop/push slice returns old element #939
Comments
Hey, could you try opening this bug as a new challenge in this folder, please? https://github.com/gnolang/gno/tree/master/gnovm/tests/challenges |
I tried to add it in challenges like so: package main
var slice = []string{"undead-element"}
func main() {
slice = slice[:len(slice)-1]
slice = append(slice, "new-element")
println(slice)
}
// Output:
// slice[("new-element" string)] but this does not fail, I think it needs to happen in two separate transactions, I could add a realm in |
Creating a slice Then, each of the elements will pass through Then, everything gets assembled here Reading from a slice and gets the value here |
I found something interesting At this line: gno/gnovm/pkg/gnolang/realm.go Line 1111 in 6d137df
If I set Maxcap: cv.Length instead of Maxcap: cv.Maxcap , it solves my minimal test, this probably breaks other stuff though
Maxcap seems to not be properly handled somewhere, my guess is serialization/de-serialization since the pop/push works when done in a single TX I'll keep digging ⛏️ |
After digging more, I feel that assigning to a slice does not properly "Marks dirty" the slice or it's base array
|
[EDIT]: ignore this post, since the underlying array is the same, this seems normal in the end Something here does not seem right gno/gnovm/pkg/gnolang/values.go Lines 279 to 282 in f50f33d
seems like it's assigning the new slice to the new slice not sure what the intended behavior is (sorry for the raw information and thoughts, I barely understand the code for now) |
Could someone explain
|
These are part of the ownership system. |
@n0izn0iz i haven't tested it but my hunch is that there is no problem with the Can you test out this theory? For example, make a 10 element slice and |
@peter7891 this makes a lot of sense Your test does not work like you expect though For this realm: package slice_splice
import (
"strings"
)
var slice = []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}
func Splice() []string {
slice = slice[4:5]
return slice
}
func Render(path string) string {
return strings.Join(slice, ",")
} Render returns |
Right. My theory was wrong but it eliminated the possibility of there being a bug with the slicing. |
Maybe it thinks the new slice’s capacity is already hit, then it will first copy to new larger array, as per spec. |
This should be fixed by #1305 |
Fixed by #1305 |
Pop/push slice returns old element
Description
If you pop an element from a slice (via
slice = slice[:len(slice)-1]
) and append a new element afterwards, the last element of the slice will be the popped element and not the new element(Sorry for the confusing issue name I can't find a better short name)
Your environment
Steps to reproduce
Pop
thenPush
Expected behaviour
The slice is
[]string{"new-element"}
afterPop
andPush
Actual behaviour
The slice is
[]string{"undead-element"}
afterPop
andPush
Additional info
If you give me some pointer (namely where the slice access operator
[:]
andappend
are handled), I could try debug thisYou can work around this by creating a new slice:
The bug seem to be at storage layer level since this works as expected:
The text was updated successfully, but these errors were encountered: