diff options
-rw-r--r-- | compiler/semtypes.nim | 2 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 9 | ||||
-rw-r--r-- | compiler/types.nim | 9 | ||||
-rw-r--r-- | tests/errmsgs/tconceptconstraint.nim | 21 | ||||
-rw-r--r-- | tests/errmsgs/tgenericconstraint.nim | 15 |
5 files changed, 51 insertions, 5 deletions
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index c0974022a..4c7786f61 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -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) & ")" diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 7a603a2d4..59add90a2 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -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) diff --git a/compiler/types.nim b/compiler/types.nim index 13b24ccf8..2b4ba12d1 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -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: diff --git a/tests/errmsgs/tconceptconstraint.nim b/tests/errmsgs/tconceptconstraint.nim new file mode 100644 index 000000000..c1f0b94eb --- /dev/null +++ b/tests/errmsgs/tconceptconstraint.nim @@ -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] + diff --git a/tests/errmsgs/tgenericconstraint.nim b/tests/errmsgs/tgenericconstraint.nim new file mode 100644 index 000000000..9129d257b --- /dev/null +++ b/tests/errmsgs/tgenericconstraint.nim @@ -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] + |