[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:
LemonBoy 2018-10-14 08:53:41 +02:00 • committed by Andreas Rumpf
commit 4808ef72db
4 changed files with 14 additions and 47 deletions

View file

@ -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

View file

@ -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:

View file

@ -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)

View file

@ -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.