Commit Graph

268 Commits

Author SHA1 Message Date
Nikolay Nikolov
e9c5b4f494 NimSuggest: Fix for the inlay exception hints with generic procs (#23610)
Based on the fix, started by SirOlaf in #23414

---------

Co-authored-by: SirOlaf <>
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
Co-authored-by: ringabout <43030857+ringabout@users.noreply.github.com>
(cherry picked from commit 478773ffb1)
2025-07-19 08:17:30 +02:00
metagn
62df0b7586 loosen compiler assert for ident node in dotcall matching [backport:2.2] (#25003)
fixes #25000

A failed match on `nfDotField` tries to assert that the name of the dot
field is an identifier node. I am not exactly sure how but at some point
typed generics causes an `nfDotField` call to contain a symchoice for
the field name. The compiler does not use the fact that the field name
is an identifier, so the assert is loosened to allow any identifier-like
node kind. Could also investigate why the symchoice gets created, my
guess is that typed generics detects that the match fails but still
sends it through generic prechecking and doesn't remove the
`nfDotField`, which is harmless and it might cause more trouble to work
around it.

(cherry picked from commit 8e5ed5dbb7)
2025-06-16 22:37:38 +02:00
metagn
c385fcb6be bring back id table algorithm instead of std table [backport:2.2] (#24930)
refs #24929, partially reverts #23403

Instead of using `Table[ItemId, T]`, the old algorithm is brought back
into `TIdTable[T]` to prevent a performance regression. The inheritance
removal from #23403 still holds, only `ItemId`s are stored.

(cherry picked from commit 82553384d1)
2025-05-06 16:04:43 +02:00
metagn
939682eba0 fix generic converter regression with var/subtype args (#24902)
refs #24867,
https://github.com/nim-lang/Nim/pull/24867#issuecomment-2821315971

The argument node of the converter can be wrapped in [hidden `addr` or
subtype conversion
nodes](dc100c5caa/compiler/sigmatch.nim (L2327-L2335))
which have to be skipped when matching the type again, since the type of
the node is the uninstantiated type taken from the proc parameter.

(cherry picked from commit 8c9a645bdf)
2025-05-05 08:17:43 +02:00
metagn
74f4042f89 isolate and rematch generic converters to get bindings (#24867)
fixes #4554, fixes #10900, fixes #13843, fixes #19471, fixes #19517

Instead of matching generic converters to their arguments using the full
call match bindings, a new match is created for them (from which the
bindings are used to instantiate the converter return type). Then when
instantiating generic converters, they are matched to their argument
again to get their bindings again instead of using the call bindings.
This prevents generic converters which match more than once from
interfering with each other's bindings.

(cherry picked from commit 334f96c05a)
2025-04-14 10:52:56 +02:00
ringabout
0dd198278e overhaul hook injections (#24841)
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.

(cherry picked from commit 40a1ec21d7)
2025-04-14 10:51:08 +02:00
Ryan McConnell
82974d91ce new-style concepts adjusments (#24697)
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)
2025-03-10 09:51:05 +01:00
Ryan McConnell
f5453e453e Fixes 3 small issues with concepts (#24481)
issue 1 - statics in the type:
This probably only handles simple cases. It's probably too accepting
only comparing the base, but that should only affect candidate selection
I think.
issue 2 - `tyArray` of length 3:
This is just a work around since I couldn't get the fix right in
previous PR
issue 3 - shadowing:
The part in `concepts.nim` that iterates candidates does not consider
imported idents if at least once module level ident matches. It does not
have to match in any other way then name.

EDIT: 2 more
issue 4 - composite typeclasses:
when declared in both the concept and the `proc` can cause problems
issue 5 - recursion:
simple recursion and scenarios where more than one concepts recurse
together (only tested two)

(cherry picked from commit e479151473)
2025-01-14 12:15:59 +01:00
metagn
6ec663f7bc fix standalone explicit generic procs with unresolved arguments (#24404)
fixes issue described in https://forum.nim-lang.org/t/12579

In #24065 explicit generic parameter matching was made to fail matches
on arguments with unresolved types in generic contexts (the sigmatch
diff, following #24010), similar to what is done for regular calls since
#22029. However unlike regular calls, a failed match in a generic
context for a standalone explicit generic instantiation did not convert
the expression into one with `tyFromExpr` type, which means it would
error immediately given any unresolved parameter. This is now done to
fix the issue.

For explicit generic instantiations on single non-overloaded symbols, a
successful match is still instantiated. For multiple overloads (i.e.
symchoice), if any of the overloads fail the match, the entire
expression is considered untyped and any instantiations are not used, so
as to not void overloads that would match later. This means even
symchoices without unresolved arguments aren't instantiated, which may
be too restrictive, but it could also be too lenient and we might need
to make symchoice instantiations always untyped. The behavior for
symchoice is not sound anyway given it causes #9997 so this is something
to consider for a redesign.

Diff follows #24276.

(cherry picked from commit 67ad1ae159)
2025-01-14 09:04:44 +01:00
metagn
ac8c44e08d implement type bound operation RFC (#24315)
closes https://github.com/nim-lang/RFCs/issues/380, fixes #4773, fixes
#14729, fixes #16755, fixes #18150, fixes #22984, refs #11167 (only some
comments fixed), refs #12620 (needs tiny workaround)

The compiler gains a concept of root "nominal" types (i.e. objects,
enums, distincts, direct `Foo = ref object`s, generic versions of all of
these). Exported top-level routines in the same module as the nominal
types that their parameter types derive from (i.e. with
`var`/`sink`/`typedesc`/generic constraints) are considered attached to
the respective type, as the RFC states. This happens for every argument
regardless of placement.

When a call is overloaded and overload matching starts, for all
arguments in the call that already have a type, we add any operation
with the same name in the scope of the root nominal type of each
argument (if it exists) to the overload match. This also happens as
arguments gradually get typed after every overload match. This restricts
the considered overloads to ones attached to the given arguments, as
well as preventing `untyped` arguments from being forcefully typed due
to unrelated overloads. There are some caveats:

* If no overloads with a name are in scope, type bound ops are not
triggered, i.e. if `foo` is not declared, `foo(x)` will not consider a
type bound op for `x`.
* If overloads in scope do not have enough parameters up to the argument
which needs its type bound op considered, then type bound ops are also
not added. For example, if only `foo()` is in scope, `foo(x)` will not
consider a type bound op for `x`.

In the cases of "generic interfaces" like `hash`, `$`, `items` etc. this
is not really a problem since any code using it will have at least one
typed overload imported. For arbitrary versions of these though, as in
the test case for #12620, a workaround is to declare a temporary
"template" overload that never matches:

```nim
# neither have to be exported, just needed for any use of `foo`:
type Placeholder = object
proc foo(_: Placeholder) = discard
```

I don't know what a "proper" version of this could be, maybe something
to do with the new concepts.

Possible directions:

A limitation with the proposal is that parameters like `a: ref Foo` are
not attached to any type, even if `Foo` is nominal. Fixing this for just
`ptr`/`ref` would be a special case, parameters like `seq[Foo]` would
still not be attached to `Foo`. We could also skip any *structural* type
but this could produce more than one nominal type, i.e. `(Foo, Bar)`
(not that this is hard to implement, it just might be unexpected).

Converters do not use type bound ops, they still need to be in scope to
implicitly convert. But maybe they could also participate in the nominal
type consideration: if `Generic[T] = distinct T` has a converter to `T`,
both `Generic` and `T` can be considered as nominal roots.

The other restriction in the proposal, being in the same scope as the
nominal type, could maybe be worked around by explicitly attaching to
the type, i.e.: `proc foo(x: T) {.attach: T.}`, similar to class
extensions in newer OOP languages. The given type `T` needs to be
obtainable from the type of the given argument `x` however, i.e.
something like `proc foo(x: ref T) {.attach: T.}` doesn't work to fix
the `ref` issue since the compiler never obtains `T` from a given `ref
T` argument. Edit: Since the module is queried now, this is likely not
possible.

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
(cherry picked from commit 2864830941)
2025-01-14 07:50:04 +01:00
metagn
2d678fa45c better errors for standalone explicit generic instantiations (#24276)
refs #8064, refs #24010

Error messages for standalone explicit generic instantiations are
revamped. Failing standalone explicit generic instantiations now only
error after overloading has finished and resolved to the default `[]`
magic (this means `[]` can now be overloaded for procs but this isn't
necessarily intentional, in #24010 it was documented that it isn't
possible). The error messages for failed instantiations are also no
longer a simple `cannot instantiate: foo` message, instead they now give
the same type mismatch error message as overloads with mismatching
explicit generic parameters.

This is now possible due to the changes in #24010 that delegate all
explicit generic proc instantiations to overload resolution. Old code
that worked around this is now removed. `maybeInstantiateGeneric` could
maybe also be removed in favor of just `explicitGenericSym`, the `result
== n` case is due to `explicitGenericInstError` which is only for niche
cases.

Also, to cause "ambiguous identifier" error messages when the explicit
instantiation is a symchoice and the expression context doesn't allow
symchoices, we semcheck the sym/symchoice created by
`explicitGenericSym` with the given expression flags.

#8064 isn't entirely fixed because the error message is still misleading
for the original case which does `values[1]`, as a consequence of
#12664.

(cherry picked from commit 0a058a6b8f)
2025-01-14 07:47:08 +01:00
ringabout
b3e02ef0c3 make PNode.typ a private field (#24326)
(cherry picked from commit 68b2e9eb6a)
2025-01-14 07:46:40 +01:00
metagn
6c96892d5e refactor to make sigmatch use LayeredIdTable for bindings (#24216)
split from #24198

This is a required refactor for the only good solution I've been able to
think of for #4858 etc. Explanation:

---

`sigmatch` currently [disables
bindings](d6a71a1067/compiler/sigmatch.nim (L1956))
(except for binding to other generic parameters) when matching against
constraints of generic parameters. This is so when the constraint is a
general metatype like `seq`, the type matching will not treat all
following uses of `seq` as the type matched against that generic
parameter.

However to solve #4858 etc we need to bind `or` types with a conversion
match to the type they are supposed to be converted to (i.e. matching
`int literal(123)` against `int8 | int16` should bind `int8`[^1], not
`int`). The generic parameter constraint binding needs some way to keep
track of this so that matching `int literal(123)` against `T: int8 |
int16` also binds `T` to `int8`[^1].

The only good way to do this IMO is to generate a new "binding context"
when matching against constraints, then binding the generic param to
what the constraint was bound to in that context (in #24198 this is
restricted to just `or` types & concrete types with convertible matches,
it doesn't work in general).

---

`semtypinst` already does something similar for bindings of generic
invocations using `LayeredIdTable`, so `LayeredIdTable` is now split
into its own module and used in `sigmatch` for type bindings as well,
rather than a single-layer `TypeMapping`. Other modules which act on
`sigmatch`'s binding map are also updated to use this type instead.

The type is also made into an `object` type rather than a `ref object`
to reduce the pointer indirection when embedding it inside
`TCandidate`/`TReplTypeVars`, but only on arc/orc since there are some
weird aliasing bugs on refc/markAndSweep that cause a segfault when
setting a layer to its previous layer. If we want we can also just
remove the conditional compilation altogether and always use `ref
object` at the cost of some performance.

[^1]: `int8` binding here and not `int16` might seem weird, since they
match equally well. But we need to resolve the ambiguity here, in #24012
I tested disallowing ambiguities like this and it broke many packages
that tries to match int literals to things like `int16 | uint16` or
`int8 | int16`. Instead of making these packages stop working I think
it's better we resolve the ambiguity with a rule like "the earliest `or`
branch with the best match, matches". This is the rule used in #24198.

(cherry picked from commit cad8726907)
2025-01-14 07:31:33 +01:00
metagn
75e50f804a delay markUsed for converters until call is resolved (#24243)
fixes #24241

(cherry picked from commit 09043f409f)
2025-01-14 07:31:22 +01:00
metagn
ff005ad7dc fix segfault in generic param mismatch error, skip typedesc (#24140)
refs #24010, refs
https://github.com/nim-lang/Nim/issues/24125#issuecomment-2358377076

The generic mismatch errors added in #24010 made it possible for `nArg`
to be `nil` in the error reporting since it checked the call argument
list, not the generic parameter list for the mismatching argument node,
which causes a segfault. This is fixed by checking the generic parameter
list immediately on any generic mismatch error.

Also the `typedesc` type is skipped for the value of the generic params
since it's redundant and the generic parameter constraints don't have
it.
2024-09-19 07:19:07 +02:00
metagn
61e04ba0ed fix calls to untyped arbitrary expressions in generics (#24100)
fixes #24099

If an arbitrary expression without a proc type (in this case
`tyFromExpr`) is called, the compiler [passes it to overload
resolution](793cee4de1/compiler/semexprs.nim (L1223)).
But overload resolution also can't handle arbitrary expressions and
treats them as not participating at all, matching with the state
`csEmpty`. The compiler checks for this and gives an "identifier
expected" error. Instead, now if we are in a generic context and an
arbitrary expression call matched with `csEmpty`, we now return
`csNoMatch` so that `semResolvedCall` can leave it untyped as
appropriate.

The expression flag `efNoDiagnostics` is replaced with this check. It's
not checked anywhere else and the only place that uses it is
`handleCaseStmtMacro`. Replacing it with `efNoUndeclared`, we just get
`csEmpty` instead of `csNoMatch`, which is handled the same way here. So
`efNoDiagnostics` is now removed and `efNoUndeclared` is used instead.
2024-09-13 11:08:22 +02:00
metagn
f223f016f3 show symchoices as ambiguous in overload type mismatches (#24077)
fixes #23397

All ambiguous symbols generate symchoices for call arguments since
#23123. So, if a type mismatch receives a symchoice node for an
argument, we now treat it as an ambiguous identifier and list the
ambiguous symbols in the error message.
2024-09-09 09:50:45 +02:00
metagn
4a548deb08 proper errors for subscript overloads (#24068)
The magic `mArrGet`/`mArrPut` subscript overloads always match, so if a
subscript doesn't match any other subscript overloads and isn't a
regular language-handled subscript, it creates a fake overload mismatch
error in `semArrGet` that doesn't have any information (gives stuff like
"first mismatch at index: 0" for every single mismatch). Instead of
generating the fake mismatches, we only generate the fake mismatch for
`mArrGet`/`mArrPut`, and process every overload except them as a real
call and get the errors from there.
2024-09-06 11:25:51 +02:00
metagn
71de7fca9e handle explicit generic routine instantiations in sigmatch (#24010)
fixes #16376

The way the compiler handled generic proc instantiations in calls (like
`foo[int](...)`) up to this point was to instantiate `foo[int]`, create
a symbol for the instantiated proc (or a symchoice for multiple procs
excluding ones with mismatching generic param counts), then perform
overload resolution on this symbol/symchoice. The exception to this was
when the called symbol was already a symchoice node, in which case it
wasn't instantiated and overloading was called directly ([these
lines](b7b1313d21/compiler/semexprs.nim (L3366-L3371))).

This has several problems:

* Templates and macros can't create instantiated symbols, so they
couldn't participate in overloaded explicit generic instantiations,
causing the issue #16376.
* Every single proc that can be instantiated with the given generic
params is fully instantiated including the body. #9997 is about this but
isn't fixed here since the instantiation isn't in a call.

The way overload resolution handles explicit instantiations by itself is
also buggy:

* It doesn't check constraints.
* It allows only partially providing the generic parameters, which makes
sense for implicit generics, but can cause ambiguity in overloading.

Here is how this PR deals with these problems:

* Overload resolution now always handles explicit generic instantiations
in calls, in `initCandidate`, as long as the symbol resolves to a
routine symbol.
* Overload resolution now checks the generic params for constraints and
correct parameter count (ignoring implicit params). If these don't
match, the entire overload is considered as not matching and not
instantiated.
* Special error messages are added for mismatching/missing/extra generic
params. This is almost all of the diff in `semcall`.
* Procs with matching generic parameters now instantiate only the type
of the signature in overload resolution, not the proc itself, which also
works for templates and macros.

Unfortunately we can't entirely remove instantiations because overload
resolution can't handle some cases with uninstantiated types even though
it's resolved in the binding (see the last 2 blocks in
`texplicitgenerics`). There are also some instantiation issues with
default params that #24005 didn't fix but I didn't want this to become
the 3rd huge generics PR in a row so I didn't dive too deep into trying
to fix them. There is still a minor instantiation fix in `semtypinst`
though for subscripts in calls.

Additional changes:

* Overloading of `[]` wasn't documented properly, it somewhat is now
because we need to mention the limitation that it can't be done for
generic procs/types.
* Tests can now enable the new type mismatch errors with just
`-d:testsConciseTypeMismatch` in the command.

Package PRs:

- using fork for now:
[combparser](https://github.com/PMunch/combparser/pull/7) (partial
generic instantiation)
- merged: [cligen](https://github.com/c-blake/cligen/pull/233) (partial
generic instantiation but non-overloaded + template)
- merged: [neo](https://github.com/andreaferretti/neo/pull/56) (trying
to instantiate template with no generic param)
2024-09-02 18:22:20 +02:00
metagn
d3af51e3ce remove fauxMatch for tyFromExpr, remove tyProxy and tyUnknown aliases (#24018)
updated version of #22193

After #22029 and the followups #23983 and #24005 which fixed issues with
it, `tyFromExpr` no longer match any proc params in generic type bodies
but delay all non-matching calls until the type is instantiated.
Previously the mechanism `fauxMatch` was used to pretend that any
failing match against `tyFromExpr` actually matched, but prevented the
instantiation of the type until later.

Since this mechanism is not needed anymore for `tyFromExpr`, it is now
only used for `tyError` to prevent cascading errors and changed to a
bool field for simplicity. A change in `semtypes` was also needed to
prevent calling `fitNode` on default param values resolving to type
`tyFromExpr` in generic procs for params with non-generic types, as this
would try to coerce the expression into a concrete type when it can't be
instantiated yet.

The aliases `tyProxy` and `tyUnknown` for `tyError` and `tyFromExpr` are
also removed for uniformity.
2024-08-28 20:46:36 +02:00
metagn
446501b53b fix error messages for wrongly typed generic param default values (#24006)
fixes #21258

When a generic proc is instantiated, if one of the default values
doesn't match the type of the parameter, `seminst` sets the default
parameter node to an `nkEmpty` node with `tyError` type. `sigmatch`
checks for this to give an error message if the default param is
actually used, but only while actively matching the proc signature,
before the proc is even instantiated. The error message also gives very
little information.

Now, we check for this in `updateDefaultParams` at the end of
`semResolvedCall`, after the proc has been instantiated. The `nkEmpty`
node also is given the original mismatching type instead rather than
`tyError`, only setting `tyError` after erroring to prevent cascading
errors. The error message is changed to the standard type mismatch error
also giving the instantiation info of the routine.
2024-08-23 18:01:43 +02:00
metagn
04da0a6028 fix subscript magic giving unresolved generic param type (#23988)
fixes #19737

As in the diff, `semResolvedCall` sets the return type of a call to a
proc to the type of the call. But in the case of the [subscript
magic](https://nim-lang.org/docs/system.html#%5B%5D%2CT%2CI), this type
is the first generic param which is also supposed to be the type of the
first argument, but this is invalid, the correct type is the element
type eventually given by `semSubscript`. Some lines above also [prevent
the subscript magics from instantiating their
params](dda638c1ba/compiler/semcall.nim (L699))
so this type ends up being an unresolved generic param.

Since the type of the node is not `nil`, `prepareOperand` doesn't try to
type it again, and this unresolved generic param type ends up being the
final type of the node. To prevent this, we just never set the type of
the node if we encountered a subscript magic.

Maybe we could also rename the generic parameters of the subscript
magics to stuff like `DummyT`, `DummyI` if we want this to be easier to
debug in the future.
2024-08-22 07:20:20 +02:00
metagn
ab18962085 sem all call nodes in generic type bodies + many required fixes (#23983)
fixes #23406, closes #23854, closes #23855 (test code of both compiles
but separate issue exists), refs #23432, follows #23411

In generic bodies, previously all regular `nkCall` nodes like `foo(a,
b)` were directly treated as generic statements and delayed immediately,
but other call kinds like `a.foo(b)`, `foo a, b` etc underwent
typechecking before making sure they have to be delayed, as implemented
in #22029. Since the behavior for `nkCall` was slightly buggy (as in
#23406), the behavior for all call kinds is now to call `semTypeExpr`.

However the vast majority of calls in generic bodies out there are
`nkCall`, and while there isn't a difference in the expected behavior,
this exposes many issues with the implementation started in #22029 given
how much more code uses it now. The portion of these issues that CI has
caught are fixed in this PR but it's possible there are more.

1. Deref expressions, dot expressions and calls to dot expressions now
handle and propagate `tyFromExpr`. This is most of the changes in
`semexprs`.
2. For deref expressions to work in `typeof`, a new type flag
`tfNonConstExpr` is added for `tyFromExpr` that calls `semExprWithType`
with `efInTypeof` on the expression instead of `semConstExpr`. This type
flag is set for every `tyFromExpr` type of a node that `prepareNode`
encounters, so that the node itself isn't evaluated at compile time when
just trying to get the type of the node.
3. Unresolved `static` types matching `static` parameters is now treated
the same as unresolved generic types matching `typedesc` parameters in
generic type bodies, it causes a failed match which delays the call
instantiation.
4. `typedesc` parameters now reject all types containing unresolved
generic types like `seq[T]`, not just generic param types by themselves.
(using `containsGenericType`)
5. `semgnrc` now doesn't leave generic param symbols it encounters in
generic type contexts as just identifiers, and instead turns them into
symbol nodes. Normally in generic procs, this isn't a problem since the
generic param symbols will be provided again at instantiation time (and
in fact creating symbol nodes causes issues since `seminst` doesn't
actually instantiate proc body node types).
But generic types can try to be instantiated early in `sigmatch` which
will give an undeclared identifier error when the param is not provided.
Nodes in generic types (specifically in `tyFromExpr` which should be the
only use for `semGenericStmt`) undergo full generic type instantiation
with `prepareNode`, so there is no issue of these symbols remaining as
uninstantiated generic types.
6. `prepareNode` now has more logic for which nodes to avoid
instantiating.
Subscripts and subscripts turned into calls to `[]` by `semgnrc` need to
avoid instantiating the first operand, since it may be a generic body
type like `Generic` in an expression like `Generic[int]`.
Dot expressions cannot instantiate their RHS as it may be a generic proc
symbol or even an undeclared identifier for generic param fields, but
have to instantiate their LHS, so calls and subscripts need to still
instantiate their first node if it's a dot expression.
This logic still isn't perfect and needs the same level of detail as in
`semexprs` for which nodes can be left as "untyped" for overloading/dot
exprs/subscripts to handle, but should handle the majority of cases.

Also the `efDetermineType` requirement for which calls become
`tyFromExpr` is removed and as a result `efDetermineType` is entirely
unused again.
2024-08-20 21:31:19 +02:00
ringabout
9b378296f6 fixes addr/hiddenAddr in strictdefs (#23477) 2024-04-10 14:41:16 +02:00
Andreas Rumpf
7657a637b8 refactoring: no inheritance for PType/PSym (#23403) 2024-03-14 19:23:18 +01:00
ringabout
1e7ca2dc78 improve error messages [backport] (#23345)
ref https://forum.nim-lang.org/t/11052


![image](https://github.com/nim-lang/Nim/assets/43030857/1df87691-32d9-46b5-b61b-6b9f7cc94862)
2024-02-26 17:24:16 +01:00
Juan M Gómez
7bf8cd3f86 Fixes a nimsuggest crash when using chronos (#23293)
The following would crash nimsuggest on init:
```nim
import chronos
type
  HistoryQuery = object
    start: int
    limit: int

  HistoryResult = object
    messages: string

type HistoryQueryHandler* = proc(req: HistoryQuery): Future[HistoryResult] {.async, gcsafe.}
```
2024-02-20 07:36:50 +01:00
Andreas Rumpf
fe18ec5dc0 types refactoring; WIP (#23086) 2023-12-17 18:43:52 +01:00
Jason Beetham
91efa49550 Overloads passed to static proc parameters now convert to the desired… (#23063)
… type mirroring proc params
2023-12-14 17:05:14 +01:00
Andreas Rumpf
e51e98997b type refactoring: part 2 (#23059) 2023-12-13 10:29:58 +01:00
Andreas Rumpf
db603237c6 Types: Refactorings; step 1 (#23055) 2023-12-12 16:54:50 +01:00
Jason Beetham
8cc3c774c8 Look up generic parameters when found inside semOverloadedCall, fixin… (#23054)
…g static procs

---------

Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2023-12-12 09:06:13 +01:00
ringabout
95e5ad6927 fixes #22902; borrow from proc return type mismatch (#22908)
fixes #22902
2023-11-04 08:50:30 +01:00
metagn
6738f44af3 unify explicit generic param semchecking in calls (#22618)
fixes #9040
2023-09-01 15:37:16 +02:00
ringabout
306b9aca48 initCandidate and friends now return values (#22570)
* `initCandidate` and friends now return values

* fixes semexprs.nim

* fixes semcall.nim

* Update compiler/semcall.nim
2023-08-28 15:57:24 +08:00
metagn
1cc4d3f622 fix generic param substitution in templates (#22535)
* fix generic param substitution in templates

fixes #13527, fixes #17240, fixes #6340, fixes #20033, fixes #19576, fixes #19076

* fix bare except in test, test updated packages in CI
2023-08-25 21:08:47 +02:00
ringabout
469c9cfab4 unpublic the sons field of PType; the precursor to PType refactorings (#22446)
* unpublic the sons field of PType

* tiny fixes

* fixes an omittance

* fixes IC

* fixes
2023-08-11 22:18:24 +08:00
Bung
2aab03bdfb fix #19304 Borrowing std/times.format causes Error: illformed AST (#20659)
* fix #19304 Borrowing std/times.format causes Error: illformed AST

* follow suggestions

* mitigate for #4121

* improve error message
2023-08-10 16:26:23 +08:00
ringabout
93ced31353 use strictdefs for compiler (#22365)
* wip; use strictdefs for compiler

* checkpoint

* complete the chores

* more fixes

* first phase cleanup

* Update compiler/bitsets.nim

* cleanup
2023-08-06 14:26:21 +02:00
SirOlaf
67122a9cb6 Let inferGenericTypes continue if a param is already bound (#22384)
* Play with typeRel

* Temp solution: Fixup call's param types

* Test result type with two generic params

* Asserts

* Tiny cleanup

* Skip sink

* Ignore proc

* Use changeType

* Remove conversion

* Remove last bits of conversion

* Flag

---------

Co-authored-by: SirOlaf <>
2023-08-06 14:23:00 +02:00
SirOlaf
8d8d75706c Add experimental inferGenericTypes switch (#22317)
* Infer generic bindings

* Simple test

* Add t

* Allow it to work for templates too

* Fix some builds by putting bindings in a template

* Fix builtins

* Slightly more exotic seq test

* Test value-based generics using array

* Pass expectedType into buildBindings

* Put buildBindings into a proc

* Manual entry

* Remove leftover `

* Improve language used in the manual

* Experimental flag and fix basic constructors

* Tiny commend cleanup

* Move to experimental manual

* Use 'kind' so tuples continue to fail like before

* Explicitly disallow tuples

* Table test and document tuples

* Test type reduction

* Disable inferGenericTypes check for CI tests

* Remove tuple info in manual

* Always reduce types. Testing CI

* Fixes

* Ignore tyGenericInst

* Prevent binding already bound generic params

* tyUncheckedArray

* Few more types

* Update manual and check for flag again

* Update tests/generics/treturn_inference.nim

* var candidate, remove flag check again for CI

* Enable check once more

---------

Co-authored-by: SirOlaf <>
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
2023-08-03 22:49:52 +02:00
metagn
6d21637245 fix scoping regression with calls in generic bodies (#22115)
refs #22029, refs https://github.com/status-im/nim-libp2p/actions/runs/5263850340/jobs/9514434659
2023-06-17 15:24:32 +08:00
metagn
894a19c6ed fix calls in generic bodies, delay typecheck when no overloads match (#22029)
* sacrifice "tgenericshardcases" for working statics

* legacy switch for CI, maybe experimental later

* convert to experimental

* apparently untyped needs the experimental switch

* try special case call semcheck

* try fix

* fix compilation

* final cleanup, not experimental, make `when` work

* remove last needed use of untyped

* fix unused warning in test

* remove untyped feature
2023-06-13 20:05:44 +02:00
Andreas Rumpf
72ca444122 hopefully easier to understand error message (#21585) 2023-03-30 15:35:00 +02:00
Andreas Rumpf
f7e3af0c2d mitigates #21272; but it's not the final fix because the first round … (#21462)
mitigates #21272; but it's not the final fix because the first round of overload resolution should already match
2023-03-20 22:53:13 +01:00
SirOlaf
7bde421e4d Fix #21272: Rewrite parts of pickBestCandidate (#21465)
* Make pickBestCandidate store syms

* Remove useless cursor

* Try making pickBestCandidate more readable

* Fix advance order

* Revert back to seq with lots of comments

---------

Co-authored-by: SirOlaf <>
2023-03-05 11:56:51 +01:00
ringabout
d950e5f3a8 remove nosinks hacks from compiler (#21469) 2023-03-04 20:07:33 +08:00
ringabout
761c5a0830 less verbose type mismatch messages (#21191)
* less verbose type mismatch messages

* Update compiler/types.nim

* fixes i386

* fixes i386
2022-12-28 20:54:15 +01:00
metagn
555c5ed1a7 fix bugs with dot & call operators [backport] (#20931)
* better error messages for dot operators [backport]

fixes #13063

* also fixes #7777

* fix #6981 and #9831 too

* fix

* minor improvement

* sus test fixes

* make test multiplatform lol

* fix nimsuggest test, extra improvements
2022-11-28 21:33:02 +01:00
Bung
eec1543baf fix semcase on tySequence and tyObject #20283 #19682 (#20339)
* fix semcase on tySequence and tyObject #20283 #19682

* use better arg name

* avoiding returns nil use errorNode instead, clean code

* use efNoDiagnostics flag

* remove tests/errmsgs/t19682.nim

* combine 2 test cases to one file
2022-11-01 10:19:37 +01:00