diff options
-rw-r--r-- | compiler/semtypes.nim | 6 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 37 | ||||
-rw-r--r-- | tests/generics/tcritical.nim | 19 |
3 files changed, 41 insertions, 21 deletions
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 62d02fe10..ba17cc307 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -831,9 +831,11 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, result.rawAddSon paramType.lastSon return addImplicitGeneric(result) - result = instGenericContainer(c, paramType.sym.info, result, + let x = instGenericContainer(c, paramType.sym.info, result, allowMetaTypes = true) - result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, result]) + result = newTypeWithSons(c, tyCompositeTypeClass, @[paramType, x]) + #result = newTypeS(tyCompositeTypeClass, c) + #for i in 0..<x.len: result.rawAddSon(x.sons[i]) result = addImplicitGeneric(result) of tyGenericInst: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 8859c30e4..88fdbbf17 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -847,7 +847,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = inc(c.inheritancePenalty, depth) result = isSubtype of tyDistinct: - if a.kind == tyDistinct and sameDistinctTypes(f, a): result = isEqual + if a.kind == tyDistinct: + if sameDistinctTypes(f, a): result = isEqual + elif f.base.kind == tyAnything: result = isGeneric + elif c.coerceDistincts: result = typeRel(c, f.base, a) elif c.coerceDistincts: result = typeRel(c, f.base, a) of tySet: if a.kind == tySet: @@ -922,19 +925,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = if a.kind == tyEmpty: result = isEqual of tyGenericInst: - let roota = a.skipGenericAlias - let rootf = f.skipGenericAlias - if a.kind == tyGenericInst and roota.base == rootf.base: - for i in 1 .. rootf.sonsLen-2: - let ff = rootf.sons[i] - let aa = roota.sons[i] - result = typeRel(c, ff, aa) - if result == isNone: return - if ff.kind == tyRange and result != isEqual: return isNone - #result = isGeneric - # XXX See bug #2220. A[int] should match A[int] better than some generic X - else: - result = typeRel(c, lastSon(f), a) + result = typeRel(c, lastSon(f), a) of tyGenericBody: considerPreviousT: @@ -1035,12 +1026,20 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = of tyCompositeTypeClass: considerPreviousT: - if typeRel(c, f.sons[1], a) != isNone: - put(c.bindings, f, a) - return isGeneric + let roota = a.skipGenericAlias + let rootf = f.lastSon + if a.kind == tyGenericInst and roota.base == rootf.base: + for i in 1 .. rootf.sonsLen-2: + let ff = rootf.sons[i] + let aa = roota.sons[i] + result = typeRel(c, ff, aa) + if result == isNone: return + if ff.kind == tyRange and result != isEqual: return isNone else: - return isNone - + result = typeRel(c, rootf.lastSon, a) + if result != isNone: + put(c.bindings, f, a) + result = isGeneric of tyGenericParam: var x = PType(idTableGet(c.bindings, f)) if x == nil: diff --git a/tests/generics/tcritical.nim b/tests/generics/tcritical.nim new file mode 100644 index 000000000..e84c03618 --- /dev/null +++ b/tests/generics/tcritical.nim @@ -0,0 +1,19 @@ +discard """ + errormsg: "type mismatch" + line: 18 +""" + +# bug #3998 + +type Vec3[T] = array[3, T] + +var vg: Vec3[float32] = Vec3([1.0f, 2.0f, 3.0f]) + +echo "vg[0]: " & $vg[0] # prints 1.0 OK +echo "vg[1]: " & $vg[1] # prints 2.0 OK +echo "vg[2]: " & $vg[2] # prints 3.0 OK +echo "" + +var ve: Vec3[float64] +ve = vg # compiles, this MUST NOT be allowed! + |