diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 64108a2bb9b6b..eba2e28bf61d0 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 @@ -1068,7 +1070,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) @@ -3110,7 +3112,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 82abe267701a0..9e3a49ae08885 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]