diff --git a/compiler/ast.nim b/compiler/ast.nim index 71d19be30b..db0321f6c0 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -608,7 +608,6 @@ type mAddF64, mSubF64, mMulF64, mDivF64, mShrI, mShlI, mAshrI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI, - mMinF64, mMaxF64, mAddU, mSubU, mMulU, mDivU, mModU, mEqI, mLeI, mLtI, mEqF64, mLeF64, mLtF64, @@ -621,7 +620,7 @@ type mXor, mEqCString, mEqProc, mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot, mUnaryPlusI, mBitnotI, - mUnaryPlusF64, mUnaryMinusF64, mAbsF64, + mUnaryPlusF64, mUnaryMinusF64, mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr, mAnd, mOr, @@ -678,7 +677,6 @@ const mAddF64, mSubF64, mMulF64, mDivF64, mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI, - mMinF64, mMaxF64, mAddU, mSubU, mMulU, mDivU, mModU, mEqI, mLeI, mLtI, mEqF64, mLeF64, mLtF64, @@ -689,7 +687,7 @@ const mEqB, mLeB, mLtB, mEqRef, mEqProc, mEqUntracedRef, mLePtr, mLtPtr, mEqCString, mXor, mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot, mUnaryPlusI, mBitnotI, - mUnaryPlusF64, mUnaryMinusF64, mAbsF64, + mUnaryPlusF64, mUnaryMinusF64, mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr, mAnd, mOr, diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 632f00f4dc..06611313cf 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -77,7 +77,6 @@ proc idNodeTablePut*(t: var TIdNodeTable, key: PIdObj, val: PNode) # --------------------------------------------------------------------------- -proc getSymFromList*(list: PNode, ident: PIdent, start: int = 0): PSym proc lookupInRecord*(n: PNode, field: PIdent): PSym proc mustRehash*(length, counter: int): bool proc nextTry*(h, maxHash: Hash): Hash {.inline.} @@ -174,7 +173,7 @@ proc getModule*(s: PSym): PSym = assert((result.kind == skModule) or (result.owner != result)) while result != nil and result.kind != skModule: result = result.owner -proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym = +proc getSymFromList*(list: PNode, ident: PIdent, start: int = 0): PSym = for i in start ..< sonsLen(list): if list.sons[i].kind == nkSym: result = list.sons[i].sym @@ -182,6 +181,45 @@ proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym = else: return nil result = nil +proc sameIgnoreBacktickGensymInfo(a, b: string): bool = + if a[0] != b[0]: return false + var last = a.len - 1 + while last > 0 and a[last] != '`': dec(last) + + var i = 1 + var j = 1 + while true: + while i < last and a[i] == '_': inc i + while j < b.len and b[j] == '_': inc j + var aa = if i < last: toLowerAscii(a[i]) else: '\0' + var bb = if j < b.len: toLowerAscii(b[j]) else: '\0' + if aa != bb: return false + + # the characters are identical: + if i >= last: + # both cursors at the end: + if j >= b.len: return true + # not yet at the end of 'b': + return false + elif j >= b.len: + return false + inc i + inc j + +proc getNamedParamFromList*(list: PNode, ident: PIdent): PSym = + ## Named parameters are special because a named parameter can be + ## gensym'ed and then they have '`' suffix that we need to + ## ignore, see compiler / evaltempl.nim, snippet: + ## + ## .. code-block:: nim + ## + ## result.add newIdentNode(getIdent(c.ic, x.name.s & "`gensym" & $x.id), + ## if c.instLines: actual.info else: templ.info) + for i in 1 ..< len(list): + let it = list[i].sym + if it.name.id == ident.id or + sameIgnoreBacktickGensymInfo(it.name.s, ident.s): return it + proc hashNode(p: RootRef): Hash = result = hash(cast[pointer](p)) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 0ab592a503..0902e2e19e 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -588,8 +588,6 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = of mBitxorI: applyFormat("($4)($1 ^ $2)") of mMinI: applyFormat("(($1 <= $2) ? $1 : $2)") of mMaxI: applyFormat("(($1 >= $2) ? $1 : $2)") - of mMinF64: applyFormat("(($1 <= $2) ? $1 : $2)") - of mMaxF64: applyFormat("(($1 >= $2) ? $1 : $2)") of mAddU: applyFormat("($4)((NU$3)($1) + (NU$3)($2))") of mSubU: applyFormat("($4)((NU$3)($1) - (NU$3)($2))") of mMulU: applyFormat("($4)((NU$3)($1) * (NU$3)($2))") @@ -663,9 +661,6 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = applyFormat("$1") of mUnaryMinusF64: applyFormat("-($1)") - of mAbsF64: - applyFormat("($1 < 0? -($1) : ($1))") - # BUGFIX: fabs() makes problems for Tiny C else: assert false, $op @@ -2086,7 +2081,7 @@ proc genEnumToStr(p: BProc, e: PNode, d: var TLoc) = proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = case op of mOr, mAnd: genAndOr(p, e, d, op) - of mNot..mAbsF64: unaryArith(p, e, d, op) + of mNot..mUnaryMinusF64: unaryArith(p, e, d, op) of mUnaryMinusI..mAbsI: unaryArithOverflow(p, e, d, op) of mAddF64..mDivF64: binaryFloatArith(p, e, d, op) of mShrI..mXor: binaryArith(p, e, d, op) diff --git a/compiler/guards.nim b/compiler/guards.nim index 1ab50b8b68..be23c15983 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -35,8 +35,8 @@ const someMul = {mMulI, mMulF64} someDiv = {mDivI, mDivF64} someMod = {mModI} - someMax = {mMaxI, mMaxF64} - someMin = {mMinI, mMinF64} + someMax = {mMaxI} + someMin = {mMinI} someBinaryOp = someAdd+someSub+someMul+someMax+someMin proc isValue(n: PNode): bool = n.kind in {nkCharLit..nkNilLit} diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim index 1d980ab6f4..78373ea478 100644 --- a/compiler/jsgen.nim +++ b/compiler/jsgen.nim @@ -389,8 +389,6 @@ const # magic checked op; magic unchecked op; ["", ""], # BitxorI ["nimMin", "nimMin"], # MinI ["nimMax", "nimMax"], # MaxI - ["nimMin", "nimMin"], # MinF64 - ["nimMax", "nimMax"], # MaxF64 ["", ""], # addU ["", ""], # subU ["", ""], # mulU @@ -430,7 +428,6 @@ const # magic checked op; magic unchecked op; ["", ""], # BitnotI ["", ""], # UnaryPlusF64 ["", ""], # UnaryMinusF64 - ["", ""], # AbsF64 ["nimCharToStr", "nimCharToStr"], ["nimBoolToStr", "nimBoolToStr"], ["cstrToNimstr", "cstrToNimstr"], @@ -566,8 +563,6 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) = of mBitxorI: applyFormat("($1 ^ $2)", "($1 ^ $2)") of mMinI: applyFormat("nimMin($1, $2)", "nimMin($1, $2)") of mMaxI: applyFormat("nimMax($1, $2)", "nimMax($1, $2)") - of mMinF64: applyFormat("nimMin($1, $2)", "nimMin($1, $2)") - of mMaxF64: applyFormat("nimMax($1, $2)", "nimMax($1, $2)") of mAddU: applyFormat("", "") of mSubU: applyFormat("", "") of mMulU: applyFormat("", "") @@ -607,7 +602,6 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) = of mBitnotI: applyFormat("~($1)", "~($1)") of mUnaryPlusF64: applyFormat("+($1)", "+($1)") of mUnaryMinusF64: applyFormat("-($1)", "-($1)") - of mAbsF64: applyFormat("Math.abs($1)", "Math.abs($1)") of mCharToStr: applyFormat("nimCharToStr($1)", "nimCharToStr($1)") of mBoolToStr: applyFormat("nimBoolToStr($1)", "nimBoolToStr($1)") of mIntToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")") diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim index 1bd703fe86..b8f1fd8327 100644 --- a/compiler/parampatterns.nim +++ b/compiler/parampatterns.nim @@ -224,14 +224,14 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult result = arLocalLValue else: result = arLValue - elif n.sym.kind == skParam and n.sym.typ.kind == tyVar: + elif n.sym.kind == skParam and n.sym.typ.kind in {tyVar, tySink}: result = arLValue elif n.sym.kind == skType: let t = n.sym.typ.skipTypes({tyTypeDesc}) if t.kind == tyVar: result = arStrange of nkDotExpr: let t = skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}) - if t.kind in {tyVar, tyPtr, tyRef}: + if t.kind in {tyVar, tySink, tyPtr, tyRef}: result = arLValue elif isUnsafeAddr and t.kind == tyLent: result = arLValue @@ -242,7 +242,7 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult result = arDiscriminant of nkBracketExpr: let t = skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc}) - if t.kind in {tyVar, tyPtr, tyRef}: + if t.kind in {tyVar, tySink, tyPtr, tyRef}: result = arLValue elif isUnsafeAddr and t.kind == tyLent: result = arLValue diff --git a/compiler/semfold.nim b/compiler/semfold.nim index cf15861449..81efc2436e 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -197,7 +197,6 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = result = newIntNodeT(toInt128(sonsLen(a)), n, g) of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away # XXX: Hides overflow/underflow - of mAbsF64: result = newFloatNodeT(abs(getFloat(a)), n, g) of mAbsI: result = foldAbs(getInt(a), n, g) of mUnaryLt: result = foldSub(getOrdValue(a), One, n, g) of mSucc: result = foldAdd(getOrdValue(a), getInt(b), n, g) @@ -277,12 +276,6 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode = of mMulF64: result = newFloatNodeT(getFloat(a) * getFloat(b), n, g) of mDivF64: result = newFloatNodeT(getFloat(a) / getFloat(b), n, g) - of mMaxF64: - if getFloat(a) > getFloat(b): result = newFloatNodeT(getFloat(a), n, g) - else: result = newFloatNodeT(getFloat(b), n, g) - of mMinF64: - if getFloat(a) > getFloat(b): result = newFloatNodeT(getFloat(b), n, g) - else: result = newFloatNodeT(getFloat(a), n, g) of mIsNil: result = newIntNodeT(ord(a.kind == nkNilLit), n, g) of mLtI, mLtB, mLtEnum, mLtCh: result = newIntNodeT(ord(getOrdValue(a) < getOrdValue(b)), n, g) diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 907d2174e4..acf32d1b32 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -80,6 +80,7 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule; while a != nil: if a.kind != skModule and (not isField or sfGenSym notin s.flags): incl(a.flags, sfUsed) + markOwnerModuleAsUsed(c, a) addSon(result, newSymNode(a, info)) onUse(info, a) a = nextOverloadIter(o, c, n) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index d307039439..2c22620daf 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -108,6 +108,7 @@ const isNilConversion = isConvertible # maybe 'isIntConv' fits better? proc markUsed*(c: PContext; info: TLineInfo, s: PSym) +proc markOwnerModuleAsUsed*(c: PContext; s: PSym) template hasFauxMatch*(c: TCandidate): bool = c.fauxMatch != tyNone @@ -380,7 +381,7 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation = isIntLit(ab) and getInt(ab.n) >= firstOrd(nil, f) and getInt(ab.n) <= lastOrd(nil, f): # passing 'nil' to firstOrd/lastOrd here as type checking rules should - # not depent on the target integer size configurations! + # not depend on the target integer size configurations! # integer literal in the proper range; we want ``i16 + 4`` to stay an # ``int16`` operation so we declare the ``4`` pseudo-equal to int16 result = isFromIntLit @@ -396,7 +397,7 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation = f.kind in {tyUInt8..tyUInt32} and a[0].kind in {tyUInt8..tyInt32}) and a.n[0].intVal >= firstOrd(nil, f) and a.n[1].intVal <= lastOrd(nil, f): # passing 'nil' to firstOrd/lastOrd here as type checking rules should - # not depent on the target integer size configurations! + # not depend on the target integer size configurations! result = isConvertible else: result = isNone @@ -408,13 +409,13 @@ proc isConvertibleToRange(f, a: PType): bool = of tyInt16: result = isIntLit(a) or a.kind in {tyInt8, tyInt16} of tyInt32: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32} # This is wrong, but seems like there's a lot of code that relies on it :( - of tyInt: result = true + of tyInt, tyUInt, tyUInt64: result = true of tyInt64: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64} of tyUInt8: result = isIntLit(a) or a.kind in {tyUInt8} of tyUInt16: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16} of tyUInt32: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32} - of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt} - of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt, tyUInt64} + #of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt} + #of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt, tyUInt64} else: result = false elif f.kind in {tyFloat..tyFloat128}: # `isIntLit` is correct and should be used above as well, see PR: @@ -2362,7 +2363,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, localError(c.config, n.sons[a].info, "named parameter has to be an identifier") noMatch() return - formal = getSymFromList(m.callee.n, n.sons[a].sons[0].ident, 1) + formal = getNamedParamFromList(m.callee.n, n.sons[a].sons[0].ident) if formal == nil: # no error message! noMatch() diff --git a/compiler/types.nim b/compiler/types.nim index 7dfc250264..a056253270 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -1309,7 +1309,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind, tyNone, tyForward, tyFromExpr: result = t of tyNil: - if kind != skConst and kind != skParam and kind != skResult: result = t + if kind != skConst and kind != skParam: result = t of tyString, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString, tyPointer: result = nil of tyOrdinal: diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 0b76828b38..8863b2dc9f 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1288,7 +1288,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = if dest < 0: dest = c.getTemp(n.typ) c.gABC(n, opcCallSite, dest) of mNGenSym: genBinaryABC(c, n, dest, opcGenSym) - of mMinI, mMaxI, mAbsF64, mMinF64, mMaxF64, mAbsI, mDotDot: + of mMinI, mMaxI, mAbsI, mDotDot: c.genCall(n, dest) of mExpandToAst: if n.len != 2: diff --git a/lib/pure/nimprof.nim b/lib/pure/nimprof.nim index 27b7d3ecac..550664f4f1 100644 --- a/lib/pure/nimprof.nim +++ b/lib/pure/nimprof.nim @@ -14,6 +14,9 @@ when not defined(profiler) and not defined(memProfiler): {.error: "Profiling support is turned off! Enable profiling by passing `--profiler:on --stackTrace:on` to the compiler (see the Nim Compiler User Guide for more options).".} +when defined(nimHasUsed): + {.used.} + # We don't want to profile the profiling code ... {.push profiler: off.} diff --git a/lib/system.nim b/lib/system.nim index 9605049fc5..d3fd9ddc81 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2880,17 +2880,21 @@ proc max*[T](x: openArray[T]): T = for i in 1..high(x): if result < x[i]: result = x[i] -proc abs*(x: float): float {.magic: "AbsF64", noSideEffect.} = +proc abs*(x: float64): float64 {.noSideEffect, inline.} = if x < 0.0: -x else: x -proc min*(x, y: float): float {.magic: "MinF64", noSideEffect.} = +proc abs*(x: float32): float32 {.noSideEffect, inline.} = + if x < 0.0: -x else: x +proc min*(x, y: float32): float32 {.noSideEffect, inline.} = + if x <= y or y != y: x else: y +proc min*(x, y: float64): float64 {.noSideEffect, inline.} = + if x <= y or y != y: x else: y +proc max*(x, y: float32): float32 {.noSideEffect, inline.} = + if y <= x or y != y: x else: y +proc max*(x, y: float64): float64 {.noSideEffect, inline.} = + if y <= x or y != y: x else: y +proc min*[T: not SomeFloat](x, y: T): T {.inline.} = if x <= y: x else: y -proc max*(x, y: float): float {.magic: "MaxF64", noSideEffect.} = - if y <= x: x else: y - -proc min*[T](x, y: T): T {.inline.}= - if x <= y: x else: y - -proc max*[T](x, y: T): T {.inline.}= +proc max*[T: not SomeFloat](x, y: T): T {.inline.} = if y <= x: x else: y {.pop.} diff --git a/tests/ccgbugs/tnil_type.nim b/tests/ccgbugs/tnil_type.nim index 12310dae9e..9921b24a32 100644 --- a/tests/ccgbugs/tnil_type.nim +++ b/tests/ccgbugs/tnil_type.nim @@ -13,6 +13,3 @@ f3(typeof(nil)) proc f4[T](_: T) = discard f4(nil) - -proc f5(): typeof(nil) = nil -discard f5() diff --git a/tests/destructor/tnewruntime_misc.nim b/tests/destructor/tnewruntime_misc.nim index d6c03b9b02..8abf0d30b7 100644 --- a/tests/destructor/tnewruntime_misc.nim +++ b/tests/destructor/tnewruntime_misc.nim @@ -85,3 +85,16 @@ testWrongAt() let (a, d) = allocCounters() discard cprintf("%ld new: %ld\n", a - unpairedEnvAllocs() - d, allocs) + +#------------------------------------------------- +type + Table[A, B] = object + x: seq[(A, B)] + + +proc toTable[A,B](p: sink openArray[(A, B)]): Table[A, B] = + for zz in mitems(p): + result.x.add move(zz) + + +let table = {"a": new(int)}.toTable() diff --git a/tests/range/trange.nim b/tests/range/trange.nim index aac9677771..c864387f69 100644 --- a/tests/range/trange.nim +++ b/tests/range/trange.nim @@ -136,3 +136,9 @@ block: const x11: range[0'f..1'f] = 2'f reject: const x12: range[0'f..1'f] = 2 + +# ensure unsigned array indexing is remains lenient: +var a: array[4'u, string] + +for i in 0.. 0: b + bar2(b = b - 1) + else: 0 + echo (total: bar2(3)) + +baz()