Skip to content

Commit

Permalink
enable experimental:strictDefs (#24225)
Browse files Browse the repository at this point in the history
  • Loading branch information
ringabout authored Nov 23, 2024
1 parent 555191a commit 2df6331
Show file tree
Hide file tree
Showing 86 changed files with 276 additions and 255 deletions.
4 changes: 3 additions & 1 deletion compiler/condsyms.nim
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimHasEnsureMove")
defineSymbol("nimHasNoReturnError")

defineSymbol("nimUseStrictDefs")
defineSymbol("nimUseStrictDefs") # deadcode
defineSymbol("nimHasNolineTooLong")

defineSymbol("nimHasCastExtendedVm")
Expand All @@ -171,3 +171,5 @@ proc initDefines*(symbols: StringTableRef) =
defineSymbol("nimHasJsNoLambdaLifting")
defineSymbol("nimHasDefaultFloatRoundtrip")
defineSymbol("nimHasXorSet")

defineSymbol("nimHasLegacyNoStrictDefs")
2 changes: 1 addition & 1 deletion compiler/nim.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ define:useStdoutAsStdmsg


@if nimUseStrictDefs:
experimental:strictDefs
experimental:strictDefs # deadcode
warningAsError[Uninit]:on
warningAsError[ProveInit]:on
@end
Expand Down
4 changes: 3 additions & 1 deletion compiler/options.nim
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ type
strictEffects,
unicodeOperators, # deadcode
flexibleOptionalParams,
strictDefs,
strictDefs, # deadcode
strictCaseObjects,
inferGenericTypes,
openSym, # remove nfDisabledOpenSym when this is default
Expand All @@ -248,6 +248,8 @@ type
## Useful for libraries that rely on local passC
jsNoLambdaLifting
## Old transformation for closures in JS backend
noStrictDefs
## disable "strictdefs"

SymbolFilesOption* = enum
disabledSf, writeOnlySf, readOnlySf, v2Sf, stressTest
Expand Down
5 changes: 3 additions & 2 deletions compiler/semexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@ proc newHiddenAddrTaken(c: PContext, n: PNode, isOutParam: bool): PNode =
if aa notin {arLValue, arLocalLValue}:
if aa == arDiscriminant and c.inUncheckedAssignSection > 0:
discard "allow access within a cast(unsafeAssign) section"
elif strictDefs in c.features and aa == arAddressableConst and
elif noStrictDefs notin c.config.legacyFeatures and aa == arAddressableConst and
sym != nil and sym.kind == skLet and isOutParam:
discard "allow let varaibles to be passed to out parameters"
else:
Expand Down Expand Up @@ -2050,7 +2050,8 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
let root = getRoot(a)
let useStrictDefLet = root != nil and root.kind == skLet and
assignable == arAddressableConst and
strictDefs in c.features and isLocalSym(root)
noStrictDefs notin c.config.legacyFeatures and
isLocalSym(root)
if le == nil:
localError(c.config, a.info, "expression has no type")
elif (skipTypes(le, {tyGenericInst, tyAlias, tySink}).kind notin {tyVar} and
Expand Down
6 changes: 3 additions & 3 deletions compiler/sempass2.nim
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ proc initVar(a: PEffects, n: PNode; volatileCheck: bool) =
if volatileCheck: makeVolatile(a, s)
for x in a.init:
if x == s.id:
if strictDefs in a.c.features and s.kind == skLet:
if noStrictDefs notin a.c.config.legacyFeatures and s.kind == skLet:
localError(a.config, n.info, errXCannotBeAssignedTo %
renderTree(n, {renderNoComments}
))
Expand Down Expand Up @@ -378,7 +378,7 @@ proc useVar(a: PEffects, n: PNode) =
if s.typ.requiresInit:
message(a.config, n.info, warnProveInit, s.name.s)
elif a.leftPartOfAsgn <= 0:
if strictDefs in a.c.features:
if noStrictDefs notin a.c.config.legacyFeatures:
if s.kind == skLet:
localError(a.config, n.info, errLetNeedsInit)
else:
Expand Down Expand Up @@ -1658,7 +1658,7 @@ proc trackProc*(c: PContext; s: PSym, body: PNode) =

if not isEmptyType(s.typ.returnType) and
(s.typ.returnType.requiresInit or s.typ.returnType.skipTypes(abstractInst).kind == tyVar or
strictDefs in c.features) and
noStrictDefs notin c.config.legacyFeatures) and
s.kind in {skProc, skFunc, skConverter, skMethod} and s.magic == mNone:
var res = s.ast[resultPos].sym # get result symbol
if res.id notin t.init and breaksBlock(body) != bsNoReturn:
Expand Down
2 changes: 1 addition & 1 deletion compiler/semstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
else:
checkNilable(c, v)
# allow let to not be initialised if imported from C:
if v.kind == skLet and sfImportc notin v.flags and (strictDefs notin c.features or not isLocalSym(v)):
if v.kind == skLet and sfImportc notin v.flags and (noStrictDefs in c.config.legacyFeatures or not isLocalSym(v)):
localError(c.config, a.info, errLetNeedsInit)
if sfCompileTime in v.flags:
var x = newNodeI(result.kind, v.info)
Expand Down
2 changes: 1 addition & 1 deletion compiler/sigmatch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2290,7 +2290,7 @@ proc isLValue(c: PContext; n: PNode, isOutParam = false): bool {.inline.} =
result = c.inUncheckedAssignSection > 0
of arAddressableConst:
let sym = getRoot(n)
result = strictDefs in c.features and sym != nil and sym.kind == skLet and isOutParam
result = noStrictDefs notin c.config.legacyFeatures and sym != nil and sym.kind == skLet and isOutParam
else:
result = false

Expand Down
1 change: 1 addition & 0 deletions config/config.nims
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ when defined(nimStrictMode):
# future work: XDeclaredButNotUsed

switch("define", "nimVersion:" & NimVersion) # deadcode
switch("experimental", "strictDefs")
13 changes: 7 additions & 6 deletions lib/impure/nre.nim
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ else:
`=destroy`(pattern.captureNameToId)

proc getinfo[T](pattern: Regex, opt: cint): T =
result = default(T)
let retcode = pcre.fullinfo(pattern.pcreObj, pattern.pcreExtra, opt, addr result)

if retcode < 0:
Expand Down Expand Up @@ -275,8 +276,8 @@ proc initRegex(pattern: string, flags: int, study = true): Regex =
new(result, destroyRegex)
result.pattern = pattern

var errorMsg: cstring
var errOffset: cint
var errorMsg: cstring = ""
var errOffset: cint = 0

result.pcreObj = pcre.compile(cstring(pattern),
# better hope int is at least 4 bytes..
Expand All @@ -288,7 +289,7 @@ proc initRegex(pattern: string, flags: int, study = true): Regex =

if study:
var options: cint = 0
var hasJit: cint
var hasJit: cint = cint(0)
if pcre.config(pcre.CONFIG_JIT, addr hasJit) == 0:
if hasJit == 1'i32:
options = pcre.STUDY_JIT_COMPILE
Expand All @@ -313,7 +314,7 @@ proc matchesCrLf(pattern: Regex): bool =
return true

# get flags from build config
var confFlags: cint
var confFlags: cint = cint(0)
if pcre.config(pcre.CONFIG_NEWLINE, addr confFlags) != 0:
assert(false, "CONFIG_NEWLINE apparently got screwed up")

Expand Down Expand Up @@ -573,7 +574,7 @@ iterator findIter*(str: string, pattern: Regex, start = 0, endpos = int.high): R
pcre.UTF8) > 0u32
let strlen = if endpos == int.high: str.len else: endpos+1
var offset = start
var match: Option[RegexMatch]
var match: Option[RegexMatch] = default(Option[RegexMatch])
var neverMatched = true

while true:
Expand Down Expand Up @@ -762,7 +763,7 @@ proc escapeRe*(str: string): string {.gcsafe.} =
const SpecialCharMatcher = {'\\', '+', '*', '?', '[', '^', ']', '$', '(',
')', '{', '}', '=', '!', '<', '>', '|', ':',
'-'}

result = ""
for c in items(str):
case c
of SpecialCharMatcher:
Expand Down
2 changes: 1 addition & 1 deletion lib/impure/re.nim
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ template `=~` *(s: string, pattern: Regex): untyped =
doAssert parse(" # comment ... ") == """("# comment ... ",)"""
bind MaxSubpatterns
when not declaredInScope(matches):
var matches {.inject.}: array[MaxSubpatterns, string]
var matches {.inject.}: array[MaxSubpatterns, string] = default(array[MaxSubpatterns, string])
match(s, pattern, matches)

# ------------------------- more string handling ------------------------------
Expand Down
1 change: 1 addition & 0 deletions lib/pure/algorithm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ proc reversed*[T](a: openArray[T]): seq[T] {.inline.} =
runnableExamples:
assert [10, 11, 12].reversed == @[12, 11, 10]
assert seq[string].default.reversed == @[]
result = @[]
let n = a.len
result.setLen(n)
for i in 0..<n: result[i] = a[n - (i + 1)]
Expand Down
4 changes: 2 additions & 2 deletions lib/pure/asyncmacro.nim
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,9 @@ proc asyncSingleProc(prc: NimNode): NimNode =
procBody.insert(0): quote do:
{.push warning[resultshadowed]: off.}
when `subRetType` isnot void:
var `resultIdent`: `subRetType`
var `resultIdent`: `subRetType` = default(`subRetType`)
else:
var `resultIdent`: Future[void]
var `resultIdent`: Future[void] = nil
{.pop.}

var `needsCompletionSym` = false
Expand Down
2 changes: 2 additions & 0 deletions lib/pure/base64.nim
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,12 @@ proc encode*[T: byte|char](s: openArray[T], safe = false): string =
assert encode(['n', 'i', 'm']) == "bmlt"
assert encode(@['n', 'i', 'm']) == "bmlt"
assert encode([1'u8, 2, 3, 4, 5]) == "AQIDBAU="
result = ""
encodeImpl()

proc encode*[T: SomeInteger and not byte](s: openArray[T], safe = false): string
{.deprecated: "use `byte` or `char` instead".} =
result = ""
encodeImpl()

proc encodeMime*(s: string, lineLen = 75.Positive, newLine = "\r\n",
Expand Down
4 changes: 3 additions & 1 deletion lib/pure/collections/critbits.nim
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func len*[T](c: CritBitTree[T]): int {.inline.} =
result = c.count

proc rawGet[T](c: CritBitTree[T], key: string): Node[T] =
result = nil
var it = c.root
while it != nil:
if not it.isLeaf:
Expand Down Expand Up @@ -145,7 +146,7 @@ func exclImpl[T](c: var CritBitTree[T], key: string): int =
var whereq: ptr Node[T] = nil
if p == nil: return c.count
var dir = 0
var q: Node[T]
var q: Node[T] = nil
while not p.isLeaf:
whereq = wherep
q = p
Expand Down Expand Up @@ -394,6 +395,7 @@ iterator mpairs*[T](c: var CritBitTree[T]): tuple[key: string, val: var T] =
for x in leaves(c.root): yield (x.key, x.val)

proc allprefixedAux[T](c: CritBitTree[T], key: string): Node[T] =
result = nil
var p = c.root
var top = p
if p != nil:
Expand Down
3 changes: 2 additions & 1 deletion lib/pure/collections/deques.nim
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ proc initDeque*[T](initialSize: int = defaultInitialSize): Deque[T] =
##
## **See also:**
## * `toDeque proc <#toDeque,openArray[T]>`_
result = Deque[T]()
result.initImpl(initialSize)

func len*[T](deq: Deque[T]): int {.inline.} =
Expand Down Expand Up @@ -297,7 +298,7 @@ proc toDeque*[T](x: openArray[T]): Deque[T] {.since: (1, 3).} =
let a = toDeque([7, 8, 9])
assert len(a) == 3
assert $a == "[7, 8, 9]"

result = Deque[T]()
result.initImpl(x.len)
for item in items(x):
result.addLast(item)
Expand Down
2 changes: 1 addition & 1 deletion lib/pure/collections/heapqueue.nim
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ proc toHeapQueue*[T](x: openArray[T]): HeapQueue[T] {.since: (1, 3).} =
assert heap[0] == 8

# see https://en.wikipedia.org/wiki/Binary_heap#Building_a_heap
result.data = @x
result = HeapQueue[T](data: @x)
for i in countdown(x.len div 2 - 1, 0):
siftdown(result, i)

Expand Down
12 changes: 8 additions & 4 deletions lib/pure/collections/lists.nim
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ proc initSinglyLinkedList*[T](): SinglyLinkedList[T] =
runnableExamples:
let a = initSinglyLinkedList[int]()

discard
result = default(SinglyLinkedList[T])

proc initDoublyLinkedList*[T](): DoublyLinkedList[T] =
## Creates a new doubly linked list that is empty.
Expand All @@ -125,7 +125,7 @@ proc initDoublyLinkedList*[T](): DoublyLinkedList[T] =
runnableExamples:
let a = initDoublyLinkedList[int]()

discard
result = default(DoublyLinkedList[T])

proc initSinglyLinkedRing*[T](): SinglyLinkedRing[T] =
## Creates a new singly linked ring that is empty.
Expand All @@ -135,7 +135,7 @@ proc initSinglyLinkedRing*[T](): SinglyLinkedRing[T] =
runnableExamples:
let a = initSinglyLinkedRing[int]()

discard
result = default(SinglyLinkedRing[T])

proc initDoublyLinkedRing*[T](): DoublyLinkedRing[T] =
## Creates a new doubly linked ring that is empty.
Expand All @@ -145,7 +145,7 @@ proc initDoublyLinkedRing*[T](): DoublyLinkedRing[T] =
runnableExamples:
let a = initDoublyLinkedRing[int]()

discard
result = default(DoublyLinkedRing[T])

proc newDoublyLinkedNode*[T](value: T): DoublyLinkedNode[T] =
## Creates a new doubly linked node with the given `value`.
Expand Down Expand Up @@ -319,6 +319,10 @@ proc find*[T](L: SomeLinkedCollection[T], value: T): SomeLinkedNode[T] =
let a = [9, 8].toSinglyLinkedList
assert a.find(9).value == 9
assert a.find(1) == nil
when typeof(nodes(L)) is SinglyLinkedNode[T]:
result = SinglyLinkedNode[T](nil)
else:
result = DoublyLinkedNode[T](nil)

for x in nodes(L):
if x.value == value: return x
Expand Down
6 changes: 3 additions & 3 deletions lib/pure/collections/sequtils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func count*[T](s: openArray[T], x: T): int =
assert count(a, 2) == 4
assert count(a, 99) == 0
assert count(b, 'r') == 2

result = 0
for itm in items(s):
if itm == x:
inc result
Expand Down Expand Up @@ -244,7 +244,7 @@ func minIndex*[T](s: openArray[T]): int {.since: (1, 1).} =
assert minIndex(b) == 3
assert minIndex(c) == 1
assert minIndex(d) == 2

result = 0
for i in 1..high(s):
if s[i] < s[result]: result = i

Expand All @@ -261,7 +261,7 @@ func maxIndex*[T](s: openArray[T]): int {.since: (1, 1).} =
assert maxIndex(b) == 0
assert maxIndex(c) == 2
assert maxIndex(d) == 0

result = 0
for i in 1..high(s):
if s[i] > s[result]: result = i

Expand Down
2 changes: 1 addition & 1 deletion lib/pure/collections/setimpl.nim
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ proc enlarge[A](s: var HashSet[A]) =
template inclImpl() {.dirty.} =
if s.data.len == 0:
initImpl(s, defaultInitialSize)
var hc: Hash
var hc: Hash = default(Hash)
var index = rawGet(s, key, hc)
if index < 0:
if mustRehash(s):
Expand Down
2 changes: 1 addition & 1 deletion lib/pure/collections/sets.nim
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ proc initOrderedSet*[A](initialSize = defaultInitialSize): OrderedSet[A] =
var a = initOrderedSet[int]()
a.incl(3)
assert len(a) == 1

result = OrderedSet[A]()
result.init(initialSize)

proc toOrderedSet*[A](keys: openArray[A]): OrderedSet[A] =
Expand Down
15 changes: 9 additions & 6 deletions lib/pure/collections/sharedtables.nim
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,15 @@ template withValue*[A, B](t: var SharedTable[A, B], key: A,
proc mget*[A, B](t: var SharedTable[A, B], key: A): var B =
## Retrieves the value at `t[key]`. The value can be modified.
## If `key` is not in `t`, the `KeyError` exception is raised.
withLock t:
var hc: Hash
var index = rawGet(t, key, hc)
let hasKey = index >= 0
if hasKey: result = t.data[index].val
if not hasKey:
acquire(t.lock)
var hc: Hash = Hash(0)
var index = rawGet(t, key, hc)
let hasKey = index >= 0
if hasKey:
result = t.data[index].val
release(t.lock)
else:
release(t.lock)
when compiles($key):
raise newException(KeyError, "key not found: " & $key)
else:
Expand Down
Loading

0 comments on commit 2df6331

Please sign in to comment.