Merge branch 'devel' into araq-detect-unused-imports
This commit is contained in:
commit
fbb0642e27
105 changed files with 1275 additions and 792 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
55
changelogs/changelog_0_20_2.md
Normal file
55
changelogs/changelog_0_20_2.md
Normal 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
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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) =
|
||||||
|
|
|
||||||
|
|
@ -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) =
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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', '_'}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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])
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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) =
|
||||||
|
|
|
||||||
|
|
@ -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) =
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 -----------------------------
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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'
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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* = ","
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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]) =
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
|
|
||||||
import
|
import
|
||||||
hashes, math
|
hashes
|
||||||
|
|
||||||
type
|
type
|
||||||
BitScalar = uint
|
BitScalar = uint
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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``
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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.`$`
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
172
tests/errmsgs/tsigmatch.nim
Normal 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")
|
||||||
|
|
||||||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue