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.nim41
1 files changed, 30 insertions, 11 deletions
diff --git a/compiler/aliases.nim b/compiler/aliases.nim
index 0006c9fe6..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
+  ast, astalgo, types, trees
+
+import std/intsets
+
+when defined(nimPreviewSlimSystem):
+  import std/assertions
 
 type
   TAnalysisResult* = enum
@@ -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[0] != nil:
-      result = isPartOfAux(a[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, tySink:
-    result = isPartOfAux(lastSon(a), b, marker)
-  of tyArray, tySet, tyTuple:
-    for i in 0..<a.len:
-      result = isPartOfAux(a[i], b, marker)
+    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,6 +118,8 @@ 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 a.len >= 2 and b.len >= 2:
@@ -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,7 +193,9 @@ 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:
+          result = arNo
+      else: result = arNo
     of nkObjConstr:
       result = arNo
       for i in 1..<b.len:
@@ -196,4 +213,6 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
     of nkBracket:
       if b.len > 0:
         result = isPartOf(a, b[0])
-    else: discard
+      else:
+        result = arNo
+    else: result = arNo