fixes #21840; nested local template lookup regression (#21841)

* fixes #21840; nested local template lookup regression

* use original types

* fixes js vm tests
This commit is contained in:
ringabout
2023-05-12 19:38:10 +08:00
committed by GitHub
parent 161f50643a
commit 9c40dd2406
2 changed files with 81 additions and 7 deletions

View File

@@ -578,14 +578,14 @@ proc defaultFieldsForTuple(c: PContext, recNode: PNode, hasDefault: var bool): s
result.add newTree(nkExprColonExpr, recNode, asgnExpr)
return
let asgnType = newType(tyTypeDesc, nextTypeId(c.idgen), recType.owner)
rawAddSon(asgnType, recType)
let asgnType = newType(tyTypeDesc, nextTypeId(c.idgen), recNode.typ.owner)
rawAddSon(asgnType, recNode.typ)
let asgnExpr = newTree(nkCall,
newSymNode(getSysMagic(c.graph, recNode.info, "zeroDefault", mZeroDefault)),
newNodeIT(nkType, recNode.info, asgnType)
)
asgnExpr.flags.incl nfSkipFieldChecking
asgnExpr.typ = recType
asgnExpr.typ = recNode.typ
result.add newTree(nkExprColonExpr, recNode, asgnExpr)
else:
doAssert false
@@ -615,9 +615,9 @@ proc defaultFieldsForTheUninitialized(c: PContext, recNode: PNode): seq[PNode] =
if field.ast != nil: #Try to use default value
result.add newTree(nkExprColonExpr, recNode, field.ast)
elif recType.kind in {tyObject, tyArray, tyTuple}:
let asgnExpr = defaultNodeField(c, recNode, recType)
let asgnExpr = defaultNodeField(c, recNode, recNode.typ)
if asgnExpr != nil:
asgnExpr.typ = recType
asgnExpr.typ = recNode.typ
asgnExpr.flags.incl nfSkipFieldChecking
result.add newTree(nkExprColonExpr, recNode, asgnExpr)
else:
@@ -628,8 +628,8 @@ proc defaultNodeField(c: PContext, a: PNode, aTyp: PType): PNode =
if aTypSkip.kind == tyObject:
let child = defaultFieldsForTheUninitialized(c, aTypSkip.n)
if child.len > 0:
var asgnExpr = newTree(nkObjConstr, newNodeIT(nkType, a.info, aTypSkip))
asgnExpr.typ = aTypSkip
var asgnExpr = newTree(nkObjConstr, newNodeIT(nkType, a.info, aTyp))
asgnExpr.typ = aTyp
asgnExpr.sons.add child
result = semExpr(c, asgnExpr)
elif aTypSkip.kind == tyArray:

View File

@@ -614,6 +614,80 @@ template main {.dirty.} =
type SearchOptions = object
evaluation = evaluate
block:
type
Result[T, E] = object
when T is void:
when E is void:
oResultPrivate: bool
else:
case oResultPrivate: bool
of false:
eResultPrivate: E
of true:
discard
else:
when E is void:
case oResultPrivate: bool
of false:
discard
of true:
vResultPrivate: T
else:
case oResultPrivate: bool
of false:
eResultPrivate: E
of true:
vResultPrivate: T
template `?`[T, E](self: Result[T, E]): auto =
let v = (self)
if not v.oResultPrivate:
when compiles(`assignResult?`(default(typeof(result)))):
when typeof(result) is typeof(v):
`assignResult?`(v)
elif E is void:
`assignResult?`(err(typeof(result)))
else:
`assignResult?`(err(typeof(result), v.eResultPrivate))
return
else:
return
when typeof(result) is typeof(v):
v
elif E is void:
err(typeof(result))
else:
err(typeof(result), v.eResultPrivate)
when not(T is void):
v.vResultPrivate
type R = Result[int, string]
proc testAssignResult() =
var assigned: bool
template `assignResult?`(v: Result) =
assigned = true
result = v
proc failed(): Result[int, string] =
discard
proc calling(): Result[int, string] =
let _ = ? failed()
doAssert false
let r = calling()
doAssert assigned
when nimvm:
when not defined(js):
testAssignResult()
else:
testAssignResult()
static: main()
main()