Merge branch 'devel' of github.com:nim-lang/Nim into devel
This commit is contained in:
commit
7426e9c246
4 changed files with 78 additions and 9 deletions
|
|
@ -900,6 +900,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||||
if sameDistinctTypes(f, a): result = isEqual
|
if sameDistinctTypes(f, a): result = isEqual
|
||||||
elif f.base.kind == tyAnything: result = isGeneric
|
elif f.base.kind == tyAnything: result = isGeneric
|
||||||
elif c.coerceDistincts: result = typeRel(c, f.base, a)
|
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)
|
elif c.coerceDistincts: result = typeRel(c, f.base, a)
|
||||||
of tySet:
|
of tySet:
|
||||||
if a.kind == tySet:
|
if a.kind == tySet:
|
||||||
|
|
|
||||||
|
|
@ -219,7 +219,7 @@ when not defined(JS):
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
## echo ceil(-2.1) ## -2.0
|
## echo ceil(-2.1) ## -2.0
|
||||||
|
|
||||||
when defined(windows) and defined(vcc):
|
when defined(windows) and defined(vcc):
|
||||||
proc round0[T: float32|float64](x: T): T =
|
proc round0[T: float32|float64](x: T): T =
|
||||||
## Windows compilers prior to MSVC 2012 do not implement 'round',
|
## 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 =
|
proc `^`*[T](x, y: T): T =
|
||||||
## Computes ``x`` to the power ``y`. ``x`` must be non-negative, use
|
## Computes ``x`` to the power ``y`. ``x`` must be non-negative, use
|
||||||
## `pow <#pow,float,float>` for negative exponents.
|
## `pow <#pow,float,float>` for negative exponents.
|
||||||
assert y >= 0
|
assert y >= T(0)
|
||||||
var (x, y) = (x, y)
|
var (x, y) = (x, y)
|
||||||
result = 1
|
result = 1
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,10 @@ type
|
||||||
|
|
||||||
proc mapMem*(m: var MemFile, mode: FileMode = fmRead,
|
proc mapMem*(m: var MemFile, mode: FileMode = fmRead,
|
||||||
mappedSize = -1, offset = 0): pointer =
|
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
|
var readonly = mode == fmRead
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
result = mapViewOfFileEx(
|
result = mapViewOfFileEx(
|
||||||
|
|
@ -68,7 +72,9 @@ proc mapMem*(m: var MemFile, mode: FileMode = fmRead,
|
||||||
proc unmapMem*(f: var MemFile, p: pointer, size: int) =
|
proc unmapMem*(f: var MemFile, p: pointer, size: int) =
|
||||||
## unmaps the memory region ``(p, <p+size)`` of the mapped file `f`.
|
## unmaps the memory region ``(p, <p+size)`` of the mapped file `f`.
|
||||||
## All changes are written back to the file system, if `f` was opened
|
## All changes are written back to the file system, if `f` was opened
|
||||||
## with write access. ``size`` must be of exactly the size that was requested
|
## with write access.
|
||||||
|
##
|
||||||
|
## ``size`` must be of exactly the size that was requested
|
||||||
## via ``mapMem``.
|
## via ``mapMem``.
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
if unmapViewOfFile(p) == 0: raiseOSError(osLastError())
|
if unmapViewOfFile(p) == 0: raiseOSError(osLastError())
|
||||||
|
|
@ -79,9 +85,17 @@ proc unmapMem*(f: var MemFile, p: pointer, size: int) =
|
||||||
proc open*(filename: string, mode: FileMode = fmRead,
|
proc open*(filename: string, mode: FileMode = fmRead,
|
||||||
mappedSize = -1, offset = 0, newFileSize = -1): MemFile =
|
mappedSize = -1, offset = 0, newFileSize = -1): MemFile =
|
||||||
## opens a memory mapped file. If this fails, ``EOS`` is raised.
|
## opens a memory mapped file. If this fails, ``EOS`` is raised.
|
||||||
## `newFileSize` can only be set if the file does not exist and is opened
|
##
|
||||||
## with write access (e.g., with fmReadWrite). `mappedSize` and `offset`
|
## ``newFileSize`` can only be set if the file does not exist and is opened
|
||||||
## can be used to map only a slice of the file. Example:
|
## with write access (e.g., with fmReadWrite).
|
||||||
|
##
|
||||||
|
##``mappedSize`` and ``offset``
|
||||||
|
## can be used to map only a slice of the file.
|
||||||
|
##
|
||||||
|
## ``offset`` must be multiples of the PAGE SIZE of your OS
|
||||||
|
## (usually 4K or 8K but is unique to your OS)
|
||||||
|
##
|
||||||
|
## Example:
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
## var
|
## var
|
||||||
|
|
@ -285,7 +299,9 @@ iterator memSlices*(mfile: MemFile, delim='\l', eat='\r'): MemSlice {.inline.} =
|
||||||
## iterate over line-like records in a file. However, returned (data,size)
|
## iterate over line-like records in a file. However, returned (data,size)
|
||||||
## objects are not Nim strings, bounds checked Nim arrays, or even terminated
|
## objects are not Nim strings, bounds checked Nim arrays, or even terminated
|
||||||
## C strings. So, care is required to access the data (e.g., think C mem*
|
## C strings. So, care is required to access the data (e.g., think C mem*
|
||||||
## functions, not str* functions). Example:
|
## functions, not str* functions).
|
||||||
|
##
|
||||||
|
## Example:
|
||||||
##
|
##
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
## var count = 0
|
## var count = 0
|
||||||
|
|
@ -318,7 +334,9 @@ iterator lines*(mfile: MemFile, buf: var TaintedString, delim='\l', eat='\r'): T
|
||||||
## Replace contents of passed buffer with each new line, like
|
## Replace contents of passed buffer with each new line, like
|
||||||
## `readLine(File) <system.html#readLine,File,TaintedString>`_.
|
## `readLine(File) <system.html#readLine,File,TaintedString>`_.
|
||||||
## `delim`, `eat`, and delimiting logic is exactly as for
|
## `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
|
## .. code-block:: nim
|
||||||
## var buffer: TaintedString = ""
|
## 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
|
## Return each line in a file as a Nim string, like
|
||||||
## `lines(File) <system.html#lines.i,File>`_.
|
## `lines(File) <system.html#lines.i,File>`_.
|
||||||
## `delim`, `eat`, and delimiting logic is exactly as for
|
## `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
|
## .. code-block:: nim
|
||||||
## for line in lines(memfiles.open("foo")):
|
## for line in lines(memfiles.open("foo")):
|
||||||
|
|
|
||||||
47
tests/distinct/tnil.nim
Normal file
47
tests/distinct/tnil.nim
Normal file
|
|
@ -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)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue