summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2016-03-28 02:13:07 +0200
committerAndreas Rumpf <rumpf_a@web.de>2016-03-28 02:26:38 +0200
commite97d640ce8a8f16112a3e17241ed89c993f83fee (patch)
treecb629ee6eb8049d840276ab8e6ea04cdebaad177
parentc684f5588ac3e91a21c05af259c6d66b428225b4 (diff)
downloadNim-e97d640ce8a8f16112a3e17241ed89c993f83fee.tar.gz
fixes #3998
-rw-r--r--compiler/semtypes.nim6
-rw-r--r--compiler/sigmatch.nim37
-rw-r--r--tests/generics/tcritical.nim19
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!
+
10' href='#n310'>310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367