[backport] fixes #4086, #9355 for v2.2.x (#25799)#25804
Closed
puffball1567 wants to merge 2 commits into
Closed
Conversation
…eference other type params
Generic type parameter defaults that reference other type parameters
currently fail in Nim, even though C++ / TypeScript / Rust / Scala all
support the pattern. This change enables four related sub-cases:
1. type-side reference: `type Foo[T; U = seq[T]]`
(also `U = ref T`, `U = array[3, T]`, alias, distinct, cascade)
2. type-side direct: `type Foo[T; U = T]`
3. type-side 0-arg invocation: `var f: Foo` for `type Foo[T = int]`
4. proc-side: `func foo[T](U = T): U` and `func foo[T](U: type = T): U`
Implementation
--------------
compiler/semtypes.nim
- semGeneric: accumulate already-resolved generic params into a
layered type map and substitute them in subsequent default values
before they are added to the invocation. Handles cascade defaults
like `[T; U = seq[T]; V = seq[U]]` left-to-right. Gated on
`hasAnyDefault` so generic types with no defaults pay no overhead.
- semProcTypeNode: treat a bare generic-param default (`U = T`) as
an unbound typedesc parameter, equivalent to `U: type = T`, so the
existing typedesc-param machinery handles it.
- tryGenericBodyDefaultInvocation: helper that synthesizes a
`Foo[default1, default2, ...]` invocation when every generic param
has a default, and dispatches to semGeneric.
compiler/semstmts.nim
- semVarOrLet / semConst: after type resolution, if the resulting
type is a tyGenericBody whose every param has a default, expand
it via tryGenericBodyDefaultInvocation. Restricted to var/let/
const so type-level computations like `arity(SomeGeneric)` in
template/typetraits contexts keep treating bare generic-body
references as intended.
compiler/sigmatch.nim
- matches default-completion: when the default value is a bare
reference to an earlier generic type param (recognised by the
default's static type being `tyGenericParam`), substitute T
against the explicit-instantiation bindings via prepareTypesInBody
and wrap the result as `tyTypeDesc` so the implicit
`tfImplicitTypeParam` binding path treats it like a literal type
default. Defaults whose type is anything else — value expressions
like `arr.high`, proc-call expressions like `newTensor[T](0)` whose
result type is `tyGenericInvocation`/`tyGenericInst`, etc. — are
left untouched, so the existing default-handling machinery (and
later sem stages) continue to handle them as before. Verified by
locally building tests/test_indep_import.nim from arraymancer
against ~/.nimble pkgs2.
Tests
-----
tests/generics/tgeneric_param_default_deps.nim covers all four
sub-cases and the cascade / alias / distinct variants. Local
regression on tests/{generic,generics,objects,typerel,types,
metatype,statictypes,concepts,proc,overload,template,macros,tuples,
collections,distinct,varstmt,let,varres,assign,init}: 663 reSuccess
across 19 categories. The single non-success entry,
tests/types/tforwardcycletimeout reTimeout, reproduces on clean
upstream/devel and is unrelated.
closes nim-lang#4086
closes nim-lang#9355
…g#9355 Adds three review-requested tests to tgeneric_param_default_deps.nim covering generic param defaults in combination with: 1. union constraint: type Foo[T; U: seq[T]|Deque[T] = seq[T]] 2. typeclass constraint: type Foo[T: SomeInteger = int] 3. concept constraint: type Foo[T: HasLen = string] These exercise the default-completion machinery added in 18f250e across constraint kinds adjacent to higher-kinded-type accidental behavior (RFCs#5). All three pass under both --mm:orc (default) and --mm:refc. Local regression on tests/concepts: 45/46 reSuccess, 0 reFail (1 reDisabled is unrelated). Local regression on tests/generics: 116/116 reSuccess, 0 reFail.
3 tasks
Member
|
Sorry for this late reply but this is exactly the kind of backport we should avoid. Can cause unforeseen regressions on the now-finally stable again 2.2.x line. |
Contributor
Author
|
Thanks for your reply. I'll respect the project's backport policy and close this PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport of #25799 to v2.2.x
Backport of #25799 ("fixes #4086, #9355; allow generic param defaults to reference other type params") to the v2.2.x maintenance branch.
Prerequisite: #25799 should be merged to devel first.
How this differs from a plain cherry-pick
Direct cherry-pick of #25799 onto version-2-2 doesn't work as-is because:
containsForwardType*helpers (= thehasForwardTypeParammachinery from fixes #16754 #25519) don't exist in v2.2.x — inlined locallyresult.flags.incl Xvs devel'sresult.incl X, absence ofLazySymwrapper foraddPureEnum,c.skipTypes.add nvsc.forwardTypeUpdates.add (...))The patch adapts to v2.2.x by inlining the missing helpers and matching the older API. Touched file set is the same as #25799:
Verification
Local on Linux x86_64, Nim 2.2.11 (bin/nim built fresh from this branch via csources_v3 + koch boot):
nim check compiler/nim.nim— [SuccessX]tests/generics/tgeneric_param_default_deps.nim— PASSgeneric generics objects typerel types metatype statictypes concepts proc overload template macros tuples collections distinct varstmt let varres assign init) — no FAILURE summary in any cat. (One valgrind-tagged test inobjectsaborted locally because valgrind is not installed; CI should cover that path.)ref: #25799 (devel)
Related issues: #4086, #9355