Fix #4737
This commit is contained in:
parent
16eb4b1fee
commit
a6006e56a7
5 changed files with 51 additions and 5 deletions
|
|
@ -1131,7 +1131,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||||
m.isNoCall = true
|
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:
|
||||||
let err = "cannot instantiate " & typeToString(t) & "\n" &
|
let err = "cannot instantiate " & typeToString(t) & "\n" &
|
||||||
"got: (" & describeArgs(c, n) & ")\n" &
|
"got: (" & describeArgs(c, n) & ")\n" &
|
||||||
"but expected: (" & describeArgs(c, t.n, 0) & ")"
|
"but expected: (" & describeArgs(c, t.n, 0) & ")"
|
||||||
|
|
|
||||||
|
|
@ -307,12 +307,13 @@ proc describeArgs*(c: PContext, n: PNode, startIdx = 1;
|
||||||
proc typeRelImpl*(c: var TCandidate, f, aOrig: PType,
|
proc typeRelImpl*(c: var TCandidate, f, aOrig: PType,
|
||||||
flags: TTypeRelFlags = {}): TTypeRelation
|
flags: TTypeRelFlags = {}): TTypeRelation
|
||||||
|
|
||||||
var nextTypeRel = 0
|
const traceTypeRel = false
|
||||||
|
|
||||||
|
when traceTypeRel:
|
||||||
|
var nextTypeRel = 0
|
||||||
|
|
||||||
template typeRel*(c: var TCandidate, f, aOrig: PType,
|
template typeRel*(c: var TCandidate, f, aOrig: PType,
|
||||||
flags: TTypeRelFlags = {}): TTypeRelation =
|
flags: TTypeRelFlags = {}): TTypeRelation =
|
||||||
const traceTypeRel = false
|
|
||||||
|
|
||||||
when traceTypeRel:
|
when traceTypeRel:
|
||||||
var enteringAt = nextTypeRel
|
var enteringAt = nextTypeRel
|
||||||
if mdbg:
|
if mdbg:
|
||||||
|
|
@ -320,6 +321,7 @@ template typeRel*(c: var TCandidate, f, aOrig: PType,
|
||||||
echo "----- TYPE REL ", enteringAt
|
echo "----- TYPE REL ", enteringAt
|
||||||
debug f
|
debug f
|
||||||
debug aOrig
|
debug aOrig
|
||||||
|
# writeStackTrace()
|
||||||
|
|
||||||
let r = typeRelImpl(c, f, aOrig, flags)
|
let r = typeRelImpl(c, f, aOrig, flags)
|
||||||
|
|
||||||
|
|
@ -1487,6 +1489,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
|
||||||
result = typeRel(c, f.lastSon, a)
|
result = typeRel(c, f.lastSon, a)
|
||||||
else:
|
else:
|
||||||
considerPreviousT:
|
considerPreviousT:
|
||||||
|
if aOrig == f: return isEqual
|
||||||
var matched = matchUserTypeClass(c.c, c, f, aOrig)
|
var matched = matchUserTypeClass(c.c, c, f, aOrig)
|
||||||
if matched != nil:
|
if matched != nil:
|
||||||
bindConcreteTypeToUserTypeClass(matched, a)
|
bindConcreteTypeToUserTypeClass(matched, a)
|
||||||
|
|
|
||||||
|
|
@ -440,6 +440,13 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
result = t.sym.name.s & " literal(" & $t.n.intVal & ")"
|
result = t.sym.name.s & " literal(" & $t.n.intVal & ")"
|
||||||
elif prefer == preferName or t.sym.owner.isNil:
|
elif prefer == preferName or t.sym.owner.isNil:
|
||||||
result = t.sym.name.s
|
result = t.sym.name.s
|
||||||
|
if t.kind == tyGenericParam and t.sons != nil and t.sonsLen > 0:
|
||||||
|
result.add ": "
|
||||||
|
var first = true
|
||||||
|
for son in t.sons:
|
||||||
|
if not first: result.add " or "
|
||||||
|
result.add son.typeToString
|
||||||
|
first = false
|
||||||
else:
|
else:
|
||||||
result = t.sym.owner.name.s & '.' & t.sym.name.s
|
result = t.sym.owner.name.s & '.' & t.sym.name.s
|
||||||
result.addTypeFlags(t)
|
result.addTypeFlags(t)
|
||||||
|
|
@ -461,7 +468,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||||
add(result, ']')
|
add(result, ']')
|
||||||
of tyTypeDesc:
|
of tyTypeDesc:
|
||||||
if t.sons[0].kind == tyNone: result = "typedesc"
|
if t.sons[0].kind == tyNone: result = "typedesc"
|
||||||
else: result = "typedesc[" & typeToString(t.sons[0]) & "]"
|
else: result = "type " & typeToString(t.sons[0])
|
||||||
of tyStatic:
|
of tyStatic:
|
||||||
internalAssert t.len > 0
|
internalAssert t.len > 0
|
||||||
if prefer == preferGenericArg and t.n != nil:
|
if prefer == preferGenericArg and t.n != nil:
|
||||||
|
|
|
||||||
21
tests/errmsgs/tconceptconstraint.nim
Normal file
21
tests/errmsgs/tconceptconstraint.nim
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
discard """
|
||||||
|
errormsg: "cannot instantiate B"
|
||||||
|
line: 20
|
||||||
|
nimout: '''
|
||||||
|
got: (type string)
|
||||||
|
but expected: (T: A)
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
type
|
||||||
|
A = concept c
|
||||||
|
advance(c)
|
||||||
|
|
||||||
|
B[T: A] = object
|
||||||
|
child: ref B[T]
|
||||||
|
|
||||||
|
proc advance(x: int): int = x + 1
|
||||||
|
|
||||||
|
var a: B[int]
|
||||||
|
var b: B[string]
|
||||||
|
|
||||||
15
tests/errmsgs/tgenericconstraint.nim
Normal file
15
tests/errmsgs/tgenericconstraint.nim
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
discard """
|
||||||
|
errormsg: "cannot instantiate B"
|
||||||
|
line: 14
|
||||||
|
nimout: '''
|
||||||
|
got: (type int)
|
||||||
|
but expected: (T: string or float)
|
||||||
|
'''
|
||||||
|
"""
|
||||||
|
|
||||||
|
type
|
||||||
|
B[T: string|float] = object
|
||||||
|
child: ref B[T]
|
||||||
|
|
||||||
|
var b: B[int]
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue