diff options
author | metagn <metagngn@gmail.com> | 2023-08-17 19:52:28 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-17 18:52:28 +0200 |
commit | 98c39e8e571b95e7d9351c7115f897ce9af1a218 (patch) | |
tree | 69cc5b34456e36fd659d412ef90b1a0488f77748 | |
parent | fede75723824e06f59f23b38a9016d3f8cdf71db (diff) | |
download | Nim-98c39e8e571b95e7d9351c7115f897ce9af1a218.tar.gz |
cascade tyFromExpr in type conversions in generic bodies (#22499)
fixes #22490, fixes #22491, adapts #22029 to type conversions
-rw-r--r-- | compiler/semexprs.nim | 12 | ||||
-rw-r--r-- | tests/statictypes/tgenericcomputedrange.nim | 8 |
2 files changed, 15 insertions, 5 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index df65b3371..52d1f0628 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -311,7 +311,7 @@ proc isOwnedSym(c: PContext; n: PNode): bool = let s = qualifiedLookUp(c, n, {}) result = s != nil and sfSystemModule in s.owner.flags and s.name.s == "owned" -proc semConv(c: PContext, n: PNode; expectedType: PType = nil): PNode = +proc semConv(c: PContext, n: PNode; flags: TExprFlags = {}, expectedType: PType = nil): PNode = if n.len != 2: localError(c.config, n.info, "a type conversion takes exactly one argument") return n @@ -358,7 +358,7 @@ proc semConv(c: PContext, n: PNode; expectedType: PType = nil): PNode = if n[1].kind == nkExprEqExpr and targetType.skipTypes(abstractPtrs).kind == tyObject: localError(c.config, n.info, "object construction uses ':', not '='") - var op = semExprWithType(c, n[1]) + var op = semExprWithType(c, n[1], flags * {efDetermineType}) if op.kind == nkClosedSymChoice and op.len > 0 and op[0].sym.kind == skEnumField: # resolves overloadedable enums op = ambiguousSymChoice(c, n, op) @@ -373,7 +373,9 @@ proc semConv(c: PContext, n: PNode; expectedType: PType = nil): PNode = # here or needs to be overwritten too then. result.add op - if targetType.kind == tyGenericParam: + if targetType.kind == tyGenericParam or + (op.typ != nil and op.typ.kind == tyFromExpr and c.inGenericContext > 0): + # expression is compiled early in a generic body result.typ = makeTypeFromExpr(c, copyTree(result)) return result @@ -1075,7 +1077,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType t = skipTypes(n[0].typ, abstractInst+{tyOwned}-{tyTypeDesc, tyDistinct}) if t != nil and t.kind == tyTypeDesc: if n.len == 1: return semObjConstr(c, n, flags, expectedType) - return semConv(c, n) + return semConv(c, n, flags) let nOrig = n.copyTree semOpAux(c, n) @@ -3123,7 +3125,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}, expectedType: PType # XXX think about this more (``set`` procs) let ambig = c.isAmbiguous if not (n[0].kind in {nkClosedSymChoice, nkOpenSymChoice, nkIdent} and ambig) and n.len == 2: - result = semConv(c, n, expectedType) + result = semConv(c, n, flags, expectedType) elif ambig and n.len == 1: errorUseQualifier(c, n.info, s) elif n.len == 1: diff --git a/tests/statictypes/tgenericcomputedrange.nim b/tests/statictypes/tgenericcomputedrange.nim index 82abe2677..9e3a49ae0 100644 --- a/tests/statictypes/tgenericcomputedrange.nim +++ b/tests/statictypes/tgenericcomputedrange.nim @@ -115,3 +115,11 @@ block: # issue #22187 k: array[p(m(T, s)), int64] var x: F[int, 3] doAssert x.k is array[3, int64] + +block: # issue #22490 + proc log2trunc(x: uint64): int = + if x == 0: int(0) else: int(0) + template maxChunkIdx(T: typedesc): int64 = 0'i64 + template layer(vIdx: int64): int = log2trunc(0'u64) + type HashList[T] = object + indices: array[int(layer(maxChunkIdx(T))), int] |