fixes#24806
Blocks don't merge symbols that are used before destruction to the
parent scope, which causes `wasMoved; destroy` to elide incorrectly
(cherry picked from commit 73aeac81d1)
fixes#24801
Because distinct `seq` types match `proc `=destroy`*[T](x: var T)
{.inline, magic: "Destroy".}`. But the Nim compiler generates lifted seq
types for corresponding distinct types. So we skip the address for
distinct types.
Related to https://github.com/nim-lang/Nim/pull/22207 I had a hard time
finding the other place where generic destructors get replaced by
attachedDestructors
(cherry picked from commit 4352fa2ef0)
```nim
proc foo =
var x = "1234"
var y = x
when nimvm:
discard
else:
var s = x
doAssert s == "1234"
doAssert y == "1234"
static: foo()
foo()
```
`dfa` chooses the `nimvm` branch, `x` is misread as a last read and
`wasMoved`.
`injectDestructor` is used for codegen and is not used for vmgen. It's
reasonable to choose the codegen path instead of the `nimvm` path so the
code works for codegen. Though the problem is often hidden by
`cursorinference` or `optimizer`.
found in https://github.com/nim-lang/Nim/pull/24831
(cherry picked from commit 3617d2e077)
closes#24780
This proc `genStmt` is only called to run the VM in `vm.evalStmt`,
otherwise it's not used in vmgen. Now it acts the same as `proc
gen(PCtx, PNode)`, used by `discard` statements, which just calls
`freeTemp` on the dest if it was set rather than erroring.
(cherry picked from commit fcba14707a)
fixes#24773
`c.inheritancePenalty` is supposed to be used for the entire match, but
in these places the inheritance penalty of a single argument overrides
the entire match penalty. The `+ ord(c.inheritancePenalty < 0)` is
copied from other places that use the same idiom, the intent is that the
existing penalty changes from -1 to 0 first to mark that it participates
in inheritance before adding the inheritance depth.
---------
Co-authored-by: Andreas Rumpf <araq4k@proton.me>
(cherry picked from commit fb93295344)
Otherwise, `sink T` is kept as it is. This PR treats sink types as its
base types for the arguments. So the concept would match both cases
Required by https://github.com/nim-lang/Nim/pull/24724
(cherry picked from commit 9ebfa7973a)
fixes#24770
e.g. `seq[(ObjectWithDestructors, string)]`/ For refc, a seq with
elements that have destructors will have `hasAsgn` flags. The flag is
the criteria whether a seq is thought as `containsGarbageCollectedRef`.
i.e. whether to `registerTraverseProc` for the type.
The culprit seems to be that `searchTypeForAux` doesn't consider the
element type of sequence, even it contains a string that should belong
to `GarbageCollectedRef`.
With this PR:
It now generates
```
nimRegisterThreadLocalMarker(TM__mSF73dT1lSI7DG58StKHLQ_5);
```
in refc
(cherry picked from commit dfa482e292)
refs #24766
Detect when we track a call to a forward declaration without explicit
`raises` effects, then when the `raises` check fails for the proc, give
a hint that this forward declaration was tracked as potentially raising
any exception.
(cherry picked from commit 82891e6850)
motivating example:
```nim
iterator p(a: openArray[char]): int =
if a.len != 0:
if a[0] != '/':
discard
for t in p(""): discard
```
The compiler wants to evaluate `a[0]` at compile time even though it is
protected by the if statement above it. Similarly expressions like
`a.len != 0 and a[0] == '/'` have problems. It seems like the logic in
semfold needs to be more aware of branches to positively identify when
it is okay to fail compilation in these scenarios. It's a bit tough
though because it may be the case that non-constant expressions in
branching logic can properly protect some constant expressions.
(cherry picked from commit 850f327713)
fixes#24755, refs #24710
Instead of using the node from `indexTypesMatch` which inserts a hidden
conv node, just change the type of the node back to the old type
directly
(cherry picked from commit 38ad336c69)
fixes#24751
`typeof` leaves the object constructor as a call node for some reason,
in this case it tries to access the first child of the type node but the
object has no fields so the type field is empty. Alternatively the
optimizer can stop looking into `typeof`
(cherry picked from commit e2e7790779)
### Issue
When using `tcc` as backend to compile a trivial program
```
nim c --cc:tcc --skipCfg a.nim
```
, errors reported:
```
tcc: error: undefined symbol 'fabs'
```
### Solution
`fabs` belongs to libm. With these two options added, one can compile
with an additional clib option:
```
nim c --cc:tcc --skipCfg --clib:m a.nim
```
(cherry picked from commit dfd2987118)
Yet another one of these. Multiple changes piled up in this one. I've
only minimally cleaned it for now (debug code is still here etc). Just
want to start putting this up so I might get feedback. I know this is a
lot and you all are busy with bigger things. As per my last PR, this
might just contain changes that are not ready.
### concept instantiation uniqueness
It has already been said that concepts like `ArrayLike[int]` is not
unique for each matching type of that concept. Likewise the compiler
needs to instantiate a new proc for each unique *bound* type not each
unique invocation of `ArrayLike`
### generic parameter bindings
Couple of things here. The code in sigmatch has to give it's bindings to
the code in concepts, else the information is lost in that step. The
code that prepares the generic variables bound in concepts was also
changed slightly. Net effect is that it works better.
I did choose to use the `LayedIdTable` instead of the `seq`s in
`concepts.nim`. This was mostly to avoid confusing myself. It also
avoids some unnecessary movings around. I wouldn't doubt this is
slightly less performant, but not much in the grand scheme of things and
I would prefer to keep things as easy to understand as possible for as
long as possible because this stuff can get confusing.
### various fixes in the matching logic
Certain forms of modifiers like `var` and generic types like
`tyGenericInst` and `tyGenericInvocation` have logic adjustments based
on my testing and usage
### signature matching method adjustment
This is the weird one, like my last PR. I thought a lot about the
feedback from my last attempt and this is what I came up with. Perhaps
unfortunately I am preoccupied with a slight grey area. consider the
follwing:
```nim
type
C1 = concept
proc p[T](s: Self; x: T)
C2[T] = concept
proc p(s: Self; x: T)
```
It would be temping to say that these are the same, but I don't think
they are. `C2` makes each invocation distinct, and this has important
implications in the type system. eg `C2[int]` is not the same type as
`C2[string]` and this means that signatures are meant to accept a type
that only matches `p` for a single type per unique binding. For `C1` all
are the same and the binding `p` accepts multiple types. There are
multiple variations of this type classes, `tyAnything` and the like.
The make things more complicated, an implementation might match:
```nim
type
A = object
C3 = concept
proc p(s: Self; x: A)
```
if the implementation defines:
```nim
proc p(x: Impl; y: object)
```
while a concept that fits `C2` may be satisfied by something like:
```nim
proc p(x: Impl; y: int)
proc spring[T](x: C2[T])
```
it just depends. None of this is really a problem, it just seems to
provoke some more logic in `concepts.nim` that makes all of this (appear
to?) work. The logic checks for both kinds of matches with a couple of
caveats. The fist is that some unbind-able arrangements may be matched
during overload resolution. I don't think this is avoidable and I
actually think this is a good way to get a failed compilation. So, first
note imo is that failing during binding is preferred to forcing the
programming to write annoying stub procs and putting insane gymnastics
in the compiler. Second thing is: I think this logic is way to accepting
for some parts of overload resolutions. Particularly in `checkGeneric`
when disambiguation is happening. Things get hard to understand for me
here. ~~I made it so the implicit bindings to not count during
disambiguation~~. I still need to test this more, but the thought is
that it would help curb excessive ambiguity errors.
Again, I'm sorry for this being so many changes. It's probably
inconvenient.
---------
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
(cherry picked from commit dfab30734b)
fixes#24743, refs #24718
We cannot do this in general for any expression with generic type
because the `typeof` logic is called for things like `type Foo` in:
```nim
type Foo[T] = object
proc init(_: type Foo) = discard
```
We also cannot use `containsUnresolvedType` to work around this specific
case because the base type of `static[auto]` is not unresolved, it is a
typeclass that isn't lifted to a parameter. The behavior of generating
`tyFromExpr` is also consistent with pre-2.0, so we do this in this
special case of `static`.
(cherry picked from commit 569d02e212)
fixes#24736
The VM can produce integer nodes with no types as set elements, which
are later reannotated in `semmacrosanity.annotateType`. However the case
of ranges was not handled properly. Not sure why this is a regression,
probably unrelated but will have to see the bisect result to make sure.
Note. Originally tried to fix this in `opcInclRange`, generated for and
only for range expressions in set constructors, this seems to add the
range node directly to the set node without checking if it has overlap
with the existing elements by calling `nimsets` so an expression like
`{cctNone, cctNone..cctHeader}` can produce `{0, 0..5}`. Doesn't seem to
cause problems but `opcIncl` for single elements does check for overlap.
Something else to note is that integer nodes produced by `nimsets` have
proper types, so another option instead of relying on semmacrosanity to
fix this would be to make `opcIncl` and `opcInclRange` call `nimsets` to
add to the set node, but this might lose performance.
(cherry picked from commit e39d152b89)
fixes#24705
```nim
proc xxx(v: static int) =
echo v
xxx(10)
xxx(20)
```
They are mangled as `_ZN14titaniummangle7xxx_s10E` and
`_ZN14titaniummangle7xxx_s20E` with `--debugger:native`. Static
parameters are prefixed with `_s` to distinguish simple cases like
`xxx(10, 15)` and `xxx(101, 5)` if `xxx` supports two `static[int]`
parameters
(cherry picked from commit c452275e29)
fixes#24698
The same aim as #24224 but for tuple constructors. The difference here
is that the type of a tuple constructor is always going to be valid
unlike array constructors which can have `seq` etc types, so we can just
generate a conversion again. If the conversion fails, it is ignored
similar to #24611, this is to protect against modified typed nodes in
macros.
Also #24611 was only adapted to `semTupleFieldsConstr` and not
`semTuplePositionsConstr`, this is now fixed.
(cherry picked from commit 49dfc3a0d4)
fixes#24715
In generic typechecking, unresolved static param symbols (i.e.
`skGenericParam`) have [the static type
itself](1f8da3835f/compiler/semexprs.nim (L1483-L1485))
as their type when used in an expression. This is not the case when the
static param is resolved (the type is wrapped in static when necessary),
but semchecking of types and generic typechecking expects the type of
the value to be wrapped in `static` (at least `array[N, int]` breaks).
So for now, to solve the issue, `typeof` just skips static types.
(cherry picked from commit 514a25c9a2)
fixes#24725
`lacksMTypeField` doesn't take the base types into consideration. And
for ` {.inheritable, pure.}`, it shouldn't generate a `m_type` field.
(cherry picked from commit e449813c61)
Both cases are now valid. Though, it could be problematic to mix two
cases together as built-in types have non var T destructors
(cherry picked from commit 93fb219f10)
Applies #24144 to the equivalent matches of generic types, and adds the
behavior to matches of generic invocations to generic invocations. Not
encountered in many cases so it's hard to come up with tests but an
example is the test code in #24688, the match to the generic body never
sets the inheritance penalty leaving it at -1, but the match to the
generic invocation sets it to 0 which matches worse, when it should set
it to -1 because the object does not participate in inheritance.
(cherry picked from commit ebeef1067f)
ref https://github.com/nim-lang/Nim/pull/24686
With this PR
```nim
import std/streams
proc foo() =
var name = newStringStream("2r2")
raise newException(ValueError, "sh")
try:
foo()
except:
discard
echo 123
```
this example no longer leaks
---------
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
(cherry picked from commit 510ac84518)
fixes#8758, fixes#10828, fixes#12172, fixes#21610, fixes#23803,
fixes#24633, fixes#24634, succeeds #24085
We simply track the symbol ID of every traversed `var`/`let` definition
in `vmgen`, then these symbols are always considered evaluable in the
current `vmgen` context. The set of symbols is reset before every
generation, but both tests worked properly without doing this including
the nested `const`, so maybe it's already done in some way I'm not
seeing.
(cherry picked from commit a5cc33c1d3)
fixes#24644
Another option is to include the symbol names and owners in the type
listing as in #24645 but this is a bit verbose.
(cherry picked from commit 0861dabfa7)