Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove allowMetaTypes for inferStaticParam + properly annotate unresolved range #24086

Open
wants to merge 3 commits into
base: devel
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/semdata.nim
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ proc makeNotType*(c: PContext, t1: PType): PType =
result.flags.incl tfHasMeta

proc nMinusOne(c: PContext; n: PNode): PNode =
result = newTreeI(nkCall, n.info, newSymNode(getSysMagic(c.graph, n.info, "pred", mPred)), n)
result = newTreeI(nkCall, n.info, newSymNode(getSysMagic(c.graph, n.info, "pred", mPred), n.info), n)

# Remember to fix the procs below this one when you make changes!
proc makeRangeWithStaticExpr*(c: PContext, n: PNode): PType =
Expand Down
5 changes: 5 additions & 0 deletions compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ proc semArrayIndex(c: PContext, n: PNode): PType =
let e = semExprWithType(c, n, {efDetermineType})
if e.typ.kind == tyFromExpr:
result = makeRangeWithStaticExpr(c, e.typ.n)
result.flags.incl tfUnresolved
elif e.kind in {nkIntLit..nkUInt64Lit}:
if e.intVal < 0:
localError(c.config, n.info,
Expand All @@ -411,6 +412,10 @@ proc semArrayIndex(c: PContext, n: PNode): PType =
# properly filled-out in semtypinst (see how tyStaticExpr
# is handled there).
result = makeRangeWithStaticExpr(c, e)
# makeRangeWithStaticExpr doesn't mark range as unresolved unless
# type of e is nil or has nil node, but we know it's unresolved
# even if it has a type because of hasUnresolvedArgs
result.flags.incl tfUnresolved
elif e.kind == nkIdent:
result = e.typ.skipTypes({tyTypeDesc})
else:
Expand Down
14 changes: 6 additions & 8 deletions compiler/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,6 @@ proc maybeSkipDistinct(m: TCandidate; t: PType, callee: PSym): PType =
result = t

proc tryResolvingStaticExpr(c: var TCandidate, n: PNode,
allowUnresolved = false,
allowCalls = false,
expectedType: PType = nil): PNode =
# Consider this example:
Expand All @@ -1005,8 +1004,7 @@ proc tryResolvingStaticExpr(c: var TCandidate, n: PNode,
# Here, N-1 will be initially nkStaticExpr that can be evaluated only after
# N is bound to a concrete value during the matching of the first param.
# This proc is used to evaluate such static expressions.
let instantiated = replaceTypesInBody(c.c, c.bindings, n, nil,
allowMetaTypes = allowUnresolved)
let instantiated = replaceTypesInBody(c.c, c.bindings, n, nil)
if not allowCalls and instantiated.kind in nkCallKinds:
return nil
result = c.c.semExpr(c.c, instantiated)
Expand Down Expand Up @@ -1083,7 +1081,9 @@ proc inferStaticParam*(c: var TCandidate, lhs: PNode, rhs: BiggestInt): bool =
(lhs.typ.n == nil or idTableGet(c.bindings, lhs.typ) == nil):
var inferred = newTypeS(tyStatic, c.c, lhs.typ.elementType)
inferred.n = newIntNode(nkIntLit, rhs)
put(c, lhs.typ, inferred)
# lhs.typ might be instantiated copy, use original type instead,
# obtained from type sym:
put(c, lhs.typ.sym.typ, inferred)
if c.c.matchedConcept != nil:
# inside concepts, binding is currently done with
# direct mutation of the involved types:
Expand All @@ -1100,10 +1100,8 @@ proc failureToInferStaticParam(conf: ConfigRef; n: PNode) =

proc inferStaticsInRange(c: var TCandidate,
inferred, concrete: PType): TTypeRelation =
let lowerBound = tryResolvingStaticExpr(c, inferred.n[0],
allowUnresolved = true)
let upperBound = tryResolvingStaticExpr(c, inferred.n[1],
allowUnresolved = true)
let lowerBound = tryResolvingStaticExpr(c, inferred.n[0], allowCalls = true)
let upperBound = tryResolvingStaticExpr(c, inferred.n[1], allowCalls = true)
template doInferStatic(e: PNode, r: Int128) =
var exp = e
var rhs = r
Expand Down
21 changes: 21 additions & 0 deletions tests/proc/tstaticsignature.nim
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,24 @@ block: # `when` in static signature
proc foo[T](): T = test()
proc bar[T](x = foo[T]()): T = x
doAssert bar[int]() == 123

block: # issue #19923
type Test[S: static[Natural]] = object
proc run(self: Test, idx: 0..(self.S * 8)) = discard
# This causes segfault ^^^^^^^^^^^^
proc run(self: Test, a: array[self.S * 8, int]) = discard
# And this too ^^^^^^^^^^
var x = Test[3]()
var y: array[24, int]
run(x, y.low)
var z: array[x.S * 8, int]
run(x, z)

block:
proc foo[I: static int](x: array[I, int]) = discard
foo([1, 2, 3, 4])
proc bar[I: static int](x: array[I * 2, int]) = discard
bar([1, 2, 3, 4])
proc double(x: int): int = x * 2
proc baz[I: static int](x: array[double(I), int]) = discard
doAssert not compiles(baz([1, 2, 3, 4]))