fixes#3011
In https://github.com/nim-lang/Nim/pull/23532, meta fields that defined
in the object are handled.
In this PR, RefObjectTy is handled as well:
```nim
type
Type = ref object
context: ref object
```
Ref alias won't trigger mata fields checking so there won't have
cascaded errors on `TypeBase`.
```nim
type
TypeBase = object
context: ref object
Type = ref TypeBase
context: ref object
```
makes new hash the default, with an opt-out (& js-no-big-int) define.
Also update changelog (& fix one typo).
Only really expect the chronos hash-order sensitive test to fail until
they merge that PR and tag a new release.
This pr redefines the relation between lambda lifting and closureiter
transformation.
Key takeaways:
- Lambdalifting now has less distinction between closureiters and
regular closures. Namely instead of lifting _all_ closureiter variables,
it lifts only those variables it would also lift for simple closure,
i.e. those not owned by the closure.
- It is now closureiter transformation's responsibility to lift all the
locals that need lifting and are not lifted by lambdalifting. So now we
lift only those locals that appear in more than one state. The rest
remains on stack, yay!
- Closureiter transformation always relies on the closure env param
created by lambdalifting. Special care taken to make lambdalifting
create it even in cases when it's "too early" to lift.
- Environments created by lambdalifting will contain `:state` only for
closureiters, whereas previously any closure env contained it.
IMO this is a more reasonable approach as it simplifies not only
lambdalifting, but transf too (e.g. freshVarsForClosureIters is now gone
for good).
I tried to organize the changes logically by commits, so it might be
easier to review this on per commit basis.
Some ugliness:
- Adding lifting to closureiters transformation I had to repeat this
matching of `return result = value` node. I tried to understand why it
is needed, but that was just another rabbit hole, so I left it for
another time. @Araq your input is welcome.
- In the last commit I've reused currently undocumented `liftLocals`
pragma for symbols so that closureiter transformation will forcefully
lift those even if they don't require lifting otherwise. This is needed
for [yasync](https://github.com/yglukhov/yasync) or else it will be very
sad.
Overall I'm quite happy with the results, I'm seeing some noticeable
code size reductions in my projects. Heavy closureiter/async users,
please give it a go.
(for `string` or any other key type). Independence is nice to ever
change orders. So, change it to just `len` & a `doAssert` like the other
test in the same file.
```
$ curl -v http://example.com/404 |& grep 'HTTP/1.1'
> GET /404 HTTP/1.1
< HTTP/1.1 500 Internal Server Error
```
So, the test with http://example.com/404 should be disabled, I think.
fixes#23749, refs #22716
`semIndirectOp` is used here because of the callback expressions, in
this case `db.getProc(...)`, and `semIndirectOp` calls `semOpAux` to
type its arguments before overloading starts. Hence it can opt in to
symchoices since overloading will resolve them.
Unlike present Nim this actually fills `Hash` for `string` & related.
For the curious, note that `hashData` remains the aboriginal Nim string
hasher & `import hashes {.all.}` allows simultaneous test/time of {orig,
murmur, farm} on your favorite CPU & back end compiler.
Update tests also conditioned upon `nimPreviewHashFarm` so they should
pass either with or without that `define` on.
In `--jsbigint=on` mode, only the lower 32-bits of `Hash` match nimvm &
run-time values because `type Hash = int` and on JS int=int32, not int64
as for 64-bit Nim platforms. Due to the matching, `const` Table should
match run-time `Table` on all platforms.
To operate in `--jsbigint=off` mode is feasible but needs much "double
precision mul/xor/ror/shr-arithmetic"-style work. That is distracting &
also of questionable value since JS added BigInt in 2018, ringabout
added Nim support for it in 2021 & `nimPreviewHashFarm` is unlikely to
swap from an opt-in to an opt-out default before 2025..2026 which will
have given a backward looking time window of 7..8 years for deployment
platforms - reasonably generous.
Add a changelog entry for 2.2.
fixes#23730
Since #23188 the compiler errors when matching a type variable to an
uninstantiated static value. However sometimes an uninstantiated static
value is given even when only a type match is being performed to the
base type of the static type, in the given issue this case is:
```nim
proc foo[T: SomeInteger](x: T): int = int(x)
proc bar(x: static int): array[foo(x), int] = discard
discard bar(123)
```
To deal with this issue we only error when matching against a type
variable constrained to `static`.
Not sure if the `q.typ.kind == tyGenericParam and
q.typ.genericConstraint == tyStatic` check is necessary, the code above
for deciding whether the variable becomes `skConst` doesn't use it.
fixes#23690
```nim
dest.`:state` = src.`:state`
var :tmp_553651276 = dest.e1.a
`=wasMoved`(dest.e1.a)
dest.e1.a.kind = src.e1.a.kind
case dest.e1.a.kind
of 0:
dest.e1.a.a = src.e1.a.a
of 1:
`=copy`(dest.e1.a.c, src.e1.a.c)
case :tmp_553651276.kind
of 0:
of 1:
`=destroy`(:tmp_553651276.c)
```
`dest.e1.a.kind = src.e1.a.kind` changes the discrimant but it fails to
clear the memory of `dest.e1.a`. Before using hooks for copying, we need
to clear the dest, e.g. `=wasMoved(dest.e1.a.c)`.
```nim
dest.`:state` = src.`:state`
var :tmp_553651276 = dest.e1.a
`=wasMoved`(dest.e1.a)
dest.e1.a.kind = src.e1.a.kind
case dest.e1.a.kind
of 0:
`=wasMoved`(dest.e1.a.a)
dest.e1.a.a = src.e1.a.a
`=wasMoved`(dest.e1.a.b)
of 1:
`=wasMoved`(dest.e1.a.c)
`=copy`(dest.e1.a.c, src.e1.a.c)
case :tmp_553651276.kind
of 0:
of 1:
`=destroy`(:tmp_553651276.c)
```
fixes#10440, fixes#13871, fixes#14665, fixes#19672, fixes#23677
The false positive in #23677 was caused by behavior in
`implicitlyDiscardable` where only the last node of `if`/`case`/`try`
etc expressions were considered, as in the final node of the final
branch (in this case `else`). To fix this we use the same iteration in
`implicitlyDiscardable` that we use in `endsInNoReturn`, with the
difference that for an `if`/`case`/`try` statement to be implicitly
discardable, all of its branches must be implicitly discardable.
`noreturn` calls are also considered implicitly discardable for this
reason, otherwise stuff like `if true: discardableCall() else: error()`
doesn't compile.
However `endsInNoReturn` also had bugs, one where `finally` was
considered in noreturn checking when it shouldn't, another where only
`nkIfStmt` was checked and not `nkIfExpr`, and the node given for the
error message was bad. So `endsInNoReturn` now skips over
`skipForDiscardable` which no longer contains
`nkIfStmt`/`nkCaseStmt`/`nkTryStmt`, stores the first encountered
returning node in a var parameter for the error message, and handles
`finally` and `nkIfExpr`.
Fixing #23677 already broke a line in `syncio` so some package code
might be affected.
Because of the bug in `tools/parse_unicodedata.nim`, CJK Ideographs were
not considered letters in `isAlpha()`, even though they have category
Lo. This is because they are specified as range in `UnicodeData.txt`,
not as separate characters:
```
4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;
9FEF;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
```
The parser was not prepared to parse such ranges and thus omitted almost
all CJK Ideographs from consideration.
To fix this, we need to consider ranges from `UnicodeData.txt` in
`tools/parse_unicodedata.nim`.
fixes#23627
```nim
type
TestObj = object of RootObj
TestTestObj = object of RootObj
testo: TestObj
proc `=destroy`(x: TestTestObj) =
echo "Destructor for TestTestObj"
proc testCaseT() =
echo "\nTest Case T"
let tt1 {.used.} = TestTestObj(testo: TestObj())
```
When generating const object fields, it's likely that
we need to generate type infos for the object, which may be an object
with
custom hooks. We need to generate potential consts in the hooks first.
https://github.com/nim-lang/Nim/pull/20433 changed the semantics of
initialization. It should evaluate`BracedInit` first.
fixes#23596
When importing a module and declaring an overloadable symbol with the
same name as the module in the same scope, the module symbol can take
over and make the declared overload impossible to access. Previously
enum overloading had a quirk that bypassed this in a context where a
specific enum type was expected but this was removed in #23588. Now this
is bypassed in every place where a specific type is expected since
module symbols don't have a type and so wouldn't be compatible anyway.
But the issue still exists in places where no type is expected like `let
x = modulename`. I don't see a way of fixing this without nerfing module
symbols to the point where they're not accessible by default, which
might break some macro code.