diff options
author | metagn <metagngn@gmail.com> | 2024-09-06 12:44:38 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-06 11:44:38 +0200 |
commit | a93c5d79b95b569711478b81d2ae9d19675fc4d8 (patch) | |
tree | 9e7d314c830bfefa145224010ee92bf2c7d95dbe /compiler/semexprs.nim | |
parent | c10f84b9d75b6a6f2a187132e9c27c7693648bad (diff) | |
download | Nim-a93c5d79b95b569711478b81d2ae9d19675fc4d8.tar.gz |
adapt generic default parameters to recent generics changes (#24065)
fixes #16700, fixes #20916, refs #24010 Fixes the instantiation issues for proc param default values encountered in #24010 by: 1. semchecking generic default param values with `inGenericContext` for #22029 and followups to apply (the bigger change in semtypes), 2. rejecting explicit generic instantiations with unresolved generic types inside `inGenericContext` (sigmatch change), 3. instantiating the default param values using `prepareNode` rather than an insufficient manual method (the bigger change in seminst). This had an important side effect of references to other parameters not working since they would be resolved as a symbol belonging to the uninstantiated original generic proc rather than the later instantiated proc. There is a more radical way to fix this which is generating ident nodes with `tyFromExpr` in specifically this context, but instead we just count them as belonging to the same proc in `hoistParamsUsedInDefault`. Other minor bugfixes: * To make the error message in t20883 make sense, we now give a "cannot instantiate" error when trying to instantiate a proc generic param with `tyFromExpr`. * Object constructors as default param values generated default values of private fields going through `evalConstExpr` more than once, but the VM doesn't mark the object fields as `nfSkipFieldChecking` which gives a "cannot access field" error. So the VM now marks object fields it generates as `nfSkipFieldChecking`. Not sure if this affects VM performance, don't see why it would. * The nkRecWhen changes in #24042 didn't cover the case where all conditions are constantly false correctly, this is fixed with a minor change. This isn't needed for this PR now but I encountered it after forgetting to `dec c.inGenericContext`.
Diffstat (limited to 'compiler/semexprs.nim')
-rw-r--r-- | compiler/semexprs.nim | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 9b255bdf4..bb82a7cd7 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -3084,7 +3084,11 @@ proc hoistParamsUsedInDefault(c: PContext, call, letSection, defExpr: var PNode) # duty is activated by returning a non-nil value. The caller is responsible # for replacing the input to the function with the returned non-nil value. # (which is the hoisted symbol) - if defExpr.kind == nkSym and defExpr.sym.kind == skParam and defExpr.sym.owner == call[0].sym: + if defExpr.kind == nkSym and defExpr.sym.kind == skParam and + (defExpr.sym.owner == call[0].sym or + # symbol was resolved before proc was instantiated: + (sfFromGeneric in call[0].sym.flags and + defExpr.sym.owner == call[0].sym.instantiatedFrom)): let paramPos = defExpr.sym.position + 1 if call[paramPos].skipAddr.kind != nkSym and not ( |