mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 08:54:53 +00:00
fixes #3998
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
19
tests/generics/tcritical.nim
Normal file
19
tests/generics/tcritical.nim
Normal file
@@ -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!
|
||||
|
||||
Reference in New Issue
Block a user