diff options
author | andri lim <jangko128@gmail.com> | 2017-03-16 14:04:36 +0700 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2017-03-16 08:04:36 +0100 |
commit | e99721a593cfceb43b8b0c3869d82565c03f3fae (patch) | |
tree | 7e2df46e8eaa62fe1e6ddce49436d0b81274a54a /compiler | |
parent | 19c436ab20ff1749455ef1606b0884387cb21f5e (diff) | |
download | Nim-e99721a593cfceb43b8b0c3869d82565c03f3fae.tar.gz |
fixes #5360, fixes #5238 (#5539); fixes type alias inequality for types coming from templates/macros
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/semtypes.nim | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index cb3d24a76..e86b527d6 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1145,14 +1145,29 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType = if tx != result and tx.kind == tyObject and tx.sons[0] != nil: semObjectTypeForInheritedGenericInst(c, n, tx) +proc maybeAliasType(c: PContext; typeExpr, prev: PType): PType + proc semTypeExpr(c: PContext, n: PNode; prev: PType): PType = var n = semExprWithType(c, n, {efDetermineType}) if n.typ.kind == tyTypeDesc: result = n.typ.base - # fix types constructed by macros: - if prev != nil and prev.sym != nil and result.sym.isNil: - result.sym = prev.sym - result.sym.typ = result + # fix types constructed by macros/template: + if prev != nil and prev.sym != nil: + if result.sym.isNil: + # Behold! you're witnessing enormous power yielded + # by macros. Only macros can summon unnamed types + # and cast spell upon AST. Here we need to give + # it a name taken from left hand side's node + result.sym = prev.sym + result.sym.typ = result + else: + # Less powerful routine like template do not have + # the ability to produce unnamed types. But still + # it has wild power to push a type a bit too far. + # So we need to hold it back using alias and prevent + # unnecessary new type creation + let alias = maybeAliasType(c, result, prev) + if alias != nil: result = alias else: localError(n.info, errTypeExpected, n.renderTree) result = errorType(c) |