diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2019-02-18 15:23:43 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2019-02-18 15:23:43 +0100 |
commit | c8cb5679381b7e00fdfbdfd4fdd24b8794fdb84d (patch) | |
tree | df54e0b909b09dc124e941faa6774bcd331dfdc2 | |
parent | 739dc8094e4a4f6dd2f0eb0fb2eb8ce8191cb001 (diff) | |
parent | 2deb1e354fb7eba063c125579af04911f14382ed (diff) | |
download | Nim-c8cb5679381b7e00fdfbdfd4fdd24b8794fdb84d.tar.gz |
Merge branch 'devel' of github.com:nim-lang/Nim into devel
-rw-r--r-- | compiler/pragmas.nim | 28 | ||||
-rw-r--r-- | compiler/semstmts.nim | 41 | ||||
-rw-r--r-- | koch.nim | 8 | ||||
-rw-r--r-- | lib/core/macros.nim | 2 | ||||
-rw-r--r-- | tests/macros/tmacrotypes.nim | 34 | ||||
-rw-r--r-- | tests/pragmas/tcustom_pragma.nim | 7 |
6 files changed, 85 insertions, 35 deletions
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 3b6f82c40..9b3c66104 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -719,26 +719,34 @@ proc pragmaGuard(c: PContext; it: PNode; kind: TSymKind): PSym = result = qualifiedLookUp(c, n, {checkUndeclared}) proc semCustomPragma(c: PContext, n: PNode): PNode = + var callNode: PNode + if n.kind == nkIdent: - result = newTree(nkCall, n) + # pragma -> pragma() + callNode = newTree(nkCall, n) elif n.kind == nkExprColonExpr: # pragma: arg -> pragma(arg) - result = newTree(nkCall, n[0], n[1]) + callNode = newTree(nkCall, n[0], n[1]) elif n.kind in nkPragmaCallKinds: - result = n + callNode = n else: invalidPragma(c, n) return n - let r = c.semOverloadedCall(c, result, n, {skTemplate}, {efNoUndeclared}) + let r = c.semOverloadedCall(c, callNode, n, {skTemplate}, {efNoUndeclared}) + if r.isNil or sfCustomPragma notin r[0].sym.flags: invalidPragma(c, n) - else: - result = r - if n.kind == nkIdent: - result = result[0] - elif n.kind == nkExprColonExpr: - result.kind = n.kind # pragma(arg) -> pragma: arg + return n + + result = r + # Transform the nkCall node back to its original form if possible + if n.kind == nkIdent and r.len == 1: + # pragma() -> pragma + result = result[0] + elif n.kind == nkExprColonExpr and r.len == 2: + # pragma(arg) -> pragma: arg + result.kind = n.kind proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, validPragmas: TSpecialWords, comesFromPush: bool) : bool = diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 5b7556b2e..cd570caad 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1136,7 +1136,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) = # its evaluated result here so that we don't execute it once again in the # final pass if a[2].kind in nkCallKinds: - a[2] = newNodeIT(nkType, a[2].info, t) + incl a[2].flags, nfSem # bug #10548 if sfExportc in s.flags and s.typ.kind == tyAlias: localError(c.config, name.info, "{.exportc.} not allowed for type aliases") let aa = a.sons[2] @@ -1191,24 +1191,27 @@ proc typeSectionFinalPass(c: PContext, n: PNode) = # compute the type's size and check for illegal recursions: if a.sons[1].kind == nkEmpty: var x = a[2] - while x.kind in {nkStmtList, nkStmtListExpr} and x.len > 0: - x = x.lastSon - if x.kind notin {nkObjectTy, nkDistinctTy, nkEnumTy, nkEmpty} and - s.typ.kind notin {tyObject, tyEnum}: - # type aliases are hard: - var t = semTypeNode(c, x, nil) - assert t != nil - if s.typ != nil and s.typ.kind notin {tyAlias, tySink}: - if t.kind in {tyProc, tyGenericInst} and not t.isMetaType: - assignType(s.typ, t) - s.typ.id = t.id - elif t.kind in {tyObject, tyEnum, tyDistinct}: - assert s.typ != nil - assignType(s.typ, t) - s.typ.id = t.id # same id - checkConstructedType(c.config, s.info, s.typ) - if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil: - checkForMetaFields(c, s.typ.n) + if x.kind in nkCallKinds and nfSem in x.flags: + discard "already semchecked, see line marked with bug #10548" + else: + while x.kind in {nkStmtList, nkStmtListExpr} and x.len > 0: + x = x.lastSon + if x.kind notin {nkObjectTy, nkDistinctTy, nkEnumTy, nkEmpty} and + s.typ.kind notin {tyObject, tyEnum}: + # type aliases are hard: + var t = semTypeNode(c, x, nil) + assert t != nil + if s.typ != nil and s.typ.kind notin {tyAlias, tySink}: + if t.kind in {tyProc, tyGenericInst} and not t.isMetaType: + assignType(s.typ, t) + s.typ.id = t.id + elif t.kind in {tyObject, tyEnum, tyDistinct}: + assert s.typ != nil + assignType(s.typ, t) + s.typ.id = t.id # same id + checkConstructedType(c.config, s.info, s.typ) + if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil: + checkForMetaFields(c, s.typ.n) instAllTypeBoundOp(c, n.info) diff --git a/koch.nim b/koch.nim index 5deda5ecd..ac95c1566 100644 --- a/koch.nim +++ b/koch.nim @@ -291,13 +291,14 @@ proc boot(args: string) = hostOs & "_" & hostCpu let nimStart = findStartNim() - copyExe(nimStart, 0.thVersion) for i in 0..2: let defaultCommand = if useCpp: "cpp" else: "c" let bootOptions = if args.len == 0 or args.startsWith("-"): defaultCommand else: "" echo "iteration: ", i+1 var extraOption = "" + var nimi = i.thVersion if i == 0: + nimi = nimStart extraOption.add " --skipUserCfg --skipParentCfg" # The configs are skipped for bootstrap # (1st iteration) to prevent newer flags from breaking bootstrap phase. @@ -307,8 +308,9 @@ proc boot(args: string) = if version.startsWith "Nim Compiler Version 0.19.0": extraOption.add " -d:nimBoostrapCsources0_19_0" # remove this when csources get updated - exec i.thVersion & " $# $# $# --nimcache:$# compiler" / "nim.nim" % - [bootOptions, extraOption, args, smartNimcache] + + exec "$# $# $# $# --nimcache:$# compiler" / "nim.nim" % + [nimi, bootOptions, extraOption, args, smartNimcache] if sameFileContent(output, i.thVersion): copyExe(output, finalDest) echo "executables are equal: SUCCESS!" diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 43e61d660..7ec1eefc6 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -1515,7 +1515,7 @@ macro getCustomPragmaVal*(n: typed, cp: typed{nkSym}): untyped = else: let def = p[0].getImpl[3] result = newTree(nnkPar) - for i in 1..<p.len: + for i in 1 ..< def.len: let key = def[i][0] let val = p[i] result.add newTree(nnkExprColonExpr, key, val) diff --git a/tests/macros/tmacrotypes.nim b/tests/macros/tmacrotypes.nim index b4d708240..ab8bcfa95 100644 --- a/tests/macros/tmacrotypes.nim +++ b/tests/macros/tmacrotypes.nim @@ -14,10 +14,10 @@ macro checkType(ex: typed; expected: string): untyped = macro checkProcType(fn: typed): untyped = let fn_sym = if fn.kind == nnkProcDef: fn[0] else: fn echo fn_sym, "; ", fn_sym.typeKind, "; ", fn_sym.getType.repr, "; ", fn_sym.getTypeImpl.repr - + proc voidProc = echo "hello" -proc intProc(a: int, b: float): int {.checkProcType.} = 10 +proc intProc(a: int, b: float): int {.checkProcType.} = 10 checkType(voidProc(), "void") checkType(intProc(10, 20.0), "int") @@ -38,3 +38,33 @@ block: Club = Blub static: doAssert(c == 1) + +# bug #10702 +type + VectorElementType = SomeNumber | bool + Vec*[N : static[int], T: VectorElementType] = object + arr*: array[N, T] + +type + Vec4*[T: VectorElementType] = Vec[4,T] + Vec3*[T: VectorElementType] = Vec[3,T] + Vec2*[T: VectorElementType] = Vec[2,T] + +template vecGen(U:untyped,V:typed):typed= + ## ``U`` suffix + ## ``V`` valType + ## + type + `Vec2 U`* {.inject.} = Vec2[V] + `Vec3 U`* {.inject.} = Vec3[V] + `Vec4 U`* {.inject.} = Vec4[V] + +vecGen(f, float32) + +macro foobar(arg: typed): untyped = + let typ = arg.getTypeInst + doAssert typ.getImpl[^1].kind == nnkCall + +var x: Vec2f + +foobar(x) diff --git a/tests/pragmas/tcustom_pragma.nim b/tests/pragmas/tcustom_pragma.nim index 0dc85cf67..9f2fc024b 100644 --- a/tests/pragmas/tcustom_pragma.nim +++ b/tests/pragmas/tcustom_pragma.nim @@ -233,3 +233,10 @@ block: doAssert ps.first == ps[0] and ps.first == "one" doAssert ps.second == ps[1] and ps.second == 2 doAssert ps.third == ps[2] and ps.third == 3.0 + +# pragma with implicit&explicit generic types +block: + template fooBar[T](x: T; c: static[int] = 42; m: char) {.pragma.} + var e {.fooBar("foo", 123, 'u').}: int + doAssert(hasCustomPragma(e, fooBar)) + doAssert(getCustomPragmaVal(e, fooBar).c == 123) |