diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 19ef8a1177..7cde101cbb 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -900,6 +900,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation = if sameDistinctTypes(f, a): result = isEqual elif f.base.kind == tyAnything: result = isGeneric elif c.coerceDistincts: result = typeRel(c, f.base, a) + elif a.kind == tyNil and f.base.kind in NilableTypes: + result = f.allowsNil elif c.coerceDistincts: result = typeRel(c, f.base, a) of tySet: if a.kind == tySet: diff --git a/lib/pure/math.nim b/lib/pure/math.nim index c088e3d7dc..58d9879b20 100644 --- a/lib/pure/math.nim +++ b/lib/pure/math.nim @@ -219,7 +219,7 @@ when not defined(JS): ## ## .. code-block:: nim ## echo ceil(-2.1) ## -2.0 - + when defined(windows) and defined(vcc): proc round0[T: float32|float64](x: T): T = ## Windows compilers prior to MSVC 2012 do not implement 'round', @@ -360,7 +360,7 @@ proc `mod`*[T: float32|float64](x, y: T): T = proc `^`*[T](x, y: T): T = ## Computes ``x`` to the power ``y`. ``x`` must be non-negative, use ## `pow <#pow,float,float>` for negative exponents. - assert y >= 0 + assert y >= T(0) var (x, y) = (x, y) result = 1 diff --git a/lib/pure/memfiles.nim b/lib/pure/memfiles.nim index ff3e74d59f..aa32778c52 100644 --- a/lib/pure/memfiles.nim +++ b/lib/pure/memfiles.nim @@ -42,6 +42,10 @@ type proc mapMem*(m: var MemFile, mode: FileMode = fmRead, mappedSize = -1, offset = 0): pointer = + ## returns a pointer to a mapped portion of MemFile `m` + ## + ## ``mappedSize`` of ``-1`` maps to the whole file, and + ## ``offset`` must be multiples of the PAGE SIZE of your OS var readonly = mode == fmRead when defined(windows): result = mapViewOfFileEx( @@ -68,7 +72,9 @@ proc mapMem*(m: var MemFile, mode: FileMode = fmRead, proc unmapMem*(f: var MemFile, p: pointer, size: int) = ## unmaps the memory region ``(p, `_. ## `delim`, `eat`, and delimiting logic is exactly as for - ## `memSlices <#memSlices>`_, but Nim strings are returned. Example: + ## `memSlices <#memSlices>`_, but Nim strings are returned. + ## + ## Example: ## ## .. code-block:: nim ## var buffer: TaintedString = "" @@ -335,7 +353,9 @@ iterator lines*(mfile: MemFile, delim='\l', eat='\r'): TaintedString {.inline.} ## Return each line in a file as a Nim string, like ## `lines(File) `_. ## `delim`, `eat`, and delimiting logic is exactly as for - ## `memSlices <#memSlices>`_, but Nim strings are returned. Example: + ## `memSlices <#memSlices>`_, but Nim strings are returned. + ## + ## Example: ## ## .. code-block:: nim ## for line in lines(memfiles.open("foo")): diff --git a/tests/distinct/tnil.nim b/tests/distinct/tnil.nim new file mode 100644 index 0000000000..ed0ac995a0 --- /dev/null +++ b/tests/distinct/tnil.nim @@ -0,0 +1,47 @@ +discard """ + file: "tnil.nim" + output: '''0x1 + +nil + +nil + +''' +""" + +type + MyPointer = distinct pointer + MyString = distinct string + MyStringNotNil = distinct (string not nil) + MyInt = distinct int + +proc foo(a: MyPointer) = + echo a.repr + +foo(cast[MyPointer](1)) +foo(cast[MyPointer](nil)) +foo(nil) + +var p: MyPointer +p = cast[MyPointer](1) +p = cast[MyPointer](nil) +p = nil.MyPointer +p = nil + +var c: MyString +c = "Test".MyString +c = nil.MyString +c = nil + +p = nil +doAssert(compiles(c = p) == false) + +var n: MyStringNotNil = "Test".MyStringNotNil # Cannot prove warning ... +n = "Test".MyStringNotNil +doAssert(compiles(n = nil.MyStringNotNil) == false) +doAssert(compiles(n = nil.MyStringNotNil) == false) +doAssert(compiles(n = nil) == false) + +var i: MyInt +i = 1.MyInt +doAssert(compiles(i = nil) == false)