Merge branch 'devel' into araq-detect-unused-imports

This commit is contained in:
Andreas Rumpf 2019-07-18 18:16:32 +02:00
commit fbb0642e27
105 changed files with 1275 additions and 792 deletions

View file

@ -1,39 +1,20 @@
# v0.20.2 - XXXX-XX-XX # v0.20.4 - xxxx-xx-xx
## Changes affecting backwards compatibility ## Changes affecting backwards compatibility
- All `strutils.rfind` procs now take `start` and `last` like `strutils.find`
with the same data slice/index meaning. This is backwards compatible for
calls *not* changing the `rfind` `start` parameter from its default. (#11487)
In the unlikely case that you were using `rfind X, start=N`, or `rfind X, N`,
then you need to change that to `rfind X, last=N` or `rfind X, 0, N`. (This
should minimize gotchas porting code from other languages like Python or C++.)
- On Windows stderr/stdout/stdin are not opened as binary files anymore. Use the switch
`-d:nimBinaryStdFiles` for a transition period.
### Breaking changes in the standard library ### Breaking changes in the standard library
- Mac OS X / BSD: TSa_Family is now the ``uint8`` type, so type
conversions like ``x.sin_family = uint16 toInt(nativesockets.AF_INET)``
need to be changed into ``x.sin_family = TSa_Family toInt(nativesockets.AF_INET)``.
### Breaking changes in the compiler ### Breaking changes in the compiler
## Library additions ## Library additions
- `toOpenArray` is now available for the JS target.
## Library changes ## Library changes
- Fix async IO operations stalling even after socket is closed. (#11232)
- More informative error message for `streams.openFileStream`. (#11438)
## Language additions ## Language additions
@ -46,10 +27,5 @@
### Compiler changes ### Compiler changes
- Better error message for IndexError for empty containers. (#11476)
- Fix regression in semfold for old right shift. (#11477)
- Fix for passing tuples as static params to macros. (#11423)
## Bugfixes ## Bugfixes

View file

@ -0,0 +1,55 @@
# v0.20.2 - 2019-07-17
## Changes affecting backwards compatibility
- All `strutils.rfind` procs now take `start` and `last` like `strutils.find`
with the same data slice/index meaning. This is backwards compatible for
calls *not* changing the `rfind` `start` parameter from its default. (#11487)
In the unlikely case that you were using `rfind X, start=N`, or `rfind X, N`,
then you need to change that to `rfind X, last=N` or `rfind X, 0, N`. (This
should minimize gotchas porting code from other languages like Python or C++.)
- On Windows stderr/stdout/stdin are not opened as binary files anymore. Use the switch
`-d:nimBinaryStdFiles` for a transition period.
### Breaking changes in the standard library
- Mac OS X / BSD: TSa_Family is now the ``uint8`` type, so type
conversions like ``x.sin_family = uint16 toInt(nativesockets.AF_INET)``
need to be changed into ``x.sin_family = TSa_Family toInt(nativesockets.AF_INET)``.
### Breaking changes in the compiler
## Library additions
- `toOpenArray` is now available for the JS target.
## Library changes
- Fix async IO operations stalling even after socket is closed. (#11232)
- More informative error message for `streams.openFileStream`. (#11438)
## Language additions
## Language changes
### Tool changes
### Compiler changes
- Better error message for IndexError for empty containers. (#11476)
- Fix regression in semfold for old right shift. (#11477)
- Fix for passing tuples as static params to macros. (#11423)
## Bugfixes

View file

@ -1,27 +1,33 @@
## v0.XX.0 - XX/XX/2018 # vx.xx.x - yyyy-mm-dd
### Changes affecting backwards compatibility
- Example item: ``Foo`` changed to ``Bar``.
#### Breaking changes in the standard library
#### Breaking changes in the compiler ## Changes affecting backwards compatibility
### Library additions - Example item: `Foo` changed to `Bar`.
### Library changes
### Language additions ### Breaking changes in the standard library
### Language changes ### Breaking changes in the compiler
## Library additions
## Library changes
## Language additions
## Language changes
### Tool changes ### Tool changes
### Compiler changes ### Compiler changes
### Bugfixes
## Bugfixes

View file

@ -10,8 +10,7 @@
# abstract syntax tree + symbol table # abstract syntax tree + symbol table
import import
lineinfos, hashes, nversion, options, strutils, std / sha1, ropes, idents, lineinfos, hashes, options, ropes, idents, idgen
intsets, idgen
type type
TCallingConvention* = enum TCallingConvention* = enum

View file

@ -11,8 +11,8 @@
## is needed for incremental compilation. ## is needed for incremental compilation.
import import
ast, astalgo, ropes, options, strutils, nimlexbase, msgs, cgendata, rodutils, ast, ropes, options, strutils, nimlexbase, cgendata, rodutils,
intsets, platform, llstream, tables, sighashes, modulegraphs, pathutils intsets, llstream, tables, modulegraphs, pathutils
# Careful! Section marks need to contain a tabulator so that they cannot # Careful! Section marks need to contain a tabulator so that they cannot
# be part of C string literals. # be part of C string literals.

View file

@ -10,7 +10,7 @@
# This module declares some helpers for the C code generator. # This module declares some helpers for the C code generator.
import import
ast, astalgo, ropes, hashes, strutils, types, msgs, wordrecg, ast, hashes, strutils, msgs, wordrecg,
platform, trees, options platform, trees, options
proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode = proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode =

View file

@ -11,9 +11,9 @@
import import
ast, astalgo, hashes, trees, platform, magicsys, extccomp, options, intsets, ast, astalgo, hashes, trees, platform, magicsys, extccomp, options, intsets,
nversion, nimsets, msgs, std / sha1, bitsets, idents, types, nversion, nimsets, msgs, bitsets, idents, types,
ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth, ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth,
condsyms, rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases, condsyms, rodutils, renderer, cgendata, ccgmerge, aliases,
lowerings, tables, sets, ndi, lineinfos, pathutils, transf, enumtostr lowerings, tables, sets, ndi, lineinfos, pathutils, transf, enumtostr
when not defined(leanCompiler): when not defined(leanCompiler):

View file

@ -10,7 +10,7 @@
## This module contains the data structures for the C code generation phase. ## This module contains the data structures for the C code generation phase.
import import
ast, astalgo, ropes, passes, options, intsets, platform, sighashes, ast, ropes, passes, options, intsets,
tables, ndi, lineinfos, pathutils, modulegraphs tables, ndi, lineinfos, pathutils, modulegraphs
type type

View file

@ -10,7 +10,7 @@
## This module implements code generation for multi methods. ## This module implements code generation for multi methods.
import import
intsets, options, ast, astalgo, msgs, idents, renderer, types, magicsys, intsets, options, ast, msgs, idents, renderer, types, magicsys,
sempass2, strutils, modulegraphs, lineinfos sempass2, strutils, modulegraphs, lineinfos
proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode = proc genConv(n: PNode, d: PType, downcast: bool; conf: ConfigRef): PNode =

View file

@ -131,8 +131,8 @@
# break :stateLoop # break :stateLoop
import import
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, idents, ast, msgs, idents,
renderer, types, magicsys, lowerings, lambdalifting, modulegraphs, lineinfos renderer, magicsys, lowerings, lambdalifting, modulegraphs, lineinfos
type type
Ctx = object Ctx = object

View file

@ -27,7 +27,7 @@ bootSwitch(usedNoGC, defined(nogc), "--gc:none")
import import
os, msgs, options, nversion, condsyms, strutils, extccomp, platform, os, msgs, options, nversion, condsyms, strutils, extccomp, platform,
wordrecg, parseutils, nimblecmd, idents, parseopt, sequtils, lineinfos, wordrecg, parseutils, nimblecmd, parseopt, sequtils, lineinfos,
pathutils, strtabs pathutils, strtabs
# but some have deps to imported modules. Yay. # but some have deps to imported modules. Yay.

View file

@ -10,7 +10,7 @@
# This module handles the conditional symbols. # This module handles the conditional symbols.
import import
strtabs, platform, strutils, idents strtabs
from options import Feature from options import Feature
from lineinfos import HintsToStr, WarningsToStr from lineinfos import HintsToStr, WarningsToStr

View file

@ -10,8 +10,7 @@
# This module implements a dependency file generator. # This module implements a dependency file generator.
import import
os, options, ast, astalgo, msgs, ropes, idents, passes, modulepaths, options, ast, ropes, idents, passes, modulepaths, pathutils
pathutils
from modulegraphs import ModuleGraph, PPassContext from modulegraphs import ModuleGraph, PPassContext

View file

@ -29,7 +29,7 @@
## "A Graph–Free Approach to Data–Flow Analysis" by Markus Mohnen. ## "A Graph–Free Approach to Data–Flow Analysis" by Markus Mohnen.
## https://link.springer.com/content/pdf/10.1007/3-540-45937-5_6.pdf ## https://link.springer.com/content/pdf/10.1007/3-540-45937-5_6.pdf
import ast, astalgo, types, intsets, tables, msgs, options, lineinfos, renderer import ast, types, intsets, lineinfos, renderer
from patterns import sameTrees from patterns import sameTrees

View file

@ -16,7 +16,7 @@ import
wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast, wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast,
packages/docutils/rst, packages/docutils/rstgen, packages/docutils/rst, packages/docutils/rstgen,
packages/docutils/highlite, json, xmltree, cgi, trees, types, packages/docutils/highlite, json, xmltree, cgi, trees, types,
typesrenderer, astalgo, modulepaths, lineinfos, sequtils, intsets, typesrenderer, astalgo, modulepaths, lineinfos, intsets,
pathutils, trees pathutils, trees
const const

View file

@ -11,8 +11,7 @@
# semantic checking. # semantic checking.
import import
os, options, ast, astalgo, msgs, ropes, idents, passes, docgen, lineinfos, options, ast, msgs, idents, passes, docgen, lineinfos, pathutils
pathutils
from modulegraphs import ModuleGraph, PPassContext from modulegraphs import ModuleGraph, PPassContext

View file

@ -10,8 +10,7 @@
## Template evaluation engine. Now hygienic. ## Template evaluation engine. Now hygienic.
import import
strutils, options, ast, astalgo, msgs, os, idents, wordrecg, renderer, strutils, options, ast, astalgo, msgs, renderer, lineinfos
lineinfos
type type
TemplCtx = object TemplCtx = object

View file

@ -949,6 +949,8 @@ proc callCCompiler*(conf: ConfigRef) =
#from json import escapeJson #from json import escapeJson
import json, std / sha1 import json, std / sha1
template hashNimExe(): string = $secureHashFile(os.getAppFilename())
proc writeJsonBuildInstructions*(conf: ConfigRef) = proc writeJsonBuildInstructions*(conf: ConfigRef) =
template lit(x: untyped) = f.write x template lit(x: untyped) = f.write x
template str(x: untyped) = template str(x: untyped) =
@ -1028,7 +1030,9 @@ proc writeJsonBuildInstructions*(conf: ConfigRef) =
str conf.commandLine str conf.commandLine
lit ",\L\"nimfiles\":[\L" lit ",\L\"nimfiles\":[\L"
nimfiles(conf, f) nimfiles(conf, f)
lit "]\L" lit "],\L\"nimexe\": \L"
str hashNimExe()
lit "\L"
lit "\L}\L" lit "\L}\L"
close(f) close(f)
@ -1045,6 +1049,8 @@ proc changeDetectedViaJsonBuildInstructions*(conf: ConfigRef; projectfile: Absol
let oldCmdLine = data["cmdline"].getStr let oldCmdLine = data["cmdline"].getStr
if conf.commandLine != oldCmdLine: if conf.commandLine != oldCmdLine:
return true return true
if hashNimExe() != data["nimexe"].getStr:
return true
let nimfilesPairs = data["nimfiles"] let nimfilesPairs = data["nimfiles"]
doAssert nimfilesPairs.kind == JArray doAssert nimfilesPairs.kind == JArray
for p in nimfilesPairs: for p in nimfilesPairs:

View file

@ -10,8 +10,8 @@
# This module implements Nim's standard template filter. # This module implements Nim's standard template filter.
import import
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, llstream, strutils, ast, msgs, options,
renderer, filters, lineinfos, pathutils filters, lineinfos, pathutils
type type
TParseState = enum TParseState = enum

View file

@ -10,7 +10,7 @@
# This module implements Nim's simple filters and helpers for filters. # This module implements Nim's simple filters and helpers for filters.
import import
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, llstream, idents, strutils, ast, msgs, options,
renderer, pathutils renderer, pathutils
proc invalidPragma(conf: ConfigRef; n: PNode) = proc invalidPragma(conf: ConfigRef; n: PNode) =

View file

@ -9,7 +9,7 @@
## Module that implements ``gorge`` for the compiler. ## Module that implements ``gorge`` for the compiler.
import msgs, std / sha1, os, osproc, streams, strutils, options, import msgs, std / sha1, os, osproc, streams, options,
lineinfos, pathutils lineinfos, pathutils
proc readOutput(p: Process): (string, int) = proc readOutput(p: Process): (string, int) =

View file

@ -12,7 +12,7 @@
# id. This module is essential for the compiler's performance. # id. This module is essential for the compiler's performance.
import import
hashes, strutils, wordrecg hashes, wordrecg
type type
TIdObj* = object of RootObj TIdObj* = object of RootObj

View file

@ -9,7 +9,7 @@
## This module contains a simple persistent id generator. ## This module contains a simple persistent id generator.
import idents, strutils, os, options, pathutils import idents, strutils, options, pathutils
var gFrontEndId*: int var gFrontEndId*: int

View file

@ -10,8 +10,8 @@
## This module implements the symbol importing mechanism. ## This module implements the symbol importing mechanism.
import import
intsets, strutils, os, ast, astalgo, msgs, options, idents, lookups, intsets, ast, astalgo, msgs, options, idents, lookups,
semdata, passes, renderer, modulepaths, sigmatch, lineinfos semdata, modulepaths, sigmatch, lineinfos
proc readExceptSet*(c: PContext, n: PNode): IntSet = proc readExceptSet*(c: PContext, n: PNode): IntSet =
assert n.kind in {nkImportExceptStmt, nkExportExceptStmt} assert n.kind in {nkImportExceptStmt, nkExportExceptStmt}

View file

@ -12,10 +12,10 @@
const nimIncremental* = defined(nimIncremental) const nimIncremental* = defined(nimIncremental)
import options, lineinfos, pathutils import options, lineinfos
when nimIncremental: when nimIncremental:
import ast, msgs, intsets, btrees, db_sqlite, std / sha1 import ast, msgs, intsets, btrees, db_sqlite, std / sha1, pathutils
from strutils import parseInt from strutils import parseInt
type type

View file

@ -134,7 +134,7 @@ to do it.
]# ]#
import import
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, intsets, ast, msgs, renderer, magicsys, types, idents,
strutils, options, dfa, lowerings, tables, modulegraphs, msgs, strutils, options, dfa, lowerings, tables, modulegraphs, msgs,
lineinfos, parampatterns, sighashes lineinfos, parampatterns, sighashes

View file

@ -29,11 +29,11 @@ implements the required case distinction.
import import
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options, ast, strutils, trees, magicsys, options,
nversion, nimsets, msgs, std / sha1, bitsets, idents, types, os, tables, nversion, msgs, idents, types, tables,
times, ropes, math, passes, ccgutils, wordrecg, renderer, ropes, math, passes, ccgutils, wordrecg, renderer,
intsets, cgmeth, lowerings, sighashes, modulegraphs, lineinfos, rodutils, intsets, cgmeth, lowerings, sighashes, modulegraphs, lineinfos, rodutils,
pathutils, transf transf
from modulegraphs import ModuleGraph, PPassContext from modulegraphs import ModuleGraph, PPassContext

View file

@ -10,7 +10,7 @@
# This file implements lambda lifting for the transformator. # This file implements lambda lifting for the transformator.
import import
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, intsets, strutils, options, ast, astalgo, msgs,
idents, renderer, types, magicsys, lowerings, tables, modulegraphs, lineinfos, idents, renderer, types, magicsys, lowerings, tables, modulegraphs, lineinfos,
transf, liftdestructors transf, liftdestructors

View file

@ -32,7 +32,7 @@ type
ltTab, ltTab,
ltOptionalNewline, ## optional newline introduced by nimpretty ltOptionalNewline, ## optional newline introduced by nimpretty
ltComment, ltLit, ltKeyword, ltExportMarker, ltIdent, ltComment, ltLit, ltKeyword, ltExportMarker, ltIdent,
ltOther, ltOpr, ltOther, ltOpr, ltSomeParLe, ltSomeParRi,
ltBeginSection, ltEndSection ltBeginSection, ltEndSection
Emitter* = object Emitter* = object
@ -142,7 +142,7 @@ proc optionalIsGood(em: var Emitter; pos, currentLen: int): bool =
result = true result = true
elif em.tokens[p+1].len < ourIndent: elif em.tokens[p+1].len < ourIndent:
result = isLongEnough(lineLen, pos, p) result = isLongEnough(lineLen, pos, p)
elif em.kinds[pos+1] == ltOther: # note: pos+1, not p+1 elif em.kinds[pos+1] in {ltOther, ltSomeParLe, ltSomeParRi}: # note: pos+1, not p+1
result = false result = false
else: else:
result = isLongEnough(lineLen, pos, p) result = isLongEnough(lineLen, pos, p)
@ -153,13 +153,28 @@ proc lenOfNextTokens(em: Emitter; pos: int): int =
if em.kinds[pos+i] in {ltCrucialNewline, ltSplittingNewline, ltOptionalNewline}: break if em.kinds[pos+i] in {ltCrucialNewline, ltSplittingNewline, ltOptionalNewline}: break
inc result, em.tokens[pos+i].len inc result, em.tokens[pos+i].len
proc guidingInd(em: Emitter; pos: int): int =
var i = pos - 1
while i >= 0 and em.kinds[i] != ltSomeParLe:
dec i
while i+1 <= em.kinds.high and em.kinds[i] != ltSomeParRi:
if em.kinds[i] == ltSplittingNewline and em.kinds[i+1] == ltSpaces:
return em.tokens[i+1].len
inc i
result = -1
proc closeEmitter*(em: var Emitter) = proc closeEmitter*(em: var Emitter) =
template defaultCase() =
content.add em.tokens[i]
inc lineLen, em.tokens[i].len
let outFile = em.config.absOutFile let outFile = em.config.absOutFile
var content = newStringOfCap(16_000) var content = newStringOfCap(16_000)
var maxLhs = 0 var maxLhs = 0
var lineLen = 0 var lineLen = 0
var lineBegin = 0 var lineBegin = 0
var openPars = 0
var i = 0 var i = 0
while i <= em.tokens.high: while i <= em.tokens.high:
when defined(debug): when defined(debug):
@ -201,8 +216,13 @@ proc closeEmitter*(em: var Emitter) =
let spaces = em.tokens[i-1].len let spaces = em.tokens[i-1].len
content.setLen(content.len - spaces) content.setLen(content.len - spaces)
content.add "\L" content.add "\L"
content.add em.tokens[i] let guide = if openPars > 0: guidingInd(em, i) else: -1
lineLen = em.tokens[i].len if guide >= 0:
content.add repeat(' ', guide)
lineLen = guide
else:
content.add em.tokens[i]
lineLen = em.tokens[i].len
lineBegin = i+1 lineBegin = i+1
if i+1 < em.kinds.len and em.kinds[i+1] == ltSpaces: if i+1 < em.kinds.len and em.kinds[i+1] == ltSpaces:
# inhibit extra spaces at the start of a new line # inhibit extra spaces at the start of a new line
@ -215,9 +235,15 @@ proc closeEmitter*(em: var Emitter) =
else: else:
inc lineLen, em.tokens[i].len inc lineLen, em.tokens[i].len
content.add em.tokens[i] content.add em.tokens[i]
of ltSomeParLe:
inc openPars
defaultCase()
of ltSomeParRi:
doAssert openPars > 0
dec openPars
defaultCase()
else: else:
content.add em.tokens[i] defaultCase()
inc lineLen, em.tokens[i].len
inc i inc i
if fileExists(outFile) and readFile(outFile.string) == content: if fileExists(outFile) and readFile(outFile.string) == content:
@ -292,7 +318,7 @@ const
tkCurlyLe} tkCurlyLe}
closedPars = {tkParRi, tkParDotRi, closedPars = {tkParRi, tkParDotRi,
tkBracketRi, tkCurlyDotRi, tkBracketRi, tkCurlyDotRi,
tkCurlyRi} tkCurlyRi, tkBracketDotRi}
splitters = openPars + {tkComma, tkSemiColon} # do not add 'tkColon' here! splitters = openPars + {tkComma, tkSemiColon} # do not add 'tkColon' here!
oprSet = {tkOpr, tkDiv, tkMod, tkShl, tkShr, tkIn, tkNotin, tkIs, oprSet = {tkOpr, tkDiv, tkMod, tkShl, tkShr, tkIn, tkNotin, tkIs,
@ -416,7 +442,8 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
var newlineKind = ltCrucialNewline var newlineKind = ltCrucialNewline
if em.keepIndents > 0: if em.keepIndents > 0:
em.indentLevel = tok.indent em.indentLevel = tok.indent
elif (em.lastTok in (splitters + oprSet) and tok.tokType notin closedPars): elif (em.lastTok in (splitters + oprSet) and
tok.tokType notin (closedPars - {tkBracketDotRi})):
# aka: we are in an expression context: # aka: we are in an expression context:
let alignment = max(tok.indent - em.indentStack[^1], 0) let alignment = max(tok.indent - em.indentStack[^1], 0)
em.indentLevel = alignment + em.indentStack.high * em.indWidth em.indentLevel = alignment + em.indentStack.high * em.indWidth
@ -471,18 +498,14 @@ proc emitTok*(em: var Emitter; L: TLexer; tok: TToken) =
wr(em, TokTypeToStr[tok.tokType], ltOther) wr(em, TokTypeToStr[tok.tokType], ltOther)
rememberSplit(splitComma) rememberSplit(splitComma)
wrSpace em wrSpace em
of tkParDotLe, tkParLe, tkBracketDotLe, tkBracketLe, of openPars:
tkCurlyLe, tkCurlyDotLe, tkBracketLeColon:
if tok.strongSpaceA > 0 and not em.endsInWhite and not em.wasExportMarker: if tok.strongSpaceA > 0 and not em.endsInWhite and not em.wasExportMarker:
wrSpace em wrSpace em
wr(em, TokTypeToStr[tok.tokType], ltOther) wr(em, TokTypeToStr[tok.tokType], ltSomeParLe)
rememberSplit(splitParLe) rememberSplit(splitParLe)
of tkParRi, of closedPars:
tkBracketRi, tkCurlyRi, wr(em, TokTypeToStr[tok.tokType], ltSomeParRi)
tkBracketDotRi, of tkColonColon:
tkCurlyDotRi,
tkParDotRi,
tkColonColon:
wr(em, TokTypeToStr[tok.tokType], ltOther) wr(em, TokTypeToStr[tok.tokType], ltOther)
of tkDot: of tkDot:
lastTokWasTerse = true lastTokWasTerse = true

View file

@ -13,7 +13,7 @@
# Todo: # Todo:
# - use openArray instead of array to avoid over-specializations # - use openArray instead of array to avoid over-specializations
import modulegraphs, lineinfos, idents, ast, astalgo, renderer, semdata, import modulegraphs, lineinfos, idents, ast, renderer, semdata,
sighashes, lowerings, options, types, msgs, magicsys, tables sighashes, lowerings, options, types, msgs, magicsys, tables
type type

View file

@ -10,7 +10,7 @@
## This module implements the '.liftLocals' pragma. ## This module implements the '.liftLocals' pragma.
import import
intsets, strutils, options, ast, astalgo, msgs, strutils, options, ast, msgs,
idents, renderer, types, lowerings, lineinfos idents, renderer, types, lowerings, lineinfos
from pragmas import getPragmaVal from pragmas import getPragmaVal

View file

@ -9,11 +9,9 @@
## This module implements the style checker. ## This module implements the style checker.
import import strutils
strutils, os, intsets, strtabs
import options, ast, astalgo, msgs, semdata, ropes, idents, import options, ast, msgs, idents, lineinfos, wordrecg
lineinfos, pathutils, wordrecg
const const
Letters* = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'} Letters* = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'}

View file

@ -10,7 +10,7 @@
## Low-level streams for high performance. ## Low-level streams for high performance.
import import
strutils, pathutils pathutils
# support '-d:useGnuReadline' for backwards compatibility: # support '-d:useGnuReadline' for backwards compatibility:
when not defined(windows) and (defined(useGnuReadline) or defined(useLinenoise)): when not defined(windows) and (defined(useGnuReadline) or defined(useLinenoise)):
@ -97,7 +97,7 @@ proc continueLine(line: string, inTripleString: bool): bool {.inline.} =
proc countTriples(s: string): int = proc countTriples(s: string): int =
var i = 0 var i = 0
while i < s.len: while i+2 < s.len:
if s[i] == '"' and s[i+1] == '"' and s[i+2] == '"': if s[i] == '"' and s[i+1] == '"' and s[i+2] == '"':
inc result inc result
inc i, 2 inc i, 2

View file

@ -11,7 +11,7 @@
import import
intsets, ast, astalgo, idents, semdata, types, msgs, options, intsets, ast, astalgo, idents, semdata, types, msgs, options,
renderer, wordrecg, idgen, nimfix/prettybase, lineinfos, strutils renderer, nimfix/prettybase, lineinfos, strutils
proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope)

View file

@ -14,7 +14,6 @@ const
import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs, import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs,
lineinfos lineinfos
from trees import getMagic
proc newDeref*(n: PNode): PNode {.inline.} = proc newDeref*(n: PNode): PNode {.inline.} =
result = newNodeIT(nkHiddenDeref, n.info, n.typ.sons[0]) result = newNodeIT(nkHiddenDeref, n.info, n.typ.sons[0])

View file

@ -9,7 +9,7 @@
## This module implements helpers for the macro cache. ## This module implements helpers for the macro cache.
import lineinfos, ast, modulegraphs, vmdef, magicsys import lineinfos, ast, modulegraphs, vmdef
proc recordInc*(c: PCtx; info: TLineInfo; key: string; by: BiggestInt) = proc recordInc*(c: PCtx; info: TLineInfo; key: string; by: BiggestInt) =
var recorded = newNodeI(nkCommentStmt, info) var recorded = newNodeI(nkCommentStmt, info)

View file

@ -10,7 +10,7 @@
# Built-in types and compilerprocs are registered here. # Built-in types and compilerprocs are registered here.
import import
ast, astalgo, hashes, msgs, platform, nversion, times, idents, ast, astalgo, msgs, platform, idents,
modulegraphs, lineinfos modulegraphs, lineinfos
export createMagic export createMagic

View file

@ -13,12 +13,12 @@ when not defined(nimcore):
{.error: "nimcore MUST be defined for Nim's core tooling".} {.error: "nimcore MUST be defined for Nim's core tooling".}
import import
llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs, llstream, strutils, ast, lexer, syntaxes, options, msgs,
os, condsyms, times, condsyms, times,
wordrecg, sem, semdata, idents, passes, extccomp, sem, idents, passes, extccomp,
cgen, json, nversion, cgen, json, nversion,
platform, nimconf, importer, passaux, depends, vm, vmdef, types, idgen, platform, nimconf, passaux, depends, vm, idgen,
parser, modules, ccgutils, sigmatch, ropes, parser, modules,
modulegraphs, tables, rod, lineinfos, pathutils modulegraphs, tables, rod, lineinfos, pathutils
when not defined(leanCompiler): when not defined(leanCompiler):

View file

@ -8,7 +8,7 @@
# #
import ast, renderer, strutils, msgs, options, idents, os, lineinfos, import ast, renderer, strutils, msgs, options, idents, os, lineinfos,
pathutils, nimblecmd pathutils
when false: when false:
const const

View file

@ -10,8 +10,8 @@
## Implements the module handling, including the caching of modules. ## Implements the module handling, including the caching of modules.
import import
ast, astalgo, magicsys, std / sha1, msgs, cgendata, sigmatch, options, ast, astalgo, magicsys, msgs, options,
idents, os, lexer, idgen, passes, syntaxes, llstream, modulegraphs, rod, idents, lexer, idgen, passes, syntaxes, llstream, modulegraphs, rod,
lineinfos, pathutils, tables lineinfos, pathutils, tables
proc resetSystemArtifacts*(g: ModuleGraph) = proc resetSystemArtifacts*(g: ModuleGraph) =

View file

@ -8,7 +8,7 @@
# #
import import
options, strutils, os, tables, ropes, platform, terminal, macros, options, strutils, os, tables, ropes, terminal, macros,
lineinfos, pathutils lineinfos, pathutils
proc toCChar*(c: char; result: var string) = proc toCChar*(c: char; result: var string) =

View file

@ -19,9 +19,9 @@ when defined(i386) and defined(windows) and defined(vcc):
{.link: "../icons/nim-i386-windows-vcc.res".} {.link: "../icons/nim-i386-windows-vcc.res".}
import import
commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes, commands, options, msgs,
extccomp, strutils, os, osproc, platform, main, parseopt, extccomp, strutils, os, main, parseopt,
scriptconfig, idents, modulegraphs, lineinfos, cmdlinehelper, idents, lineinfos, cmdlinehelper,
pathutils pathutils
include nodejs include nodejs

View file

@ -10,7 +10,7 @@
# This module handles the reading of the config file. # This module handles the reading of the config file.
import import
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, lexer, llstream, commands, os, strutils, msgs, lexer,
options, idents, wordrecg, strtabs, lineinfos, pathutils options, idents, wordrecg, strtabs, lineinfos, pathutils
# ---------------- configuration file parser ----------------------------- # ---------------- configuration file parser -----------------------------

View file

@ -8,9 +8,7 @@
# #
import strutils except Letters import strutils except Letters
import lexbase, streams
import ".." / [ast, msgs, lineinfos, idents, options, linter] import ".." / [ast, msgs, lineinfos, idents, options, linter]
from os import splitFile
proc replaceDeprecated*(conf: ConfigRef; info: TLineInfo; oldSym, newSym: PIdent) = proc replaceDeprecated*(conf: ConfigRef; info: TLineInfo; oldSym, newSym: PIdent) =
let line = sourceLine(conf, info) let line = sourceLine(conf, info)

View file

@ -10,8 +10,7 @@
# this unit handles Nim sets; it implements symbolic sets # this unit handles Nim sets; it implements symbolic sets
import import
ast, astalgo, trees, nversion, lineinfos, platform, bitsets, types, renderer, ast, astalgo, lineinfos, bitsets, types, options
options
proc inSet*(s: PNode, elem: PNode): bool = proc inSet*(s: PNode, elem: PNode): bool =
assert s.kind == nkCurly assert s.kind == nkCurly

View file

@ -8,7 +8,7 @@
# #
import import
os, strutils, strtabs, osproc, sets, lineinfos, platform, os, strutils, strtabs, sets, lineinfos, platform,
prefixmatches, pathutils prefixmatches, pathutils
from terminal import isatty from terminal import isatty

View file

@ -10,7 +10,7 @@
## This module implements the pattern matching features for term rewriting ## This module implements the pattern matching features for term rewriting
## macro support. ## macro support.
import strutils, ast, astalgo, types, msgs, idents, renderer, wordrecg, trees, import strutils, ast, types, msgs, idents, renderer, wordrecg, trees,
options options
# we precompile the pattern here for efficiency into some internal # we precompile the pattern here for efficiency into some internal

View file

@ -27,7 +27,7 @@ when isMainModule:
outp.close outp.close
import import
llstream, lexer, idents, strutils, ast, astalgo, msgs, options, lineinfos, llstream, lexer, idents, strutils, ast, msgs, options, lineinfos,
pathutils pathutils
when defined(nimpretty): when defined(nimpretty):
@ -1203,6 +1203,13 @@ proc parseFor(p: var TParser): PNode =
colcom(p, result) colcom(p, result)
addSon(result, parseStmt(p)) addSon(result, parseStmt(p))
template nimprettyDontTouch(body) =
when defined(nimpretty):
inc p.em.keepIndents
body
when defined(nimpretty):
dec p.em.keepIndents
proc parseExpr(p: var TParser): PNode = proc parseExpr(p: var TParser): PNode =
#| expr = (blockExpr #| expr = (blockExpr
#| | ifExpr #| | ifExpr
@ -1212,12 +1219,26 @@ proc parseExpr(p: var TParser): PNode =
#| | tryExpr) #| | tryExpr)
#| / simpleExpr #| / simpleExpr
case p.tok.tokType: case p.tok.tokType:
of tkBlock: result = parseBlock(p) of tkBlock:
of tkIf: result = parseIfExpr(p, nkIfExpr) nimprettyDontTouch:
of tkFor: result = parseFor(p) result = parseBlock(p)
of tkWhen: result = parseIfExpr(p, nkWhenExpr) of tkIf:
of tkCase: result = parseCase(p) nimprettyDontTouch:
of tkTry: result = parseTry(p, isExpr=true) result = parseIfExpr(p, nkIfExpr)
of tkFor:
nimprettyDontTouch:
result = parseFor(p)
of tkWhen:
nimprettyDontTouch:
result = parseIfExpr(p, nkWhenExpr)
of tkCase:
# Currently we think nimpretty is good enough with case expressions,
# so it is allowed to touch them:
#nimprettyDontTouch:
result = parseCase(p)
of tkTry:
nimprettyDontTouch:
result = parseTry(p, isExpr=true)
else: result = simpleExpr(p) else: result = simpleExpr(p)
proc parseEnum(p: var TParser): PNode proc parseEnum(p: var TParser): PNode

View file

@ -10,7 +10,7 @@
## implements some little helper passes ## implements some little helper passes
import import
strutils, ast, astalgo, passes, idents, msgs, options, idgen, lineinfos ast, passes, idents, msgs, options, idgen, lineinfos
from modulegraphs import ModuleGraph, PPassContext from modulegraphs import ModuleGraph, PPassContext

View file

@ -11,9 +11,9 @@
## `TPass` interface. ## `TPass` interface.
import import
strutils, options, ast, astalgo, llstream, msgs, platform, os, options, ast, llstream, msgs,
condsyms, idents, renderer, types, extccomp, math, magicsys, nversion, idents,
nimsets, syntaxes, times, idgen, modulegraphs, reorder, rod, syntaxes, idgen, modulegraphs, reorder, rod,
lineinfos, pathutils lineinfos, pathutils
type type

View file

@ -10,7 +10,7 @@
## Path handling utilities for Nim. Strictly typed code in order ## Path handling utilities for Nim. Strictly typed code in order
## to avoid the never ending time sink in getting path handling right. ## to avoid the never ending time sink in getting path handling right.
import os, strutils, pathnorm import os, pathnorm
type type
AbsoluteFile* = distinct string AbsoluteFile* = distinct string

View file

@ -11,8 +11,7 @@
## macro support. ## macro support.
import import
ast, astalgo, types, semdata, sigmatch, msgs, idents, aliases, parampatterns, ast, types, semdata, sigmatch, idents, aliases, parampatterns, trees
trees
type type
TPatternContext = object TPatternContext = object

View file

@ -9,9 +9,7 @@
## Plugin to transform an inline iterator into a data structure. ## Plugin to transform an inline iterator into a data structure.
import ".." / [ast, astalgo, import ".." / [ast, lookups, semdata, lambdalifting, msgs]
magicsys, lookups, semdata,
lambdalifting, msgs]
proc iterToProcImpl*(c: PContext, n: PNode): PNode = proc iterToProcImpl*(c: PContext, n: PNode): PNode =
result = newNodeI(nkStmtList, n.info) result = newNodeI(nkStmtList, n.info)

View file

@ -9,7 +9,7 @@
## The builtin 'system.locals' implemented as a plugin. ## The builtin 'system.locals' implemented as a plugin.
import ".." / [pluginsupport, ast, astalgo, import ".." / [ast, astalgo,
magicsys, lookups, semdata, lowerings] magicsys, lookups, semdata, lowerings]
proc semLocals*(c: PContext, n: PNode): PNode = proc semLocals*(c: PContext, n: PNode): PNode =

View file

@ -1,7 +1,7 @@
import import
intsets, ast, idents, algorithm, renderer, parser, os, strutils, intsets, ast, idents, algorithm, renderer, os, strutils,
sequtils, msgs, modulegraphs, syntaxes, options, modulepaths, tables, msgs, modulegraphs, syntaxes, options, modulepaths,
lineinfos lineinfos
type type

View file

@ -9,7 +9,7 @@
## This module implements the canonalization for the various caching mechanisms. ## This module implements the canonalization for the various caching mechanisms.
import ast, idgen, lineinfos, msgs, incremental, modulegraphs, pathutils import ast, idgen, lineinfos, incremental, modulegraphs, pathutils
when not nimIncremental: when not nimIncremental:
template setupModuleCache*(g: ModuleGraph) = discard template setupModuleCache*(g: ModuleGraph) = discard

View file

@ -11,9 +11,10 @@
## language. ## language.
import import
ast, modules, idents, passes, passaux, condsyms, ast, modules, idents, passes, condsyms,
options, nimconf, sem, semdata, llstream, vm, vmdef, commands, msgs, options, sem, llstream, vm, vmdef, commands, msgs,
os, times, osproc, wordrecg, strtabs, modulegraphs, lineinfos, pathutils os, times, osproc, wordrecg, strtabs, modulegraphs,
lineinfos, pathutils
# we support 'cmpIgnoreStyle' natively for efficiency: # we support 'cmpIgnoreStyle' natively for efficiency:
from strutils import cmpIgnoreStyle, contains from strutils import cmpIgnoreStyle, contains

View file

@ -10,13 +10,13 @@
# This module implements the semantic checking pass. # This module implements the semantic checking pass.
import import
ast, strutils, hashes, options, lexer, astalgo, trees, treetab, ast, strutils, options, astalgo, trees,
wordrecg, ropes, msgs, os, condsyms, idents, renderer, types, platform, math, wordrecg, ropes, msgs, idents, renderer, types, platform, math,
magicsys, parser, nversion, nimsets, semfold, modulepaths, importer, magicsys, nversion, nimsets, semfold, modulepaths, importer,
procfind, lookups, pragmas, passes, semdata, semtypinst, sigmatch, procfind, lookups, pragmas, passes, semdata, semtypinst, sigmatch,
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting, intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
evaltempl, patterns, parampatterns, sempass2, linter, semmacrosanity, evaltempl, patterns, parampatterns, sempass2, linter, semmacrosanity,
lowerings, pluginsupport, plugins/active, rod, lineinfos, strtabs, int128 lowerings, plugins/active, rod, lineinfos, strtabs, int128
from modulegraphs import ModuleGraph, PPassContext, onUse, onDef, onDefResolveForward from modulegraphs import ModuleGraph, PPassContext, onUse, onDef, onDefResolveForward

View file

@ -107,7 +107,6 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
elif errorsEnabled or z.diagnosticsEnabled: elif errorsEnabled or z.diagnosticsEnabled:
errors.add(CandidateError( errors.add(CandidateError(
sym: sym, sym: sym,
unmatchedVarParam: int z.mutabilityProblem,
firstMismatch: z.firstMismatch, firstMismatch: z.firstMismatch,
diagnostics: z.diagnostics)) diagnostics: z.diagnostics))
else: else:
@ -173,14 +172,14 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
var filterOnlyFirst = false var filterOnlyFirst = false
if optShowAllMismatches notin c.config.globalOptions: if optShowAllMismatches notin c.config.globalOptions:
for err in errors: for err in errors:
if err.firstMismatch > 1: if err.firstMismatch.arg > 1:
filterOnlyFirst = true filterOnlyFirst = true
break break
var candidates = "" var candidates = ""
var skipped = 0 var skipped = 0
for err in errors: for err in errors:
if filterOnlyFirst and err.firstMismatch == 1: if filterOnlyFirst and err.firstMismatch.arg == 1:
inc skipped inc skipped
continue continue
if err.sym.kind in routineKinds and err.sym.ast != nil: if err.sym.kind in routineKinds and err.sym.ast != nil:
@ -189,34 +188,35 @@ proc presentFailedCandidates(c: PContext, n: PNode, errors: CandidateErrors):
else: else:
add(candidates, getProcHeader(c.config, err.sym, prefer)) add(candidates, getProcHeader(c.config, err.sym, prefer))
add(candidates, "\n") add(candidates, "\n")
if err.firstMismatch != 0 and n.len > 1: let nArg = if err.firstMismatch.arg < n.len: n[err.firstMismatch.arg] else: nil
let cond = n.len > 2 let nameParam = if err.firstMismatch.formal != nil: err.firstMismatch.formal.name.s else: ""
if cond: if n.len > 1:
candidates.add(" first type mismatch at position: " & $abs(err.firstMismatch)) candidates.add(" first type mismatch at position: " & $err.firstMismatch.arg)
if err.firstMismatch >= 0: candidates.add("\n required type: ") # candidates.add "\n reason: " & $err.firstMismatch.kind # for debugging
else: candidates.add("\n unknown named parameter: " & $n[-err.firstMismatch][0]) case err.firstMismatch.kind
var wanted, got: PType = nil of kUnknownNamedParam: candidates.add("\n unknown named parameter: " & $nArg[0])
if err.firstMismatch < 0: of kAlreadyGiven: candidates.add("\n named param already provided: " & $nArg[0])
discard of kExtraArg: candidates.add("\n extra argument given")
elif err.firstMismatch < err.sym.typ.len: of kMissingParam: candidates.add("\n missing parameter: " & nameParam)
wanted = err.sym.typ.sons[err.firstMismatch] of kTypeMismatch, kVarNeeded:
if cond: candidates.add typeToString(wanted) doAssert nArg != nil
else: var wanted = err.firstMismatch.formal.typ
if cond: candidates.add "none" doAssert err.firstMismatch.formal != nil
if err.firstMismatch > 0 and err.firstMismatch < n.len: candidates.add("\n required type for " & nameParam & ": ")
if cond: candidates.add typeToString(wanted)
candidates.add "\n but expression '" candidates.add "\n but expression '"
candidates.add renderTree(n[err.firstMismatch]) if err.firstMismatch.kind == kVarNeeded:
candidates.add renderNotLValue(nArg)
candidates.add "' is immutable, not 'var'"
else:
candidates.add renderTree(nArg)
candidates.add "' is of type: " candidates.add "' is of type: "
got = n[err.firstMismatch].typ var got = nArg.typ
if cond: candidates.add typeToString(got) candidates.add typeToString(got)
if wanted != nil and got != nil: doAssert wanted != nil
effectProblem(wanted, got, candidates) if got != nil: effectProblem(wanted, got, candidates)
if cond: candidates.add "\n" of kUnknown: internalAssert(c.config, false)
if err.unmatchedVarParam != 0 and err.unmatchedVarParam < n.len: candidates.add "\n"
candidates.add(" for a 'var' type a variable needs to be passed, but '" &
renderNotLValue(n[err.unmatchedVarParam]) &
"' is immutable\n")
for diag in err.diagnostics: for diag in err.diagnostics:
candidates.add(diag & "\n") candidates.add(diag & "\n")
if skipped > 0: if skipped > 0:
@ -260,7 +260,7 @@ proc bracketNotFoundError(c: PContext; n: PNode) =
while symx != nil: while symx != nil:
if symx.kind in routineKinds: if symx.kind in routineKinds:
errors.add(CandidateError(sym: symx, errors.add(CandidateError(sym: symx,
unmatchedVarParam: 0, firstMismatch: 0, firstMismatch: MismatchInfo(),
diagnostics: @[], diagnostics: @[],
enabled: false)) enabled: false))
symx = nextOverloadIter(o, c, headSymbol) symx = nextOverloadIter(o, c, headSymbol)

View file

@ -10,11 +10,8 @@
## This module contains the data structures for the semantic checking phase. ## This module contains the data structures for the semantic checking phase.
import import
strutils, intsets, options, lexer, ast, astalgo, trees, treetab, intsets, options, ast, astalgo, msgs, idents, renderer,
wordrecg, magicsys, passes, vmdef, modulegraphs, lineinfos
ropes, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math,
magicsys, nversion, nimsets, parser, times, passes, vmdef,
modulegraphs, lineinfos
type type
TOptionEntry* = object # entries to put on a stack for pragma parsing TOptionEntry* = object # entries to put on a stack for pragma parsing

View file

@ -1414,6 +1414,9 @@ proc semDeref(c: PContext, n: PNode): PNode =
var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyAlias, tySink, tyOwned}) var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyAlias, tySink, tyOwned})
case t.kind case t.kind
of tyRef, tyPtr: n.typ = t.lastSon of tyRef, tyPtr: n.typ = t.lastSon
of tyTypeDesc:
# typeof(x[]) is still a typedesc:
n.typ = makeTypeDesc(c, t.lastSon.lastSon)
else: result = nil else: result = nil
#GlobalError(n.sons[0].info, errCircumNeedsPointer) #GlobalError(n.sons[0].info, errCircumNeedsPointer)

View file

@ -11,8 +11,8 @@
# and evaluation phase # and evaluation phase
import import
strutils, options, ast, astalgo, trees, treetab, nimsets, strutils, options, ast, trees, nimsets,
nversion, platform, math, msgs, os, condsyms, idents, renderer, types, platform, math, msgs, idents, renderer, types,
commands, magicsys, modulegraphs, strtabs, lineinfos commands, magicsys, modulegraphs, strtabs, lineinfos
proc newIntNodeT*(intVal: BiggestInt, n: PNode; g: ModuleGraph): PNode = proc newIntNodeT*(intVal: BiggestInt, n: PNode; g: ModuleGraph): PNode =

View file

@ -10,7 +10,7 @@
## Implements type sanity checking for ASTs resulting from macros. Lots of ## Implements type sanity checking for ASTs resulting from macros. Lots of
## room for improvement here. ## room for improvement here.
import ast, astalgo, msgs, types, options import ast, msgs, types, options
proc ithField(n: PNode, field: var int): PSym = proc ithField(n: PNode, field: var int): PSym =
result = nil result = nil

View file

@ -10,7 +10,7 @@
import import
intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees,
wordrecg, strutils, options, guards, lineinfos, semfold, semdata, wordrecg, strutils, options, guards, lineinfos, semfold, semdata,
modulegraphs, lowerings, sigmatch, tables modulegraphs
when not defined(leanCompiler): when not defined(leanCompiler):
import writetracking import writetracking

View file

@ -11,9 +11,7 @@
import ast, tables, ropes, md5, modulegraphs import ast, tables, ropes, md5, modulegraphs
from hashes import Hash from hashes import Hash
from astalgo import debug
import types import types
from strutils import startsWith, contains
proc `&=`(c: var MD5Context, s: string) = md5Update(c, s, s.len) proc `&=`(c: var MD5Context, s: string) = md5Update(c, s, s.len)
proc `&=`(c: var MD5Context, ch: char) = md5Update(c, unsafeAddr ch, 1) proc `&=`(c: var MD5Context, ch: char) = md5Update(c, unsafeAddr ch, 1)

View file

@ -12,19 +12,29 @@
import import
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst, intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees, magicsys, idents, lexer, options, parampatterns, strutils, trees,
linter, lineinfos, lowerings, modulegraphs linter, lineinfos, lowerings, modulegraphs
when (defined(booting) or defined(nimsuggest)) and not defined(leanCompiler): when (defined(booting) or defined(nimsuggest)) and not defined(leanCompiler):
import docgen import docgen
type type
MismatchKind* = enum
kUnknown, kAlreadyGiven, kUnknownNamedParam, kTypeMismatch, kVarNeeded,
kMissingParam, kExtraArg
MismatchInfo* = object
kind*: MismatchKind # reason for mismatch
arg*: int # position of provided arguments that mismatches
formal*: PSym # parameter that mismatches against provided argument
# its position can differ from `arg` because of varargs
TCandidateState* = enum TCandidateState* = enum
csEmpty, csMatch, csNoMatch csEmpty, csMatch, csNoMatch
CandidateError* = object CandidateError* = object
sym*: PSym sym*: PSym
unmatchedVarParam*, firstMismatch*: int firstMismatch*: MismatchInfo
diagnostics*: seq[string] diagnostics*: seq[string]
enabled*: bool enabled*: bool
@ -56,7 +66,6 @@ type
# a distrinct type # a distrinct type
typedescMatched*: bool typedescMatched*: bool
isNoCall*: bool # misused for generic type instantiations C[T] isNoCall*: bool # misused for generic type instantiations C[T]
mutabilityProblem*: uint8 # tyVar mismatch
inferredTypes: seq[PType] # inferred types during the current signature inferredTypes: seq[PType] # inferred types during the current signature
# matching. they will be reset if the matching # matching. they will be reset if the matching
# is not successful. may replace the bindings # is not successful. may replace the bindings
@ -70,8 +79,7 @@ type
# triggered with an idetools command in the # triggered with an idetools command in the
# future. # future.
inheritancePenalty: int # to prefer closest father object type inheritancePenalty: int # to prefer closest father object type
firstMismatch*: int # position of the first type mismatch for firstMismatch*: MismatchInfo # mismatch info for better error messages
# better error messages
diagnosticsEnabled*: bool diagnosticsEnabled*: bool
TTypeRelFlag* = enum TTypeRelFlag* = enum
@ -112,6 +120,7 @@ proc initCandidateAux(ctx: PContext,
c.intConvMatches = 0 c.intConvMatches = 0
c.genericMatches = 0 c.genericMatches = 0
c.state = csEmpty c.state = csEmpty
c.firstMismatch = MismatchInfo()
c.callee = callee c.callee = callee
c.call = nil c.call = nil
c.baseTypeMatch = false c.baseTypeMatch = false
@ -2280,42 +2289,47 @@ template isVarargsUntyped(x): untyped =
proc matchesAux(c: PContext, n, nOrig: PNode, proc matchesAux(c: PContext, n, nOrig: PNode,
m: var TCandidate, marker: var IntSet) = m: var TCandidate, marker: var IntSet) =
var
a = 1 # iterates over the actual given arguments
f = if m.callee.kind != tyGenericBody: 1
else: 0 # iterates over formal parameters
arg: PNode # current prepared argument
formal: PSym # current routine parameter
template noMatch() =
m.state = csNoMatch
m.firstMismatch.arg = a
m.firstMismatch.formal = formal
template checkConstraint(n: untyped) {.dirty.} = template checkConstraint(n: untyped) {.dirty.} =
if not formal.constraint.isNil: if not formal.constraint.isNil:
if matchNodeKinds(formal.constraint, n): if matchNodeKinds(formal.constraint, n):
# better match over other routines with no such restriction: # better match over other routines with no such restriction:
inc(m.genericMatches, 100) inc(m.genericMatches, 100)
else: else:
m.state = csNoMatch noMatch()
return return
if formal.typ.kind == tyVar: if formal.typ.kind == tyVar:
let argConverter = if arg.kind == nkHiddenDeref: arg[0] else: arg let argConverter = if arg.kind == nkHiddenDeref: arg[0] else: arg
if argConverter.kind == nkHiddenCallConv: if argConverter.kind == nkHiddenCallConv:
if argConverter.typ.kind != tyVar: if argConverter.typ.kind != tyVar:
m.state = csNoMatch m.firstMismatch.kind = kVarNeeded
m.mutabilityProblem = uint8(f-1) noMatch()
return return
elif not n.isLValue: elif not n.isLValue:
m.state = csNoMatch m.firstMismatch.kind = kVarNeeded
m.mutabilityProblem = uint8(f-1) noMatch()
return return
var
# iterates over formal parameters
f = if m.callee.kind != tyGenericBody: 1
else: 0
# iterates over the actual given arguments
a = 1
arg: PNode # current prepared argument
m.state = csMatch # until proven otherwise m.state = csMatch # until proven otherwise
m.firstMismatch = MismatchInfo()
m.call = newNodeI(n.kind, n.info) m.call = newNodeI(n.kind, n.info)
m.call.typ = base(m.callee) # may be nil m.call.typ = base(m.callee) # may be nil
var formalLen = m.callee.n.len var formalLen = m.callee.n.len
addSon(m.call, copyTree(n.sons[0])) addSon(m.call, copyTree(n.sons[0]))
var container: PNode = nil # constructed container var container: PNode = nil # constructed container
var formal: PSym = if formalLen > 1: m.callee.n.sons[1].sym else: nil formal = if formalLen > 1: m.callee.n.sons[1].sym else: nil
while a < n.len: while a < n.len:
if a >= formalLen-1 and f < formalLen and m.callee.n[f].typ.isVarargsUntyped: if a >= formalLen-1 and f < formalLen and m.callee.n[f].typ.isVarargsUntyped:
@ -2336,26 +2350,26 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
addSon(container, n.sons[a]) addSon(container, n.sons[a])
elif n.sons[a].kind == nkExprEqExpr: elif n.sons[a].kind == nkExprEqExpr:
# named param # named param
m.firstMismatch.kind = kUnknownNamedParam
# check if m.callee has such a param: # check if m.callee has such a param:
prepareNamedParam(n.sons[a], c) prepareNamedParam(n.sons[a], c)
if n.sons[a].sons[0].kind != nkIdent: if n.sons[a].sons[0].kind != nkIdent:
localError(c.config, n.sons[a].info, "named parameter has to be an identifier") localError(c.config, n.sons[a].info, "named parameter has to be an identifier")
m.state = csNoMatch noMatch()
m.firstMismatch = -a
return return
formal = getSymFromList(m.callee.n, n.sons[a].sons[0].ident, 1) formal = getSymFromList(m.callee.n, n.sons[a].sons[0].ident, 1)
if formal == nil: if formal == nil:
# no error message! # no error message!
m.state = csNoMatch noMatch()
m.firstMismatch = -a
return return
if containsOrIncl(marker, formal.position): if containsOrIncl(marker, formal.position):
m.firstMismatch.kind = kAlreadyGiven
# already in namedParams, so no match # already in namedParams, so no match
# we used to produce 'errCannotBindXTwice' here but see # we used to produce 'errCannotBindXTwice' here but see
# bug #3836 of why that is not sound (other overload with # bug #3836 of why that is not sound (other overload with
# different parameter names could match later on): # different parameter names could match later on):
when false: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s) when false: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
m.state = csNoMatch noMatch()
return return
m.baseTypeMatch = false m.baseTypeMatch = false
m.typedescMatched = false m.typedescMatched = false
@ -2363,9 +2377,9 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
n.sons[a].typ = n.sons[a].sons[1].typ n.sons[a].typ = n.sons[a].sons[1].typ
arg = paramTypesMatch(m, formal.typ, n.sons[a].typ, arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
n.sons[a].sons[1], n.sons[a].sons[1]) n.sons[a].sons[1], n.sons[a].sons[1])
m.firstMismatch.kind = kTypeMismatch
if arg == nil: if arg == nil:
m.state = csNoMatch noMatch()
m.firstMismatch = a
return return
checkConstraint(n.sons[a].sons[1]) checkConstraint(n.sons[a].sons[1])
if m.baseTypeMatch: if m.baseTypeMatch:
@ -2392,6 +2406,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
else: else:
addSon(m.call, copyTree(n.sons[a])) addSon(m.call, copyTree(n.sons[a]))
elif formal != nil and formal.typ.kind == tyVarargs: elif formal != nil and formal.typ.kind == tyVarargs:
m.firstMismatch.kind = kTypeMismatch
# beware of the side-effects in 'prepareOperand'! So only do it for # beware of the side-effects in 'prepareOperand'! So only do it for
# varargs matching. See tests/metatype/tstatic_overloading. # varargs matching. See tests/metatype/tstatic_overloading.
m.baseTypeMatch = false m.baseTypeMatch = false
@ -2405,20 +2420,24 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
incrIndexType(container.typ) incrIndexType(container.typ)
checkConstraint(n.sons[a]) checkConstraint(n.sons[a])
else: else:
m.state = csNoMatch noMatch()
return return
else: else:
m.state = csNoMatch m.firstMismatch.kind = kExtraArg
noMatch()
return return
else: else:
if m.callee.n.sons[f].kind != nkSym: if m.callee.n.sons[f].kind != nkSym:
internalError(c.config, n.sons[a].info, "matches") internalError(c.config, n.sons[a].info, "matches")
noMatch()
return return
formal = m.callee.n.sons[f].sym formal = m.callee.n.sons[f].sym
m.firstMismatch.kind = kTypeMismatch
if containsOrIncl(marker, formal.position) and container.isNil: if containsOrIncl(marker, formal.position) and container.isNil:
m.firstMismatch.kind = kAlreadyGiven
# already in namedParams: (see above remark) # already in namedParams: (see above remark)
when false: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s) when false: localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
m.state = csNoMatch noMatch()
return return
if formal.typ.isVarargsUntyped: if formal.typ.isVarargsUntyped:
@ -2435,8 +2454,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
arg = paramTypesMatch(m, formal.typ, n.sons[a].typ, arg = paramTypesMatch(m, formal.typ, n.sons[a].typ,
n.sons[a], nOrig.sons[a]) n.sons[a], nOrig.sons[a])
if arg == nil: if arg == nil:
m.state = csNoMatch noMatch()
m.firstMismatch = f
return return
if m.baseTypeMatch: if m.baseTypeMatch:
assert formal.typ.kind == tyVarargs assert formal.typ.kind == tyVarargs
@ -2465,10 +2483,13 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
# this assertion can be off # this assertion can be off
localError(c.config, n.sons[a].info, "cannot convert $1 to $2" % [ localError(c.config, n.sons[a].info, "cannot convert $1 to $2" % [
typeToString(n.sons[a].typ), typeToString(formal.typ) ]) typeToString(n.sons[a].typ), typeToString(formal.typ) ])
m.state = csNoMatch noMatch()
return return
checkConstraint(n.sons[a]) checkConstraint(n.sons[a])
inc(a) inc(a)
# for some edge cases (see tdont_return_unowned_from_owned test case)
m.firstMismatch.arg = a
m.firstMismatch.formal = formal
proc semFinishOperands*(c: PContext, n: PNode) = proc semFinishOperands*(c: PContext, n: PNode) =
# this needs to be called to ensure that after overloading resolution every # this needs to be called to ensure that after overloading resolution every
@ -2510,7 +2531,8 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
else: else:
# no default value # no default value
m.state = csNoMatch m.state = csNoMatch
m.firstMismatch = f m.firstMismatch.kind = kMissingParam
m.firstMismatch.formal = formal
break break
else: else:
if formal.ast.kind == nkEmpty: if formal.ast.kind == nkEmpty:

View file

@ -9,8 +9,8 @@
## This module implements threadpool's ``spawn``. ## This module implements threadpool's ``spawn``.
import ast, astalgo, types, idents, magicsys, msgs, options, modulegraphs, import ast, types, idents, magicsys, msgs, options, modulegraphs,
lineinfos, lowerings lowerings
from trees import getMagic from trees import getMagic
proc callProc(a: PNode): PNode = proc callProc(a: PNode): PNode =

View file

@ -32,11 +32,11 @@
# included from sigmatch.nim # included from sigmatch.nim
import algorithm, prefixmatches, lineinfos, pathutils, parseutils, linter import algorithm, prefixmatches, lineinfos, parseutils, linter
from wordrecg import wDeprecated, wError, wAddr, wYield, specialWords from wordrecg import wDeprecated, wError, wAddr, wYield, specialWords
when defined(nimsuggest): when defined(nimsuggest):
import passes, tables # importer import passes, tables, pathutils # importer
const const
sep = '\t' sep = '\t'

View file

@ -10,7 +10,7 @@
## Implements the dispatcher for the different parsers. ## Implements the dispatcher for the different parsers.
import import
strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser, strutils, llstream, ast, idents, lexer, options, msgs, parser,
filters, filter_tmpl, renderer, lineinfos, pathutils filters, filter_tmpl, renderer, lineinfos, pathutils
type type

View file

@ -19,9 +19,9 @@
# * transforms 'defer' into a 'try finally' statement # * transforms 'defer' into a 'try finally' statement
import import
intsets, strutils, options, ast, astalgo, trees, treetab, msgs, lookups, options, ast, astalgo, trees, msgs,
idents, renderer, types, passes, semfold, magicsys, cgmeth, idents, renderer, types, passes, semfold, magicsys, cgmeth,
sempass2, lowerings, injectdestructors, liftlocals, lowerings, injectdestructors, liftlocals,
modulegraphs, lineinfos modulegraphs, lineinfos
proc transformBody*(g: ModuleGraph, prc: PSym, cache = true; proc transformBody*(g: ModuleGraph, prc: PSym, cache = true;

View file

@ -10,7 +10,7 @@
# tree helper routines # tree helper routines
import import
ast, astalgo, lexer, msgs, strutils, wordrecg, idents ast, wordrecg, idents
proc cyclicTreeAux(n: PNode, visited: var seq[PNode]): bool = proc cyclicTreeAux(n: PNode, visited: var seq[PNode]): bool =
if n == nil: return if n == nil: return

View file

@ -7,7 +7,7 @@
# distribution, for details about the copyright. # distribution, for details about the copyright.
# #
import renderer, strutils, ast, msgs, types, astalgo import renderer, strutils, ast, types
const defaultParamSeparator* = "," const defaultParamSeparator* = ","

View file

@ -13,7 +13,7 @@
import ast except getstr import ast except getstr
import import
strutils, astalgo, msgs, vmdef, vmgen, nimsets, types, passes, strutils, msgs, vmdef, vmgen, nimsets, types, passes,
parser, vmdeps, idents, trees, renderer, options, transf, parseutils, parser, vmdeps, idents, trees, renderer, options, transf, parseutils,
vmmarshal, gorgeimpl, lineinfos, tables, btrees, macrocacheimpl, vmmarshal, gorgeimpl, lineinfos, tables, btrees, macrocacheimpl,
modulegraphs, sighashes modulegraphs, sighashes

View file

@ -10,8 +10,7 @@
## This module contains the type definitions for the new evaluation engine. ## This module contains the type definitions for the new evaluation engine.
## An instruction is 1-3 int32s in memory, it is a register based VM. ## An instruction is 1-3 int32s in memory, it is a register based VM.
import ast, passes, msgs, idents, intsets, options, modulegraphs, lineinfos, import ast, passes, idents, intsets, options, modulegraphs, lineinfos
tables, btrees
const const
byteExcess* = 128 # we use excess-K for immediates byteExcess* = 128 # we use excess-K for immediates

View file

@ -7,7 +7,7 @@
# distribution, for details about the copyright. # distribution, for details about the copyright.
# #
import ast, types, msgs, os, streams, options, idents, lineinfos import ast, types, msgs, os, options, idents, lineinfos
proc opSlurp*(file: string, info: TLineInfo, module: PSym; conf: ConfigRef): string = proc opSlurp*(file: string, info: TLineInfo, module: PSym; conf: ConfigRef): string =
try: try:

View file

@ -28,10 +28,8 @@
# this copy depends on the involved types. # this copy depends on the involved types.
import import
strutils, ast, astalgo, types, msgs, renderer, vmdef, strutils, ast, types, msgs, renderer, vmdef,
trees, intsets, magicsys, options, lowerings, lineinfos, transf intsets, magicsys, options, lowerings, lineinfos, transf
import platform
from os import splitFile
const const
debugEchoCode* = defined(nimVMDebug) debugEchoCode* = defined(nimVMDebug)

View file

@ -15,8 +15,7 @@
## * Computing an aliasing relation based on the assignments. This relation ## * Computing an aliasing relation based on the assignments. This relation
## is then used to compute the 'writes' and 'escapes' effects. ## is then used to compute the 'writes' and 'escapes' effects.
import intsets, idents, ast, astalgo, trees, renderer, msgs, types, options, import intsets, idents, ast, trees, msgs, types, options, lineinfos
lineinfos
const const
debug = false debug = false

View file

@ -1420,7 +1420,7 @@ proc boolVal*(n: NimNode): bool {.compileTime, noSideEffect.} =
if n.kind == nnkIntLit: n.intVal != 0 if n.kind == nnkIntLit: n.intVal != 0
else: n == bindSym"true" # hacky solution for now else: n == bindSym"true" # hacky solution for now
macro expandMacros*(body: typed): typed = macro expandMacros*(body: typed): untyped =
## Expands one level of macro - useful for debugging. ## Expands one level of macro - useful for debugging.
## Can be used to inspect what happens when a macro call is expanded, ## Can be used to inspect what happens when a macro call is expanded,
## without altering its result. ## without altering its result.

View file

@ -169,7 +169,7 @@
include "system/inclrtl" include "system/inclrtl"
import os, tables, strutils, times, heapqueue, lists, options, asyncstreams import os, tables, strutils, times, heapqueue, lists, options, asyncstreams
import options, math import options, math, std/monotimes
import asyncfutures except callSoon import asyncfutures except callSoon
import nativesockets, net, deques import nativesockets, net, deques
@ -184,7 +184,7 @@ export asyncstreams
type type
PDispatcherBase = ref object of RootRef PDispatcherBase = ref object of RootRef
timers*: HeapQueue[tuple[finishAt: float, fut: Future[void]]] timers*: HeapQueue[tuple[finishAt: MonoTime, fut: Future[void]]]
callbacks*: Deque[proc () {.gcsafe.}] callbacks*: Deque[proc () {.gcsafe.}]
proc processTimers( proc processTimers(
@ -192,7 +192,7 @@ proc processTimers(
): Option[int] {.inline.} = ): Option[int] {.inline.} =
# Pop the timers in the order in which they will expire (smaller `finishAt`). # Pop the timers in the order in which they will expire (smaller `finishAt`).
var count = p.timers.len var count = p.timers.len
let t = epochTime() let t = getMonoTime()
while count > 0 and t >= p.timers[0].finishAt: while count > 0 and t >= p.timers[0].finishAt:
p.timers.pop().fut.complete() p.timers.pop().fut.complete()
dec count dec count
@ -201,8 +201,8 @@ proc processTimers(
# Return the number of miliseconds in which the next timer will expire. # Return the number of miliseconds in which the next timer will expire.
if p.timers.len == 0: return if p.timers.len == 0: return
let milisecs = (p.timers[0].finishAt - epochTime()) * 1000 let millisecs = (p.timers[0].finishAt - getMonoTime()).inMilliseconds
return some(ceil(milisecs).int) return some(millisecs.int + 1)
proc processPendingCallbacks(p: PDispatcherBase; didSomeWork: var bool) = proc processPendingCallbacks(p: PDispatcherBase; didSomeWork: var bool) =
while p.callbacks.len > 0: while p.callbacks.len > 0:
@ -1778,7 +1778,11 @@ proc sleepAsync*(ms: int | float): owned(Future[void]) =
## ``ms`` milliseconds. ## ``ms`` milliseconds.
var retFuture = newFuture[void]("sleepAsync") var retFuture = newFuture[void]("sleepAsync")
let p = getGlobalDispatcher() let p = getGlobalDispatcher()
p.timers.push((epochTime() + (ms / 1000), retFuture)) when ms is int:
p.timers.push((getMonoTime() + initDuration(milliseconds = ms), retFuture))
elif ms is float:
let ns = (ms * 1_000_000).int64
p.timers.push((getMonoTime() + initDuration(nanoseconds = ns), retFuture))
return retFuture return retFuture
proc withTimeout*[T](fut: Future[T], timeout: int): owned(Future[bool]) = proc withTimeout*[T](fut: Future[T], timeout: int): owned(Future[bool]) =

View file

@ -20,7 +20,7 @@
import import
hashes, math hashes
type type
BitScalar = uint BitScalar = uint

View file

@ -11,10 +11,8 @@
include "system/inclrtl" include "system/inclrtl"
import strutils, os
when not defined(windows): when not defined(windows):
import posix import strutils, posix, os
when defined(linux): when defined(linux):
import linux import linux

View file

@ -44,10 +44,6 @@
## * `std/sha1 module <sha1.html>`_ for a sha1 encoder and decoder ## * `std/sha1 module <sha1.html>`_ for a sha1 encoder and decoder
## * `tables module <tables.html>`_ for hash tables ## * `tables module <tables.html>`_ for hash tables
import
strutils
type type
Hash* = int ## A hash value. Hash tables using these values should Hash* = int ## A hash value. Hash tables using these values should
## always have a size of a power of two and can use the ``and`` ## always have a size of a power of two and can use the ``and``

View file

@ -176,7 +176,7 @@
## ##
import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes, import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes,
math, random, httpcore, times, tables, streams math, random, httpcore, times, tables, streams, std/monotimes
import asyncnet, asyncdispatch, asyncfile import asyncnet, asyncdispatch, asyncfile
import nativesockets import nativesockets
@ -610,7 +610,7 @@ type
contentTotal: BiggestInt contentTotal: BiggestInt
contentProgress: BiggestInt contentProgress: BiggestInt
oneSecondProgress: BiggestInt oneSecondProgress: BiggestInt
lastProgressReport: float lastProgressReport: MonoTime
when SocketType is AsyncSocket: when SocketType is AsyncSocket:
bodyStream: FutureStream[string] bodyStream: FutureStream[string]
parseBodyFut: Future[void] parseBodyFut: Future[void]
@ -706,13 +706,13 @@ proc reportProgress(client: HttpClient | AsyncHttpClient,
progress: BiggestInt) {.multisync.} = progress: BiggestInt) {.multisync.} =
client.contentProgress += progress client.contentProgress += progress
client.oneSecondProgress += progress client.oneSecondProgress += progress
if epochTime() - client.lastProgressReport >= 1.0: if (getMonoTime() - client.lastProgressReport).inSeconds > 1:
if not client.onProgressChanged.isNil: if not client.onProgressChanged.isNil:
await client.onProgressChanged(client.contentTotal, await client.onProgressChanged(client.contentTotal,
client.contentProgress, client.contentProgress,
client.oneSecondProgress) client.oneSecondProgress)
client.oneSecondProgress = 0 client.oneSecondProgress = 0
client.lastProgressReport = epochTime() client.lastProgressReport = getMonoTime()
proc recvFull(client: HttpClient | AsyncHttpClient, size: int, timeout: int, proc recvFull(client: HttpClient | AsyncHttpClient, size: int, timeout: int,
keep: bool): Future[int] {.multisync.} = keep: bool): Future[int] {.multisync.} =
@ -784,7 +784,7 @@ proc parseBody(client: HttpClient | AsyncHttpClient,
client.contentTotal = 0 client.contentTotal = 0
client.contentProgress = 0 client.contentProgress = 0
client.oneSecondProgress = 0 client.oneSecondProgress = 0
client.lastProgressReport = 0 client.lastProgressReport = MonoTime()
when client is AsyncHttpClient: when client is AsyncHttpClient:
assert(not client.bodyStream.finished) assert(not client.bodyStream.finished)

View file

@ -142,8 +142,8 @@ runnableExamples:
doAssert $(%* Foo()) == """{"a1":0,"a2":0,"a0":0,"a3":0,"a4":0}""" doAssert $(%* Foo()) == """{"a1":0,"a2":0,"a0":0,"a3":0,"a4":0}"""
import import
hashes, tables, strutils, lexbase, streams, unicode, macros, parsejson, hashes, tables, strutils, lexbase, streams, macros, parsejson,
typetraits, options options
export export
tables.`$` tables.`$`

View file

@ -65,7 +65,8 @@
## echo("Client connected from: ", address) ## echo("Client connected from: ", address)
{.deadCodeElim: on.} # dce option deprecated {.deadCodeElim: on.} # dce option deprecated
import nativesockets, os, strutils, parseutils, times, sets, options import nativesockets, os, strutils, parseutils, times, sets, options,
std/monotimes
export Port, `$`, `==` export Port, `$`, `==`
export Domain, SockType, Protocol export Domain, SockType, Protocol
@ -1077,7 +1078,7 @@ proc recv*(socket: Socket, data: pointer, size: int): int {.tags: [ReadIOEffect]
# Save the error in case it gets reset. # Save the error in case it gets reset.
socket.lastError = osLastError() socket.lastError = osLastError()
proc waitFor(socket: Socket, waited: var float, timeout, size: int, proc waitFor(socket: Socket, waited: var Duration, timeout, size: int,
funcName: string): int {.tags: [TimeEffect].} = funcName: string): int {.tags: [TimeEffect].} =
## determines the amount of characters that can be read. Result will never ## determines the amount of characters that can be read. Result will never
## be larger than ``size``. For unbuffered sockets this will be ``1``. ## be larger than ``size``. For unbuffered sockets this will be ``1``.
@ -1092,7 +1093,7 @@ proc waitFor(socket: Socket, waited: var float, timeout, size: int,
result = socket.bufLen - socket.currPos result = socket.bufLen - socket.currPos
result = min(result, size) result = min(result, size)
else: else:
if timeout - int(waited * 1000.0) < 1: if timeout - waited.inMilliseconds < 1:
raise newException(TimeoutError, "Call to '" & funcName & "' timed out.") raise newException(TimeoutError, "Call to '" & funcName & "' timed out.")
when defineSsl: when defineSsl:
@ -1104,17 +1105,17 @@ proc waitFor(socket: Socket, waited: var float, timeout, size: int,
if sslPending != 0: if sslPending != 0:
return min(sslPending, size) return min(sslPending, size)
var startTime = epochTime() var startTime = getMonoTime()
let selRet = select(socket, timeout - int(waited * 1000.0)) let selRet = select(socket, (timeout - waited.inMilliseconds).int)
if selRet < 0: raiseOSError(osLastError()) if selRet < 0: raiseOSError(osLastError())
if selRet != 1: if selRet != 1:
raise newException(TimeoutError, "Call to '" & funcName & "' timed out.") raise newException(TimeoutError, "Call to '" & funcName & "' timed out.")
waited += (epochTime() - startTime) waited += (getMonoTIme() - startTime)
proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {. proc recv*(socket: Socket, data: pointer, size: int, timeout: int): int {.
tags: [ReadIOEffect, TimeEffect].} = tags: [ReadIOEffect, TimeEffect].} =
## overload with a ``timeout`` parameter in milliseconds. ## overload with a ``timeout`` parameter in milliseconds.
var waited = 0.0 # number of seconds already waited var waited: Duration # duration already waited
var read = 0 var read = 0
while read < size: while read < size:
@ -1223,7 +1224,7 @@ proc readLine*(socket: Socket, line: var TaintedString, timeout = -1,
if flags.isDisconnectionError(lastError): setLen(line.string, 0); return if flags.isDisconnectionError(lastError): setLen(line.string, 0); return
socket.socketError(n, lastError = lastError) socket.socketError(n, lastError = lastError)
var waited = 0.0 var waited: Duration
setLen(line.string, 0) setLen(line.string, 0)
while true: while true:
@ -1307,7 +1308,7 @@ proc skip*(socket: Socket, size: int, timeout = -1) =
## bytes takes longer than specified a TimeoutError exception will be raised. ## bytes takes longer than specified a TimeoutError exception will be raised.
## ##
## Returns the number of skipped bytes. ## Returns the number of skipped bytes.
var waited = 0.0 var waited: Duration
var dummy = alloc(size) var dummy = alloc(size)
var bytesSkipped = 0 var bytesSkipped = 0
while bytesSkipped != size: while bytesSkipped != size:

View file

@ -1849,7 +1849,7 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
break break
# getFullPathName doesn't do case corrections, so we have to use this convoluted # getFullPathName doesn't do case corrections, so we have to use this convoluted
# way of retrieving the true filename # way of retrieving the true filename
for x in walkFiles(result.string): for x in walkFiles(result):
result = x result = x
if not existsFile(result) and not existsDir(result): if not existsFile(result) and not existsDir(result):
raise newException(OSError, "file '" & result & "' does not exist") raise newException(OSError, "file '" & result & "' does not exist")

View file

@ -19,7 +19,7 @@
import macros import macros
import strformat import strformat
from strutils import toLowerAscii, `%` from strutils import toLowerAscii, `%`
import colors, tables import colors
when defined(windows): when defined(windows):
import winlean import winlean

View file

@ -1281,7 +1281,7 @@ when isMainModule:
compared = (someString == $someRunes) compared = (someString == $someRunes)
doAssert compared == true doAssert compared == true
proc test_replacements(word: string): string = proc testReplacements(word: string): string =
case word case word
of "two": of "two":
return "2" return "2"
@ -1294,8 +1294,8 @@ when isMainModule:
else: else:
return "12345" return "12345"
doAssert translate("two not alpha foo βeta", test_replacements) == "2 12345 αlpha BAR beta" doAssert translate("two not alpha foo βeta", testReplacements) == "2 12345 αlpha BAR beta"
doAssert translate(" two not foo βeta ", test_replacements) == " 2 12345 BAR beta " doAssert translate(" two not foo βeta ", testReplacements) == " 2 12345 BAR beta "
doAssert title("foo bar") == "Foo Bar" doAssert title("foo bar") == "Foo Bar"
doAssert title("αlpha βeta γamma") == "Αlpha Βeta Γamma" doAssert title("αlpha βeta γamma") == "Αlpha Βeta Γamma"

View file

@ -190,7 +190,7 @@ proc defaultConsoleFormatter*(): <//>ConsoleOutputFormatter =
var envOutLvl = os.getEnv("NIMTEST_OUTPUT_LVL").string var envOutLvl = os.getEnv("NIMTEST_OUTPUT_LVL").string
var colorOutput = isatty(stdout) var colorOutput = isatty(stdout)
if existsEnv("NIMTEST_COLOR"): if existsEnv("NIMTEST_COLOR"):
let colorEnv = getenv("NIMTEST_COLOR") let colorEnv = getEnv("NIMTEST_COLOR")
if colorEnv == "never": if colorEnv == "never":
colorOutput = false colorOutput = false
elif colorEnv == "always": elif colorEnv == "always":
@ -349,7 +349,7 @@ proc glob(matcher, filter: string): bool =
let beforeAndAfter = filter.split('*', maxsplit=1) let beforeAndAfter = filter.split('*', maxsplit=1)
if beforeAndAfter.len == 1: if beforeAndAfter.len == 1:
# "foo*" # "foo*"
return matcher.startswith(beforeAndAfter[0]) return matcher.startsWith(beforeAndAfter[0])
if matcher.len < filter.len - 1: if matcher.len < filter.len - 1:
return false # "12345" should not match "123*345" return false # "12345" should not match "123*345"
@ -366,8 +366,8 @@ proc matchFilter(suiteName, testName, filter: string): bool =
if suiteAndTestFilters.len == 1: if suiteAndTestFilters.len == 1:
# no suite specified # no suite specified
let test_f = suiteAndTestFilters[0] let testFilter = suiteAndTestFilters[0]
return glob(testName, test_f) return glob(testName, testFilter)
return glob(suiteName, suiteAndTestFilters[0]) and glob(testName, suiteAndTestFilters[1]) return glob(suiteName, suiteAndTestFilters[0]) and glob(testName, suiteAndTestFilters[1])
@ -627,7 +627,7 @@ macro check*(conditions: untyped): untyped =
# Ident !"v" # Ident !"v"
# IntLit 2 # IntLit 2
result.check[i] = exp[i][1] result.check[i] = exp[i][1]
if exp[i].typekind notin {ntyTypeDesc}: if exp[i].typeKind notin {ntyTypeDesc}:
let arg = newIdentNode(":p" & $counter) let arg = newIdentNode(":p" & $counter)
result.assigns.add getAst(asgn(arg, paramAst)) result.assigns.add getAst(asgn(arg, paramAst))
result.printOuts.add getAst(print(argStr, arg)) result.printOuts.add getAst(print(argStr, arg))
@ -640,7 +640,7 @@ macro check*(conditions: untyped): untyped =
of nnkCallKinds: of nnkCallKinds:
let (assigns, check, printOuts) = inspectArgs(checked) let (assigns, check, printOuts) = inspectArgs(checked)
let lineinfo = newStrLitNode(checked.lineinfo) let lineinfo = newStrLitNode(checked.lineInfo)
let callLit = checked.toStrLit let callLit = checked.toStrLit
result = quote do: result = quote do:
block: block:
@ -657,7 +657,7 @@ macro check*(conditions: untyped): untyped =
result.add(newCall(!"check", node)) result.add(newCall(!"check", node))
else: else:
let lineinfo = newStrLitNode(checked.lineinfo) let lineinfo = newStrLitNode(checked.lineInfo)
let callLit = checked.toStrLit let callLit = checked.toStrLit
result = quote do: result = quote do:
@ -712,7 +712,7 @@ macro expect*(exceptions: varargs[typed], body: untyped): untyped =
for i in countup(1, exp.len - 2): for i in countup(1, exp.len - 2):
errorTypes.add(exp[i]) errorTypes.add(exp[i])
result = getAst(expectBody(errorTypes, exp.lineinfo, body)) result = getAst(expectBody(errorTypes, exp.lineInfo, body))
proc disableParamFiltering* = proc disableParamFiltering* =
## disables filtering tests with the command line params ## disables filtering tests with the command line params

View file

@ -25,7 +25,7 @@ const
Usage: Usage:
nimpretty [options] file.nim nimpretty [options] file.nim
Options: Options:
--output:file set the output file (default: overwrite the input file) --out:file set the output file (default: overwrite the input file)
--indent:N[=0] set the number of spaces that is used for indentation --indent:N[=0] set the number of spaces that is used for indentation
--indent:0 means autodetection (default behaviour) --indent:0 means autodetection (default behaviour)
--maxLineLen:N set the desired maximum line length (default: 80) --maxLineLen:N set the desired maximum line length (default: 80)
@ -79,7 +79,7 @@ proc main =
of "help", "h": writeHelp() of "help", "h": writeHelp()
of "version", "v": writeVersion() of "version", "v": writeVersion()
of "backup": backup = parseBool(val) of "backup": backup = parseBool(val)
of "output", "o": outfile = val of "output", "o", "out": outfile = val
of "indent": opt.indWidth = parseInt(val) of "indent": opt.indWidth = parseInt(val)
of "maxlinelen": opt.maxLineLen = parseInt(val) of "maxlinelen": opt.maxLineLen = parseInt(val)
else: writeHelp() else: writeHelp()

View file

@ -761,3 +761,64 @@ var rows2 = await pool.rows(sql"""
"BBBB" "BBBB"
] ]
) )
# bug #11699
const keywords = @[
"foo", "bar", "foo", "bar", "foo", "bar", "foo", "bar", "foo", "bar", "foo", "bar", "foo", "bar",
"zzz", "ggg", "ddd",
]
let keywords1 = @[
"foo1", "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4", "foo5", "bar5", "foo6", "bar6", "foo7",
"zzz", "ggg", "ddd",
]
let keywords2 = @[
"foo1", "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4", "foo5", "bar5", "foo6", "bar6", "foo7",
"foo1", "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4", "foo5", "bar5", "foo6", "bar6", "foo7",
"zzz", "ggg", "ddd",
]
if true:
let keywords3 = @[
"foo1", "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4", "foo5", "bar5", "foo6", "bar6", "foo7",
"zzz", "ggg", "ddd",
]
const b = true
let fooB =
if true:
if b: 7 else: 8
else: ord(b)
let foo = if cond:
if b: T else: F
else: b
let a =
[[aaadsfas, bbb],
[ccc, ddd]]
let b = [
[aaa, bbb],
[ccc, ddd]
]
# bug #11616
proc newRecordGen(ctx: Context; typ: TypRef): PNode =
result = nkTypeDef.t(
newId(typ.optSym.name, true, pragmas = [id(if typ.isUnion: "cUnion"
else: "cStruct")]),
empty(),
nkObjectTy.t(
empty(),
empty(),
nkRecList.t(
typ.recFields.map(newRecFieldGen))))
proc f =
# doesn't break the code, but leaving indentation as is would be nice.
let x = if true: callingProcWhatever()
else: callingADifferentProc()

View file

@ -769,3 +769,69 @@ var rows2 = await pool.rows(sql"""
"BBBB" "BBBB"
] ]
) )
# bug #11699
const keywords = @[
"foo", "bar", "foo", "bar", "foo", "bar", "foo", "bar", "foo", "bar", "foo",
"bar", "foo", "bar",
"zzz", "ggg", "ddd",
]
let keywords1 = @[
"foo1", "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4", "foo5",
"bar5", "foo6", "bar6", "foo7",
"zzz", "ggg", "ddd",
]
let keywords2 = @[
"foo1", "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4", "foo5",
"bar5", "foo6", "bar6", "foo7",
"foo1", "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4", "foo5",
"bar5", "foo6", "bar6", "foo7",
"zzz", "ggg", "ddd",
]
if true:
let keywords3 = @[
"foo1", "bar1", "foo2", "bar2", "foo3", "bar3", "foo4", "bar4", "foo5",
"bar5", "foo6", "bar6", "foo7",
"zzz", "ggg", "ddd",
]
const b = true
let fooB =
if true:
if b: 7 else: 8
else: ord(b)
let foo = if cond:
if b: T else: F
else: b
let a =
[[aaadsfas, bbb],
[ccc, ddd]]
let b = [
[aaa, bbb],
[ccc, ddd]
]
# bug #11616
proc newRecordGen(ctx: Context; typ: TypRef): PNode =
result = nkTypeDef.t(
newId(typ.optSym.name, true, pragmas = [id(if typ.isUnion: "cUnion"
else: "cStruct")]),
empty(),
nkObjectTy.t(
empty(),
empty(),
nkRecList.t(
typ.recFields.map(newRecFieldGen))))
proc f =
# doesn't break the code, but leaving indentation as is would be nice.
let x = if true: callingProcWhatever()
else: callingADifferentProc()

View file

@ -1,49 +1,63 @@
discard """ discard """
errormsg: "type mismatch: got <Bar[system.int]>" errormsg: "type mismatch: got <Bar[system.int]>"
disabled: "true" disabled: "32bit"
nimout: ''' nimout: '''
t3330.nim(63, 4) Error: type mismatch: got <Bar[system.int]> t3330.nim(78, 4) Error: type mismatch: got <Bar[system.int]>
but expected one of: but expected one of:
proc test(foo: Foo[int]) proc test(foo: Foo[int])
t3330.nim(48, 8) Hint: Non-matching candidates for add(k, string, T) first type mismatch at position: 1
required type for foo: Foo[int]
but expression 'bar' is of type: Bar[system.int]
t3330.nim(63, 8) Hint: Non-matching candidates for add(k, string, T)
proc add[T](x: var seq[T]; y: openArray[T]) proc add[T](x: var seq[T]; y: openArray[T])
first type mismatch at position: 1 first type mismatch at position: 1
required type: var seq[T] required type for x: var seq[T]
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
proc add(result: var string; x: float) proc add(result: var string; x: float)
first type mismatch at position: 1 first type mismatch at position: 1
required type: var string required type for result: var string
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
proc add(x: var string; y: string) proc add(x: var string; y: string)
first type mismatch at position: 1 first type mismatch at position: 1
required type: var string required type for x: var string
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
proc add(x: var string; y: cstring) proc add(x: var string; y: cstring)
first type mismatch at position: 1 first type mismatch at position: 1
required type: var string required type for x: var string
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
proc add[T](x: var seq[T]; y: T) proc add[T](x: var seq[T]; y: T)
first type mismatch at position: 1 first type mismatch at position: 1
required type: var seq[T] required type for x: var seq[T]
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
proc add(result: var string; x: int64) proc add(result: var string; x: int64)
first type mismatch at position: 1 first type mismatch at position: 1
required type: var string required type for result: var string
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
proc add(x: var string; y: char) proc add(x: var string; y: char)
first type mismatch at position: 1 first type mismatch at position: 1
required type: var string required type for x: var string
but expression 'k' is of type: Alias but expression 'k' is of type: Alias
t3330.nim(48, 8) template/generic instantiation of `add` from here t3330.nim(63, 8) template/generic instantiation of `add` from here
t3330.nim(55, 6) Foo: 'bar.value' cannot be assigned to t3330.nim(70, 6) Foo: 'bar.value' cannot be assigned to
t3330.nim(48, 8) template/generic instantiation of `add` from here t3330.nim(63, 8) template/generic instantiation of `add` from here
t3330.nim(56, 6) Foo: 'bar.x' cannot be assigned to t3330.nim(71, 6) Foo: 'bar.x' cannot be assigned to
expression: test(bar)''' expression: test(bar)'''
""" """
# Note: currently disabled on 32bit because the candidates are presented in
# different order on travis with `NIM_COMPILE_TO_CPP=false CPU=i386`;
# a possible fix would be to sort the candidates by proc signature or
# declaration location
## line 60
type type
Foo[T] = concept k Foo[T] = concept k
add(k, string, T) add(k, string, T)

View file

@ -2,69 +2,101 @@ discard """
cmd: "nim c --verbosity:0 --colors:off $file" cmd: "nim c --verbosity:0 --colors:off $file"
nimout: ''' nimout: '''
Hint: texplain [Processing] Hint: texplain [Processing]
texplain.nim(118, 10) Hint: Non-matching candidates for e(y) texplain.nim(158, 10) Hint: Non-matching candidates for e(y)
proc e(i: int): int proc e(i: int): int
first type mismatch at position: 1
required type for i: int
but expression 'y' is of type: MatchingType
texplain.nim(121, 7) Hint: Non-matching candidates for e(10) texplain.nim(161, 7) Hint: Non-matching candidates for e(10)
proc e(o: ExplainedConcept): int proc e(o: ExplainedConcept): int
texplain.nim(84, 6) ExplainedConcept: undeclared field: 'foo' first type mismatch at position: 1
texplain.nim(84, 6) ExplainedConcept: undeclared field: '.' required type for o: ExplainedConcept
texplain.nim(84, 6) ExplainedConcept: expression '.' cannot be called but expression '10' is of type: int literal(10)
texplain.nim(84, 5) ExplainedConcept: concept predicate failed texplain.nim(124, 6) ExplainedConcept: undeclared field: 'foo'
texplain.nim(85, 6) ExplainedConcept: undeclared field: 'bar' texplain.nim(124, 6) ExplainedConcept: undeclared field: '.'
texplain.nim(85, 6) ExplainedConcept: undeclared field: '.' texplain.nim(124, 6) ExplainedConcept: expression '.' cannot be called
texplain.nim(85, 6) ExplainedConcept: expression '.' cannot be called texplain.nim(124, 5) ExplainedConcept: concept predicate failed
texplain.nim(84, 5) ExplainedConcept: concept predicate failed texplain.nim(125, 6) ExplainedConcept: undeclared field: 'bar'
texplain.nim(125, 6) ExplainedConcept: undeclared field: '.'
texplain.nim(125, 6) ExplainedConcept: expression '.' cannot be called
texplain.nim(124, 5) ExplainedConcept: concept predicate failed
texplain.nim(124, 10) Hint: Non-matching candidates for e(10) texplain.nim(164, 10) Hint: Non-matching candidates for e(10)
proc e(o: ExplainedConcept): int proc e(o: ExplainedConcept): int
texplain.nim(84, 6) ExplainedConcept: undeclared field: 'foo' first type mismatch at position: 1
texplain.nim(84, 6) ExplainedConcept: undeclared field: '.' required type for o: ExplainedConcept
texplain.nim(84, 6) ExplainedConcept: expression '.' cannot be called but expression '10' is of type: int literal(10)
texplain.nim(84, 5) ExplainedConcept: concept predicate failed texplain.nim(124, 6) ExplainedConcept: undeclared field: 'foo'
texplain.nim(85, 6) ExplainedConcept: undeclared field: 'bar' texplain.nim(124, 6) ExplainedConcept: undeclared field: '.'
texplain.nim(85, 6) ExplainedConcept: undeclared field: '.' texplain.nim(124, 6) ExplainedConcept: expression '.' cannot be called
texplain.nim(85, 6) ExplainedConcept: expression '.' cannot be called texplain.nim(124, 5) ExplainedConcept: concept predicate failed
texplain.nim(84, 5) ExplainedConcept: concept predicate failed texplain.nim(125, 6) ExplainedConcept: undeclared field: 'bar'
texplain.nim(125, 6) ExplainedConcept: undeclared field: '.'
texplain.nim(125, 6) ExplainedConcept: expression '.' cannot be called
texplain.nim(124, 5) ExplainedConcept: concept predicate failed
texplain.nim(128, 20) Error: type mismatch: got <NonMatchingType> texplain.nim(168, 20) Error: type mismatch: got <NonMatchingType>
but expected one of: but expected one of:
proc e(o: ExplainedConcept): int proc e(o: ExplainedConcept): int
texplain.nim(128, 9) template/generic instantiation of `assert` from here first type mismatch at position: 1
texplain.nim(84, 5) ExplainedConcept: concept predicate failed required type for o: ExplainedConcept
but expression 'n' is of type: NonMatchingType
texplain.nim(168, 9) template/generic instantiation of `assert` from here
texplain.nim(124, 5) ExplainedConcept: concept predicate failed
proc e(i: int): int proc e(i: int): int
first type mismatch at position: 1
required type for i: int
but expression 'n' is of type: NonMatchingType
expression: e(n) expression: e(n)
texplain.nim(129, 20) Error: type mismatch: got <NonMatchingType> texplain.nim(169, 20) Error: type mismatch: got <NonMatchingType>
but expected one of: but expected one of:
proc r(o: RegularConcept): int proc r(o: RegularConcept): int
texplain.nim(129, 9) template/generic instantiation of `assert` from here first type mismatch at position: 1
texplain.nim(88, 5) RegularConcept: concept predicate failed required type for o: RegularConcept
but expression 'n' is of type: NonMatchingType
texplain.nim(169, 9) template/generic instantiation of `assert` from here
texplain.nim(128, 5) RegularConcept: concept predicate failed
proc r[T](a: SomeNumber; b: T; c: auto) proc r[T](a: SomeNumber; b: T; c: auto)
first type mismatch at position: 1
required type for a: SomeNumber
but expression 'n' is of type: NonMatchingType
proc r(i: string): int proc r(i: string): int
first type mismatch at position: 1
required type for i: string
but expression 'n' is of type: NonMatchingType
expression: r(n) expression: r(n)
texplain.nim(130, 20) Hint: Non-matching candidates for r(y) texplain.nim(170, 20) Hint: Non-matching candidates for r(y)
proc r[T](a: SomeNumber; b: T; c: auto) proc r[T](a: SomeNumber; b: T; c: auto)
first type mismatch at position: 1
required type for a: SomeNumber
but expression 'y' is of type: MatchingType
proc r(i: string): int proc r(i: string): int
first type mismatch at position: 1
required type for i: string
but expression 'y' is of type: MatchingType
texplain.nim(138, 2) Error: type mismatch: got <MatchingType> texplain.nim(178, 2) Error: type mismatch: got <MatchingType>
but expected one of: but expected one of:
proc f(o: NestedConcept) proc f(o: NestedConcept)
texplain.nim(88, 6) RegularConcept: undeclared field: 'foo' first type mismatch at position: 1
texplain.nim(88, 6) RegularConcept: undeclared field: '.' required type for o: NestedConcept
texplain.nim(88, 6) RegularConcept: expression '.' cannot be called but expression 'y' is of type: MatchingType
texplain.nim(88, 5) RegularConcept: concept predicate failed texplain.nim(128, 6) RegularConcept: undeclared field: 'foo'
texplain.nim(89, 6) RegularConcept: undeclared field: 'bar' texplain.nim(128, 6) RegularConcept: undeclared field: '.'
texplain.nim(89, 6) RegularConcept: undeclared field: '.' texplain.nim(128, 6) RegularConcept: expression '.' cannot be called
texplain.nim(89, 6) RegularConcept: expression '.' cannot be called texplain.nim(128, 5) RegularConcept: concept predicate failed
texplain.nim(88, 5) RegularConcept: concept predicate failed texplain.nim(129, 6) RegularConcept: undeclared field: 'bar'
texplain.nim(92, 5) NestedConcept: concept predicate failed texplain.nim(129, 6) RegularConcept: undeclared field: '.'
texplain.nim(129, 6) RegularConcept: expression '.' cannot be called
texplain.nim(128, 5) RegularConcept: concept predicate failed
texplain.nim(132, 5) NestedConcept: concept predicate failed
expression: f(y) expression: f(y)'''
'''
errormsg: "type mismatch: got <MatchingType>" errormsg: "type mismatch: got <MatchingType>"
line: 138 line: 178
disabled: 32bit disabled: 32bit
""" """
@ -77,7 +109,15 @@ expression: f(y)
# line 80 HERE
# line 120 HERE
type type
ExplainedConcept {.explain.} = concept o ExplainedConcept {.explain.} = concept o

View file

@ -1,21 +1,33 @@
discard """ discard """
cmd: "nim check --newruntime --hints:off $file" cmd: "nim check --newruntime --hints:off $file"
nimout: '''tdont_return_unowned_from_owned.nim(24, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(Obj)' as the return type nimout: '''tdont_return_unowned_from_owned.nim(36, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(Obj)' as the return type
tdont_return_unowned_from_owned.nim(27, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(Obj)' as the return type tdont_return_unowned_from_owned.nim(39, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(Obj)' as the return type
tdont_return_unowned_from_owned.nim(30, 6) Error: type mismatch: got <Obj> tdont_return_unowned_from_owned.nim(42, 6) Error: type mismatch: got <Obj>
but expected one of: but expected one of:
proc new[T](a: var ref T; finalizer: proc (x: ref T) {.nimcall.}) proc new[T](a: var ref T; finalizer: proc (x: ref T) {.nimcall.})
first type mismatch at position: 2
missing parameter: finalizer
2 other mismatching symbols have been suppressed; compile with --showAllMismatches:on to see them 2 other mismatching symbols have been suppressed; compile with --showAllMismatches:on to see them
expression: new(result) expression: new(result)
tdont_return_unowned_from_owned.nim(30, 6) Error: illformed AST: tdont_return_unowned_from_owned.nim(42, 6) Error: illformed AST:
tdont_return_unowned_from_owned.nim(38, 13) Error: assignment produces a dangling ref: the unowned ref lives longer than the owned ref tdont_return_unowned_from_owned.nim(50, 13) Error: assignment produces a dangling ref: the unowned ref lives longer than the owned ref
tdont_return_unowned_from_owned.nim(39, 13) Error: assignment produces a dangling ref: the unowned ref lives longer than the owned ref tdont_return_unowned_from_owned.nim(51, 13) Error: assignment produces a dangling ref: the unowned ref lives longer than the owned ref
tdont_return_unowned_from_owned.nim(43, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(RootRef)' as the return type tdont_return_unowned_from_owned.nim(55, 10) Error: cannot return an owned pointer as an unowned pointer; use 'owned(RootRef)' as the return type
''' '''
errormsg: "cannot return an owned pointer as an unowned pointer; use 'owned(RootRef)' as the return type" errormsg: "cannot return an owned pointer as an unowned pointer; use 'owned(RootRef)' as the return type"
line: 43 line: 55
""" """
## line 30
# bug #11073 # bug #11073
type type
Obj = ref object Obj = ref object

View file

@ -4,7 +4,7 @@ discard """
proc fun0[T1: int | float | proc fun0[T1: int | float |
object | array | seq](a1: T1; a2: int) object | array | seq](a1: T1; a2: int)
first type mismatch at position: 1 first type mismatch at position: 1
required type: T1: int or float or object or array or seq[T] required type for a1: T1: int or float or object or array or seq[T]
but expression 'byte(1)' is of type: byte but expression 'byte(1)' is of type: byte
expression: fun0(byte(1), 0) expression: fun0(byte(1), 0)

View file

@ -6,7 +6,7 @@ nimout: '''
but expected one of: but expected one of:
proc main(a, b, c: string) proc main(a, b, c: string)
first type mismatch at position: 1 first type mismatch at position: 1
required type: string required type for a: string
but expression '1' is of type: int literal(1) but expression '1' is of type: int literal(1)
expression: main(1, 2, 3) expression: main(1, 2, 3)

View file

@ -8,7 +8,7 @@ proc serve(server: AsyncHttpServer; port: Port;
callback: proc (request: Request): Future[void] {.closure, gcsafe.}; callback: proc (request: Request): Future[void] {.closure, gcsafe.};
address = ""): owned(Future[void]) address = ""): owned(Future[void])
first type mismatch at position: 3 first type mismatch at position: 3
required type: proc (request: Request): Future[system.void]{.closure, gcsafe.} required type for callback: proc (request: Request): Future[system.void]{.closure, gcsafe.}
but expression 'cb' is of type: proc (req: Request): Future[system.void]{.locks: <unknown>.} but expression 'cb' is of type: proc (req: Request): Future[system.void]{.locks: <unknown>.}
This expression is not GC-safe. Annotate the proc with {.gcsafe.} to get extended error information. This expression is not GC-safe. Annotate the proc with {.gcsafe.} to get extended error information.

172
tests/errmsgs/tsigmatch.nim Normal file
View file

@ -0,0 +1,172 @@
discard """
cmd: "nim check --showAllMismatches:on --hints:off $file"
nimout: '''
tsigmatch.nim(111, 4) Error: type mismatch: got <A, string>
but expected one of:
proc f(b: B)
first type mismatch at position: 1
required type for b: B
but expression 'A()' is of type: A
proc f(a: A)
first type mismatch at position: 2
extra argument given
expression: f(A(), "extra")
tsigmatch.nim(125, 6) Error: type mismatch: got <tuple of (string, proc (){.gcsafe, locks: 0.})>
but expected one of:
proc foo(x: (string, proc ()))
first type mismatch at position: 1
required type for x: tuple of (string, proc (){.closure.})
but expression '("foobar", proc () = echo(["Hello!"]))' is of type: tuple of (string, proc (){.gcsafe, locks: 0.})
expression: foo(("foobar", proc () = echo(["Hello!"])))
tsigmatch.nim(132, 11) Error: type mismatch: got <proc (s: string): string{.noSideEffect, gcsafe, locks: 0.}>
but expected one of:
proc foo[T, S](op: proc (x: T): S {.cdecl.}): auto
first type mismatch at position: 1
required type for op: proc (x: T): S{.cdecl.}
but expression 'fun' is of type: proc (s: string): string{.noSideEffect, gcsafe, locks: 0.}
proc foo[T, S](op: proc (x: T): S {.safecall.}): auto
first type mismatch at position: 1
required type for op: proc (x: T): S{.safecall.}
but expression 'fun' is of type: proc (s: string): string{.noSideEffect, gcsafe, locks: 0.}
expression: foo(fun)
tsigmatch.nim(143, 13) Error: type mismatch: got <array[0..0, proc (x: int){.gcsafe, locks: 0.}]>
but expected one of:
proc takesFuncs(fs: openArray[proc (x: int) {.gcsafe, locks: 0.}])
first type mismatch at position: 1
required type for fs: openarray[proc (x: int){.closure, gcsafe, locks: 0.}]
but expression '[proc (x: int) {.gcsafe, locks: 0.} = echo [x]]' is of type: array[0..0, proc (x: int){.gcsafe, locks: 0.}]
expression: takesFuncs([proc (x: int) {.gcsafe, locks: 0.} = echo [x]])
tsigmatch.nim(149, 4) Error: type mismatch: got <int literal(10), a0: int literal(5), string>
but expected one of:
proc f(a0: uint8; b: string)
first type mismatch at position: 2
named param already provided: a0
expression: f(10, a0 = 5, "")
tsigmatch.nim(156, 4) Error: type mismatch: got <string, string, string, string, string, float64, string>
but expected one of:
proc f(a1: int)
first type mismatch at position: 1
required type for a1: int
but expression '"asdf"' is of type: string
proc f(a1: string; a2: varargs[string]; a3: float; a4: var string)
first type mismatch at position: 7
required type for a4: var string
but expression '"bad"' is immutable, not 'var'
expression: f("asdf", "1", "2", "3", "4", 2.3, "bad")
tsigmatch.nim(164, 4) Error: type mismatch: got <string, a0: int literal(12)>
but expected one of:
proc f(x: string; a0: var int)
first type mismatch at position: 2
required type for a0: var int
but expression 'a0 = 12' is immutable, not 'var'
proc f(x: string; a0: string)
first type mismatch at position: 2
required type for a0: string
but expression 'a0 = 12' is of type: int literal(12)
expression: f(foo, a0 = 12)
tsigmatch.nim(171, 7) Error: type mismatch: got <Mystring, string>
but expected one of:
proc fun1(a1: MyInt; a2: Mystring)
first type mismatch at position: 1
required type for a1: MyInt
but expression 'default(Mystring)' is of type: Mystring
proc fun1(a1: float; a2: Mystring)
first type mismatch at position: 1
required type for a1: float
but expression 'default(Mystring)' is of type: Mystring
expression: fun1(default(Mystring), "asdf")
'''
errormsg: "type mismatch"
"""
## line 100
block:
# bug #11061 Type mismatch error "first type mismatch at" points to wrong argument/position
# Note: the error msg now gives correct position for mismatched argument
type
A = object of RootObj
B = object of A
proc f(b: B) = discard
proc f(a: A) = discard
f(A(), "extra")
#[
this one is similar but error msg was even more misleading, since the user
would think float != float64 where in fact the issue is another param:
first type mismatch at position: 1; required type: float; but expression 'x = 1.2' is of type: float64
proc f(x: string, a0 = 0, a1 = 0, a2 = 0) = discard
proc f(x: float, a0 = 0, a1 = 0, a2 = 0) = discard
f(x = float(1.2), a0 = 0, a0 = 0)
]#
block:
# bug #7808 Passing tuple with proc leads to confusing errors
# Note: the error message now shows `closure` which helps debugging the issue
proc foo(x: (string, proc ())) = x[1]()
foo(("foobar", proc () = echo("Hello!")))
block:
# bug #8305 type mismatch error drops crucial pragma info when there's only 1 argument
proc fun(s: string): string {. .} = discard
proc foo[T, S](op: proc (x: T): S {. cdecl .}): auto = 1
proc foo[T, S](op: proc (x: T): S {. safecall .}): auto = 1
echo foo(fun)
block:
# bug #10285 Function signature don't match when inside seq/array/openarray
# Note: the error message now shows `closure` which helps debugging the issue
# out why it doesn't match
proc takesFunc(f: proc (x: int) {.gcsafe, locks: 0.}) =
echo "takes single Func"
proc takesFuncs(fs: openarray[proc (x: int) {.gcsafe, locks: 0.}]) =
echo "takes multiple Func"
takesFunc(proc (x: int) {.gcsafe, locks: 0.} = echo x) # works
takesFuncs([proc (x: int) {.gcsafe, locks: 0.} = echo x]) # fails
block:
# bug https://github.com/nim-lang/Nim/issues/11061#issuecomment-508970465
# better fix for removal of `errCannotBindXTwice` due to #3836
proc f(a0: uint8, b: string) = discard
f(10, a0 = 5, "")
block:
# bug: https://github.com/nim-lang/Nim/issues/11061#issuecomment-508969796
# sigmatch gets confused with param/arg position after varargs
proc f(a1: int) = discard
proc f(a1: string, a2: varargs[string], a3: float, a4: var string) = discard
f("asdf", "1", "2", "3", "4", 2.3, "bad")
block:
# bug: https://github.com/nim-lang/Nim/issues/11061#issuecomment-508970046
# err msg incorrectly said something is immutable
proc f(x: string, a0: var int) = discard
proc f(x: string, a0: string) = discard
var foo = ""
f(foo, a0 = 12)
block:
type Mystring = string
type MyInt = int
proc fun1(a1: MyInt, a2: Mystring) = discard
proc fun1(a1: float, a2: Mystring) = discard
fun1(Mystring.default, "asdf")

View file

@ -4,14 +4,14 @@ errormsg: "type mismatch: got <string, set[char], maxsplits: int literal(1)>"
nimout: ''' nimout: '''
proc rsplit(s: string; sep: char; maxsplit: int = -1): seq[string] proc rsplit(s: string; sep: char; maxsplit: int = -1): seq[string]
first type mismatch at position: 2 first type mismatch at position: 2
required type: char required type for sep: char
but expression '{':'}' is of type: set[char] but expression '{':'}' is of type: set[char]
proc rsplit(s: string; seps: set[char] = Whitespace; maxsplit: int = -1): seq[string] proc rsplit(s: string; seps: set[char] = Whitespace; maxsplit: int = -1): seq[string]
first type mismatch at position: 3 first type mismatch at position: 3
unknown named parameter: maxsplits unknown named parameter: maxsplits
proc rsplit(s: string; sep: string; maxsplit: int = -1): seq[string] proc rsplit(s: string; sep: string; maxsplit: int = -1): seq[string]
first type mismatch at position: 2 first type mismatch at position: 2
required type: string required type for sep: string
but expression '{':'}' is of type: set[char] but expression '{':'}' is of type: set[char]
expression: rsplit("abc:def", {':'}, maxsplits = 1) expression: rsplit("abc:def", {':'}, maxsplits = 1)

Some files were not shown because too many files have changed in this diff Show more