Avoid a spurious optimisation which forces a variable to be reused instead of redefined for assignment operation. This ensures that a variable defined in a loop is re-allocated, preserving the previous instance when used by a closure for example.
Fix#1594
Unsafe functions such as `unsafe.Alignof`, `unsafe.Offsetof` and `unsafe.Sizeof` can be used for type declarations early on during compile, and as such, must be treated as builtins returning constants at compile time. It is still necessary to explicitely enable unsafe support in yaegi.
The support of `unsafe.Add` has also been added.
Fixes#1544.
In the case of a Go short definition (i.e. `a, b := f()`), the new defined variables must be (re-)created in order to preserve the previous value (if in a loop) which can be still in use in the context of a closure. This must not apply to redeclared variables which simply see their value reassigned.
The problem was both occuring in callBin() for runtime functions and assignFromCall() for functions created in the interpreter.
Fixes#1497.
hi!
this issue is sorta blocking for me so i thought i would try to fix it.
im still learning the codebase and understanding how yaegi works, but I thought I would attempt to add a test in the style of other tests as a start.
please let me know if there is anything i need to change / run, or if anyone knows perhaps a good place to start for tackling this issue
Fixes#1496
For methods defined on interfaces (vs concrete methods), the resolution of the method is necessarily delayed at the run time and can not be completed at compile time.
The selectorExpr processing has been changed to correctly identify calls on interface methods which were confused as fields rather than methods (due to the fact that in a interface definition, methods are fields of the interface).
Then at runtime, method lookup has been fixed to correctly recurse in nested valueInterface wrappers and to find embedded interface fields in case of struct or pointer to struct.
Finally, remove receiver processing in `call()`.The receiver is already processed at method resolution and in genFunctionWrapper. Removing redundant processing in call fixes handling of variadic method, simplifies the code and makes it faster.
With those fixes, it is now possible to load and run `go.uber.org/zap` in yaegi. In turn, it makes possible for yaegi to run plugins dependent on zap, such as coraza-waf.
Fixes#1515,
Fixes#1172,
Fixes#1275,
Fixes#1485.
When generating a new type, the parameter type was not correctly duplicated in the new AST. This is fixed by making copyNode recursive if needed. The out of order processing of generic types has also been fixed.
Fixes#1488
For a long time, there was a confusion between aliased types and named types (due to my misunderstanding of alias types in Go at that time). The type category `aliasT` has been renamed into `linkedT`, which is correct semantically.
Aliased types are only declared using `typeSpecAssign`, and its processing is now distinct from `typeSpec` statement, used for named types.
A `linkedT` type is obtained by a statement like `type A uint32`, where `A` type category is therefore `linkedT`.
An aliased type is obtained by a statement like `type A = uint32` (notice the `=` sign, translating into `typeSpecAssign`).
The semantic difference is that in the first linkedT form, `A` and `uint32` are 2 distinct types, instead of being strictly equivalent in the `typeSpecAssign` form (the 2 names lead to one type definition).
Fixes#1416.
Up to now functions could be stored as node values in frame (as for interpreter defined functions) or function values, directly callable by the Go runtime. We now always store functions in the later form, making the processing of functions, anonymous closures and methods simpler and more robust. All functions, once compiled are always directly callable, with no further wrapping necessary.
Fixes#1459.
In type assertion at compile time, compare signatures between function types only.
Make `itype.numOut()` return the correct value for Go builtins (this was not strictly necessary due to above fix, but it is correct and improves maintainability).
Fixes#1454.
In [short variable declarations](https://go.dev/ref/spec#Short_variable_declarations),
The reuse of existing symbols is possible only if a new variable is defined,
otherwise a new symbol must be created, which was not the case in the issue.
Search for new symbols and correctly ignore blank variables.
Fixes#1434.
If the value on which to type-switch was already set (i.e. a variable),
there was no problem. But if it had to be obtained through a complex
expression (func call, array index, etc...), then the code to retrieve
the value prior type-switch was not scheduled. This is now fixed.
This issue is nasty because the behavior is silently changed,
leading potentially to further unrelated issues or runtime panics.
Fixes#1444.
The variable dependency check function was confused by a dependency
variable with the same name but in an external package.
This change is necessary to address #1427.
Status:
* [x] parsing code with generics
* [x] instantiate generics from concrete types
* [x] automatic type inference
* [x] support of generic recursive types
* [x] support of generic methods
* [x] support of generic receivers in methods
* [x] support of multiple type parameters
* [x] support of generic constraints
* [x] tests (see _test/gen*.go)
Fixes#1363.
Such function declaration denotes either a linkname (an access to
an arbitrary, typically unexported symbol, solved by go compiler),
or a foreign C or assembly implementation of the body.
Those cases are not supported (or planned to be) by the interpreter.
Fixes#1431.
I expect the following code to be supported.
```go
type TT http.Header
func (t TT) Set(key, val string) {
}
func (t TT) Get(key string) string {
}
```
So, I pushed this PR.
Do I need to add some test cases? I don't see the relevant test files ....
The type.val field was always pointing to the final underlying type
for aliased types, defeating a possible match if a method was
attached to a type in between. Now the complete chain of aliases
is always preserved.
We have added an underlying() itype method which returns the underlying
type of a defined type (aliasT), even in the presence of multiple
indirections.
We have added a definedType function which checks if type t1 is
defined from type t2 or t2 defined from t1, required when checking
assignability of aliasT types.
Fixes#1411.
PS: this is the 2nd attempt, as the first version #1412 wasn't passing
_test/issue-1408.go as well. This PR does pass and supersedes #1412.
In that case, the interface must be wrapped in an valueInterface
at creation.
With that fix, it is now possible to import
github.com/google/go-querystring/query. Not tested beyond that.
Fixes#1123.
The logic of goto was false due to mixing break label and goto
label, despite being opposite. In case of break, jump to node (the
exit point) instead of node.start. Also always define label symbols
before their use is parsed.
* Fix continue label, detect invalid labels for break and continue
* fix multiple goto, break, continue to the same label
Fixes#1354.
We now detect the use of special identifier _ (blank) during parsing in order to abort compiling early. It allows to not panic later during execution. We must catch all the cases where blank is used as a value, but still preserve the cases where it is assigned, used as a struct field or for import side effects.
Fixes#1386.
* interp: fix handling of redeclaration in multi-assign expression
In a statement like `a, b := f()` if `a` was previously declared,
its symbol must be reused, a new symbol must not override its
previous value. This is now fixed.
* In case of redeclaration, reuse the existing only if the redeclared
variable has the same type. Add _test/var16.go to check this use
case.
Fixes#1365.
A runtime builtin assignFromCall is added to handle multiple values returned at once. It is necessary if some of the values require to be set to interface values in the caller space, which is performed by reflect.Set in assignFromCall.
Fixes#1311.
Make sure to keep always a single copy of incomplete type structures.
Remove remnants of recursive types processing.
Now `import "go.uber.org/zap"` works again (see #1172), fixing regressions
introduced since #1236.
This adds `itype.str` which is a string representation of the type built when the type is built. The goal is to make type comparison simpler and centralise the creation of types just to constructors and `nodeType`. `nodeType` continues to build types in parts so to reuse underlying types better.
Add getConcreteType to retrieve the concrete type of a nested interface
value implementing a specific interface for which a wrapper exists.
If method resolution fails at runtime, a panic is now issued instead
of an error message and continue.
Fixes#1187.
The resolution method was not compliant with the Go specification which
requires to retain the object where the field or method is the most
shallowed.
The detection of ambiguous fields or methods (same depth in different
objects) has also been added.
Fixes#1163.
In selector resolution, struct field matching now precedes
method matching. Before struct field matching could be skipped
in case of a matching method, which is incorrect, as demontrated
by _test/issue-1156.go.
Field lookup has been fixed to operate on recursive structures.
Concrete type values are derived when filling a receiver for
interface methods.
LookupBinField has been fixed to skip non struct values.
LookupMethod has been fixed to iterate on interface values as
well as concrete type values.
Fixes#1156.
Fixes#1151
If I add a package with `Use` and import it with `ImportUsed`, the package is added to the universe scope as `<pkg>`. If I import with `Eval`, the package is added as `<pkg>/_.go`. However, `(*node).isType` (in cfg.go) only checks for `<pkg>/_.go`. Thus, packages imported with `ImportUsed` can be inaccessible.
This MR updates `(*node).isType` to fall back to `<pkg>` if `<pkg>/_.go` does not exist.
In typecheck.go, detect binary methods so we know when to skip the receiver as first parameter when checking function signatures. The signature check is not yet performed, we just avoid a false error.
In cfg.go, take care to label types with isBinMethod field to true whenever a binary method is resolved.
Also, do not attempt to wrap node in functions if the node value is already a binary function.
Fixes#1145.
This is a small change that allows use of composite array literals, such as:
```go
type Vec3 [3]float32
var foo = []Vec3{
{1, 0, 0},
{6, 0, 0},
{6, 2, 0},
{2, 2, 0},
{1, 1, 0},
}
```