diff options
Diffstat (limited to 'compiler/aliases.nim')
-rw-r--r-- | compiler/aliases.nim | 81 |
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 |