traefik / yaegi

Yaegi is Another Elegant Go Interpreter
https://pkg.go.dev/github.com/traefik/yaegi
Apache License 2.0
6.78k stars 341 forks source link

Incorrect bitmask parsing or handling behaviour #1591

Open zoola969 opened 10 months ago

zoola969 commented 10 months ago

The following program sample.go triggers an unexpected result

package main

import (
    "encoding/json"
)

type BitFlag uint8

const (
    A BitFlag = 1 << iota
    B
)

type Flag struct {
    Flag BitFlag `json:"flag"`
}

func main() {
    json_str := "{\"flag\": 1}"
    var d Flag
    json.Unmarshal([]byte(json_str), &d)
    println(
        d.Flag,
        d.Flag&A == A,
        BitFlag(1)&A == A,
    )
}

Expected result

$ go run ./sample.go 
1 true true

Got

$ yaegi ./sample.go  
1 false true

Yaegi Version

v0.15.1

Additional Notes

No response

dennwc commented 9 months ago

Confirm that it still happens on master.

I actually hit something very similar recently, but with a regular iota and typed constants:

type Enum int
const (
   A = Enum(iota)
   B
   C
)

This produced A=0, B=2, C=4 for unknown reason, breaking the code that assumed it's sequential.

I will try to make a similar small reproducer. For now I was unable to, so it might be caused by something other code in the package. Probably something interferes with these const definitions.

@mvertes Could you please tag the issue? Looks important. I will try to fix it.

dennwc commented 9 months ago

Actually, here's a small reproducer for my case:

package main

const (
    A = Enum(iota)
    B
    C
)

type Enum int

func main() {
    println(A, B, C)
}

This should produce 0 1 2, but produces 0 2 4 instead. Moving type Enum int before const fixes the problem.

dennwc commented 9 months ago

Sorry for the noise, my issue appears to be different. Opened #1596.