Change styleCheck to ignore foreign packages (#19822)

* Change `styleCheck` to ignore foreign packages

* Symbols from foreign packages are now ignored.
* Fixed `styleCheck` violations in `compiler` package.
* Added symbol ownership to custom annotation pragmas.
* Minor refactors to cleanup style check callsites.
* Minor internal documentation of reasons why a symbol isn't checked.

Style violations were fixed in the compiler after thet were exposed by
the changes. The compiler wouldn't compile otherwise.

Symbol ownership for custom pragma annotations is needed for checking
the annotation's style. A NPE was raised otherwise.

Fixes #10201
See also nim-lang/RFCs#456

* Fix a misunderstanding about excluding field style checks

I had refactored the callsites of `styleCheckUse` to apply the DRY
principle, but I misunderstood the field access handling in a template
as a general case. This corrects it.

* Fix some `styleCheck` violations in `compiler/evalffi`

The violations were exposed in CI when the compiler was built with
libffi.

* Removed some uneeded transitionary code

* Add changelog entry

Co-authored-by: quantimnot <quantimnot@users.noreply.github.com>
This commit is contained in:
quantimnot 2022-07-14 08:20:40 -04:00 • committed by GitHub
commit 800cb006e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 118 additions and 106 deletions

View file

@ -114,6 +114,8 @@ becomes an alias for `addr`.
- `nim` can now compile version 1.4.0 as follows: `nim c --lib:lib --stylecheck:off compiler/nim`, - `nim` can now compile version 1.4.0 as follows: `nim c --lib:lib --stylecheck:off compiler/nim`,
without requiring `-d:nimVersion140` which is now a noop. without requiring `-d:nimVersion140` which is now a noop.
- `--styleCheck` now only applies to the current package.
## Tool changes ## Tool changes

View file

@ -110,8 +110,8 @@ proc mapCallConv(conf: ConfigRef, cc: TCallingConvention, info: TLineInfo): TABI
else: else:
globalError(conf, info, "cannot map calling convention to FFI") globalError(conf, info, "cannot map calling convention to FFI")
template rd(T, p: untyped): untyped = (cast[ptr T](p))[] template rd(typ, p: untyped): untyped = (cast[ptr typ](p))[]
template wr(T, p, v: untyped): untyped = (cast[ptr T](p))[] = v template wr(typ, p, v: untyped): untyped = (cast[ptr typ](p))[] = v
template `+!`(x, y: untyped): untyped = template `+!`(x, y: untyped): untyped =
cast[pointer](cast[ByteAddress](x) + y) cast[pointer](cast[ByteAddress](x) + y)
@ -177,8 +177,8 @@ const maxPackDepth = 20
var packRecCheck = 0 var packRecCheck = 0
proc pack(conf: ConfigRef, v: PNode, typ: PType, res: pointer) = proc pack(conf: ConfigRef, v: PNode, typ: PType, res: pointer) =
template awr(T, v: untyped): untyped = template awr(typ, v: untyped): untyped =
wr(T, res, v) wr(typ, res, v)
case typ.kind case typ.kind
of tyBool: awr(bool, v.intVal != 0) of tyBool: awr(bool, v.intVal != 0)

View file

@ -93,13 +93,13 @@ proc getOrIncl*[T](t: var BiTable[T]; v: T): LitId =
t.vals.add v t.vals.add v
proc `[]`*[T](t: var BiTable[T]; LitId: LitId): var T {.inline.} = proc `[]`*[T](t: var BiTable[T]; litId: LitId): var T {.inline.} =
let idx = idToIdx LitId let idx = idToIdx litId
assert idx < t.vals.len assert idx < t.vals.len
result = t.vals[idx] result = t.vals[idx]
proc `[]`*[T](t: BiTable[T]; LitId: LitId): lent T {.inline.} = proc `[]`*[T](t: BiTable[T]; litId: LitId): lent T {.inline.} =
let idx = idToIdx LitId let idx = idToIdx litId
assert idx < t.vals.len assert idx < t.vals.len
result = t.vals[idx] result = t.vals[idx]

View file

@ -12,7 +12,8 @@
import std/strutils import std/strutils
from std/sugar import dup from std/sugar import dup
import options, ast, msgs, idents, lineinfos, wordrecg, astmsgs import options, ast, msgs, idents, lineinfos, wordrecg, astmsgs, semdata, packages
export packages
const const
Letters* = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'} Letters* = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'}
@ -85,24 +86,32 @@ proc differ*(line: string, a, b: int, x: string): string =
result = y result = y
proc nep1CheckDefImpl(conf: ConfigRef; info: TLineInfo; s: PSym; k: TSymKind) = proc nep1CheckDefImpl(conf: ConfigRef; info: TLineInfo; s: PSym; k: TSymKind) =
# operators stay as they are:
if k in {skResult, skTemp} or s.name.s[0] notin Letters: return
if k in {skType, skGenericParam} and sfAnon in s.flags: return
if s.typ != nil and s.typ.kind == tyTypeDesc: return
if {sfImportc, sfExportc} * s.flags != {}: return
if optStyleCheck notin s.options: return
let beau = beautifyName(s.name.s, k) let beau = beautifyName(s.name.s, k)
if s.name.s != beau: if s.name.s != beau:
lintReport(conf, info, beau, s.name.s) lintReport(conf, info, beau, s.name.s)
template styleCheckDef*(conf: ConfigRef; info: TLineInfo; s: PSym; k: TSymKind) = template styleCheckDef*(ctx: PContext; info: TLineInfo; sym: PSym; k: TSymKind) =
if {optStyleHint, optStyleError} * conf.globalOptions != {} and optStyleUsages notin conf.globalOptions: ## Check symbol definitions adhere to NEP1 style rules.
nep1CheckDefImpl(conf, info, s, k) if optStyleCheck in ctx.config.options and # ignore if styleChecks are off
hintName in ctx.config.notes and # ignore if name checks are not requested
ctx.config.belongsToProjectPackage(ctx.module) and # ignore foreign packages
optStyleUsages notin ctx.config.globalOptions and # ignore if requested to only check name usage
sym.kind != skResult and # ignore `result`
sym.kind != skTemp and # ignore temporary variables created by the compiler
sym.name.s[0] in Letters and # ignore operators TODO: what about unicode symbols???
k notin {skType, skGenericParam} and # ignore types and generic params
(sym.typ == nil or sym.typ.kind != tyTypeDesc) and # ignore `typedesc`
{sfImportc, sfExportc} * sym.flags == {} and # ignore FFI
sfAnon notin sym.flags: # ignore if created by compiler
nep1CheckDefImpl(ctx.config, info, sym, k)
template styleCheckDef*(conf: ConfigRef; info: TLineInfo; s: PSym) = template styleCheckDef*(ctx: PContext; info: TLineInfo; s: PSym) =
styleCheckDef(conf, info, s, s.kind) ## Check symbol definitions adhere to NEP1 style rules.
template styleCheckDef*(conf: ConfigRef; s: PSym) = styleCheckDef(ctx, info, s, s.kind)
styleCheckDef(conf, s.info, s, s.kind)
template styleCheckDef*(ctx: PContext; s: PSym) =
## Check symbol definitions adhere to NEP1 style rules.
styleCheckDef(ctx, s.info, s, s.kind)
proc differs(conf: ConfigRef; info: TLineInfo; newName: string): string = proc differs(conf: ConfigRef; info: TLineInfo; newName: string): string =
let line = sourceLine(conf, info) let line = sourceLine(conf, info)
@ -116,23 +125,27 @@ proc differs(conf: ConfigRef; info: TLineInfo; newName: string): string =
let last = first+identLen(line, first)-1 let last = first+identLen(line, first)-1
result = differ(line, first, last, newName) result = differ(line, first, last, newName)
proc styleCheckUse*(conf: ConfigRef; info: TLineInfo; s: PSym) = proc styleCheckUseImpl(conf: ConfigRef; info: TLineInfo; s: PSym) =
if info.fileIndex.int < 0: return
# we simply convert it to what it looks like in the definition
# for consistency
# operators stay as they are:
if s.kind == skTemp or s.name.s[0] notin Letters or sfAnon in s.flags:
return
let newName = s.name.s let newName = s.name.s
let badName = differs(conf, info, newName) let badName = differs(conf, info, newName)
if badName.len > 0: if badName.len > 0:
# special rules for historical reasons lintReport(conf, info, newName, badName, "".dup(addDeclaredLoc(conf, s)))
let forceHint = badName == "nnkArgList" and newName == "nnkArglist" or badName == "nnkArglist" and newName == "nnkArgList"
lintReport(conf, info, newName, badName, forceHint = forceHint, extraMsg = "".dup(addDeclaredLoc(conf, s)))
proc checkPragmaUse*(conf: ConfigRef; info: TLineInfo; w: TSpecialWord; pragmaName: string) = template styleCheckUse*(ctx: PContext; info: TLineInfo; sym: PSym) =
## Check symbol uses match their definition's style.
if {optStyleHint, optStyleError} * ctx.config.globalOptions != {} and # ignore if styleChecks are off
hintName in ctx.config.notes and # ignore if name checks are not requested
ctx.config.belongsToProjectPackage(ctx.module) and # ignore foreign packages
sym.kind != skTemp and # ignore temporary variables created by the compiler
sym.name.s[0] in Letters and # ignore operators TODO: what about unicode symbols???
sfAnon notin sym.flags: # ignore temporary variables created by the compiler
styleCheckUseImpl(ctx.config, info, sym)
proc checkPragmaUseImpl(conf: ConfigRef; info: TLineInfo; w: TSpecialWord; pragmaName: string) =
let wanted = $w let wanted = $w
if pragmaName != wanted: if pragmaName != wanted:
lintReport(conf, info, wanted, pragmaName) lintReport(conf, info, wanted, pragmaName)
template checkPragmaUse*(conf: ConfigRef; info: TLineInfo; w: TSpecialWord; pragmaName: string) =
if {optStyleHint, optStyleError} * conf.globalOptions != {}:
checkPragmaUseImpl(conf, info, w, pragmaName)

View file

@ -622,9 +622,9 @@ template internalAssert*(conf: ConfigRef, e: bool) =
let arg = info2.toFileLineCol let arg = info2.toFileLineCol
internalErrorImpl(conf, unknownLineInfo, arg, info2) internalErrorImpl(conf, unknownLineInfo, arg, info2)
template lintReport*(conf: ConfigRef; info: TLineInfo, beau, got: string, forceHint = false, extraMsg = "") = template lintReport*(conf: ConfigRef; info: TLineInfo, beau, got: string, extraMsg = "") =
let m = "'$1' should be: '$2'$3" % [got, beau, extraMsg] let m = "'$1' should be: '$2'$3" % [got, beau, extraMsg]
let msg = if optStyleError in conf.globalOptions and not forceHint: errGenerated else: hintName let msg = if optStyleError in conf.globalOptions: errGenerated else: hintName
liMessage(conf, info, msg, m, doNothing, instLoc()) liMessage(conf, info, msg, m, doNothing, instLoc())
proc quotedFilename*(conf: ConfigRef; i: TLineInfo): Rope = proc quotedFilename*(conf: ConfigRef; i: TLineInfo): Rope =

View file

@ -829,8 +829,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
let ident = considerQuotedIdent(c, key) let ident = considerQuotedIdent(c, key)
var userPragma = strTableGet(c.userPragmas, ident) var userPragma = strTableGet(c.userPragmas, ident)
if userPragma != nil: if userPragma != nil:
if {optStyleHint, optStyleError} * c.config.globalOptions != {}: styleCheckUse(c, key.info, userPragma)
styleCheckUse(c.config, key.info, userPragma)
# number of pragmas increase/decrease with user pragma expansion # number of pragmas increase/decrease with user pragma expansion
inc c.instCounter inc c.instCounter
@ -844,8 +843,7 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
else: else:
let k = whichKeyword(ident) let k = whichKeyword(ident)
if k in validPragmas: if k in validPragmas:
if {optStyleHint, optStyleError} * c.config.globalOptions != {}: checkPragmaUse(c.config, key.info, k, ident.s)
checkPragmaUse(c.config, key.info, k, ident.s)
case k case k
of wExportc, wExportCpp: of wExportc, wExportCpp:
makeExternExport(c, sym, getOptionalStr(c, it, "$1"), it.info) makeExternExport(c, sym, getOptionalStr(c, it, "$1"), it.info)

View file

@ -2599,7 +2599,7 @@ proc semBlock(c: PContext, n: PNode; flags: TExprFlags): PNode =
labl.owner = c.p.owner labl.owner = c.p.owner
n[0] = newSymNode(labl, n[0].info) n[0] = newSymNode(labl, n[0].info)
suggestSym(c.graph, n[0].info, labl, c.graph.usageSym) suggestSym(c.graph, n[0].info, labl, c.graph.usageSym)
styleCheckDef(c.config, labl) styleCheckDef(c, labl)
onDef(n[0].info, labl) onDef(n[0].info, labl)
n[1] = semExpr(c, n[1], flags) n[1] = semExpr(c, n[1], flags)
n.typ = n[1].typ n.typ = n[1].typ

View file

@ -179,7 +179,7 @@ proc fuzzyLookup(c: PContext, n: PNode, flags: TSemGenericFlags,
proc addTempDecl(c: PContext; n: PNode; kind: TSymKind) = proc addTempDecl(c: PContext; n: PNode; kind: TSymKind) =
let s = newSymS(skUnknown, getIdentNode(c, n), c) let s = newSymS(skUnknown, getIdentNode(c, n), c)
addPrelimDecl(c, s) addPrelimDecl(c, s)
styleCheckDef(c.config, n.info, s, kind) styleCheckDef(c, n.info, s, kind)
onDef(n.info, s) onDef(n.info, s)
proc semGenericStmt(c: PContext, n: PNode, proc semGenericStmt(c: PContext, n: PNode,

View file

@ -428,7 +428,7 @@ proc semQuantifier(c: PContext; n: PNode): PNode =
let op = considerQuotedIdent(c, it[0]) let op = considerQuotedIdent(c, it[0])
if op.id == ord(wIn): if op.id == ord(wIn):
let v = newSymS(skForVar, it[1], c) let v = newSymS(skForVar, it[1], c)
styleCheckDef(c.config, v) styleCheckDef(c, v)
onDef(it[1].info, v) onDef(it[1].info, v)
let domain = semExprWithType(c, it[2], {efWantIterator}) let domain = semExprWithType(c, it[2], {efWantIterator})
v.typ = domain.typ v.typ = domain.typ

View file

@ -375,7 +375,7 @@ proc semUsing(c: PContext; n: PNode): PNode =
let typ = semTypeNode(c, a[^2], nil) let typ = semTypeNode(c, a[^2], nil)
for j in 0..<a.len-2: for j in 0..<a.len-2:
let v = semIdentDef(c, a[j], skParam) let v = semIdentDef(c, a[j], skParam)
styleCheckDef(c.config, v) styleCheckDef(c, v)
onDef(a[j].info, v) onDef(a[j].info, v)
v.typ = typ v.typ = typ
strTableIncl(c.signatures, v) strTableIncl(c.signatures, v)
@ -664,7 +664,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
addToVarSection(c, result, n, a) addToVarSection(c, result, n, a)
continue continue
var v = semIdentDef(c, a[j], symkind, false) var v = semIdentDef(c, a[j], symkind, false)
styleCheckDef(c.config, v) styleCheckDef(c, v)
onDef(a[j].info, v) onDef(a[j].info, v)
if sfGenSym notin v.flags: if sfGenSym notin v.flags:
if not isDiscardUnderscore(v): addInterfaceDecl(c, v) if not isDiscardUnderscore(v): addInterfaceDecl(c, v)
@ -794,7 +794,7 @@ proc semConst(c: PContext, n: PNode): PNode =
var v = semIdentDef(c, a[j], skConst) var v = semIdentDef(c, a[j], skConst)
if sfGenSym notin v.flags: addInterfaceDecl(c, v) if sfGenSym notin v.flags: addInterfaceDecl(c, v)
elif v.owner == nil: v.owner = getCurrOwner(c) elif v.owner == nil: v.owner = getCurrOwner(c)
styleCheckDef(c.config, v) styleCheckDef(c, v)
onDef(a[j].info, v) onDef(a[j].info, v)
if a.kind != nkVarTuple: if a.kind != nkVarTuple:
@ -819,7 +819,7 @@ include semfields
proc symForVar(c: PContext, n: PNode): PSym = proc symForVar(c: PContext, n: PNode): PSym =
let m = if n.kind == nkPragmaExpr: n[0] else: n let m = if n.kind == nkPragmaExpr: n[0] else: n
result = newSymG(skForVar, m, c) result = newSymG(skForVar, m, c)
styleCheckDef(c.config, result) styleCheckDef(c, result)
onDef(n.info, result) onDef(n.info, result)
if n.kind == nkPragmaExpr: if n.kind == nkPragmaExpr:
pragma(c, result, n[1], forVarPragmas) pragma(c, result, n[1], forVarPragmas)
@ -1445,7 +1445,7 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
let name = typeSectionTypeName(c, a[0]) let name = typeSectionTypeName(c, a[0])
var s = name.sym var s = name.sym
# check the style here after the pragmas have been processed: # check the style here after the pragmas have been processed:
styleCheckDef(c.config, s) styleCheckDef(c, s)
# compute the type's size and check for illegal recursions: # compute the type's size and check for illegal recursions:
if a[1].kind == nkEmpty: if a[1].kind == nkEmpty:
var x = a[2] var x = a[2]
@ -2043,7 +2043,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
("'" & proto.name.s & "' from " & c.config$proto.info & ("'" & proto.name.s & "' from " & c.config$proto.info &
" '" & s.name.s & "' from " & c.config$s.info)) " '" & s.name.s & "' from " & c.config$s.info))
styleCheckDef(c.config, s) styleCheckDef(c, s)
if hasProto: if hasProto:
onDefResolveForward(n[namePos].info, proto) onDefResolveForward(n[namePos].info, proto)
else: else:
@ -2120,7 +2120,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
trackProc(c, s, s.ast[bodyPos]) trackProc(c, s, s.ast[bodyPos])
else: else:
if (s.typ[0] != nil and s.kind != skIterator): if (s.typ[0] != nil and s.kind != skIterator):
addDecl(c, newSym(skUnknown, getIdent(c.cache, "result"), nextSymId c.idgen, nil, n.info)) addDecl(c, newSym(skUnknown, getIdent(c.cache, "result"), nextSymId c.idgen, s, n.info))
openScope(c) openScope(c)
n[bodyPos] = semGenericStmt(c, n[bodyPos]) n[bodyPos] = semGenericStmt(c, n[bodyPos])

View file

@ -230,7 +230,7 @@ proc addLocalDecl(c: var TemplCtx, n: var PNode, k: TSymKind) =
if n.kind != nkSym: if n.kind != nkSym:
let local = newGenSym(k, ident, c) let local = newGenSym(k, ident, c)
addPrelimDecl(c.c, local) addPrelimDecl(c.c, local)
styleCheckDef(c.c.config, n.info, local) styleCheckDef(c.c, n.info, local)
onDef(n.info, local) onDef(n.info, local)
replaceIdentBySym(c.c, n, newSymNode(local, n.info)) replaceIdentBySym(c.c, n, newSymNode(local, n.info))
if k == skParam and c.inTemplateHeader > 0: if k == skParam and c.inTemplateHeader > 0:
@ -271,8 +271,8 @@ proc semTemplSymbol(c: PContext, n: PNode, s: PSym; isField: bool): PNode =
when defined(nimsuggest): when defined(nimsuggest):
suggestSym(c.graph, n.info, s, c.graph.usageSym, false) suggestSym(c.graph, n.info, s, c.graph.usageSym, false)
# field access (dot expr) will be handled by builtinFieldAccess # field access (dot expr) will be handled by builtinFieldAccess
if not isField and {optStyleHint, optStyleError} * c.config.globalOptions != {}: if not isField:
styleCheckUse(c.config, n.info, s) styleCheckUse(c, n.info, s)
proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode = proc semRoutineInTemplName(c: var TemplCtx, n: PNode): PNode =
result = n result = n
@ -297,7 +297,7 @@ proc semRoutineInTemplBody(c: var TemplCtx, n: PNode, k: TSymKind): PNode =
var s = newGenSym(k, ident, c) var s = newGenSym(k, ident, c)
s.ast = n s.ast = n
addPrelimDecl(c.c, s) addPrelimDecl(c.c, s)
styleCheckDef(c.c.config, n.info, s) styleCheckDef(c.c, n.info, s)
onDef(n.info, s) onDef(n.info, s)
n[namePos] = newSymNode(s, n[namePos].info) n[namePos] = newSymNode(s, n[namePos].info)
else: else:
@ -431,7 +431,7 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
# labels are always 'gensym'ed: # labels are always 'gensym'ed:
let s = newGenSym(skLabel, n[0], c) let s = newGenSym(skLabel, n[0], c)
addPrelimDecl(c.c, s) addPrelimDecl(c.c, s)
styleCheckDef(c.c.config, s) styleCheckDef(c.c, s)
onDef(n[0].info, s) onDef(n[0].info, s)
n[0] = newSymNode(s, n[0].info) n[0] = newSymNode(s, n[0].info)
n[1] = semTemplBody(c, n[1]) n[1] = semTemplBody(c, n[1])
@ -624,7 +624,7 @@ proc semTemplateDef(c: PContext, n: PNode): PNode =
s.owner.name.s == "vm" and s.name.s == "stackTrace": s.owner.name.s == "vm" and s.name.s == "stackTrace":
incl(s.flags, sfCallsite) incl(s.flags, sfCallsite)
styleCheckDef(c.config, s) styleCheckDef(c, s)
onDef(n[namePos].info, s) onDef(n[namePos].info, s)
# check parameter list: # check parameter list:
#s.scope = c.currentScope #s.scope = c.currentScope

View file

@ -139,7 +139,7 @@ proc semEnum(c: PContext, n: PNode, prev: PType): PType =
e.flags.incl {sfUsed, sfExported} e.flags.incl {sfUsed, sfExported}
result.n.add symNode result.n.add symNode
styleCheckDef(c.config, e) styleCheckDef(c, e)
onDef(e.info, e) onDef(e.info, e)
if sfGenSym notin e.flags: if sfGenSym notin e.flags:
if not isPure: if not isPure:
@ -476,7 +476,7 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType =
else: else:
result.n.add newSymNode(field) result.n.add newSymNode(field)
addSonSkipIntLit(result, typ, c.idgen) addSonSkipIntLit(result, typ, c.idgen)
styleCheckDef(c.config, a[j].info, field) styleCheckDef(c, a[j].info, field)
onDef(field.info, field) onDef(field.info, field)
if result.n.len == 0: result.n = nil if result.n.len == 0: result.n = nil
if isTupleRecursive(result): if isTupleRecursive(result):
@ -808,7 +808,7 @@ proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int,
localError(c.config, info, "attempt to redefine: '" & f.name.s & "'") localError(c.config, info, "attempt to redefine: '" & f.name.s & "'")
if a.kind == nkEmpty: father.add newSymNode(f) if a.kind == nkEmpty: father.add newSymNode(f)
else: a.add newSymNode(f) else: a.add newSymNode(f)
styleCheckDef(c.config, f) styleCheckDef(c, f)
onDef(f.info, f) onDef(f.info, f)
if a.kind != nkEmpty: father.add a if a.kind != nkEmpty: father.add a
of nkSym: of nkSym:
@ -1315,7 +1315,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
result.n.add newSymNode(arg) result.n.add newSymNode(arg)
rawAddSon(result, finalType) rawAddSon(result, finalType)
addParamOrResult(c, arg, kind) addParamOrResult(c, arg, kind)
styleCheckDef(c.config, a[j].info, arg) styleCheckDef(c, a[j].info, arg)
onDef(a[j].info, arg) onDef(a[j].info, arg)
if {optNimV1Emulation, optNimV12Emulation} * c.config.globalOptions == {}: if {optNimV1Emulation, optNimV12Emulation} * c.config.globalOptions == {}:
a[j] = newSymNode(arg) a[j] = newSymNode(arg)

View file

@ -598,8 +598,7 @@ proc markUsed(c: PContext; info: TLineInfo; s: PSym) =
if sfError in s.flags: userError(conf, info, s) if sfError in s.flags: userError(conf, info, s)
when defined(nimsuggest): when defined(nimsuggest):
suggestSym(c.graph, info, s, c.graph.usageSym, false) suggestSym(c.graph, info, s, c.graph.usageSym, false)
if {optStyleHint, optStyleError} * conf.globalOptions != {}: styleCheckUse(c, info, s)
styleCheckUse(conf, info, s)
markOwnerModuleAsUsed(c, s) markOwnerModuleAsUsed(c, s)
proc safeSemExpr*(c: PContext, n: PNode): PNode = proc safeSemExpr*(c: PContext, n: PNode): PNode =

View file

@ -119,13 +119,13 @@ template move(a, b: untyped) {.dirty.} = system.shallowCopy(a, b)
proc derefPtrToReg(address: BiggestInt, typ: PType, r: var TFullReg, isAssign: bool): bool = proc derefPtrToReg(address: BiggestInt, typ: PType, r: var TFullReg, isAssign: bool): bool =
# nim bug: `isAssign: static bool` doesn't work, giving odd compiler error # nim bug: `isAssign: static bool` doesn't work, giving odd compiler error
template fun(field, T, rkind) = template fun(field, typ, rkind) =
if isAssign: if isAssign:
cast[ptr T](address)[] = T(r.field) cast[ptr typ](address)[] = typ(r.field)
else: else:
r.ensureKind(rkind) r.ensureKind(rkind)
let val = cast[ptr T](address)[] let val = cast[ptr typ](address)[]
when T is SomeInteger | char: when typ is SomeInteger | char:
r.field = BiggestInt(val) r.field = BiggestInt(val)
else: else:
r.field = val r.field = val

View file

@ -56,13 +56,13 @@ template ioop(op) {.dirty.} =
template macrosop(op) {.dirty.} = template macrosop(op) {.dirty.} =
registerCallback(c, "stdlib.macros." & astToStr(op), `op Wrapper`) registerCallback(c, "stdlib.macros." & astToStr(op), `op Wrapper`)
template wrap1f_math(op) {.dirty.} = template wrap1fMath(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
doAssert a.numArgs == 1 doAssert a.numArgs == 1
setResult(a, op(getFloat(a, 0))) setResult(a, op(getFloat(a, 0)))
mathop op mathop op
template wrap2f_math(op) {.dirty.} = template wrap2fMath(op) {.dirty.} =
proc `op Wrapper`(a: VmArgs) {.nimcall.} = proc `op Wrapper`(a: VmArgs) {.nimcall.} =
setResult(a, op(getFloat(a, 0), getFloat(a, 1))) setResult(a, op(getFloat(a, 0), getFloat(a, 1)))
mathop op mathop op
@ -172,40 +172,40 @@ proc registerAdditionalOps*(c: PCtx) =
proc getProjectPathWrapper(a: VmArgs) = proc getProjectPathWrapper(a: VmArgs) =
setResult a, c.config.projectPath.string setResult a, c.config.projectPath.string
wrap1f_math(sqrt) wrap1fMath(sqrt)
wrap1f_math(cbrt) wrap1fMath(cbrt)
wrap1f_math(ln) wrap1fMath(ln)
wrap1f_math(log10) wrap1fMath(log10)
wrap1f_math(log2) wrap1fMath(log2)
wrap1f_math(exp) wrap1fMath(exp)
wrap1f_math(arccos) wrap1fMath(arccos)
wrap1f_math(arcsin) wrap1fMath(arcsin)
wrap1f_math(arctan) wrap1fMath(arctan)
wrap1f_math(arcsinh) wrap1fMath(arcsinh)
wrap1f_math(arccosh) wrap1fMath(arccosh)
wrap1f_math(arctanh) wrap1fMath(arctanh)
wrap2f_math(arctan2) wrap2fMath(arctan2)
wrap1f_math(cos) wrap1fMath(cos)
wrap1f_math(cosh) wrap1fMath(cosh)
wrap2f_math(hypot) wrap2fMath(hypot)
wrap1f_math(sinh) wrap1fMath(sinh)
wrap1f_math(sin) wrap1fMath(sin)
wrap1f_math(tan) wrap1fMath(tan)
wrap1f_math(tanh) wrap1fMath(tanh)
wrap2f_math(pow) wrap2fMath(pow)
wrap1f_math(trunc) wrap1fMath(trunc)
wrap1f_math(floor) wrap1fMath(floor)
wrap1f_math(ceil) wrap1fMath(ceil)
wrap1f_math(erf) wrap1fMath(erf)
wrap1f_math(erfc) wrap1fMath(erfc)
wrap1f_math(gamma) wrap1fMath(gamma)
wrap1f_math(lgamma) wrap1fMath(lgamma)
when declared(copySign): when declared(copySign):
wrap2f_math(copySign) wrap2fMath(copySign)
when declared(signbit): when declared(signbit):
wrap1f_math(signbit) wrap1fMath(signbit)
registerCallback c, "stdlib.math.round", proc (a: VmArgs) {.nimcall.} = registerCallback c, "stdlib.math.round", proc (a: VmArgs) {.nimcall.} =
let n = a.numArgs let n = a.numArgs

View file

@ -89,23 +89,23 @@ type
wLiftLocals = "liftlocals", wEnforceNoRaises = "enforceNoRaises", wLiftLocals = "liftlocals", wEnforceNoRaises = "enforceNoRaises",
wAuto = "auto", wBool = "bool", wCatch = "catch", wChar = "char", wAuto = "auto", wBool = "bool", wCatch = "catch", wChar = "char",
wClass = "class", wCompl = "compl", wConst_cast = "const_cast", wDefault = "default", wClass = "class", wCompl = "compl", wConstCast = "const_cast", wDefault = "default",
wDelete = "delete", wDouble = "double", wDynamic_cast = "dynamic_cast", wDelete = "delete", wDouble = "double", wDynamicCast = "dynamic_cast",
wExplicit = "explicit", wExtern = "extern", wFalse = "false", wFloat = "float", wExplicit = "explicit", wExtern = "extern", wFalse = "false", wFloat = "float",
wFriend = "friend", wGoto = "goto", wInt = "int", wLong = "long", wMutable = "mutable", wFriend = "friend", wGoto = "goto", wInt = "int", wLong = "long", wMutable = "mutable",
wNamespace = "namespace", wNew = "new", wOperator = "operator", wPrivate = "private", wNamespace = "namespace", wNew = "new", wOperator = "operator", wPrivate = "private",
wProtected = "protected", wPublic = "public", wRegister = "register", wProtected = "protected", wPublic = "public", wRegister = "register",
wReinterpret_cast = "reinterpret_cast", wRestrict = "restrict", wShort = "short", wReinterpretCast = "reinterpret_cast", wRestrict = "restrict", wShort = "short",
wSigned = "signed", wSizeof = "sizeof", wStatic_cast = "static_cast", wStruct = "struct", wSigned = "signed", wSizeof = "sizeof", wStaticCast = "static_cast", wStruct = "struct",
wSwitch = "switch", wThis = "this", wThrow = "throw", wTrue = "true", wTypedef = "typedef", wSwitch = "switch", wThis = "this", wThrow = "throw", wTrue = "true", wTypedef = "typedef",
wTypeid = "typeid", wTypeof = "typeof", wTypename = "typename", wTypeid = "typeid", wTypeof = "typeof", wTypename = "typename",
wUnion = "union", wPacked = "packed", wUnsigned = "unsigned", wVirtual = "virtual", wUnion = "union", wPacked = "packed", wUnsigned = "unsigned", wVirtual = "virtual",
wVoid = "void", wVolatile = "volatile", wWchar_t = "wchar_t", wVoid = "void", wVolatile = "volatile", wWchar = "wchar_t",
wAlignas = "alignas", wAlignof = "alignof", wConstexpr = "constexpr", wDecltype = "decltype", wAlignas = "alignas", wAlignof = "alignof", wConstexpr = "constexpr", wDecltype = "decltype",
wNullptr = "nullptr", wNoexcept = "noexcept", wNullptr = "nullptr", wNoexcept = "noexcept",
wThread_local = "thread_local", wStatic_assert = "static_assert", wThreadLocal = "thread_local", wStaticAssert = "static_assert",
wChar16_t = "char16_t", wChar32_t = "char32_t", wChar16 = "char16_t", wChar32 = "char32_t",
wStdIn = "stdin", wStdOut = "stdout", wStdErr = "stderr", wStdIn = "stdin", wStdOut = "stdout", wStdErr = "stderr",