mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
Fix #4737
This commit is contained in:
committed by
Andreas Rumpf
parent
16eb4b1fee
commit
a6006e56a7
@@ -1131,7 +1131,7 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
||||
m.isNoCall = true
|
||||
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" &
|
||||
"got: (" & describeArgs(c, n) & ")\n" &
|
||||
"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,
|
||||
flags: TTypeRelFlags = {}): TTypeRelation
|
||||
|
||||
var nextTypeRel = 0
|
||||
const traceTypeRel = false
|
||||
|
||||
when traceTypeRel:
|
||||
var nextTypeRel = 0
|
||||
|
||||
template typeRel*(c: var TCandidate, f, aOrig: PType,
|
||||
flags: TTypeRelFlags = {}): TTypeRelation =
|
||||
const traceTypeRel = false
|
||||
|
||||
when traceTypeRel:
|
||||
var enteringAt = nextTypeRel
|
||||
if mdbg:
|
||||
@@ -320,6 +321,7 @@ template typeRel*(c: var TCandidate, f, aOrig: PType,
|
||||
echo "----- TYPE REL ", enteringAt
|
||||
debug f
|
||||
debug aOrig
|
||||
# writeStackTrace()
|
||||
|
||||
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)
|
||||
else:
|
||||
considerPreviousT:
|
||||
if aOrig == f: return isEqual
|
||||
var matched = matchUserTypeClass(c.c, c, f, aOrig)
|
||||
if matched != nil:
|
||||
bindConcreteTypeToUserTypeClass(matched, a)
|
||||
|
||||
@@ -440,6 +440,13 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
result = t.sym.name.s & " literal(" & $t.n.intVal & ")"
|
||||
elif prefer == preferName or t.sym.owner.isNil:
|
||||
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:
|
||||
result = t.sym.owner.name.s & '.' & t.sym.name.s
|
||||
result.addTypeFlags(t)
|
||||
@@ -461,7 +468,7 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
add(result, ']')
|
||||
of tyTypeDesc:
|
||||
if t.sons[0].kind == tyNone: result = "typedesc"
|
||||
else: result = "typedesc[" & typeToString(t.sons[0]) & "]"
|
||||
else: result = "type " & typeToString(t.sons[0])
|
||||
of tyStatic:
|
||||
internalAssert t.len > 0
|
||||
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]
|
||||
|
||||
Reference in New Issue
Block a user