fix#25976
Initialize tagEffects for proc types that declare .forbids but omit
.tags,
so they behave like explicit tags: [] during indirect-call effect
tracking.
Add a regression for the nested callback assignment case.
fix#25608
This pull request improves how the compiler handles warnings for
implicit range conversions, ensuring that only non-constant values
trigger downsizing warnings. It also adds new test cases to verify that
assignments and function calls involving compile-time constants do not
produce unnecessary warnings.
Improvements to range conversion warnings:
* Updated the logic in `compiler/sempass2.nim` to skip implicit range
conversion warnings for compile-time constants by checking if an
expression is constant with `getConstExpr`. Now, only non-constant
values will trigger the warning.
Testing enhancements:
* Added new test cases in `tests/range/timplicitrangedownsizing.nim` to
confirm that assignments and function calls with constant enum and
integer values do not trigger downsizing warnings.
fixes#25949
track still walks both branches of preserved when nimvm, but it now sets
a small inNimvmBranch flag while visiting the VM branch, and trackCall
skips sfCompileTime marking only when that flag is set.
fixes #22122
The commit fixes a bug in Nim's effects checker where raise statements
with case/if expressions (commonly from template expansion) failed to
track exception types from individual branches.
Problem: addRaiseEffect only saw the outermost expression. When a
template like getTransportError(err) expanded to a case expression
raising 3 different exception types, the compiler only registered the
top-level call — missing the branch-level exceptions.
Fix (2 files):
- compiler/sempass2.nim: Added skipHiddenConv to strip implicit type
coercion nodes (nkHiddenStdConv/nkHiddenSubConv) that hide the control
flow structure. Added addRaiseEffectsFromExpr that recursively walks
into case/if/block/stmtlist expressions to find raise effects in each
branch body. Changed the nkRaiseStmt handler to use this new function.
- tests/effects/tcase_raises.nim: Test with templates that expand to
case expressions raising different exception types, verified via
{.raises: [].} pragma.
Reverts nim-lang/Nim#25845
```nim
case ecode
of ECONNABORTED, EPERM, ETIMEDOUT, ENOTCONN:
getConnectionAbortedError(ecode)
of EMFILE, ENFILE, ENOBUFS, ENOMEM:
getTransportTooManyError(ecode)
else:
(ref TransportOsError)(code: ecode,
msg: "(" & $int(ecode) & ") " & osErrorMsg(ecode))
```
The compiler inserts a hidden conv for the case expression. Perhaps we
can skip hidden convs to inspect the types that are actually raised
fixes#22122
The root cause is in the effect tracker: raise was recording the whole
conditional expression as one exception source, so semantic checking
only saw the widened common base type instead of the concrete exception
classes from each branch.
fixes#25857
## Bug
`typeof(result)` inside the expression that builds `result` gets counted
as a read
of `result` before it's set. On a `{.requiresInit.}` return type that's
a hard error
("'result' requires explicit initialization"). `typeof` never evaluates
its operand,
so it's a false positive. On 2.2.4 it compiles, but the same line still
emits a bogus
`ProveInit` warning, so no released version gets it right.
Regression from #25151. That PR made a used-before-init `requiresInit`
result a hard
error instead of a warning, which is correct on its own. The side effect
was that
this old false-positive warning became a build error.
## Root cause
`track` in `compiler/sempass2.nim` has no arm for `nkTypeOfExpr`, so it
hits the
default that recurses into every child, reaches the `result` `nkSym`
inside the
`typeof`, and calls `useVar`. `sizeof`/`compiles`/`declared` don't hit
this because
they fold to a constant before `track` runs. A `typeof(result)` typedesc
argument
survives into `track`.
## Fix
Skip `nkTypeOfExpr` in `track`. Its operand is never evaluated, so it
isn't a
definite-assignment use. After the patch there's no error and no warning
here, even
with `--warnings:on`. The #25151 check is untouched: a real use of
`result` before
init is a plain `nkSym`, not inside a `typeof`, so it still reaches
`useVar`.
## Test
`tests/init/t25857.nim`, a positive test that compiles and prints `1`.
## Checks
- Repro compiles and runs on patched 2.2.6 and patched devel.
- `tests/errmsgs/t25117.nim` still fails as expected. A real
`xxx(result)` before
init still errors.
- `testament cat init` and `testament cat errmsgs` green on patched
devel (55 tests,
0 failures), including the `--warningAsError:ProveInit` tests.
- Bisect: parent `1ab68797` good, `576c4018` (#25151) bad.
fixes#22950
This pull request improves the tracking and reporting of effect
annotations (such as `raises`, `tags`, and `forbids`) in pragma blocks,
particularly when using the `cast` pragma. It ensures that the source of
these effect annotations is correctly preserved and referenced, which
improves error reporting and effect analysis. Additionally, a new test
was added to check for violations when using `cast` with effect
annotations.
Effect annotation source tracking and propagation:
* Added new fields (`excSource`, `tagsSource`, `forbidsSource`) to the
`PragmaBlockContext` type to store the original source node for each
effect annotation.
* Updated `castBlock` to set these new source fields when processing
`raises`, `tags`, and `forbids` pragmas, ensuring the source node is
preserved for later error reporting.
* Modified `unapplyBlockContext` to use the stored source node (if
available) when calling `addRaiseEffect`, `addTag`, and `addNotTag`,
improving the accuracy of effect tracking and diagnostics.
Pragma handling improvements:
* Changed the call to `castBlock` in the main pragma processing loop to
pass the entire pragma node, enabling access to the original source for
effect annotations.
Testing:
* Added a new test (`tests/effects/tcast_effect_violation.nim`) to
verify that using `cast(raises: ValueError)` inside a procedure with
`.raises: [].` correctly triggers an error message about an unlisted
exception.
fixes#25727, regression from #24627 which was backported to 2.2.2 and
2.0.16
Instead of calling `createTypeBoundOps` for explicit hook calls and when
generating default hooks, only the called destructor is generated at a
time. This allows defining more than 1 hook for recursive types.
`=sink` for `useSeqOrStrOp` and also `atomicRefOp` always need a
`=destroy` hook generated so that is also generated separately. There
might be more that I missed, only the atomicRefOp one failed `trtree` in
CI, and it was just from a compiler assert that got triggered, otherwise
it would still have functioned.
Unfortunately I do not have a test case for this (although I can link
[this package
test](60f1be9037/tests/test_simple_combined.nim)
which broke), but this is a regression caused by #24841 (which was
backported to 2.2.4) that causes the following compiler crash:
```
assertions.nim(34) raiseAssert
Error: unhandled exception: ccgtypes.nim(230, 13) `false` mapType: tyGenericInvocation [AssertionDefect]
```
Codegen is traversing the type of the symbol of an explicit destructor
call, but the symbol is the uninstantiated generic hook. This happens
because #24841 changed the code which gives explicit destructor calls
the proper attached destructor to use `replaceHookMagic`, which now
skips `abstractVar` from the type to get the destructor whereas
previously it was just `{tyAlias, tyVar}`. This skips `tyGenericInst`
and also `tyDistinct`. I cannot explain why the skipped `tyGenericInst`
does not have the right destructor but it's not really unexpected, and
skipping `tyDistinct` is just wrong.
To fix this, just `{tyAlias, tyVar, tySink}` are skipped.
First performance numbers:
time tests/arc/torcbench -- YRC
true peak memory: true
real 0m0,163s
user 0m0,161s
sys 0m0,002s
time tests/arc/torcbench -- ORC
true peak memory: true
real 0m0,107s
user 0m0,104s
sys 0m0,003s
So it's 1.6x slower. But it's threadsafe and provably correct. (Lean and
model checking via TLA+ used.)
Of course there is always the chance that the implementation is wrong
and doesn't match the model.
TODO:
- [ ] test writing of .nif files
- [x] implement loading of fields in PType/PSym that might not have been
loaded
- [ ] implement interface logic
- [ ] implement pragma "replays"
- [ ] implement special logic for `converter`
- [ ] implement special logic for `method`
- [ ] test the logic holds up for `export`
- [ ] implement logic to free the memory of PSym/PType if memory
pressure is high
- [ ] implement logic to close memory mapped files if too many are open.
---------
Co-authored-by: demotomohiro <gpuppur@gmail.com>
Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
Co-authored-by: Jacek Sieka <arnetheduck@gmail.com>
fixes#24760
I tried `incl` `tfHasAsgn` to nontrivial assignment, but that solution
seems to break too many things. Instead, in this PR, `passCopyToSink`
now checks nontrivial assignment
fixes#25117
errors on `requiresInit` of `result` if it is used before
initialization. Otherwise
```nim
# prevent superfluous warnings about the same variable:
a.init.add s.id
```
It produces a warning, and this line prevents it from being recognized
by the `requiresInit` check in `trackProc`
ref https://github.com/nim-lang/Nim/issues/24764
To keep destructors injected consistently, we need to transform `mAsgn`
properly into `nkSinkAsgn` and `nkAsgn`. This PR is the first step
towards overhauling hook injections.
In this PR, hooks (except mAsgn) are treated consistently whether it is
resolved in matching or instantiated by sempass2. It also fixes a
spelling `=wasMoved` to its normalized version, which caused no
replacing generic hook calls with lifted hook calls.
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
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.
fixes#24626
`createTypeboundOps` in sempass2 is called when generating destructors
for types including for explicit destructor calls, however it blocks
destructors from getting generated in a `nodestroy` proc. This causes
issues when a destructor is explicitly called in a `nodestroy` proc. To
fix this, allow destructors to get generated only for explicit
destructor calls in nodestroy procs.
fixes#24112
Sym nodes in templates that could be open are [given `nil`
type](22d2cf2175/compiler/semtempl.nim (L274))
when `--experimentalOpenSym` is disabled so that they can be semchecked
to give a warning since #24007. The first nodes of object constructors
(in this case) and in type conversions don't replace their first node
(the symbol) with a typechecked one, they only call `semTypeNode` on it
and leave it as is.
Effect tracking checks if the type of a sym node has a destructor to
check if the node type should be replaced with the sym type. But this
causes a segfault when the type of the node is nil. To fix this, we
always set the node type to the sym type if the node type is nil.
Alternatively `semObjConstr` and `semConv` could be changed to set the
type of their first node to the found type but I'm not sure if this
would break anything. They could call `semExprWithType` on the first
node but `semTypeNode` would still have to be called (maybe call it
before?). This isn't a problem if the sym node has a type but is just
nested in `nkOpenSym` or `nkOpenSymChoice` which have nil type instead
(i.e. with openSym enabled), so maybe this still is the "most general"
solution, I don't know.
This adds nimsuggest support for displaying inlay hints for exceptions.
An inlay hint is displayed around function calls, that can raise an
exception, which isn't handled in the current subroutine (in other
words, exceptions that can propagate back to the caller). On mouse hover
on top of the hint, a list of exceptions that could propagate is shown.
The changes, required to support this are already commited to
nimlangserver and the VS code extension. The extension and the server
allow configuration for whether these new exception hints are enabled
(they can be enabled or disabled independently from the type hints), as
well as the inlay strings that are inserted before and after the name of
the function, around the function call. Potentially, one of these
strings can be empty, for example, the user can choose to add an inlay
hint only before the name of the function, or only after the name of the
function.