mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-18 21:40:32 +00:00
@@ -891,6 +891,9 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
|
||||
processOnOffSwitchG(conf, {optProfileVM}, arg, pass, info)
|
||||
of "sinkinference":
|
||||
processOnOffSwitch(conf, {optSinkInference}, arg, pass, info)
|
||||
of "cursorinference":
|
||||
# undocumented, for debugging purposes only:
|
||||
processOnOffSwitch(conf, {optCursorInference}, arg, pass, info)
|
||||
of "panics":
|
||||
processOnOffSwitchG(conf, {optPanics}, arg, pass, info)
|
||||
if optPanics in conf.globalOptions:
|
||||
|
||||
@@ -1006,7 +1006,8 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
|
||||
echoCfg(c.g)
|
||||
echo n
|
||||
|
||||
computeCursors(owner, n, g.config)
|
||||
if optCursorInference in g.config.options:
|
||||
computeCursors(owner, n, g.config)
|
||||
|
||||
var scope: Scope
|
||||
let body = p(n, c, scope, normal)
|
||||
|
||||
@@ -41,6 +41,7 @@ type # please make sure we have under 32 options
|
||||
optMemTracker,
|
||||
optNilSeqs,
|
||||
optSinkInference # 'sink T' inference
|
||||
optCursorInference
|
||||
|
||||
|
||||
TOptions* = set[TOption]
|
||||
@@ -372,7 +373,7 @@ const
|
||||
DefaultOptions* = {optObjCheck, optFieldCheck, optRangeCheck,
|
||||
optBoundsCheck, optOverflowCheck, optAssert, optWarns, optRefCheck,
|
||||
optHints, optStackTrace, optLineTrace, # consider adding `optStackTraceMsgs`
|
||||
optTrMacros, optStyleCheck}
|
||||
optTrMacros, optStyleCheck, optCursorInference}
|
||||
DefaultGlobalOptions* = {optThreadAnalysis,
|
||||
optExcessiveStackTrace, optListFullPaths}
|
||||
|
||||
|
||||
@@ -392,9 +392,18 @@ proc deps(c: var Partitions; dest, src: PNode) =
|
||||
analyseAsgn(c, c.s[vid], src)
|
||||
# do not borrow from a different local variable, this is easier
|
||||
# than tracking reassignments, consider 'var cursor = local; local = newNode()'
|
||||
if src.kind == nkSym and (src.sym.kind in {skVar, skResult, skTemp} or
|
||||
if src.kind == nkSym:
|
||||
if (src.sym.kind in {skVar, skResult, skTemp} or
|
||||
(src.sym.kind in {skLet, skParam, skForVar} and hasDisabledAsgn(src.sym.typ))):
|
||||
c.s[vid].flags.incl preventCursor
|
||||
c.s[vid].flags.incl preventCursor
|
||||
elif src.sym.kind in {skVar, skResult, skTemp, skLet, skForVar}:
|
||||
# XXX: we need to compute variable alive ranges before doing anything else:
|
||||
let srcid = variableId(c, src.sym)
|
||||
if srcid >= 0 and preventCursor in c.s[srcid].flags:
|
||||
# you cannot borrow from a local that lives shorter than 'vid':
|
||||
if c.s[srcid].aliveStart > c.s[vid].aliveStart or
|
||||
c.s[srcid].aliveEnd < c.s[vid].aliveEnd:
|
||||
c.s[vid].flags.incl preventCursor
|
||||
|
||||
if src.kind == nkSym and hasDestructor(src.typ):
|
||||
rhsIsSink(c, src)
|
||||
|
||||
126
tests/arc/tcursor_on_localvar.nim
Normal file
126
tests/arc/tcursor_on_localvar.nim
Normal file
@@ -0,0 +1,126 @@
|
||||
discard """
|
||||
output: '''Section: common
|
||||
Param: Floats1
|
||||
Section: local
|
||||
Param: Str
|
||||
Param: Bool
|
||||
Param: Floats2'''
|
||||
cmd: '''nim c --gc:arc $file'''
|
||||
"""
|
||||
|
||||
# bug #15325
|
||||
|
||||
import tables
|
||||
import strutils
|
||||
|
||||
const defaultSection = "***"
|
||||
|
||||
type
|
||||
Config* = ref object
|
||||
table: OrderedTableRef[string, OrderedTable[string, string]]
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
proc newConfig*(): Config =
|
||||
result = new(Config)
|
||||
result.table = newOrderedTable[string, OrderedTable[string, string]]()
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
proc add*(self: Config, param, value, section: string) {.nosinks.} =
|
||||
let s = if section == "": defaultSection else: section
|
||||
|
||||
if not self.table.contains(s):
|
||||
self.table[s] = initOrderedTable[string, string]()
|
||||
|
||||
self.table[s][param] = value
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
proc sections*(self: Config): seq[string] =
|
||||
for i in self.table.keys:
|
||||
let s = if i == defaultSection: "" else: i
|
||||
result.add(s)
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
proc params*(self: Config, section: string): seq[string] =
|
||||
let s = if section == "": defaultSection else: section
|
||||
|
||||
if self.table.contains(s):
|
||||
for i in self.table[s].keys:
|
||||
result.add(i)
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
proc extract*(str, start, finish: string): string =
|
||||
let startPos = str.find(start)
|
||||
|
||||
if startPos < 0:
|
||||
return ""
|
||||
|
||||
let endPos = str.find(finish, startPos)
|
||||
|
||||
if endPos < 0:
|
||||
return ""
|
||||
|
||||
return str[startPos + start.len() ..< endPos]
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
proc loadString*(self: Config, text: string): tuple[valid: bool, errorInLine: int] {.discardable.} =
|
||||
self.table.clear()
|
||||
|
||||
var data = ""
|
||||
|
||||
data = text
|
||||
|
||||
var
|
||||
actualSection = ""
|
||||
lineCount = 0
|
||||
|
||||
for i in splitLines(data):
|
||||
lineCount += 1
|
||||
|
||||
var line = strip(i)
|
||||
|
||||
if line.len() == 0:
|
||||
continue
|
||||
|
||||
if line[0] == '#' or line[0] == ';':
|
||||
continue
|
||||
|
||||
if line[0] == '[':
|
||||
let section = strip(extract(line, "[", "]"))
|
||||
|
||||
if section.len() != 0:
|
||||
actualSection = section
|
||||
else:
|
||||
self.table.clear()
|
||||
return (false, lineCount)
|
||||
else:
|
||||
let equal = find(line, '=')
|
||||
|
||||
if equal <= 0:
|
||||
self.table.clear()
|
||||
return (false, lineCount)
|
||||
else:
|
||||
let
|
||||
param = strip(line[0 .. equal - 1])
|
||||
value = strip(line[equal + 1 .. ^1])
|
||||
|
||||
if param.len() == 0:
|
||||
self.table.clear()
|
||||
return (false, lineCount)
|
||||
else:
|
||||
self.add(param, value, actualSection)
|
||||
|
||||
return (true, 0)
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------
|
||||
when isMainModule:
|
||||
var cfg = newConfig()
|
||||
|
||||
cfg.loadString("[common]\nFloats1 = 1,2,3\n[local]\nStr = \"String...\"\nBool = true\nFloats2 = 4, 5, 6\n")
|
||||
|
||||
for s in cfg.sections():
|
||||
echo "Section: " & s
|
||||
|
||||
for p in cfg.params(s):
|
||||
echo " Param: " & p
|
||||
|
||||
|
||||
Reference in New Issue
Block a user