summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semtypinst.nim11
-rw-r--r--compiler/sigmatch.nim12
-rw-r--r--tests/distinct/tborrow.nim32
-rw-r--r--tests/generics/timpl_ast.nim35
4 files changed, 34 insertions, 56 deletions
diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim
index 54ea9769c..0157ecd0b 100644
--- a/compiler/semtypinst.nim
+++ b/compiler/semtypinst.nim
@@ -434,17 +434,6 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
   # handleGenericInvocation will handle the alias-to-alias-to-alias case
   if newbody.isGenericAlias: newbody = newbody.skipGenericAlias
 
-  let origSym = newbody.sym
-  if origSym != nil and sfFromGeneric notin origSym.flags:
-    # same as `replaceTypeVarsS` but directly set the type without recursion:
-    newbody.sym = copySym(origSym, cl.c.idgen)
-    incl(newbody.sym.flags, sfFromGeneric)
-    newbody.sym.owner = origSym.owner
-    newbody.sym.typ = newbody
-    # unfortunately calling `replaceTypeVarsN` causes recursion, so this AST
-    # is the original generic body AST
-    newbody.sym.ast = copyTree(origSym.ast)
-
   rawAddSon(result, newbody)
   checkPartialConstructedType(cl.c.config, cl.info, newbody)
   if not cl.allowMetaTypes:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index a6cda65b1..bb99463b6 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -505,13 +505,6 @@ proc skipToObject(t: PType; skipped: var SkippedPtr): PType =
   if r.kind == tyObject and ptrs <= 1: result = r
   else: result = nil
 
-proc getObjectSym(t: PType): PSym =
-  if tfFromGeneric in t.flags and t.typeInst.kind == tyGenericInst:
-    var dummy: SkippedPtr
-    result = t.typeInst[0].skipToObject(dummy).sym
-  else:
-    result = t.sym
-
 proc isGenericSubtype(c: var TCandidate; a, f: PType, d: var int, fGenericOrigin: PType): bool =
   assert f.kind in {tyGenericInst, tyGenericInvocation, tyGenericBody}
   var askip = skippedNone
@@ -519,12 +512,11 @@ proc isGenericSubtype(c: var TCandidate; a, f: PType, d: var int, fGenericOrigin
   var t = a.skipToObject(askip)
   let r = f.skipToObject(fskip)
   if r == nil: return false
-  let rSym = getObjectSym(r)
   var depth = 0
   var last = a
   # XXX sameObjectType can return false here. Need to investigate
   # why that is but sameObjectType does way too much work here anyway.
-  while t != nil and rSym != getObjectSym(t) and askip == fskip:
+  while t != nil and r.sym != t.sym and askip == fskip:
     t = t[0]
     if t == nil: break
     last = t
@@ -1610,7 +1602,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
         # crossing path with metatypes/aliases, so we need to separate them
         # by checking sym.id
         let genericSubtype = isGenericSubtype(c, x, f, depth, f)
-        if not (genericSubtype and getObjectSym(aobj).id != getObjectSym(fobj).id) and aOrig.kind != tyGenericBody:
+        if not (genericSubtype and aobj.sym.id != fobj.sym.id) and aOrig.kind != tyGenericBody:
           depth = -1
 
       if depth >= 0:
diff --git a/tests/distinct/tborrow.nim b/tests/distinct/tborrow.nim
index 8a40982a8..e34248de5 100644
--- a/tests/distinct/tborrow.nim
+++ b/tests/distinct/tborrow.nim
@@ -98,3 +98,35 @@ block: # issue #22069
     MuscleCar = Car[128]
   var x: MuscleCar
   doAssert x.color is array[128, int]
+
+block: # issue #22646
+  type
+    Vec[N : static[int], T: SomeNumber] = object
+      arr: array[N, T]
+    Vec3[T: SomeNumber] = Vec[3, T]
+
+  proc `[]=`[N,T](v: var Vec[N,T]; ix:int; c:T): void {.inline.} = v.arr[ix] = c
+  proc `[]`[N,T](v: Vec[N,T]; ix: int): T {.inline.} = v.arr[ix]
+
+  proc dot[N,T](u,v: Vec[N,T]): T {. inline .} = discard
+  proc length[N,T](v: Vec[N,T]): T = discard
+  proc cross[T](v1,v2:Vec[3,T]): Vec[3,T] = discard
+  proc normalizeWorks[T](v: Vec[3,T]): Vec[3,T] = discard ## <- Explicit size makes it work!
+  proc foo[N,T](u, v: Vec[N,T]): Vec[N,T] = discard ## <- broken
+  proc normalize[N,T](v: Vec[N,T]): Vec[N,T] = discard ## <- broken
+
+  type Color = distinct Vec3[float]
+
+  template borrowOps(typ: typedesc): untyped =
+    proc `[]=`(v: var typ; ix: int; c: float): void {.borrow.}
+    proc `[]`(v: typ; ix: int): float {.borrow.}
+    proc dot(v, u: typ): float {.borrow.}
+    proc cross(v, u: typ): typ {.borrow.}
+    proc length(v: typ): float {.borrow.}
+    proc normalizeWorks(v: typ): typ {.borrow.} ## Up to here everything works
+    proc foo(u, v: typ): typ {.borrow.} ## Broken
+    proc normalize(v: typ): typ {.borrow.} ## Broken
+  borrowOps(Color)
+  var x: Vec[3, float]
+  let y = Color(x)
+  doAssert Vec3[float](y) == x
diff --git a/tests/generics/timpl_ast.nim b/tests/generics/timpl_ast.nim
index 97fe128cd..016128e30 100644
--- a/tests/generics/timpl_ast.nim
+++ b/tests/generics/timpl_ast.nim
@@ -43,38 +43,3 @@ block: # issues #9899, ##14708
     macro parse(s: static string) =
       result = parseStmt(s)
     parse("type " & implRepr(Option))
-
-block: # issue #22639
-  type
-    Spectrum[N: static int] = object
-      data: array[N, float]
-    AngleInterpolator = object
-      data: seq[Spectrum[60]]
-  proc initInterpolator(num: int): AngleInterpolator =
-    result = AngleInterpolator()
-    for i in 0 ..< num:
-      result.data.add Spectrum[60]()
-  macro genCompatibleTuple(t: typed): untyped =
-    let typ = t.getType[1].getTypeImpl[2]
-    result = nnkTupleTy.newTree()
-    for i, ch in typ: # is `nnkObjectTy`
-      result.add nnkIdentDefs.newTree(ident(ch[0].strVal), # ch is `nnkIdentDefs`
-                                      ch[1],
-                                      newEmptyNode())
-  proc fullSize[T: object | tuple](x: T): int =
-    var tmp: genCompatibleTuple(T)
-    result = 0
-    for field, val in fieldPairs(x):
-      result += sizeof(val)
-    doAssert result == sizeof(tmp)
-
-  let reflectivity = initInterpolator(1)
-  for el in reflectivity.data:
-    doAssert fullSize(el) == sizeof(el)
-  doAssert fullSize(reflectivity.data[0]) == sizeof(reflectivity.data[0])
-  doAssert genCompatibleTuple(Spectrum[60]) is tuple[data: array[60, float]]
-  doAssert genCompatibleTuple(Spectrum[120]) is tuple[data: array[120, float]]
-  type Foo[T] = object
-    data: T
-  doAssert genCompatibleTuple(Foo[int]) is tuple[data: int]
-  doAssert genCompatibleTuple(Foo[float]) is tuple[data: float]