[WIP] Early evaluation of mIs (#8723)
* Early evaluation of mIs The `evalIs` implementation was just a broken copy of `isOpImpl` so let's just avoid it alltogether: `mIs` nodes are either resolved during the semantic phase or bust. * Remove dead code and tidy it up
This commit is contained in:
parent
9f8b93641e
commit
4808ef72db
4 changed files with 14 additions and 47 deletions
|
|
@ -403,10 +403,8 @@ proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
n[1] = makeTypeSymNode(c, lhsType, n[1].info)
|
n[1] = makeTypeSymNode(c, lhsType, n[1].info)
|
||||||
lhsType = n[1].typ
|
lhsType = n[1].typ
|
||||||
else:
|
else:
|
||||||
if lhsType.base.kind == tyNone:
|
internalAssert c.config, lhsType.base.kind != tyNone
|
||||||
# this is a typedesc variable, leave for evals
|
if c.inGenericContext > 0 and lhsType.base.containsGenericType:
|
||||||
return
|
|
||||||
if lhsType.base.containsGenericType:
|
|
||||||
# BUGFIX: don't evaluate this too early: ``T is void``
|
# BUGFIX: don't evaluate this too early: ``T is void``
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -174,43 +174,6 @@ proc makeRangeF(typ: PType, first, last: BiggestFloat; g: ModuleGraph): PType =
|
||||||
result.n = n
|
result.n = n
|
||||||
addSonSkipIntLit(result, skipTypes(typ, {tyRange}))
|
addSonSkipIntLit(result, skipTypes(typ, {tyRange}))
|
||||||
|
|
||||||
proc evalIs(n: PNode, lhs: PSym, g: ModuleGraph): PNode =
|
|
||||||
# XXX: This should use the standard isOpImpl
|
|
||||||
internalAssert g.config,
|
|
||||||
n.sonsLen == 3 and
|
|
||||||
lhs.typ != nil and
|
|
||||||
n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
|
|
||||||
|
|
||||||
var
|
|
||||||
res = false
|
|
||||||
t1 = lhs.typ
|
|
||||||
t2 = n[2].typ
|
|
||||||
|
|
||||||
if t1.kind == tyTypeDesc and t2.kind != tyTypeDesc:
|
|
||||||
t1 = t1.base
|
|
||||||
|
|
||||||
if n[2].kind in {nkStrLit..nkTripleStrLit}:
|
|
||||||
case n[2].strVal.normalize
|
|
||||||
of "closure":
|
|
||||||
let t = skipTypes(t1, abstractRange)
|
|
||||||
res = t.kind == tyProc and
|
|
||||||
t.callConv == ccClosure and
|
|
||||||
tfIterator notin t.flags
|
|
||||||
of "iterator":
|
|
||||||
let t = skipTypes(t1, abstractRange)
|
|
||||||
res = t.kind == tyProc and
|
|
||||||
t.callConv == ccClosure and
|
|
||||||
tfIterator in t.flags
|
|
||||||
else:
|
|
||||||
res = false
|
|
||||||
else:
|
|
||||||
# XXX semexprs.isOpImpl is slightly different and requires a context. yay.
|
|
||||||
let t2 = n[2].typ
|
|
||||||
res = sameType(t1, t2)
|
|
||||||
|
|
||||||
result = newIntNode(nkIntLit, ord(res))
|
|
||||||
result.typ = n.typ
|
|
||||||
|
|
||||||
proc fitLiteral(c: ConfigRef, n: PNode): PNode =
|
proc fitLiteral(c: ConfigRef, n: PNode): PNode =
|
||||||
# Trim the literal value in order to make it fit in the destination type
|
# Trim the literal value in order to make it fit in the destination type
|
||||||
if n == nil:
|
if n == nil:
|
||||||
|
|
@ -673,9 +636,9 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
||||||
of mConStrStr:
|
of mConStrStr:
|
||||||
result = foldConStrStr(m, n, g)
|
result = foldConStrStr(m, n, g)
|
||||||
of mIs:
|
of mIs:
|
||||||
let lhs = getConstExpr(m, n[1], g)
|
# The only kind of mIs node that comes here is one depending on some
|
||||||
if lhs != nil and lhs.kind == nkSym:
|
# generic parameter and that's (hopefully) handled at instantiation time
|
||||||
result = evalIs(n, lhs.sym, g)
|
discard
|
||||||
else:
|
else:
|
||||||
result = magicCall(m, n, g)
|
result = magicCall(m, n, g)
|
||||||
except OverflowError:
|
except OverflowError:
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,10 @@ true
|
||||||
false
|
false
|
||||||
true
|
true
|
||||||
true
|
true
|
||||||
|
false
|
||||||
|
true
|
||||||
|
true
|
||||||
|
false
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -27,3 +31,5 @@ echo bar(4, Foo)
|
||||||
echo bar(any, int)
|
echo bar(any, int)
|
||||||
echo bar(int, any)
|
echo bar(int, any)
|
||||||
echo bar(Foo, Foo)
|
echo bar(Foo, Foo)
|
||||||
|
echo bar(any, Foo)
|
||||||
|
echo bar(Foo, any)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''true true false yes
|
output: '''true true false yes
|
||||||
false
|
false
|
||||||
false
|
true
|
||||||
false
|
false
|
||||||
true
|
true
|
||||||
true
|
true
|
||||||
|
|
@ -68,8 +68,8 @@ type SeqOrSet[E] = seq[E] or set[E]
|
||||||
type SeqOfInt = seq[int]
|
type SeqOfInt = seq[int]
|
||||||
type SeqOrSetOfInt = SeqOrSet[int]
|
type SeqOrSetOfInt = SeqOrSet[int]
|
||||||
|
|
||||||
# This prints "false", which seems less correct that (1) printing "true" or (2)
|
# This prints "true", as expected. Previously "false" was returned and that
|
||||||
# raising a compiler error.
|
# seemed less correct that (1) printing "true" or (2) raising a compiler error.
|
||||||
echo seq is SeqOrSet
|
echo seq is SeqOrSet
|
||||||
|
|
||||||
# This prints "false", as expected.
|
# This prints "false", as expected.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue