mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-19 15:31:28 +00:00
fixes #5360, fixes #5238 (#5539); fixes type alias inequality for types coming from templates/macros
This commit is contained in:
@@ -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)
|
||||
|
||||
50
tests/types/taliasassignment.nim
Normal file
50
tests/types/taliasassignment.nim
Normal file
@@ -0,0 +1,50 @@
|
||||
discard """
|
||||
output: '''19
|
||||
(c: 0)
|
||||
(c: 13)
|
||||
@[(c: 11)]
|
||||
@[(c: 17)]'''
|
||||
"""
|
||||
# bug #5238
|
||||
|
||||
type
|
||||
Rgba8 = object
|
||||
c: int
|
||||
BlenderRgb*[ColorT] = object
|
||||
|
||||
template getColorType*[C](x: typedesc[BlenderRgb[C]]): typedesc = C
|
||||
|
||||
type
|
||||
ColorT = getColorType(BlenderRgb[int])
|
||||
|
||||
proc setColor(c: var ColorT) =
|
||||
c = 19
|
||||
|
||||
var n: ColorT
|
||||
n.setColor()
|
||||
echo n
|
||||
|
||||
type
|
||||
ColorType = getColorType(BlenderRgb[Rgba8])
|
||||
|
||||
var x: ColorType
|
||||
echo x
|
||||
|
||||
proc setColor(c: var ColorType) =
|
||||
c = Rgba8(c: 13)
|
||||
|
||||
proc setColor(c: var seq[ColorType]) =
|
||||
c[0] = Rgba8(c: 11)
|
||||
|
||||
proc setColorArray(c: var openArray[ColorType]) =
|
||||
c[0] = Rgba8(c: 17)
|
||||
|
||||
x.setColor()
|
||||
echo x
|
||||
|
||||
var y = @[Rgba8(c:15)]
|
||||
y.setColor()
|
||||
echo y
|
||||
|
||||
y.setColorArray()
|
||||
echo y
|
||||
66
tests/types/taliasinequality.nim
Normal file
66
tests/types/taliasinequality.nim
Normal file
@@ -0,0 +1,66 @@
|
||||
discard """
|
||||
msg: '''true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true'''
|
||||
output: '''true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
true
|
||||
R
|
||||
R
|
||||
R
|
||||
R'''
|
||||
"""
|
||||
|
||||
# bug #5360
|
||||
import macros
|
||||
|
||||
type
|
||||
Order = enum
|
||||
R
|
||||
OrderAlias = Order
|
||||
|
||||
template getOrderTypeA(): typedesc = Order
|
||||
template getOrderTypeB(): typedesc = OrderAlias
|
||||
|
||||
type
|
||||
OrderR = getOrderTypeA()
|
||||
OrderG = getOrderTypeB()
|
||||
|
||||
macro typeRep(a, b: typed): untyped =
|
||||
if sameType(a, b):
|
||||
echo "true"
|
||||
else:
|
||||
echo "false"
|
||||
|
||||
template test(a, b: typedesc) =
|
||||
when a is b:
|
||||
echo "true"
|
||||
else:
|
||||
echo "false"
|
||||
|
||||
test(OrderAlias, Order)
|
||||
test(OrderR, Order)
|
||||
test(OrderG, Order)
|
||||
|
||||
test(OrderR, OrderG)
|
||||
test(OrderR, OrderAlias)
|
||||
test(OrderG, OrderAlias)
|
||||
|
||||
typeRep(OrderAlias, Order) # true
|
||||
typeRep(OrderR, Order) # true
|
||||
typeRep(OrderG, Order) # true
|
||||
|
||||
typeRep(OrderR, OrderAlias) # true
|
||||
typeRep(OrderG, OrderAlias) # true
|
||||
typeRep(OrderR, OrderG) # true
|
||||
|
||||
echo OrderR.R # R
|
||||
echo OrderG.R # R
|
||||
echo OrderAlias.R # R
|
||||
echo Order.R # R
|
||||
Reference in New Issue
Block a user