warn about inconsistent spacing around binary operators; fixes #7582

This commit is contained in:
Andreas Rumpf 2018-05-05 14:58:33 +02:00
commit 1aa359febb
12 changed files with 28 additions and 27 deletions

View file

@ -17,6 +17,9 @@
- The ``not nil`` type annotation now has to be enabled explicitly - The ``not nil`` type annotation now has to be enabled explicitly
via ``{.experimental: "notnil"}`` as we are still not pleased with how this via ``{.experimental: "notnil"}`` as we are still not pleased with how this
feature works with Nim's containers. feature works with Nim's containers.
- The parser now warns about inconsistent spacing around binary operators as
these can easily be confused with unary operators. This warning will likely
become an error in the future.
#### Breaking changes in the standard library #### Breaking changes in the standard library
@ -89,7 +92,7 @@
- Accessing the binary zero terminator in Nim's native strings - Accessing the binary zero terminator in Nim's native strings
is now invalid. Internally a Nim string still has the trailing zero for is now invalid. Internally a Nim string still has the trailing zero for
zero-copy interoperability with ``cstring``. Compile your code with the zero-copy interoperability with ``cstring``. Compile your code with the
next switch ``--laxStrings:on`` if you need a transition period. new switch ``--laxStrings:on`` if you need a transition period.
### Tool changes ### Tool changes

View file

@ -131,7 +131,7 @@ type
warnEachIdentIsTuple, warnShadowIdent, warnEachIdentIsTuple, warnShadowIdent,
warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2, warnProveInit, warnProveField, warnProveIndex, warnGcUnsafe, warnGcUnsafe2,
warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed, warnUninit, warnGcMem, warnDestructor, warnLockLevel, warnResultShadowed,
warnUser, warnInconsistentSpacing, warnUser,
hintSuccess, hintSuccessX, hintSuccess, hintSuccessX,
hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded, hintLineTooLong, hintXDeclaredButNotUsed, hintConvToBaseNotNeeded,
hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled, hintConvFromXtoItselfNotNeeded, hintExprAlwaysX, hintQuitCalled,
@ -416,6 +416,7 @@ const
warnDestructor: "usage of a type with a destructor in a non destructible context. This will become a compile time error in the future.", warnDestructor: "usage of a type with a destructor in a non destructible context. This will become a compile time error in the future.",
warnLockLevel: "$1", warnLockLevel: "$1",
warnResultShadowed: "Special variable 'result' is shadowed.", warnResultShadowed: "Special variable 'result' is shadowed.",
warnInconsistentSpacing: "Number of spaces around '$#' is not consistent",
warnUser: "$1", warnUser: "$1",
hintSuccess: "operation successful", hintSuccess: "operation successful",
hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#; $#)", hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#; $#)",
@ -454,7 +455,8 @@ const
"TypelessParam", "UseBase", "WriteToForeignHeap", "TypelessParam", "UseBase", "WriteToForeignHeap",
"UnsafeCode", "EachIdentIsTuple", "ShadowIdent", "UnsafeCode", "EachIdentIsTuple", "ShadowIdent",
"ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit", "ProveInit", "ProveField", "ProveIndex", "GcUnsafe", "GcUnsafe2", "Uninit",
"GcMem", "Destructor", "LockLevel", "ResultShadowed", "User"] "GcMem", "Destructor", "LockLevel", "ResultShadowed",
"Spacing", "User"]
HintsToStr* = ["Success", "SuccessX", "LineTooLong", HintsToStr* = ["Success", "SuccessX", "LineTooLong",
"XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded", "XDeclaredButNotUsed", "ConvToBaseNotNeeded", "ConvFromXtoItselfNotNeeded",

View file

@ -268,13 +268,9 @@ proc isUnary(p: TParser): bool =
proc checkBinary(p: TParser) {.inline.} = proc checkBinary(p: TParser) {.inline.} =
## Check if the current parser token is a binary operator. ## Check if the current parser token is a binary operator.
# we don't check '..' here as that's too annoying # we don't check '..' here as that's too annoying
if p.strongSpaces and p.tok.tokType == tkOpr: if p.tok.tokType == tkOpr:
if p.tok.strongSpaceB > 0 and p.tok.strongSpaceA != p.tok.strongSpaceB: if p.tok.strongSpaceB > 0 and p.tok.strongSpaceA != p.tok.strongSpaceB:
parMessage(p, errGenerated, parMessage(p, warnInconsistentSpacing, prettyTok(p.tok))
"Number of spaces around '$#' not consistent" %
prettyTok(p.tok))
elif p.tok.strongSpaceA notin {0,1,2,4,8}:
parMessage(p, errGenerated, "Number of spaces must be 0,1,2,4 or 8")
#| module = stmt ^* (';' / IND{=}) #| module = stmt ^* (';' / IND{=})
#| #|

View file

@ -74,7 +74,7 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) =
var dst = cast[ByteAddress](cast[PPointer](dest)[]) var dst = cast[ByteAddress](cast[PPointer](dest)[])
for i in 0..seq.len-1: for i in 0..seq.len-1:
genericAssignAux( genericAssignAux(
cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), cast[pointer](dst +% i *% mt.base.size +% GenericSeqSize),
cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +% cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +%
GenericSeqSize), GenericSeqSize),
mt.base, shallow) mt.base, shallow)
@ -100,8 +100,8 @@ proc genericAssignAux(dest, src: pointer, mt: PNimType, shallow: bool) =
genericAssignAux(dest, src, mt.node, shallow) genericAssignAux(dest, src, mt.node, shallow)
of tyArray, tyArrayConstr: of tyArray, tyArrayConstr:
for i in 0..(mt.size div mt.base.size)-1: for i in 0..(mt.size div mt.base.size)-1:
genericAssignAux(cast[pointer](d +% i*% mt.base.size), genericAssignAux(cast[pointer](d +% i *% mt.base.size),
cast[pointer](s +% i*% mt.base.size), mt.base, shallow) cast[pointer](s +% i *% mt.base.size), mt.base, shallow)
of tyRef: of tyRef:
unsureAsgnRef(cast[PPointer](dest), cast[PPointer](s)[]) unsureAsgnRef(cast[PPointer](dest), cast[PPointer](s)[])
of tyOptAsRef: of tyOptAsRef:
@ -166,8 +166,8 @@ proc genericAssignOpenArray(dest, src: pointer, len: int,
d = cast[ByteAddress](dest) d = cast[ByteAddress](dest)
s = cast[ByteAddress](src) s = cast[ByteAddress](src)
for i in 0..len-1: for i in 0..len-1:
genericAssign(cast[pointer](d +% i*% mt.base.size), genericAssign(cast[pointer](d +% i *% mt.base.size),
cast[pointer](s +% i*% mt.base.size), mt.base) cast[pointer](s +% i *% mt.base.size), mt.base)
proc objectInit(dest: pointer, typ: PNimType) {.compilerProc, benign.} proc objectInit(dest: pointer, typ: PNimType) {.compilerProc, benign.}
proc objectInitAux(dest: pointer, n: ptr TNimNode) {.benign.} = proc objectInitAux(dest: pointer, n: ptr TNimNode) {.benign.} =
@ -235,7 +235,7 @@ proc genericReset(dest: pointer, mt: PNimType) =
pint[] = nil pint[] = nil
of tyArray, tyArrayConstr: of tyArray, tyArrayConstr:
for i in 0..(mt.size div mt.base.size)-1: for i in 0..(mt.size div mt.base.size)-1:
genericReset(cast[pointer](d +% i*% mt.base.size), mt.base) genericReset(cast[pointer](d +% i *% mt.base.size), mt.base)
else: else:
zeroMem(dest, mt.size) # set raw bits to zero zeroMem(dest, mt.size) # set raw bits to zero

View file

@ -105,7 +105,7 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) =
var dst = cast[ByteAddress](cast[PPointer](dest)[]) var dst = cast[ByteAddress](cast[PPointer](dest)[])
for i in 0..seq.len-1: for i in 0..seq.len-1:
genericDeepCopyAux( genericDeepCopyAux(
cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize), cast[pointer](dst +% i *% mt.base.size +% GenericSeqSize),
cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +% cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +%
GenericSeqSize), GenericSeqSize),
mt.base, tab) mt.base, tab)
@ -122,8 +122,8 @@ proc genericDeepCopyAux(dest, src: pointer, mt: PNimType; tab: var PtrTable) =
genericDeepCopyAux(dest, src, mt.node, tab) genericDeepCopyAux(dest, src, mt.node, tab)
of tyArray, tyArrayConstr: of tyArray, tyArrayConstr:
for i in 0..(mt.size div mt.base.size)-1: for i in 0..(mt.size div mt.base.size)-1:
genericDeepCopyAux(cast[pointer](d +% i*% mt.base.size), genericDeepCopyAux(cast[pointer](d +% i *% mt.base.size),
cast[pointer](s +% i*% mt.base.size), mt.base, tab) cast[pointer](s +% i *% mt.base.size), mt.base, tab)
of tyRef, tyOptAsRef: of tyRef, tyOptAsRef:
let s2 = cast[PPointer](src)[] let s2 = cast[PPointer](src)[]
if s2 == nil: if s2 == nil:
@ -183,5 +183,5 @@ proc genericDeepCopyOpenArray(dest, src: pointer, len: int,
d = cast[ByteAddress](dest) d = cast[ByteAddress](dest)
s = cast[ByteAddress](src) s = cast[ByteAddress](src)
for i in 0..len-1: for i in 0..len-1:
genericDeepCopy(cast[pointer](d +% i*% mt.base.size), genericDeepCopy(cast[pointer](d +% i *% mt.base.size),
cast[pointer](s +% i*% mt.base.size), mt.base) cast[pointer](s +% i *% mt.base.size), mt.base)

View file

@ -535,7 +535,7 @@ proc growObj(old: pointer, newsize: int, gch: var GcHeap): pointer =
var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize
copyMem(res, ol, oldsize + sizeof(Cell)) copyMem(res, ol, oldsize + sizeof(Cell))
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(Cell)), zeroMem(cast[pointer](cast[ByteAddress](res) +% oldsize +% sizeof(Cell)),
newsize-oldsize) newsize-oldsize)
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3") sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
# This can be wrong for intermediate temps that are nevertheless on the # This can be wrong for intermediate temps that are nevertheless on the

View file

@ -58,7 +58,7 @@ when defined(emscripten):
# Convert pointer to PageSize correct one. # Convert pointer to PageSize correct one.
var new_pos = cast[ByteAddress](pos) +% (PageSize - (pos %% PageSize)) var new_pos = cast[ByteAddress](pos) +% (PageSize - (pos %% PageSize))
if (new_pos-pos)< sizeof(EmscriptenMMapBlock): if (new_pos-pos) < sizeof(EmscriptenMMapBlock):
new_pos = new_pos +% PageSize new_pos = new_pos +% PageSize
result = cast[pointer](new_pos) result = cast[pointer](new_pos)