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