parent
862ee8d1d3
commit
b0b716fca7
6 changed files with 33 additions and 3 deletions
|
|
@ -525,6 +525,8 @@ const
|
||||||
tfOldSchoolExprStmt* = tfVarargs # for now used to distinguish \
|
tfOldSchoolExprStmt* = tfVarargs # for now used to distinguish \
|
||||||
# 'varargs[expr]' from 'varargs[untyped]'. Eventually 'expr' will be
|
# 'varargs[expr]' from 'varargs[untyped]'. Eventually 'expr' will be
|
||||||
# deprecated and this mess can be cleaned up.
|
# deprecated and this mess can be cleaned up.
|
||||||
|
tfVoid* = tfVarargs # for historical reasons we conflated 'void' with
|
||||||
|
# 'empty' ('@[]' has the type 'seq[empty]').
|
||||||
skError* = skUnknown
|
skError* = skUnknown
|
||||||
|
|
||||||
# type flags that are essential for type equality:
|
# type flags that are essential for type equality:
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
if result.typ.kind == tyVar: result = newDeref(result)
|
if result.typ.kind == tyVar: result = newDeref(result)
|
||||||
elif {efWantStmt, efAllowStmt} * flags != {}:
|
elif {efWantStmt, efAllowStmt} * flags != {}:
|
||||||
result.typ = newTypeS(tyEmpty, c)
|
result.typ = newTypeS(tyEmpty, c)
|
||||||
|
result.typ.flags.incl tfVoid
|
||||||
else:
|
else:
|
||||||
localError(n.info, errExprXHasNoType,
|
localError(n.info, errExprXHasNoType,
|
||||||
renderTree(result, {renderNoComments}))
|
renderTree(result, {renderNoComments}))
|
||||||
|
|
|
||||||
|
|
@ -1051,6 +1051,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||||
return newOrPrevType(tyError, prev, c)
|
return newOrPrevType(tyError, prev, c)
|
||||||
else:
|
else:
|
||||||
var m = newCandidate(c, t)
|
var m = newCandidate(c, t)
|
||||||
|
m.isNoCall = true
|
||||||
matches(c, n, copyTree(n), m)
|
matches(c, n, copyTree(n), m)
|
||||||
|
|
||||||
if m.state != csMatch and not m.typedescMatched:
|
if m.state != csMatch and not m.typedescMatched:
|
||||||
|
|
@ -1338,7 +1339,11 @@ proc processMagicType(c: PContext, m: PSym) =
|
||||||
of mTypeDesc:
|
of mTypeDesc:
|
||||||
setMagicType(m, tyTypeDesc, 0)
|
setMagicType(m, tyTypeDesc, 0)
|
||||||
rawAddSon(m.typ, newTypeS(tyNone, c))
|
rawAddSon(m.typ, newTypeS(tyNone, c))
|
||||||
of mVoidType: setMagicType(m, tyEmpty, 0)
|
of mVoidType:
|
||||||
|
setMagicType(m, tyEmpty, 0)
|
||||||
|
# for historical reasons we conflate 'void' with 'empty' so that '@[]'
|
||||||
|
# has the type 'seq[void]'.
|
||||||
|
m.typ.flags.incl tfVoid
|
||||||
of mArray:
|
of mArray:
|
||||||
setMagicType(m, tyArray, 0)
|
setMagicType(m, tyArray, 0)
|
||||||
of mOpenArray:
|
of mOpenArray:
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ type
|
||||||
coerceDistincts*: bool # this is an explicit coercion that can strip away
|
coerceDistincts*: bool # this is an explicit coercion that can strip away
|
||||||
# a distrinct type
|
# a distrinct type
|
||||||
typedescMatched*: bool
|
typedescMatched*: bool
|
||||||
|
isNoCall*: bool # misused for generic type instantiations C[T]
|
||||||
inheritancePenalty: int # to prefer closest father object type
|
inheritancePenalty: int # to prefer closest father object type
|
||||||
errors*: CandidateErrors # additional clarifications to be displayed to the
|
errors*: CandidateErrors # additional clarifications to be displayed to the
|
||||||
# user if overload resolution fails
|
# user if overload resolution fails
|
||||||
|
|
@ -259,7 +260,7 @@ proc describeArgs*(c: PContext, n: PNode, startIdx = 1;
|
||||||
if i != sonsLen(n) - 1: add(result, ", ")
|
if i != sonsLen(n) - 1: add(result, ", ")
|
||||||
|
|
||||||
proc typeRel*(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation
|
proc typeRel*(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation
|
||||||
proc concreteType(c: TCandidate, t: PType): PType =
|
proc concreteType(c: TCandidate, t: PType; forAny=false): PType =
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyArrayConstr:
|
of tyArrayConstr:
|
||||||
# make it an array
|
# make it an array
|
||||||
|
|
@ -268,6 +269,12 @@ proc concreteType(c: TCandidate, t: PType): PType =
|
||||||
addSonSkipIntLit(result, t.sons[1]) # XXX: semantic checking for the type?
|
addSonSkipIntLit(result, t.sons[1]) # XXX: semantic checking for the type?
|
||||||
of tyNil:
|
of tyNil:
|
||||||
result = nil # what should it be?
|
result = nil # what should it be?
|
||||||
|
of tyEmpty:
|
||||||
|
if tfVoid in t.flags and not forAny: result = nil
|
||||||
|
else: result = t
|
||||||
|
of tyTypeDesc:
|
||||||
|
if c.isNoCall: result = t
|
||||||
|
else: result = nil
|
||||||
of tySequence, tySet:
|
of tySequence, tySet:
|
||||||
if t.sons[0].kind == tyEmpty: result = nil
|
if t.sons[0].kind == tyEmpty: result = nil
|
||||||
else: result = t
|
else: result = t
|
||||||
|
|
@ -967,7 +974,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||||
|
|
||||||
of tyAnything:
|
of tyAnything:
|
||||||
considerPreviousT:
|
considerPreviousT:
|
||||||
var concrete = concreteType(c, a)
|
var concrete = concreteType(c, a, forAny=true)
|
||||||
if concrete != nil and doBind:
|
if concrete != nil and doBind:
|
||||||
put(c.bindings, f, concrete)
|
put(c.bindings, f, concrete)
|
||||||
return isGeneric
|
return isGeneric
|
||||||
|
|
|
||||||
6
tests/typerel/ttypedesc_as_genericparam1.nim
Normal file
6
tests/typerel/ttypedesc_as_genericparam1.nim
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
discard """
|
||||||
|
line: 6
|
||||||
|
errormsg: "type mismatch: got (typedesc[int])"
|
||||||
|
"""
|
||||||
|
# bug #3079, #1146
|
||||||
|
echo repr(int)
|
||||||
9
tests/typerel/ttypedesc_as_genericparam2.nim
Normal file
9
tests/typerel/ttypedesc_as_genericparam2.nim
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
discard """
|
||||||
|
line: 9
|
||||||
|
errormsg: "type mismatch: got (empty)"
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #2879
|
||||||
|
|
||||||
|
var s: seq[int]
|
||||||
|
echo repr(s.new_seq(3))
|
||||||
Loading…
Add table
Add a link
Reference in a new issue