summary refs log tree commit diff stats
path: root/compiler/aliases.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/aliases.nim')
-rw-r--r--compiler/aliases.nim81
1 files changed, 58 insertions, 23 deletions
diff --git a/compiler/aliases.nim b/compiler/aliases.nim
index c0371e159..fa1167753 100644
--- a/compiler/aliases.nim
+++ b/compiler/aliases.nim
@@ -10,7 +10,12 @@
 ## Simple alias analysis for the HLO and the code generators.
 
 import
-  ast, astalgo, types, trees, intsets, msgs
+  ast, astalgo, types, trees
+
+import std/intsets
+
+when defined(nimPreviewSlimSystem):
+  import std/assertions
 
 type
   TAnalysisResult* = enum
@@ -22,22 +27,22 @@ proc isPartOfAux(n: PNode, b: PType, marker: var IntSet): TAnalysisResult =
   result = arNo
   case n.kind
   of nkRecList:
-    for i in countup(0, sonsLen(n) - 1):
-      result = isPartOfAux(n.sons[i], b, marker)
+    for i in 0..<n.len:
+      result = isPartOfAux(n[i], b, marker)
       if result == arYes: return
   of nkRecCase:
-    assert(n.sons[0].kind == nkSym)
-    result = isPartOfAux(n.sons[0], b, marker)
+    assert(n[0].kind == nkSym)
+    result = isPartOfAux(n[0], b, marker)
     if result == arYes: return
-    for i in countup(1, sonsLen(n) - 1):
-      case n.sons[i].kind
+    for i in 1..<n.len:
+      case n[i].kind
       of nkOfBranch, nkElse:
-        result = isPartOfAux(lastSon(n.sons[i]), b, marker)
+        result = isPartOfAux(lastSon(n[i]), b, marker)
         if result == arYes: return
-      else: internalError("isPartOfAux(record case branch)")
+      else: discard "isPartOfAux(record case branch)"
   of nkSym:
     result = isPartOfAux(n.sym.typ, b, marker)
-  else: internalError(n.info, "isPartOfAux()")
+  else: discard
 
 proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult =
   result = arNo
@@ -46,14 +51,16 @@ proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult =
   if compareTypes(a, b, dcEqIgnoreDistinct): return arYes
   case a.kind
   of tyObject:
-    if a.sons[0] != nil:
-      result = isPartOfAux(a.sons[0].skipTypes(skipPtrs), b, marker)
+    if a.baseClass != nil:
+      result = isPartOfAux(a.baseClass.skipTypes(skipPtrs), b, marker)
     if result == arNo: result = isPartOfAux(a.n, b, marker)
-  of tyGenericInst, tyDistinct, tyAlias:
-    result = isPartOfAux(lastSon(a), b, marker)
-  of tyArray, tySet, tyTuple:
-    for i in countup(0, sonsLen(a) - 1):
-      result = isPartOfAux(a.sons[i], b, marker)
+  of tyGenericInst, tyDistinct, tyAlias, tySink:
+    result = isPartOfAux(skipModifier(a), b, marker)
+  of tySet, tyArray:
+    result = isPartOfAux(a.elementType, b, marker)
+  of tyTuple:
+    for aa in a.kids:
+      result = isPartOfAux(aa, b, marker)
       if result == arYes: return
   else: discard
 
@@ -74,24 +81,29 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
   ## cases:
   ##
   ## YES-cases:
+  ##  ```
   ##  x    <| x   # for general trees
   ##  x[]  <| x
   ##  x[i] <| x
   ##  x.f  <| x
+  ##  ```
   ##
   ## NO-cases:
+  ## ```
   ## x           !<| y    # depending on type and symbol kind
   ## x[constA]   !<| x[constB]
   ## x.f         !<| x.g
   ## x.f         !<| y.f  iff x !<= y
+  ## ```
   ##
   ## MAYBE-cases:
   ##
+  ##  ```
   ##  x[] ?<| y[]   iff compatible type
   ##
   ##
   ##  x[]  ?<| y  depending on type
-  ##
+  ##  ```
   if a.kind == b.kind:
     case a.kind
     of nkSym:
@@ -106,9 +118,11 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
         # use expensive type check:
         if isPartOf(a.sym.typ, b.sym.typ) != arNo:
           result = arMaybe
+        else:
+          result = arNo
     of nkBracketExpr:
       result = isPartOf(a[0], b[0])
-      if len(a) >= 2 and len(b) >= 2:
+      if a.len >= 2 and b.len >= 2:
         # array accesses:
         if result == arYes and isDeepConstExpr(a[1]) and isDeepConstExpr(b[1]):
           # we know it's the same array and we have 2 constant indexes;
@@ -141,7 +155,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
       result = isPartOf(a[1], b[1])
     of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
       result = isPartOf(a[0], b[0])
-    else: discard
+    else: result = arNo
     # Calls return a new location, so a default of ``arNo`` is fine.
   else:
     # go down recursively; this is quite demanding:
@@ -157,6 +171,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
 
     of DerefKinds:
       # a* !<| b[] iff
+      result = arNo
       if isPartOf(a.typ, b.typ) != arNo:
         result = isPartOf(a, b[0])
         if result == arNo: result = arMaybe
@@ -178,6 +193,26 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
         if isPartOf(a.typ, b.typ) != arNo:
           result = isPartOf(a[0], b)
           if result == arNo: result = arMaybe
-      else: discard
-    else: discard
-
+        else:
+          result = arNo
+      else: result = arNo
+    of nkObjConstr:
+      result = arNo
+      for i in 1..<b.len:
+        let res = isPartOf(a, b[i][1])
+        if res != arNo:
+          result = res
+          if res == arYes: break
+    of nkCallKinds:
+      result = arNo
+      for i in 1..<b.len:
+        let res = isPartOf(a, b[i])
+        if res != arNo:
+          result = res
+          if res == arYes: break
+    of nkBracket:
+      if b.len > 0:
+        result = isPartOf(a, b[0])
+      else:
+        result = arNo
+    else: result = arNo