Showing with 5,100 additions and 2,895 deletions.
  1. +42 −1 changelog.md
  2. +1 −1 changelogs/changelog_2_0_0_details.md
  3. +17 −6 compiler/ast.nim
  4. +6 −0 compiler/astmsgs.nim
  5. +16 −3 compiler/ccgcalls.nim
  6. +31 −10 compiler/ccgexprs.nim
  7. +5 −2 compiler/ccgstmts.nim
  8. +20 −7 compiler/ccgtypes.nim
  9. +4 −1 compiler/ccgutils.nim
  10. +88 −30 compiler/cgen.nim
  11. +3 −1 compiler/cgendata.nim
  12. +2 −1 compiler/cgmeth.nim
  13. +5 −0 compiler/cmdlinehelper.nim
  14. +5 −1 compiler/commands.nim
  15. +1 −1 compiler/concepts.nim
  16. +3 −1 compiler/condsyms.nim
  17. +3 −2 compiler/extccomp.nim
  18. +1 −1 compiler/ic/ic.nim
  19. +9 −1 compiler/importer.nim
  20. +45 −23 compiler/injectdestructors.nim
  21. +1 −1 compiler/installer.ini
  22. +6 −2 compiler/jsgen.nim
  23. +35 −15 compiler/lambdalifting.nim
  24. +30 −11 compiler/liftdestructors.nim
  25. +5 −1 compiler/lineinfos.nim
  26. +40 −1 compiler/lookups.nim
  27. +0 −19 compiler/lowerings.nim
  28. +10 −6 compiler/modulepaths.nim
  29. +9 −5 compiler/msgs.nim
  30. +2 −1 compiler/options.nim
  31. +17 −18 compiler/parser.nim
  32. +22 −2 compiler/pragmas.nim
  33. +3 −4 compiler/renderer.nim
  34. +30 −2 compiler/sem.nim
  35. +30 −13 compiler/semcall.nim
  36. +3 −1 compiler/semdata.nim
  37. +130 −31 compiler/semexprs.nim
  38. +7 −1 compiler/semfold.nim
  39. +72 −3 compiler/semgnrc.nim
  40. +11 −2 compiler/seminst.nim
  41. +3 −1 compiler/semmagic.nim
  42. +44 −23 compiler/semobjconstr.nim
  43. +22 −11 compiler/sempass2.nim
  44. +99 −52 compiler/semstmts.nim
  45. +68 −77 compiler/semtempl.nim
  46. +74 −25 compiler/semtypes.nim
  47. +27 −12 compiler/semtypinst.nim
  48. +121 −69 compiler/sigmatch.nim
  49. +3 −4 compiler/sizealignoffsetimpl.nim
  50. +1 −1 compiler/sourcemap.nim
  51. +14 −2 compiler/spawn.nim
  52. +3 −2 compiler/suggest.nim
  53. +8 −6 compiler/transf.nim
  54. +5 −3 compiler/trees.nim
  55. +8 −4 compiler/typeallowed.nim
  56. +9 −1 compiler/types.nim
  57. +7 −1 compiler/varpartitions.nim
  58. +3 −0 compiler/vm.nim
  59. +4 −0 compiler/vmdeps.nim
  60. +6 −6 compiler/vmgen.nim
  61. +19 −8 compiler/wordrecg.nim
  62. +57 −28 doc/destructors.md
  63. +1 −1 doc/grammar.txt
  64. +4 −2 doc/manual.md
  65. +1 −0 doc/manual_experimental.md
  66. +25 −15 doc/nep1.md
  67. +0 −3 doc/nimc.md
  68. +1 −1 doc/tut2.md
  69. +5 −2 koch.nim
  70. +7 −3 lib/core/macros.nim
  71. +5 −2 lib/core/typeinfo.nim
  72. +2 −2 lib/packages/docutils/rst.nim
  73. +2 −1 lib/posix/inotify.nim
  74. +10 −10 lib/posix/posix_utils.nim
  75. +19 −19 lib/pure/asyncdispatch.nim
  76. +16 −16 lib/pure/asyncfile.nim
  77. +2 −2 lib/pure/asyncnet.nim
  78. +1 −1 lib/pure/base64.nim
  79. +4 −1 lib/pure/collections/hashcommon.nim
  80. +1 −1 lib/pure/collections/setimpl.nim
  81. +2 −2 lib/pure/collections/sets.nim
  82. +4 −4 lib/pure/collections/tableimpl.nim
  83. +2 −2 lib/pure/collections/tables.nim
  84. +18 −3 lib/pure/complex.nim
  85. +3 −2 lib/pure/distros.nim
  86. +1 −1 lib/pure/dynlib.nim
  87. +1 −1 lib/pure/encodings.nim
  88. +8 −8 lib/pure/includes/unicode_ranges.nim
  89. +1 −1 lib/pure/json.nim
  90. +2 −1 lib/pure/marshal.nim
  91. +2 −3 lib/pure/math.nim
  92. +910 −1,780 lib/pure/mimetypes.nim
  93. +2 −2 lib/pure/options.nim
  94. +15 −10 lib/pure/os.nim
  95. +1 −4 lib/pure/random.nim
  96. +97 −39 lib/pure/strformat.nim
  97. +18 −18 lib/pure/strutils.nim
  98. +13 −8 lib/pure/unicode.nim
  99. +1 −1 lib/std/editdistance.nim
  100. +3 −2 lib/std/enumutils.nim
  101. +1 −1 lib/std/exitprocs.nim
  102. +3 −3 lib/std/formatfloat.nim
  103. +3 −10 lib/std/private/gitutils.nim
  104. +1 −1 lib/std/private/osfiles.nim
  105. +20 −7 lib/std/private/ospaths2.nim
  106. +13 −13 lib/std/syncio.nim
  107. +4 −3 lib/std/tasks.nim
  108. +2 −1 lib/std/widestrs.nim
  109. +28 −10 lib/system.nim
  110. +3 −0 lib/system/ansi_c.nim
  111. +3 −3 lib/system/arc.nim
  112. +1 −1 lib/system/channels_builtin.nim
  113. +1 −1 lib/system/compilation.nim
  114. +3 −2 lib/system/embedded.nim
  115. +49 −32 lib/system/excpt.nim
  116. +7 −7 lib/system/fatal.nim
  117. +35 −27 lib/system/iterators.nim
  118. +13 −4 lib/system/iterators_1.nim
  119. +1 −1 lib/system/mm/go.nim
  120. +28 −16 lib/system/orc.nim
  121. +1 −1 lib/system/osalloc.nim
  122. +1 −1 lib/system/repr.nim
  123. +1 −11 lib/system/repr_v2.nim
  124. +81 −8 lib/system/seqs_v2.nim
  125. +17 −24 lib/system/sysstr.nim
  126. +1 −2 nimdoc/extlinks/project/expected/main.html
  127. +1 −2 nimdoc/testproject/expected/subdir/subdir_b/utils.html
  128. +5 −11 nimdoc/testproject/expected/testproject.html
  129. +3 −6 nimsuggest/nimsuggest.nim
  130. +11 −0 nimsuggest/tests/t22448.nim
  131. +12 −0 nimsuggest/tests/timport_highlight.nim
  132. +0 −3 parse/pragmas.nim
  133. +13 −1 testament/important_packages.nim
  134. +9 −4 testament/testament.nim
  135. +25 −0 tests/arc/t22218.nim
  136. +37 −0 tests/arc/t22787.nim
  137. +52 −0 tests/arc/t23247.nim
  138. +12 −1 tests/arc/tarc_macro.nim
  139. +24 −1 tests/arc/tarc_orc.nim
  140. +102 −0 tests/arc/tarcmisc.nim
  141. +26 −0 tests/arc/tcaseobj.nim
  142. +8 −4 tests/arc/topt_no_cursor.nim
  143. +18 −0 tests/array/tlargeindex.nim
  144. +6 −6 tests/async/twinasyncrw.nim
  145. +1 −0 tests/c/temit.nim
  146. +14 −0 tests/casestmt/tcasestmt.nim
  147. +2 −1 tests/ccgbugs/t10964.nim
  148. +3 −3 tests/codegen/titaniummangle.nim
  149. +25 −1 tests/concepts/tconcepts_issues.nim
  150. +41 −4 tests/controlflow/tunreachable.nim
  151. +22 −1 tests/cpp/tconstructor.nim
  152. +20 −0 tests/cpp/torc.nim
  153. +8 −0 tests/destructor/tdistinctseq.nim
  154. +18 −0 tests/destructor/tmove.nim
  155. +18 −17 tests/destructor/tmove_objconstr.nim
  156. +16 −0 tests/destructor/tsink.nim
  157. +20 −3 tests/distinct/tinvalidborrow.nim
  158. +8 −0 tests/distinct/typeclassborrow.nim
  159. +26 −0 tests/enum/tambiguousoverloads.nim
  160. +0 −8 tests/enum/toverloadable_enums.nim
  161. +24 −0 tests/errmsgs/t10542.nim
  162. +1 −1 tests/errmsgs/t16654.nim
  163. +2 −2 tests/errmsgs/t17460.nim
  164. +25 −0 tests/errmsgs/t22284.nim
  165. +7 −0 tests/errmsgs/t22996.nim
  166. +5 −0 tests/errmsgs/t23060.nim
  167. +5 −0 tests/errmsgs/t23419.nim
  168. +26 −0 tests/errmsgs/t23536.nim
  169. +2 −2 tests/errmsgs/t5167_5.nim
  170. +1 −1 tests/errmsgs/tassignunpack.nim
  171. +25 −0 tests/errmsgs/tinconsistentgensym.nim
  172. +61 −0 tests/errmsgs/tmetaobjectfields.nim
  173. +4 −0 tests/exception/m22469.nim
  174. +16 −0 tests/exception/t22469.nim
  175. +16 −0 tests/generics/m14509.nim
  176. +6 −0 tests/generics/mtypenodes.nim
  177. +9 −0 tests/generics/t12938.nim
  178. +6 −0 tests/generics/t14193.nim
  179. +4 −0 tests/generics/t14509.nim
  180. +8 −0 tests/generics/t1500.nim
  181. +6 −0 tests/generics/t18823.nim
  182. +10 −0 tests/generics/t21742.nim
  183. +8 −0 tests/generics/t21760.nim
  184. +155 −0 tests/generics/t23186.nim
  185. +2 −2 tests/generics/t6137.nim
  186. +14 −0 tests/generics/tgenerics_various.nim
  187. +35 −0 tests/generics/timpl_ast.nim
  188. +2 −1 tests/generics/timplicit_and_explicit.nim
  189. +5 −1 tests/generics/timports.nim
  190. +115 −0 tests/generics/tmacroinjectedsym.nim
  191. +50 −0 tests/generics/tmacroinjectedsymwarning.nim
  192. +24 −0 tests/generics/tnestedissues.nim
  193. +5 −0 tests/import/t23167.nim
  194. +28 −0 tests/iter/t20891.nim
  195. +22 −0 tests/iter/t21737.nim
  196. +21 −0 tests/iter/t22548.nim
  197. +6 −2 tests/iter/t22619.nim
  198. +18 −0 tests/iter/titer.nim
  199. +4 −0 tests/js/t7109.nim
  200. +6 −0 tests/lookups/issue_23172/m23172.nim
  201. +9 −0 tests/lookups/t23172.nim
  202. +2 −5 tests/lookups/tambsym3.nim
  203. +4 −0 tests/macros/t14329.nim
  204. +11 −0 tests/macros/t15751.nim
  205. +30 −0 tests/macros/t20435.nim
  206. +15 −0 tests/macros/tfail_parse.nim
  207. +4 −0 tests/macros/ttryparseexpr.nim
  208. +5 −0 tests/metatype/tmetatype_various.nim
  209. +21 −0 tests/method/t22673.nim
  210. +1 −1 tests/misc/t12869.nim
  211. +12 −0 tests/misc/t20883.nim
  212. +10 −0 tests/misc/t3907.nim
  213. +2 −1 tests/misc/t8545.nim
  214. +16 −0 tests/misc/tconv.nim
  215. +7 −0 tests/modules/tmodulesymtype.nim
  216. +1 −0 tests/nimdoc/m13129.nim
  217. +1 −1 tests/niminaction/Chapter8/sdl/sdl_test.nim
  218. +3 −6 tests/objects/tdefaultfieldscheck.nim
  219. +43 −1 tests/objects/tobject_default_value.nim
  220. +35 −0 tests/openarray/topenarray.nim
  221. +10 −0 tests/overflow/twronginference.nim
  222. +13 −12 tests/overload/tor_isnt_better.nim
  223. +1 −0 tests/parallel/tuseafterdef.nim
  224. +17 −0 tests/parser/ttupleunpack.nim
  225. +12 −0 tests/pragmas/t22713.nim
  226. +5 −0 tests/pragmas/tpragmas_misc.nim
  227. +13 −0 tests/pragmas/tpush.nim
  228. +36 −0 tests/proc/tinferlambdareturn.nim
  229. +17 −0 tests/refc/tsinkbug.nim
  230. +38 −0 tests/sets/tsets.nim
  231. +8 −0 tests/statictypes/tgenericcomputedrange.nim
  232. +7 −0 tests/stdlib/t19304.nim
  233. +4 −2 tests/stdlib/t21406.nim
  234. +2 −0 tests/stdlib/tbase64.nim
  235. +3 −0 tests/stdlib/tcomplex.nim
  236. +4 −0 tests/stdlib/tencodings.nim
  237. +41 −1 tests/stdlib/tmarshal.nim
  238. +8 −0 tests/stdlib/tmimetypes.nim
  239. +7 −1 tests/stdlib/toptions.nim
  240. +32 −0 tests/stdlib/tos.nim
  241. +18 −0 tests/stdlib/trandom.nim
  242. +4 −2 tests/stdlib/trepr.nim
  243. +14 −1 tests/stdlib/tstrformat.nim
  244. +15 −4 tests/stdlib/tstrutils.nim
  245. +22 −21 tests/stdlib/tsugar.nim
  246. +17 −0 tests/stdlib/ttypeinfo.nim
  247. +7 −0 tests/system/tsystem_misc.nim
  248. +37 −0 tests/template/tgensymhijack.nim
  249. +38 −0 tests/template/tnested.nim
  250. +9 −0 tests/template/tparams_gensymed.nim
  251. +12 −0 tests/tuples/ttuples_various.nim
  252. +1 −1 tests/types/t15836.nim
  253. +0 −5 tests/types/t15836_2.nim
  254. +1 −1 tests/types/tassignemptytuple.nim
  255. +8 −0 tests/types/texportgeneric.nim
  256. +19 −0 tests/views/tviews1.nim
  257. +37 −0 tests/views/tviews2.nim
  258. +10 −0 tests/vm/tconst.nim
  259. +10 −0 tests/vm/tconstresem.nim
  260. +8 −8 tests/vm/tvmmisc.nim
  261. +1 −0 tools/niminst/buildsh.nimf
  262. +1 −0 tools/niminst/makefile.nimf
43 changes: 42 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@

[//]: # "Additions:"

- Added `newStringUninit` to system, which creates a new string of length `len` like `newString` but with uninitialized content.
- Added `setLenUninit` to system, which doesn't initalize
slots when enlarging a sequence.
- Added `hasDefaultValue` to `std/typetraits` to check if a type has a valid default value.
- Added Viewport API for the JavaScript targets in the `dom` module.

[//]: # "Deprecations:"


Expand All @@ -21,10 +27,45 @@



## Compiler changes
- An experimental option `genericsOpenSym` has been added to allow captured
symbols in generic routine bodies to be replaced by symbols injected locally
by templates/macros at instantiation time. `bind` may be used to keep the
captured symbols over the injected ones regardless of enabling the option.

Since this change may affect runtime behavior, the experimental switch
`genericsOpenSym` needs to be enabled, and a warning is given in the case
where an injected symbol would replace a captured symbol not bound by `bind`
and the experimental switch isn't enabled.

```nim
const value = "captured"
template foo(x: int, body: untyped) =
let value {.inject.} = "injected"
body
proc old[T](): string =
foo(123):
return value # warning: a new `value` has been injected, use `bind` or turn on `experimental:genericsOpenSym`
echo old[int]() # "captured"
{.experimental: "genericsOpenSym".}
proc bar[T](): string =
foo(123):
return value
assert bar[int]() == "injected" # previously it would be "captured"
proc baz[T](): string =
bind value
foo(123):
return value
assert baz[int]() == "captured"
```

## Compiler changes


## Tool changes

- koch now allows bootstrapping with `-d:nimHasLibFFI`, replacing the older option of building the compiler directly w/ the `libffi` nimble package in tow.

2 changes: 1 addition & 1 deletion changelogs/changelog_2_0_0_details.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
- `shallowCopy` and `shallow` are removed for ARC/ORC. Use `move` when possible or combine assignment and
`sink` for optimization purposes.

- The experimental `nimPreviewDotLikeOps` switch is going to be removed or deprecated because it didn't fullfill its promises.
- The experimental `nimPreviewDotLikeOps` switch is going to be removed or deprecated because it didn't fulfill its promises.

- The `{.this.}` pragma, deprecated since 0.19, has been removed.
- `nil` literals can no longer be directly assigned to variables or fields of `distinct` pointer types. They must be converted instead.
Expand Down
23 changes: 17 additions & 6 deletions compiler/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# abstract syntax tree + symbol table

import
lineinfos, hashes, options, ropes, idents, int128, tables
lineinfos, hashes, options, ropes, idents, int128, tables, wordrecg
from strutils import toLowerAscii

when defined(nimPreviewSlimSystem):
Expand Down Expand Up @@ -516,6 +516,7 @@ type
nfFirstWrite # this node is a first write
nfHasComment # node has a comment
nfSkipFieldChecking # node skips field visable checking
nfOpenSym # node is a captured sym but can be overriden by local symbols

TNodeFlags* = set[TNodeFlag]
TTypeFlag* = enum # keep below 32 for efficiency reasons (now: 47)
Expand Down Expand Up @@ -589,6 +590,7 @@ type
tfEffectSystemWorkaround
tfIsOutParam
tfSendable
tfImplicitStatic

TTypeFlags* = set[TTypeFlag]

Expand Down Expand Up @@ -638,7 +640,7 @@ const
skError* = skUnknown

var
eqTypeFlags* = {tfIterator, tfNotNil, tfVarIsPtr, tfGcSafe, tfNoSideEffect, tfIsOutParam, tfSendable}
eqTypeFlags* = {tfIterator, tfNotNil, tfVarIsPtr, tfGcSafe, tfNoSideEffect, tfIsOutParam}
## type flags that are essential for type equality.
## This is now a variable because for emulation of version:1.0 we
## might exclude {tfGcSafe, tfNoSideEffect}.
Expand Down Expand Up @@ -1087,7 +1089,8 @@ const
nfIsRef, nfIsPtr, nfPreventCg, nfLL,
nfFromTemplate, nfDefaultRefsParam,
nfExecuteOnReload, nfLastRead,
nfFirstWrite, nfSkipFieldChecking}
nfFirstWrite, nfSkipFieldChecking,
nfOpenSym}
namePos* = 0
patternPos* = 1 # empty except for term rewriting macros
genericParamsPos* = 2
Expand Down Expand Up @@ -2015,18 +2018,20 @@ proc isImportedException*(t: PType; conf: ConfigRef): bool =
result = true

proc isInfixAs*(n: PNode): bool =
return n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.s == "as"
return n.kind == nkInfix and n[0].kind == nkIdent and n[0].ident.id == ord(wAs)

proc skipColon*(n: PNode): PNode =
result = n
if n.kind == nkExprColonExpr:
result = n[1]

proc findUnresolvedStatic*(n: PNode): PNode =
# n.typ == nil: see issue #14802
if n.kind == nkSym and n.typ != nil and n.typ.kind == tyStatic and n.typ.n == nil:
return n

if n.typ != nil and n.typ.kind == tyTypeDesc:
let t = skipTypes(n.typ, {tyTypeDesc})
if t.kind == tyGenericParam and t.len == 0:
return n
for son in n:
let n = son.findUnresolvedStatic
if n != nil: return n
Expand Down Expand Up @@ -2064,6 +2069,12 @@ proc isClosureIterator*(typ: PType): bool {.inline.} =
proc isClosure*(typ: PType): bool {.inline.} =
typ.kind == tyProc and typ.callConv == ccClosure

proc isNimcall*(s: PSym): bool {.inline.} =
s.typ.callConv == ccNimCall

proc isExplicitCallConv*(s: PSym): bool {.inline.} =
tfExplicitCallConv in s.typ.flags

proc isSinkParam*(s: PSym): bool {.inline.} =
s.kind == skParam and (s.typ.kind == tySink or tfHasOwned in s.typ.flags)

Expand Down
6 changes: 6 additions & 0 deletions compiler/astmsgs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ proc addDeclaredLoc*(result: var string, conf: ConfigRef; typ: PType) =
result.add " declared in " & toFileLineCol(conf, typ.sym.info)
result.add "]"

proc addTypeNodeDeclaredLoc*(result: var string, conf: ConfigRef; typ: PType) =
result.add " [$1" % typ.kind.toHumanStr
if typ.sym != nil:
result.add " declared in " & toFileLineCol(conf, typ.sym.info)
result.add "]"

proc addDeclaredLocMaybe*(result: var string, conf: ConfigRef; typ: PType) =
if optDeclaredLocs in conf.globalOptions: addDeclaredLoc(result, conf, typ)

Expand Down
19 changes: 16 additions & 3 deletions compiler/ccgcalls.nim
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ proc canRaiseDisp(p: BProc; n: PNode): bool =

proc preventNrvo(p: BProc; dest, le, ri: PNode): bool =
proc locationEscapes(p: BProc; le: PNode; inTryStmt: bool): bool =
result = false
var n = le
while true:
# do NOT follow nkHiddenDeref here!
Expand Down Expand Up @@ -82,6 +83,10 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
# getUniqueType() is too expensive here:
var typ = skipTypes(ri[0].typ, abstractInst)
if typ[0] != nil:
var flags: TAssignmentFlags = {}
if typ[0].kind in {tyOpenArray, tyVarargs}:
# perhaps generate no temp if the call doesn't have side effects
flags.incl needTempForOpenArray
if isInvalidReturnType(p.config, typ):
if params.len != 0: pl.add(", ")
# beware of 'result = p(result)'. We may need to allocate a temporary:
Expand Down Expand Up @@ -129,15 +134,15 @@ proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc,
var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown)
list.r = pl
genAssignment(p, d, list, {}) # no need for deep copying
genAssignment(p, d, list, flags) # no need for deep copying
if canRaise: raiseExit(p)
else:
var tmp: TLoc
getTemp(p, typ[0], tmp, needsInit=true)
var list: TLoc
initLoc(list, locCall, d.lode, OnUnknown)
list.r = pl
genAssignment(p, tmp, list, {}) # no need for deep copying
genAssignment(p, tmp, list, flags) # no need for deep copying
if canRaise: raiseExit(p)
genAssignment(p, d, tmp, {})
else:
Expand Down Expand Up @@ -166,7 +171,10 @@ proc genOpenArraySlice(p: BProc; q: PNode; formalType, destType: PType; prepareF
genBoundsCheck(p, a, b, c)
if prepareForMutation:
linefmt(p, cpsStmts, "#nimPrepareStrMutationV2($1);$n", [byRefLoc(p, a)])
let ty = skipTypes(a.t, abstractVar+{tyPtr})
# bug #23321: In the function mapType, ptrs (tyPtr, tyVar, tyLent, tyRef)
# are mapped into ctPtrToArray, the dereference of which is skipped
# in the `genref`. We need to skip these ptrs here
let ty = skipTypes(a.t, abstractVar+{tyPtr, tyRef})
let dest = getTypeDesc(p.module, destType)
let lengthExpr = "($1)-($2)+1" % [rdLoc(c), rdLoc(b)]
case ty.kind
Expand Down Expand Up @@ -313,6 +321,11 @@ proc genArg(p: BProc, n: PNode, param: PSym; call: PNode; result: var Rope; need
addRdLoc(a, result)
else:
initLocExprSingleUse(p, n, a)
if param.typ.kind in abstractPtrs:
let typ = skipTypes(param.typ, abstractPtrs)
if typ.sym != nil and sfImportc in typ.sym.flags:
a.r = "(($1) ($2))" %
[getTypeDesc(p.module, param.typ), rdCharLoc(a)]
addRdLoc(withTmpIfNeeded(p, a, needsTmp), result)
#assert result != nil

Expand Down
41 changes: 31 additions & 10 deletions compiler/ccgexprs.nim
Original file line number Diff line number Diff line change
Expand Up @@ -285,15 +285,23 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
linefmt(p, cpsStmts, "#genericAssign((void*)$1, (void*)$2, $3);$n",
[addrLoc(p.config, dest), addrLoc(p.config, src), genTypeInfoV1(p.module, dest.t, dest.lode.info)])

proc genOpenArrayConv(p: BProc; d: TLoc; a: TLoc) =
proc genOpenArrayConv(p: BProc; d: TLoc; a: TLoc; flags: TAssignmentFlags) =
assert d.k != locNone
# getTemp(p, d.t, d)

case a.t.skipTypes(abstractVar).kind
of tyOpenArray, tyVarargs:
if reifiedOpenArray(a.lode):
linefmt(p, cpsStmts, "$1.Field0 = $2.Field0; $1.Field1 = $2.Field1;$n",
[rdLoc(d), a.rdLoc])
if needTempForOpenArray in flags:
var tmp: TLoc
getTemp(p, a.t, tmp)
linefmt(p, cpsStmts, "$2 = $1; $n",
[a.rdLoc, tmp.rdLoc])
linefmt(p, cpsStmts, "$1.Field0 = $2.Field0; $1.Field1 = $2.Field1;$n",
[rdLoc(d), tmp.rdLoc])
else:
linefmt(p, cpsStmts, "$1.Field0 = $2.Field0; $1.Field1 = $2.Field1;$n",
[rdLoc(d), a.rdLoc])
else:
linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $2Len_0;$n",
[rdLoc(d), a.rdLoc])
Expand Down Expand Up @@ -392,7 +400,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
# open arrays are always on the stack - really? What if a sequence is
# passed to an open array?
if reifiedOpenArray(dest.lode):
genOpenArrayConv(p, dest, src)
genOpenArrayConv(p, dest, src, flags)
elif containsGarbageCollectedRef(dest.t):
linefmt(p, cpsStmts, # XXX: is this correct for arrays?
"#genericAssignOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n",
Expand Down Expand Up @@ -1496,7 +1504,7 @@ proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) =
initLocExpr(p, e[1], a)
if optSeqDestructors in p.config.globalOptions:
if d.k == locNone: getTemp(p, e.typ, d, needsInit=false)
linefmt(p, cpsStmts, "$1.len = 0; $1.p = ($4*) #newSeqPayload($2, sizeof($3), NIM_ALIGNOF($3));$n",
linefmt(p, cpsStmts, "$1.len = 0; $1.p = ($4*) #newSeqPayloadUninit($2, sizeof($3), NIM_ALIGNOF($3));$n",
[d.rdLoc, a.rdLoc, getTypeDesc(p.module, seqtype.lastSon),
getSeqPayloadType(p.module, seqtype),
])
Expand Down Expand Up @@ -2125,7 +2133,7 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mCard:
var a: TLoc
initLocExpr(p, e[1], a)
putIntoDest(p, d, e, ropecg(p.module, "#cardSet($1, $2)", [addrLoc(p.config, a), size]))
putIntoDest(p, d, e, ropecg(p.module, "#cardSet($1, $2)", [rdCharLoc(a), size]))
of mLtSet, mLeSet:
getTemp(p, getSysType(p.module.g.graph, unknownLineInfo, tyInt), i) # our counter
initLocExpr(p, e[1], a)
Expand Down Expand Up @@ -2368,9 +2376,22 @@ proc genMove(p: BProc; n: PNode; d: var TLoc) =
if op == nil:
resetLoc(p, a)
else:
let addrExp = makeAddr(n[1], p.module.idgen)
let wasMovedCall = newTreeI(nkCall, n.info, newSymNode(op), addrExp)
genCall(p, wasMovedCall, d)
var b: TLoc
initLocExpr(p, newSymNode(op), b)
case skipTypes(a.t, abstractVar+{tyStatic}).kind
of tyOpenArray, tyVarargs: # todo fixme generated `wasMoved` hooks for
# openarrays, but it probably shouldn't?
var s: string
if reifiedOpenArray(a.lode):
if a.t.kind in {tyVar, tyLent}:
s = "$1->Field0, $1->Field1" % [rdLoc(a)]
else:
s = "$1.Field0, $1.Field1" % [rdLoc(a)]
else:
s = "$1, $1Len_0" % [rdLoc(a)]
linefmt(p, cpsStmts, "$1($2);$n", [rdLoc(b), s])
else:
linefmt(p, cpsStmts, "$1($2);$n", [rdLoc(b), byRefLoc(p, a)])
else:
let flags = if not canMove(p, n[1], d): {needToCopy} else: {}
genAssignment(p, d, a, flags)
Expand Down Expand Up @@ -2612,7 +2633,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
of mDeepCopy:
if p.config.selectedGC in {gcArc, gcAtomicArc, gcOrc} and optEnableDeepCopy notin p.config.globalOptions:
localError(p.config, e.info,
"for --gc:arc|orc 'deepcopy' support has to be enabled with --deepcopy:on")
"for --mm:arc|atomicArc|orc 'deepcopy' support has to be enabled with --deepcopy:on")

var a, b: TLoc
let x = if e[1].kind in {nkAddr, nkHiddenAddr}: e[1][0] else: e[1]
Expand Down
7 changes: 5 additions & 2 deletions compiler/ccgstmts.nim
Original file line number Diff line number Diff line change
Expand Up @@ -971,8 +971,11 @@ proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) =
hasDefault = true
exprBlock(p, branch.lastSon, d)
lineF(p, cpsStmts, "break;$n", [])
if (hasAssume in CC[p.config.cCompiler].props) and not hasDefault:
lineF(p, cpsStmts, "default: __assume(0);$n", [])
if not hasDefault:
if hasBuiltinUnreachable in CC[p.config.cCompiler].props:
lineF(p, cpsStmts, "default: __builtin_unreachable();$n", [])
elif hasAssume in CC[p.config.cCompiler].props:
lineF(p, cpsStmts, "default: __assume(0);$n", [])
lineF(p, cpsStmts, "}$n", [])
if lend != "": fixLabel(p, lend)

Expand Down
27 changes: 20 additions & 7 deletions compiler/ccgtypes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ proc mangleProc(m: BModule; s: PSym; makeUnique: bool): string =
proc fillBackendName(m: BModule; s: PSym) =
if s.loc.r == "":
var result: Rope
if s.kind in routineKinds and optCDebug in m.g.config.globalOptions and
if not m.compileToCpp and s.kind in routineKinds and optCDebug in m.g.config.globalOptions and
m.g.config.symbolFiles == disabledSf:
result = mangleProc(m, s, false).rope
else:
Expand Down Expand Up @@ -270,7 +270,10 @@ proc isInvalidReturnType(conf: ConfigRef; typ: PType, isProc = true): bool =
{tyVar, tyLent, tyRef, tyPtr})
of ctStruct:
let t = skipTypes(rettype, typedescInst)
if rettype.isImportedCppType or t.isImportedCppType: return false
if rettype.isImportedCppType or t.isImportedCppType or
(typ.callConv == ccCDecl and conf.selectedGC in {gcArc, gcAtomicArc, gcOrc}):
# prevents nrvo for cdecl procs; # bug #23401
return false
result = containsGarbageCollectedRef(t) or
(t.kind == tyObject and not isObjLackingTypeField(t))
else: result = false
Expand Down Expand Up @@ -660,6 +663,13 @@ proc mangleRecFieldName(m: BModule; field: PSym): Rope =
result = rope(mangleField(m, field.name))
if result == "": internalError(m.config, field.info, "mangleRecFieldName")

proc hasCppCtor(m: BModule; typ: PType): bool =
result = false
if m.compileToCpp and typ != nil and typ.itemId in m.g.graph.memberProcsPerType:
for prc in m.g.graph.memberProcsPerType[typ.itemId]:
if sfConstructor in prc.flags:
return true

proc genRecordFieldsAux(m: BModule; n: PNode,
rectype: PType,
check: var IntSet; result: var Rope; unionPrefix = "") =
Expand Down Expand Up @@ -724,7 +734,7 @@ proc genRecordFieldsAux(m: BModule; n: PNode,
else:
# don't use fieldType here because we need the
# tyGenericInst for C++ template support
if fieldType.isOrHasImportedCppType():
if fieldType.isOrHasImportedCppType() or hasCppCtor(m, field.owner.typ):
result.addf("\t$1$3 $2{};$n", [getTypeDescAux(m, field.loc.t, check, dkField), sname, noAlias])
else:
result.addf("\t$1$3 $2;$n", [getTypeDescAux(m, field.loc.t, check, dkField), sname, noAlias])
Expand Down Expand Up @@ -1927,8 +1937,11 @@ proc genTypeSection(m: BModule, n: PNode) =
if len(n[i]) == 0: continue
if n[i][0].kind != nkPragmaExpr: continue
for p in 0..<n[i][0].len:
if (n[i][0][p].kind != nkSym): continue
if sfExportc in n[i][0][p].sym.flags:
discard getTypeDescAux(m, n[i][0][p].typ, intSet, descKindFromSymKind(n[i][0][p].sym.kind))
if (n[i][0][p].kind notin {nkSym, nkPostfix}): continue
var s = n[i][0][p]
if s.kind == nkPostfix:
s = n[i][0][p][1]
if {sfExportc, sfCompilerProc} * s.sym.flags == {sfExportc}:
discard getTypeDescAux(m, s.typ, intSet, descKindFromSymKind(s.sym.kind))
if m.g.generatedHeader != nil:
discard getTypeDescAux(m.g.generatedHeader, n[i][0][p].typ, intSet, descKindFromSymKind(n[i][0][p].sym.kind))
discard getTypeDescAux(m.g.generatedHeader, s.typ, intSet, descKindFromSymKind(s.sym.kind))
Loading