Skip to content

Commit

Permalink
test fixes for #24184
Browse files Browse the repository at this point in the history
refs #24184, refs (fixes) #23010, #22793
  • Loading branch information
metagn committed Sep 28, 2024
1 parent 4f5c0ef commit 32aa764
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 21 deletions.
62 changes: 44 additions & 18 deletions compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -722,29 +722,46 @@ proc arrayConstrType(c: PContext, n: PNode): PType =

proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PType = nil): PNode =
result = newNodeI(nkBracket, n.info)
result.typ = newTypeS(tyArray, c)
# 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
var expectedElementType, expectedIndexType: PType = nil
if expectedType != nil:
let expected = expectedType.skipTypes(abstractRange-{tyDistinct})
if constructType:
result.typ = newTypeS(tyArray, c)
if expectedType != nil:
let expected = expectedType.skipTypes(abstractRange-{tyDistinct})
case expected.kind
of tyArray:
expectedIndexType = expected[0]
expectedElementType = expected[1]
of tyOpenArray:
expectedElementType = expected[0]
else: discard
rawAddSon(result.typ, nil) # index type
else:
result.typ = n.typ
let expected = n.typ.skipTypes(abstractRange) # include tyDistinct this time
case expected.kind
of tyArray:
expectedIndexType = expected[0]
expectedElementType = expected[1]
of tyOpenArray:
of tyOpenArray, tySequence:
# typed bracket expressions can also have seq type
expectedElementType = expected[0]
else: discard
rawAddSon(result.typ, nil) # index type
var
firstIndex, lastIndex: Int128 = Zero
indexType = getSysType(c.graph, n.info, tyInt)
lastValidIndex = lastOrd(c.config, indexType)
if n.len == 0:
rawAddSon(result.typ,
if expectedElementType != nil and
typeAllowed(expectedElementType, skLet, c) == nil:
expectedElementType
else:
newTypeS(tyEmpty, c)) # needs an empty basetype!
if constructType:
rawAddSon(result.typ,
if expectedElementType != nil and
typeAllowed(expectedElementType, skLet, c) == nil:
expectedElementType
else:
newTypeS(tyEmpty, c)) # needs an empty basetype!
lastIndex = toInt128(-1)
else:
var x = n[0]
Expand All @@ -761,9 +778,13 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp
x = x[1]

let yy = semExprWithType(c, x, {efTypeAllowed}, expectedElementType)
var typ = yy.typ
if expectedElementType == nil:
expectedElementType = typ
var typ: PType
if constructType:
typ = yy.typ
if expectedElementType == nil:
expectedElementType = typ
else:
typ = expectedElementType
result.add yy
#var typ = skipTypes(result[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal})
for i in 1..<n.len:
Expand All @@ -783,15 +804,20 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags; expectedType: PTyp

let xx = semExprWithType(c, x, {efTypeAllowed}, expectedElementType)
result.add xx
typ = commonType(c, typ, xx.typ)
if constructType:
typ = commonType(c, typ, xx.typ)
#n[i] = semExprWithType(c, x, {})
#result.add fitNode(c, typ, n[i])
inc(lastIndex)
addSonSkipIntLit(result.typ, typ, c.idgen)
if constructType:
addSonSkipIntLit(result.typ, typ, c.idgen)
for i in 0..<result.len:
result[i] = fitNode(c, typ, result[i], result[i].info)
result.typ.setIndexType makeRangeType(c, toInt64(firstIndex), toInt64(lastIndex), n.info,
indexType)
if constructType:
result.typ.setIndexType(
makeRangeType(c,
toInt64(firstIndex), toInt64(lastIndex),
n.info, indexType))

proc fixAbstractType(c: PContext, n: PNode) =
for i in 1..<n.len:
Expand Down
5 changes: 4 additions & 1 deletion compiler/semtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1408,7 +1408,10 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
def = fitNode(c, typ, def, def.info)
elif typ.kind == tyStatic:
def = semConstExpr(c, def)
def = fitNode(c, typ, def, def.info)
# do we need to set `def.typ` to `tyStatic` here?
def = fitNode(c, typ.skipTypes({tyStatic}), def, def.info)
# keep proc AST updated
a[^1] = def.copyTree

if not hasType and not hasDefault:
if isType: localError(c.config, a.info, "':' expected")
Expand Down
4 changes: 2 additions & 2 deletions tests/errmsgs/tunknown_named_parameter.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ func rsplit(s: string; sep: string; maxsplit: int = -1): seq[string]
first type mismatch at position: 2
required type for sep: string
but expression '{':'}' is of type: set[char]
func rsplit(s: string; seps: set[char] = Whitespace; maxsplit: int = -1): seq[
string]
func rsplit(s: string; seps: set[char] = {' ', '\t', '\v', '\r', '\n', '\f'};
maxsplit: int = -1): seq[string]
first type mismatch at position: 3
unknown named parameter: maxsplits
Expand Down
50 changes: 50 additions & 0 deletions tests/proc/tdefaultvalueprocast.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
discard """
nimout: '''
ProcDef
Sym "foo"
Empty
Empty
FormalParams
Empty
IdentDefs
Sym "x"
Empty
Call
Sym "none"
Sym "Natural"
Empty
Empty
DiscardStmt
Empty
ProcDef
Sym "example"
Empty
Empty
FormalParams
Empty
IdentDefs
Sym "a"
Empty
Sym "thing"
Empty
Empty
DiscardStmt
TupleConstr
Sym "a"
Sym "thing"
'''
"""

import options, macros

macro typedTree(n: typed): untyped =
result = n
echo treeRepr n

# issue #19118
proc foo(x = none(Natural)) {.typedTree.} = discard

# issue #12942
var thing = 2
proc example(a = thing) {.typedTree.} =
discard (a, thing)
50 changes: 50 additions & 0 deletions tests/proc/tdefaultvalueresem.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
discard """
output: '''
seq[string]
@[]
seq[string]
@[]
seq[string]
@[]
seq[string]
@[]
seq[string]
@[]
seq[string]
@[]
'''
"""

# regression from #24184, see #24191

const a: seq[string] = @[]

proc foo(x = a) =
echo typeof(x)
echo x

proc bar(x: static seq[string] = a) =
echo typeof(x)
echo x

# issue #22793
proc baz(x: static seq[string] = @[]) =
echo typeof(x)
echo x

import macros

macro resem(x: typed) =
expectKind x, nnkSym
result = getImpl(x)

foo()
bar()
baz()
block:
resem(foo) # Error: cannot infer the type of parameter 'x'
resem(bar)
resem(baz)
foo()
bar()
baz()
22 changes: 22 additions & 0 deletions tests/proc/tdefaultvaluestatic.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
block: # issue #22793
const x = @["a", "b"]

proc myProc(x: seq[string]): seq[string] =
result = x
doAssert x.myProc() == @["a", "b"]
doAssert x.myProc() == x

proc myProc2(x: seq[string] = @[]): seq[string] = # Compiler correctly infers that `@[]` is `seq[string]`
result = x
doAssert x.myProc2() == @["a", "b"]
doAssert x.myProc2() == x

proc myProc3(x: static seq[string]): seq[string] =
result = x
doAssert x.myProc3() == @["a", "b"]
doAssert x.myProc3() == x

proc myProc4(x: static seq[string] = @[]): seq[string] = # This proc causes a compiler error. Compiler does not infer that `@[]` is `static seq[string]`
result = x
doAssert x.myProc4() == @["a", "b"]
doAssert x.myProc4() == x
29 changes: 29 additions & 0 deletions tests/vm/tconstarrayresem.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# issue #23010

type
Result[T, E] = object
case oResult: bool
of false:
discard
of true:
vResult: T

Opt[T] = Result[T, void]

template ok[T, E](R: type Result[T, E], x: untyped): R =
R(oResult: true, vResult: x)

template c[T](v: T): Opt[T] = Opt[T].ok(v)

type
FixedBytes[N: static[int]] = distinct array[N, byte]

H = object
d: FixedBytes[2]

const b = default(H)
template g(): untyped =
const t = default(H)
b

discard c(g())

0 comments on commit 32aa764

Please sign in to comment.