diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 1ec8c07b01..df832c814f 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -707,11 +707,6 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode = localError(c.c.config, n.info, "invalid expression") result = n - proc stupidStmtListExpr(n: PNode): bool = - for i in 0.. 0 and stupidStmtListExpr(n): + n = n.lastSon + else: + break of nkCallKinds: if n.len > 1: if (n.typ != nil and classifyViewType(n.typ) != noView) or getMagic(n) == mSlice: @@ -551,6 +556,10 @@ proc borrowingAsgn(c: var Partitions; dest, src: PNode) = localError(c.config, dest.info, "attempt to mutate a borrowed location from an immutable view") of noView: discard "nothing to do" +proc containsPointer(t: PType): bool = + proc wrap(t: PType): bool {.nimcall.} = t.kind in {tyRef, tyPtr} + result = types.searchTypeFor(t, wrap) + proc deps(c: var Partitions; dest, src: PNode) = if borrowChecking in c.goals: borrowingAsgn(c, dest, src) @@ -559,9 +568,7 @@ proc deps(c: var Partitions; dest, src: PNode) = allRoots(dest, targets) allRoots(src, sources) - proc wrap(t: PType): bool {.nimcall.} = t.kind in {tyRef, tyPtr} - - let destIsComplex = types.searchTypeFor(dest.typ, wrap) + let destIsComplex = containsPointer(dest.typ) for t in targets: if dest.kind != nkSym and c.inNoSideEffectSection == 0: @@ -607,6 +614,14 @@ const nkFuncDef, nkConstSection, nkConstDef, nkIncludeStmt, nkImportStmt, nkExportStmt, nkPragma, nkCommentStmt, nkBreakState, nkTypeOfExpr} +proc potentialMutationViaArg(c: var Partitions; n: PNode; callee: PType) = + if constParameters in c.goals and tfNoSideEffect in callee.flags: + discard "we know there are no hidden mutations through an immutable parameter" + elif c.inNoSideEffectSection == 0 and containsPointer(n.typ): + var roots: seq[PSym] + allRoots(n, roots) + for r in roots: potentialMutation(c, r, n.info) + proc traverse(c: var Partitions; n: PNode) = inc c.abstractTime case n.kind @@ -640,6 +655,7 @@ proc traverse(c: var Partitions; n: PNode) = let parameters = n[0].typ let L = if parameters != nil: parameters.len else: 0 + let m = getMagic(n) for i in 1..