Fix weirdness with typevar declaration not being correctly wrapped
This commit is contained in:
2
nim.cfg
2
nim.cfg
@@ -1,5 +1,5 @@
|
||||
--deepCopy:on
|
||||
--exceptions:setjmp
|
||||
--hints:off
|
||||
-d:danger
|
||||
-d:debug
|
||||
path="src"
|
||||
@@ -1125,25 +1125,27 @@ proc replaceGenerics(self: TypeChecker, typ: Type, generics: TableRef[string, Ty
|
||||
proc concretize(self: TypeChecker, name: Name, args: seq[TypedExpr], node: ASTNode = nil): Type =
|
||||
## Takes in a generic type and its arguments and returns a concrete instantiation
|
||||
## of it
|
||||
##
|
||||
let typ = name.valueType.unwrapType()
|
||||
case typ.kind:
|
||||
of Typevar:
|
||||
return Type(kind: Typevar, wrapped: args[0].kind)
|
||||
else:
|
||||
if typ.generics.len() == 0:
|
||||
self.error(&"cannot create concrete instance of objects of type {self.stringify(typ)} (type is not a generic)")
|
||||
elif len(args) != typ.generics.len():
|
||||
self.error(&"invalid number of arguments supplied for generic instantiation (expecting exactly {typ.generics.len()}, got {len(args)} instead)", node=node)
|
||||
# Construct a concrete copy of the original generic type
|
||||
result = typ.deepCopy()
|
||||
var replaced = newTable[string, Type]()
|
||||
var i = 0
|
||||
for key in typ.generics.keys():
|
||||
replaced[key] = self.check(args[i].kind, typ.generics[key], args[i].node)
|
||||
inc(i)
|
||||
# Now replaced contains a mapping from the names of the type variables to
|
||||
# their respective (concrete) type. All we have to do is recursively replace
|
||||
# every occurrence of them
|
||||
self.replaceGenerics(typ, replaced)
|
||||
|
||||
if typ.generics.len() == 0:
|
||||
self.error(&"cannot create concrete instance of objects of type {self.stringify(typ)} (type is not a generic)")
|
||||
elif len(args) != typ.generics.len():
|
||||
self.error(&"invalid number of arguments supplied for generic instantiation (expecting exactly {typ.generics.len()}, got {len(args)} instead)", node=node)
|
||||
# Construct a concrete copy of the original generic type
|
||||
result = typ.deepCopy()
|
||||
var replaced = newTable[string, Type]()
|
||||
var i = 0
|
||||
for key in typ.generics.keys():
|
||||
replaced[key] = self.check(args[i].kind, typ.generics[key], args[i].node)
|
||||
inc(i)
|
||||
# Now replaced contains a mapping from the names of the type variables to
|
||||
# their respective (concrete) type. All we have to do is recursively replace
|
||||
# every occurrence of them
|
||||
self.replaceGenerics(typ, replaced)
|
||||
|
||||
|
||||
proc expandTypeConstraints(self: TypeChecker, condition: Expression, list: var seq[tuple[match: bool, kind: Type, value: Expression]], accept: bool = true) =
|
||||
## Recursively unpacks a type constraint
|
||||
@@ -1475,16 +1477,7 @@ proc expression(self: TypeChecker, node: Expression): TypedExpr =
|
||||
# as generics (and are even declared as such in the stdlib),
|
||||
# but under the hood they're much simpler (they're just wrappers
|
||||
# over a type, after all)
|
||||
let node = GenericExpr(node)
|
||||
let name = self.find(node.ident.token.lexeme, "typevar".toIntrinsic())
|
||||
if not name.isNil() and name.valueType.intrinsic:
|
||||
# Bonus points: if this is a generic, it'll also be handled nicely.
|
||||
# Recursion is cool!
|
||||
result = self.infer(node.args[0])
|
||||
result.node = node
|
||||
result.kind = result.kind.wrapType()
|
||||
else:
|
||||
result = self.genericExpr(GenericExpr(node))
|
||||
result = self.genericExpr(GenericExpr(node))
|
||||
of NodeKind.refExpr:
|
||||
result = self.refExpr(Ref(node))
|
||||
of NodeKind.ptrExpr:
|
||||
@@ -1718,8 +1711,7 @@ proc typeDecl(self: TypeChecker, node: TypeDecl, name: Name = nil): TypedTypeDec
|
||||
result.fields[field.ident.token.lexeme] = newTypedExpr(field.ident, result.parent.valueType.fields[field.ident.token.lexeme])
|
||||
# Turn the declared type into a typevar so that future references
|
||||
# to it will be distinct from its instances
|
||||
if not name.valueType.isTypevar():
|
||||
name.valueType = name.valueType.wrapType()
|
||||
name.valueType = name.valueType.wrapType()
|
||||
# TODO: Check interfaces
|
||||
self.endScope()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user