diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index 83f5e90172..bc9c06fa1d 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -1237,6 +1237,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) = else: scope = initScope(p.s(cpsStmts)) # we handled the error: + linefmt(p, cpsStmts, "T$1_ = nullptr;$n", [etmp]) expr(p, t[i][0], d) linefmt(p, cpsStmts, "#popCurrentException();$n", []) endBlockWith(p): diff --git a/compiler/guards.nim b/compiler/guards.nim index 553cc744df..fcfafc954a 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -46,7 +46,7 @@ proc isLocation(n: PNode): bool = not n.isValue proc isLet(n: PNode): bool = if n.kind == nkSym: - if n.sym.kind in {skLet, skTemp, skForVar}: + if n.sym.kind in {skLet, skConst, skTemp, skForVar}: # guard immutable variables result = true elif n.sym.kind == skParam and skipTypes(n.sym.typ, abstractInst).kind notin {tyVar}: diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index 9c84b721ad..f1e2e69cbe 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -1208,6 +1208,7 @@ type enforcedGcSafety, enforceNoSideEffects: bool oldExc, oldTags, oldForbids: int exc, tags, forbids: PNode + excSource, tagsSource, forbidsSource: PNode proc createBlockContext(tracked: PEffects): PragmaBlockContext = var oldForbidsLen = 0 @@ -1230,17 +1231,18 @@ proc unapplyBlockContext(tracked: PEffects; bc: PragmaBlockContext) = # anything about 'raises' in the 'cast' at all. Same applies for 'tags'. setLen(tracked.exc.sons, bc.oldExc) for e in bc.exc: - addRaiseEffect(tracked, e, e) + addRaiseEffect(tracked, e, if bc.excSource != nil: bc.excSource else: e) if bc.tags != nil: setLen(tracked.tags.sons, bc.oldTags) for t in bc.tags: - addTag(tracked, t, t) + addTag(tracked, t, if bc.tagsSource != nil: bc.tagsSource else: t) if bc.forbids != nil: setLen(tracked.forbids.sons, bc.oldForbids) for t in bc.forbids: - addNotTag(tracked, t, t) + addNotTag(tracked, t, if bc.forbidsSource != nil: bc.forbidsSource else: t) -proc castBlock(tracked: PEffects, pragma: PNode, bc: var PragmaBlockContext) = +proc castBlock(tracked: PEffects, castPragma: PNode, bc: var PragmaBlockContext) = + let pragma = castPragma[1] case whichPragma(pragma) of wGcSafe: bc.enforcedGcSafety = true @@ -1253,6 +1255,7 @@ proc castBlock(tracked: PEffects, pragma: PNode, bc: var PragmaBlockContext) = else: bc.tags = newNodeI(nkArgList, pragma.info) bc.tags.add n + bc.tagsSource = castPragma of wForbids: let n = pragma[1] if n.kind in {nkCurly, nkBracket}: @@ -1260,6 +1263,7 @@ proc castBlock(tracked: PEffects, pragma: PNode, bc: var PragmaBlockContext) = else: bc.forbids = newNodeI(nkArgList, pragma.info) bc.forbids.add n + bc.forbidsSource = castPragma of wRaises: let n = pragma[1] if n.kind in {nkCurly, nkBracket}: @@ -1267,6 +1271,7 @@ proc castBlock(tracked: PEffects, pragma: PNode, bc: var PragmaBlockContext) = else: bc.exc = newNodeI(nkArgList, pragma.info) bc.exc.add n + bc.excSource = castPragma of wUncheckedAssign: discard "handled in sempass1" else: @@ -1520,7 +1525,7 @@ proc track(tracked: PEffects, n: PNode) = of wNoSideEffect: bc.enforceNoSideEffects = true of wCast: - castBlock(tracked, pragmaList[i][1], bc) + castBlock(tracked, pragmaList[i], bc) else: discard applyBlockContext(tracked, bc) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index bf9c2d2050..dd5944899b 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -791,8 +791,10 @@ proc procParamTypeRel(c: var TCandidate; f, a: PType): TTypeRelation = # different C types (size_t vs unsigned long long). let fCheck = concreteType(c, f) let aCheck = concreteType(c, a) + # Note that `result` is equal; now check whether they have the same + # backend type. if fCheck != nil and aCheck != nil and - not sameBackendTypePickyAliases(fCheck, aCheck): + not sameBackendTypePickyAliases(fCheck, aCheck, {IgnoreFlags}): result = isNone if result <= isSubrange or inconsistentVarTypes(f, a): @@ -2471,6 +2473,10 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType, return arg elif f.kind == tyStatic and arg.typ.n != nil: return arg.typ.n + elif f.kind == tyUntyped: + # bug #25693: a different overload candidate may have sem-checked the + # operand and left symbols behind; templates expect the pristine AST. + return argOrig else: return argSemantized # argOrig diff --git a/compiler/types.nim b/compiler/types.nim index de24471e7d..f4c7e74bc5 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1069,9 +1069,10 @@ proc sameBackendTypeIgnoreRange*(x, y: PType): bool = c.cmp = dcEqIgnoreDistinct result = sameTypeAux(x, y, c) -proc sameBackendTypePickyAliases*(x, y: PType): bool = +proc sameBackendTypePickyAliases*(x, y: PType, flags: TTypeCmpFlags = {}): bool = var c = initSameTypeClosure() c.flags.incl {IgnoreTupleFields, IgnoreRangeShallow, PickyCAliases, PickyBackendAliases} + c.flags.incl flags c.cmp = dcEqIgnoreDistinct result = sameTypeAux(x, y, c) diff --git a/lib/pure/parsejson.nim b/lib/pure/parsejson.nim index 9292a85964..657f8cc697 100644 --- a/lib/pure/parsejson.nim +++ b/lib/pure/parsejson.nim @@ -175,23 +175,48 @@ proc parseEscapedUTF16*(buf: cstring, pos: var int): int = else: return -1 +proc addSpan(dst: var string; src: string; startPos, endPos: int) {.inline.} = + let n = endPos - startPos + if n <= 0: + return + + let old = dst.len + dst.setLen old + n + + template impl = + for i in 0..