mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-24 23:51:41 +00:00
Merge branch 'devel' into araq-ic7
This commit is contained in:
@@ -103,7 +103,15 @@ errors.
|
||||
|
||||
## Compiler changes
|
||||
|
||||
- Fixed a bug where `sizeof(T)` inside a `typedesc` template called from a generic type's
|
||||
`when` clause would error with "'sizeof' requires '.importc' types to be '.completeStruct'".
|
||||
The issue was that `hasValuelessStatics` in `semtypinst.nim` didn't recognize
|
||||
`tyTypeDesc(tyGenericParam)` as an unresolved generic parameter.
|
||||
|
||||
## Tool changes
|
||||
|
||||
- Added `--stdinfile` flag to name of the file used when running program from stdin (defaults to `stdinfile.nim`)
|
||||
|
||||
## Documentation changes
|
||||
|
||||
- Added documentation for the `completeStruct` pragma in the manual.
|
||||
|
||||
@@ -549,18 +549,28 @@ proc addAllowNil*(father, son: PNode) {.inline.} =
|
||||
father.sons.add(son)
|
||||
|
||||
proc add*(father, son: PType) =
|
||||
assert father.kind != tyProc or father.sonsImpl.len == 0
|
||||
assert son != nil
|
||||
father.sonsImpl.add son
|
||||
|
||||
proc addAllowNil*(father, son: PType) {.inline.} =
|
||||
assert father.kind != tyProc or father.sonsImpl.len == 0
|
||||
father.sonsImpl.add son
|
||||
|
||||
template `[]`*(n: PType, i: int): PType =
|
||||
if n.state == Partial: loadType(n)
|
||||
n.sonsImpl[i]
|
||||
if n.kind == tyProc and i > 0:
|
||||
assert n.nImpl[i] != nil and n.nImpl[i].sym != nil
|
||||
n.nImpl[i].sym.typ
|
||||
else:
|
||||
n.sonsImpl[i]
|
||||
template `[]=`*(n: PType, i: int; x: PType) =
|
||||
if n.state == Partial: loadType(n)
|
||||
n.sonsImpl[i] = x
|
||||
if n.kind == tyProc and i > 0:
|
||||
assert n.nImpl[i] != nil and n.nImpl[i].sym != nil
|
||||
n.nImpl[i].sym.typ = x
|
||||
else:
|
||||
n.sonsImpl[i] = x
|
||||
|
||||
template `[]`*(n: PType, i: BackwardsIndex): PType =
|
||||
if n.state == Partial: loadType(n)
|
||||
@@ -806,7 +816,10 @@ proc replaceSon*(n: PNode; i: int; newson: PNode) {.inline.} =
|
||||
|
||||
proc last*(n: PType): PType {.inline.} =
|
||||
if n.state == Partial: loadType(n)
|
||||
n.sonsImpl[^1]
|
||||
if n.kind == tyProc and n.nImpl.len > 1:
|
||||
n.nImpl[^1].sym.typ
|
||||
else:
|
||||
n.sonsImpl[^1]
|
||||
|
||||
proc elementType*(n: PType): PType {.inline.} =
|
||||
if n.state == Partial: loadType(n)
|
||||
@@ -842,7 +855,10 @@ proc setIndexType*(n, idx: PType) {.inline.} =
|
||||
|
||||
proc firstParamType*(n: PType): PType {.inline.} =
|
||||
if n.state == Partial: loadType(n)
|
||||
n.sonsImpl[1]
|
||||
if n.kind == tyProc:
|
||||
n.nImpl[1].sym.typ
|
||||
else:
|
||||
n.sonsImpl[1]
|
||||
|
||||
proc firstGenericParam*(n: PType): PType {.inline.} =
|
||||
if n.state == Partial: loadType(n)
|
||||
@@ -914,10 +930,13 @@ proc `$`*(s: PSym): string =
|
||||
result = "<nil>"
|
||||
|
||||
proc len*(n: PType): int {.inline.} =
|
||||
result = n.sonsImpl.len
|
||||
if n.kind == tyProc:
|
||||
result = if n.nImpl == nil: 0 else: n.nImpl.len
|
||||
else:
|
||||
result = n.sonsImpl.len
|
||||
|
||||
proc sameTupleLengths*(a, b: PType): bool {.inline.} =
|
||||
result = a.sonsImpl.len == b.sonsImpl.len
|
||||
result = a.len == b.len
|
||||
|
||||
iterator tupleTypePairs*(a, b: PType): (int, PType, PType) =
|
||||
for i in 0 ..< a.len:
|
||||
@@ -1012,15 +1031,20 @@ proc newType*(kind: TTypeKind; idgen: IdGenerator; owner: PSym; son: sink PType
|
||||
alignImpl: defaultAlignment, itemId: id,
|
||||
uniqueId: id, sonsImpl: @[])
|
||||
if son != nil:
|
||||
assert kind != tyProc
|
||||
result.sonsImpl.add son
|
||||
when false:
|
||||
if result.itemId.module == 55 and result.itemId.item == 2:
|
||||
echo "KNID ", kind
|
||||
writeStackTrace()
|
||||
|
||||
proc setSons*(dest: PType; sons: sink seq[PType]) {.inline.} = dest.sonsImpl = sons
|
||||
proc setSon*(dest: PType; son: sink PType) {.inline.} = dest.sonsImpl = @[son]
|
||||
proc setSons*(dest: PType; sons: sink seq[PType]) {.inline.} =
|
||||
assert dest.kind != tyProc or sons.len <= 1
|
||||
dest.sonsImpl = sons
|
||||
proc setSon*(dest: PType; son: sink PType) {.inline.} =
|
||||
dest.sonsImpl = @[son]
|
||||
proc setSonsLen*(dest: PType; len: int) {.inline.} =
|
||||
assert dest.kind != tyProc or len <= 1
|
||||
setLen(dest.sonsImpl, len)
|
||||
|
||||
proc mergeLoc(a: var TLoc, b: TLoc) =
|
||||
@@ -1034,6 +1058,7 @@ proc newSons*(father: PNode, length: int) =
|
||||
setLen(father.sons, length)
|
||||
|
||||
proc newSons*(father: PType, length: int) =
|
||||
assert father.kind != tyProc or length <= 1
|
||||
setLen(father.sonsImpl, length)
|
||||
|
||||
proc truncateInferredTypeCandidates*(t: PType) {.inline.} =
|
||||
@@ -1058,8 +1083,16 @@ proc assignType*(dest, src: PType) =
|
||||
mergeLoc(dest.sym.locImpl, src.sym.loc)
|
||||
else:
|
||||
dest.symImpl = src.sym
|
||||
newSons(dest, src.len)
|
||||
for i in 0..<src.len: dest[i] = src[i]
|
||||
if src.kind == tyProc:
|
||||
# `tyProc` uses only `sonsImpl[0]` to store return type.
|
||||
# parameter symbols and types are stored in `nImpl`.
|
||||
assert src.sonsImpl.len <= 1
|
||||
if src.len > 0:
|
||||
setLen(dest.sonsImpl, 1)
|
||||
dest.sonsImpl[0] = src.sonsImpl[0]
|
||||
else:
|
||||
newSons(dest, src.len)
|
||||
for i in 0..<src.len: dest[i] = src[i]
|
||||
|
||||
proc copyType*(t: PType, idgen: IdGenerator, owner: PSym): PType =
|
||||
result = newType(t.kind, idgen, owner)
|
||||
@@ -1169,7 +1202,8 @@ proc propagateToOwner*(owner, elem: PType; propagateHasAsgn = true) =
|
||||
|
||||
proc rawAddSon*(father, son: PType; propagateHasAsgn = true) =
|
||||
ensureMutable father
|
||||
father.sonsImpl.add(son)
|
||||
if father.kind != tyProc or father.sonsImpl.len == 0:
|
||||
father.sonsImpl.add(son)
|
||||
if not son.isNil: propagateToOwner(father, son, propagateHasAsgn)
|
||||
|
||||
proc addSonNilAllowed*(father, son: PNode) =
|
||||
@@ -1575,7 +1609,7 @@ proc newProcType*(info: TLineInfo; idgen: IdGenerator; owner: PSym): PType =
|
||||
result.n.add newNodeI(nkEffectList, info)
|
||||
|
||||
proc addParam*(procType: PType; param: PSym) =
|
||||
param.position = procType.sons.len-1
|
||||
param.position = procType.n.len - 1
|
||||
procType.n.add newSymNode(param)
|
||||
rawAddSon(procType, param.typ)
|
||||
|
||||
|
||||
@@ -337,7 +337,10 @@ proc genLineDir(p: BProc, t: PNode) =
|
||||
let line = t.info.safeLineNm
|
||||
|
||||
if optEmbedOrigSrc in p.config.globalOptions:
|
||||
p.s(cpsStmts).add("//" & sourceLine(p.config, t.info) & "\L")
|
||||
var code = sourceLine(p.config, t.info)
|
||||
if code.endsWith('\\'):
|
||||
code.add "#"
|
||||
p.s(cpsStmts).add("// " & code & "\L")
|
||||
let lastFileIndex = p.lastLineInfo.fileIndex
|
||||
let freshLine = freshLineInfo(p, t.info)
|
||||
if freshLine:
|
||||
|
||||
@@ -370,8 +370,14 @@ proc storeType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemI
|
||||
paddingAtEnd: t.paddingAtEnd)
|
||||
storeNode(p, t, n)
|
||||
p.typeInst = t.typeInst.storeType(c, m)
|
||||
for kid in kids t:
|
||||
p.types.add kid.storeType(c, m)
|
||||
if t.kind == tyProc and t.len > 0:
|
||||
# if kind == tyProc, parameter types are stored in t.n
|
||||
# and you can access them with `kits` iterator.
|
||||
# return type is stored in t.sons[0].
|
||||
p.types.add t[0].storeType(c, m)
|
||||
else:
|
||||
for kid in kids t:
|
||||
p.types.add kid.storeType(c, m)
|
||||
c.addMissing t.sym
|
||||
p.sym = t.sym.safeItemId(c, m)
|
||||
c.addMissing t.owner
|
||||
|
||||
@@ -244,7 +244,8 @@ proc instantiateProcType(c: PContext, pt: LayeredIdTable,
|
||||
var result = instCopyType(cl, prc.typ)
|
||||
let originalParams = result.n
|
||||
result.n = originalParams.shallowCopy
|
||||
for i, resulti in paramTypes(result):
|
||||
for i in 1 ..< originalParams.len:
|
||||
let resulti = originalParams[i].sym.typ
|
||||
# twrong_field_caching requires these 'resetIdTable' calls:
|
||||
if i > FirstParamAt:
|
||||
resetIdTable(cl.symMap)
|
||||
@@ -258,23 +259,23 @@ proc instantiateProcType(c: PContext, pt: LayeredIdTable,
|
||||
let needsTypeDescSkipping = resulti.kind == tyTypeDesc and tfUnresolved in resulti.flags
|
||||
if resulti.kind == tyFromExpr:
|
||||
resulti.incl tfNonConstExpr
|
||||
result[i] = replaceTypeVarsT(cl, resulti)
|
||||
var paramType = replaceTypeVarsT(cl, resulti)
|
||||
if needsStaticSkipping:
|
||||
result[i] = result[i].skipTypes({tyStatic})
|
||||
paramType = paramType.skipTypes({tyStatic})
|
||||
if needsTypeDescSkipping:
|
||||
result[i] = result[i].skipTypes({tyTypeDesc})
|
||||
typeToFit = result[i]
|
||||
paramType = paramType.skipTypes({tyTypeDesc})
|
||||
typeToFit = paramType
|
||||
|
||||
# ...otherwise, we use the instantiated type in `fitNode`
|
||||
if (typeToFit.kind != tyTypeDesc or typeToFit.base.kind != tyNone) and
|
||||
(typeToFit.kind != tyStatic):
|
||||
typeToFit = result[i]
|
||||
typeToFit = paramType
|
||||
|
||||
internalAssert c.config, originalParams[i].kind == nkSym
|
||||
let oldParam = originalParams[i].sym
|
||||
let param = copySym(oldParam, c.idgen)
|
||||
setOwner(param, prc)
|
||||
param.typ = result[i]
|
||||
param.typ = paramType
|
||||
|
||||
# The default value is instantiated and fitted against the final
|
||||
# concrete param type. We avoid calling `replaceTypeVarsN` on the
|
||||
@@ -305,12 +306,12 @@ proc instantiateProcType(c: PContext, pt: LayeredIdTable,
|
||||
param.ast.typ = def.typ
|
||||
else:
|
||||
param.ast = fitNodePostMatch(c, typeToFit, converted)
|
||||
param.typ = result[i]
|
||||
param.typ = paramType
|
||||
|
||||
result.n[i] = newSymNode(param)
|
||||
if isRecursiveStructuralType(result[i]):
|
||||
if isRecursiveStructuralType(paramType):
|
||||
localError(c.config, originalParams[i].sym.info, "illegal recursion in type '" & typeToString(result[i]) & "'")
|
||||
propagateToOwner(result, result[i])
|
||||
propagateToOwner(result, paramType)
|
||||
addDecl(c, param)
|
||||
|
||||
resetIdTable(cl.symMap)
|
||||
|
||||
@@ -249,13 +249,24 @@ proc hasValuelessStatics(n: PNode): bool =
|
||||
a
|
||||
proc doThing(_: MyThing)
|
||||
]#
|
||||
result = false
|
||||
if n.safeLen == 0 and n.kind != nkEmpty: # Some empty nodes can get in here
|
||||
n.typ == nil or n.typ.kind == tyStatic
|
||||
if n.typ == nil:
|
||||
result = true
|
||||
elif n.typ.kind == tyStatic:
|
||||
result = true
|
||||
elif n.typ.kind == tyTypeDesc:
|
||||
# Check if the base type is an unresolved generic parameter.
|
||||
# This handles cases where a template containing sizeof(T) is called
|
||||
# inside a generic object's when clause - the T needs to be resolved
|
||||
# before we can evaluate the condition.
|
||||
let base = n.typ.skipTypes({tyTypeDesc})
|
||||
if base.kind == tyGenericParam:
|
||||
result = true
|
||||
else:
|
||||
for x in n:
|
||||
if hasValuelessStatics(x):
|
||||
return true
|
||||
false
|
||||
|
||||
proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode; start=0; expectedType: PType = nil): PNode =
|
||||
if n == nil: return
|
||||
@@ -542,14 +553,12 @@ proc eraseVoidParams*(t: PType) =
|
||||
|
||||
for i in FirstParamAt..<t.signatureLen:
|
||||
# don't touch any memory unless necessary
|
||||
if t[i].kind == tyVoid:
|
||||
if t.n[i].kind == nkRecList or t[i].kind == tyVoid:
|
||||
var pos = i
|
||||
for j in i+1..<t.signatureLen:
|
||||
if t[j].kind != tyVoid:
|
||||
t[pos] = t[j]
|
||||
t.n[pos] = t.n[j]
|
||||
inc pos
|
||||
newSons t, pos
|
||||
setLen t.n.sons, pos
|
||||
break
|
||||
|
||||
@@ -743,7 +752,8 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType, isInstValue = false):
|
||||
let r2 = r.skipTypes({tyAlias, tySink, tyOwned})
|
||||
if r2.kind in {tyPtr, tyRef}:
|
||||
r = skipTypes(r2, {tyPtr, tyRef})
|
||||
result[i] = r
|
||||
if result.kind != tyProc or i == 0:
|
||||
result[i] = r
|
||||
if result.kind != tyArray or i != 0:
|
||||
propagateToOwner(result, r)
|
||||
# bug #4677: Do not instantiate effect lists
|
||||
|
||||
@@ -233,13 +233,11 @@ proc copyingEraseVoidParams(m: TCandidate, t: var PType) =
|
||||
if not copied:
|
||||
# keep first i children
|
||||
t = copyType(original, m.c.idgen, t.owner)
|
||||
t.setSonsLen(i)
|
||||
t.n = copyNode(original.n)
|
||||
t.n.sons = original.n.sons
|
||||
t.n.sons.setLen(i)
|
||||
copied = true
|
||||
elif copied:
|
||||
t.add(f)
|
||||
t.n.add(original.n[i])
|
||||
|
||||
proc initCandidate*(ctx: PContext, callee: PSym,
|
||||
|
||||
@@ -38,7 +38,7 @@ proc checkForSink*(config: ConfigRef; idgen: IdGenerator; owner: PSym; arg: PNod
|
||||
sinkType.add argType
|
||||
|
||||
arg.sym.typ = sinkType
|
||||
owner.typ[arg.sym.position+1] = sinkType
|
||||
assert owner.typ.n[arg.sym.position+1].sym == arg.sym
|
||||
|
||||
#message(config, arg.info, warnUser,
|
||||
# ("turned '$1' to a sink parameter") % [$arg])
|
||||
|
||||
@@ -1723,6 +1723,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||
let max = (1.BiggestInt shl (rb-1))-1
|
||||
if regs[ra].intVal < min or regs[ra].intVal > max:
|
||||
stackTrace(c, tos, pc, "unhandled exception: value out of range")
|
||||
of opcNarrowR:
|
||||
decodeBC(rkInt)
|
||||
let min = regs[rb].intVal
|
||||
let max = regs[rc].intVal
|
||||
if regs[ra].intVal < min or regs[ra].intVal > max:
|
||||
stackTrace(c, tos, pc, "unhandled exception: value out of range")
|
||||
of opcNarrowU:
|
||||
decodeB(rkInt)
|
||||
regs[ra].intVal = regs[ra].intVal and ((1'i64 shl rb)-1)
|
||||
|
||||
@@ -105,7 +105,7 @@ type
|
||||
opcIsNil, opcOf, opcIs,
|
||||
opcParseFloat, opcConv, opcCast,
|
||||
opcQuit, opcInvalidField,
|
||||
opcNarrowS, opcNarrowU,
|
||||
opcNarrowS, opcNarrowU, opcNarrowR
|
||||
opcSignExtend,
|
||||
|
||||
opcAddStrCh,
|
||||
|
||||
@@ -798,6 +798,11 @@ proc genNarrow(c: PCtx; n: PNode; dest: TDest) =
|
||||
c.gABC(n, opcNarrowU, dest, TRegister(size*8))
|
||||
elif t.kind in {tyInt8..tyInt32} or (t.kind == tyInt and size < 8):
|
||||
c.gABC(n, opcNarrowS, dest, TRegister(size*8))
|
||||
elif t.kind in {tyEnum, tyRange}:
|
||||
let intType = getSysType(c.graph, n.info, tyInt)
|
||||
let first = c.genx(newIntTypeNode(firstOrd(c.config, t), intType))
|
||||
let last = c.genx(newIntTypeNode(lastOrd(c.config, t), intType))
|
||||
c.gABC(n, opcNarrowR, dest, first, last)
|
||||
|
||||
proc genNarrowU(c: PCtx; n: PNode; dest: TDest) =
|
||||
let t = skipTypes(n.typ, abstractVar-{tyTypeDesc})
|
||||
|
||||
@@ -7981,6 +7981,35 @@ underlying C `struct`:c: in a `sizeof` expression:
|
||||
```
|
||||
|
||||
|
||||
CompleteStruct pragma
|
||||
---------------------
|
||||
The `completeStruct` pragma is a contract indicating that an `importc` type
|
||||
declaration contains all fields of the corresponding C type, allowing
|
||||
`sizeof`, `alignof`, and `offsetof` to be computed at compile-time.
|
||||
|
||||
By default, `importc` types are assumed to be incomplete (their size is
|
||||
unknown at compile-time). Use `completeStruct` when you need compile-time
|
||||
size information and can guarantee the Nim definition matches the C layout:
|
||||
|
||||
```Nim
|
||||
type
|
||||
InotifyEvent {.importc: "struct inotify_event", header: "<sys/inotify.h>",
|
||||
completeStruct.} = object
|
||||
wd: cint
|
||||
mask: uint32
|
||||
cookie: uint32
|
||||
len: uint32
|
||||
# All fields must match the C struct exactly
|
||||
```
|
||||
|
||||
If the Nim fields don't match the C struct, a static assertion will fail
|
||||
during C code generation.
|
||||
|
||||
Without `completeStruct`, attempting to use `sizeof` on an `importc` type
|
||||
at compile-time will error with "'sizeof' requires '.importc' types to be
|
||||
'.completeStruct'".
|
||||
|
||||
|
||||
Compile pragma
|
||||
--------------
|
||||
The `compile` pragma can be used to compile and link a C/C++ source file
|
||||
|
||||
@@ -181,6 +181,7 @@ body {
|
||||
|
||||
.nine.columns {
|
||||
width: 75.0%;
|
||||
margin-left: 0;
|
||||
padding-left: 1.5em; }
|
||||
|
||||
.twelve.columns {
|
||||
@@ -192,7 +193,9 @@ body {
|
||||
display: none;
|
||||
}
|
||||
.nine.columns {
|
||||
width: 98.0%;
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
body {
|
||||
font-size: 1em;
|
||||
|
||||
@@ -304,6 +304,35 @@ else:
|
||||
proc rotl32(x: uint32, r: int): uint32 {.inline.} =
|
||||
(x shl r) or (x shr (32 - r))
|
||||
|
||||
proc load4e(s: openArray[byte], o=0): uint32 {.inline.} =
|
||||
uint32(s[o + 3]) shl 24 or uint32(s[o + 2]) shl 16 or
|
||||
uint32(s[o + 1]) shl 8 or uint32(s[o + 0])
|
||||
|
||||
proc load8e(s: openArray[byte], o=0): uint64 {.inline.} =
|
||||
uint64(s[o + 7]) shl 56 or uint64(s[o + 6]) shl 48 or
|
||||
uint64(s[o + 5]) shl 40 or uint64(s[o + 4]) shl 32 or
|
||||
uint64(s[o + 3]) shl 24 or uint64(s[o + 2]) shl 16 or
|
||||
uint64(s[o + 1]) shl 8 or uint64(s[o + 0])
|
||||
|
||||
when declared(copyMem):
|
||||
from std/endians import littleEndian64, littleEndian32
|
||||
|
||||
proc load4(s: openArray[byte], o=0): uint32 {.inline.} =
|
||||
when nimvm: result = load4e(s, o)
|
||||
else:
|
||||
when declared copyMem:
|
||||
result = uint32(0)
|
||||
littleEndian32(addr result, addr s[o])
|
||||
else: result = load4e(s, o)
|
||||
|
||||
proc load8(s: openArray[byte], o=0): uint64 {.inline.} =
|
||||
when nimvm: result = load8e(s, o)
|
||||
else:
|
||||
when declared copyMem:
|
||||
result = uint64(0)
|
||||
littleEndian64(addr result, addr s[o])
|
||||
else: result = load8e(s, o)
|
||||
|
||||
proc murmurHash(x: openArray[byte]): Hash =
|
||||
# https://github.com/PeterScott/murmur3/blob/master/murmur3.c
|
||||
const
|
||||
@@ -320,24 +349,10 @@ proc murmurHash(x: openArray[byte]): Hash =
|
||||
h1: uint32 = uint32(0)
|
||||
i = 0
|
||||
|
||||
|
||||
template impl =
|
||||
var j = stepSize
|
||||
while j > 0:
|
||||
dec j
|
||||
k1 = (k1 shl 8) or (ord(x[i+j])).uint32
|
||||
|
||||
# body
|
||||
while i < n * stepSize:
|
||||
var k1: uint32 = uint32(0)
|
||||
var k1 = load4(x, i)
|
||||
|
||||
when nimvm:
|
||||
impl()
|
||||
else:
|
||||
when declared(copyMem):
|
||||
copyMem(addr k1, addr x[i], 4)
|
||||
else:
|
||||
impl()
|
||||
inc i, stepSize
|
||||
|
||||
k1 = imul(k1, c1)
|
||||
@@ -384,32 +399,6 @@ const k0 = 0xc3a5c85c97cb3127u64 # Primes on (2^63, 2^64) for various uses
|
||||
const k1 = 0xb492b66fbe98f273u64
|
||||
const k2 = 0x9ae16a3b2f90404fu64
|
||||
|
||||
proc load4e(s: openArray[byte], o=0): uint32 {.inline.} =
|
||||
uint32(s[o + 3]) shl 24 or uint32(s[o + 2]) shl 16 or
|
||||
uint32(s[o + 1]) shl 8 or uint32(s[o + 0])
|
||||
|
||||
proc load8e(s: openArray[byte], o=0): uint64 {.inline.} =
|
||||
uint64(s[o + 7]) shl 56 or uint64(s[o + 6]) shl 48 or
|
||||
uint64(s[o + 5]) shl 40 or uint64(s[o + 4]) shl 32 or
|
||||
uint64(s[o + 3]) shl 24 or uint64(s[o + 2]) shl 16 or
|
||||
uint64(s[o + 1]) shl 8 or uint64(s[o + 0])
|
||||
|
||||
proc load4(s: openArray[byte], o=0): uint32 {.inline.} =
|
||||
when nimvm: result = load4e(s, o)
|
||||
else:
|
||||
when declared copyMem:
|
||||
result = uint32(0)
|
||||
copyMem result.addr, s[o].addr, result.sizeof
|
||||
else: result = load4e(s, o)
|
||||
|
||||
proc load8(s: openArray[byte], o=0): uint64 {.inline.} =
|
||||
when nimvm: result = load8e(s, o)
|
||||
else:
|
||||
when declared copyMem:
|
||||
result = uint64(0)
|
||||
copyMem result.addr, s[o].addr, result.sizeof
|
||||
else: result = load8e(s, o)
|
||||
|
||||
proc lenU(s: openArray[byte]): uint64 {.inline.} = s.len.uint64
|
||||
|
||||
proc shiftMix(v: uint64): uint64 {.inline.} = v xor (v shr 47)
|
||||
|
||||
@@ -573,7 +573,7 @@ proc generateHeaders(requestUrl: Uri, httpMethod: HttpMethod, headers: HttpHeade
|
||||
result = $httpMethod
|
||||
result.add ' '
|
||||
|
||||
if proxy.isNil or (requestUrl.scheme == "https" and proxy.url.scheme == "socks5h"):
|
||||
if proxy.isNil or requestUrl.scheme == "https":
|
||||
# /path?query
|
||||
if not requestUrl.path.startsWith("/"): result.add '/'
|
||||
result.add(requestUrl.path)
|
||||
|
||||
@@ -181,6 +181,7 @@ body {
|
||||
|
||||
.nine.columns {
|
||||
width: 75.0%;
|
||||
margin-left: 0;
|
||||
padding-left: 1.5em; }
|
||||
|
||||
.twelve.columns {
|
||||
@@ -192,7 +193,9 @@ body {
|
||||
display: none;
|
||||
}
|
||||
.nine.columns {
|
||||
width: 98.0%;
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
body {
|
||||
font-size: 1em;
|
||||
|
||||
8
tests/ccgbugs/t25387.nim
Normal file
8
tests/ccgbugs/t25387.nim
Normal file
@@ -0,0 +1,8 @@
|
||||
discard """
|
||||
matrix: "--embedsrc=on"
|
||||
"""
|
||||
|
||||
proc trim() =
|
||||
let s = 10
|
||||
let x = s + 5 # user entered literal \
|
||||
trim()
|
||||
17
tests/errmsgs/tvmranges.nim
Normal file
17
tests/errmsgs/tvmranges.nim
Normal file
@@ -0,0 +1,17 @@
|
||||
discard """
|
||||
action: reject
|
||||
nimout: '''
|
||||
stack trace: (most recent call last)
|
||||
tvmranges.nim(14, 10)
|
||||
tvmranges.nim(14, 10) Error: unhandled exception: value out of range
|
||||
'''
|
||||
"""
|
||||
|
||||
type X = enum
|
||||
a
|
||||
b
|
||||
|
||||
when pred(a) == b:
|
||||
echo "a"
|
||||
else:
|
||||
echo "b"
|
||||
34
tests/generic/tgeneric_typedesc_sizeof.nim
Normal file
34
tests/generic/tgeneric_typedesc_sizeof.nim
Normal file
@@ -0,0 +1,34 @@
|
||||
discard """
|
||||
output: '''
|
||||
42
|
||||
'''
|
||||
"""
|
||||
|
||||
# Regression test for semtypinst.nim hasValuelessStatics bug.
|
||||
#
|
||||
# Bug: hasValuelessStatics only checked for tyStatic, missing tyTypeDesc(tyGenericParam)
|
||||
# Fix: Added check for tyTypeDesc wrapping tyGenericParam in compiler/semtypinst.nim
|
||||
#
|
||||
# The bug triggers when:
|
||||
# 1. A generic type has a when clause calling a typedesc template with sizeof(T)
|
||||
# 2. A generic proc on that type is called, triggering instantiation
|
||||
# 3. The T in sizeof(T) becomes tyTypeDesc(tyGenericParam), which wasn't recognized as unresolved
|
||||
#
|
||||
# Error without fix: 'sizeof' requires '.importc' types to be '.completeStruct'
|
||||
|
||||
template isSmall(T: typedesc): bool =
|
||||
sizeof(T) <= 8
|
||||
|
||||
type Foo[T] = object
|
||||
when isSmall(T):
|
||||
a: T
|
||||
else:
|
||||
b: ptr T
|
||||
|
||||
proc bar[T](x: var Foo[T]) =
|
||||
discard
|
||||
|
||||
var x: Foo[int]
|
||||
x.a = 42
|
||||
x.bar()
|
||||
echo x.a
|
||||
@@ -3,7 +3,7 @@ discard """
|
||||
matrix: "--hint:processing"
|
||||
nimout: '''
|
||||
compile start
|
||||
...
|
||||
....
|
||||
warn_module.nim(6, 6) Hint: 'test' is declared but not used [XDeclaredButNotUsed]
|
||||
compile end
|
||||
'''
|
||||
|
||||
Reference in New Issue
Block a user