From 0cd53076337e6c6656eef00284bdead10179a620 Mon Sep 17 00:00:00 2001 From: metagn Date: Fri, 11 Apr 2025 19:38:35 +0300 Subject: [PATCH] fix array/set/tuple literals with generic expression elements (#24497) fixes #24484, fixes #24672 When an array, set or tuple constructor has an element that resolves to `tyFromExpr`, the type of the entire literal is now set to `tyFromExpr` and the subsequent elements are not matched to any type. The remaining expressions are still typed (a version of the PR before this called `semGenericStmt` on them instead), however elements with int literal types have their types set to `nil`, since generic instantiation removes int literal types and the int literal type is required for implicitly converting the int literal element to the set type. Tuples should not really need this but it is done for them anyway in case it messes up some type inference --------- Co-authored-by: Andreas Rumpf (cherry picked from commit 897126a7117c5bed90ec9c29a8792ee878278f55) --- compiler/semexprs.nim | 74 ++++++++++++++++++++++++----- tests/proc/tgenericdefaultparam.nim | 37 +++++++++++++++ 2 files changed, 100 insertions(+), 11 deletions(-) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 98f2950c90..de4ea2cc2b 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -724,7 +724,7 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp # nkBracket nodes can also be produced by the VM as seq constant nodes # in which case, we cannot produce a new array type for the node, # as this might lose type info even when the node has array type - let constructType = n.typ.isNil + let constructType = n.typ.isNil or n.typ.kind == tyFromExpr var expectedElementType, expectedIndexType: PType = nil var expectedBase: PType = nil if constructType: @@ -773,7 +773,11 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp let yy = semExprWithType(c, x, {efTypeAllowed}, expectedElementType) var typ: PType - if constructType: + var isGeneric = false + if yy.typ != nil and yy.typ.kind == tyFromExpr: + isGeneric = true + typ = nil # will not be used + elif constructType: typ = yy.typ if expectedElementType == nil: expectedElementType = typ @@ -798,11 +802,21 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp let xx = semExprWithType(c, x, {efTypeAllowed}, expectedElementType) result.add xx - if constructType: + if xx.typ != nil and xx.typ.kind == tyFromExpr: + isGeneric = true + elif constructType: typ = commonType(c, typ, xx.typ) #n[i] = semExprWithType(c, x, {}) #result.add fitNode(c, typ, n[i]) inc(lastIndex) + if isGeneric: + for i in 0..