diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 5 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 7 | ||||
-rw-r--r-- | compiler/cgen.nim | 2 | ||||
-rw-r--r-- | compiler/condsyms.nim | 1 | ||||
-rw-r--r-- | compiler/msgs.nim | 1 | ||||
-rw-r--r-- | compiler/semcall.nim | 5 | ||||
-rw-r--r-- | compiler/semdata.nim | 3 | ||||
-rw-r--r-- | compiler/semexprs.nim | 62 | ||||
-rw-r--r-- | compiler/semfold.nim | 9 | ||||
-rw-r--r-- | compiler/semgnrc.nim | 23 | ||||
-rw-r--r-- | compiler/seminst.nim | 2 | ||||
-rw-r--r-- | compiler/semmagic.nim | 34 | ||||
-rw-r--r-- | compiler/semstmts.nim | 2 | ||||
-rw-r--r-- | compiler/semtempl.nim | 51 | ||||
-rw-r--r-- | compiler/semtypes.nim | 35 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 4 |
16 files changed, 206 insertions, 40 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 860bf67e8..be11e80be 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -477,6 +477,8 @@ type # wildcard type. tfHasAsgn # type has overloaded assignment operator tfBorrowDot # distinct type borrows '.' + tfTriggersCompileTime # uses the NimNode type which make the proc + # implicitly '.compiletime' TTypeFlags* = set[TTypeFlag] @@ -1380,6 +1382,9 @@ proc propagateToOwner*(owner, elem: PType) = o2.flags.incl tfHasAsgn owner.flags.incl tfHasAsgn + if tfTriggersCompileTime in elem.flags: + owner.flags.incl tfTriggersCompileTime + if owner.kind notin {tyProc, tyGenericInst, tyGenericBody, tyGenericInvocation, tyPtr}: let elemB = elem.skipTypes({tyGenericInst}) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 54063229f..32fc76470 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1741,6 +1741,8 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = of mEcho: genEcho(p, e[1].skipConv) of mArrToSeq: genArrToSeq(p, e, d) of mNLen..mNError, mSlurp..mQuoteAst: + echo "from here ", p.prc.name.s, " ", p.prc.info + writestacktrace() localError(e.info, errXMustBeCompileTime, e.sons[0].sym.name.s) of mSpawn: let n = lowerings.wrapProcForSpawn(p.module.module, e, e.typ, nil, nil) @@ -1973,6 +1975,9 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = genProc(p.module, sym) putLocIntoDest(p, d, sym.loc) of skProc, skConverter, skIterators: + if sfCompileTime in sym.flags: + localError(n.info, "request to generate code for .compileTime proc: " & + sym.name.s) genProc(p.module, sym) if sym.loc.r == nil or sym.loc.t == nil: internalError(n.info, "expr: proc not init " & sym.name.s) @@ -2126,7 +2131,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) = # due to a bug/limitation in the lambda lifting, unused inner procs # are not transformed correctly. We work around this issue (#411) here # by ensuring it's no inner proc (owner is a module): - if prc.skipGenericOwner.kind == skModule: + if prc.skipGenericOwner.kind == skModule and sfCompileTime notin prc.flags: if (optDeadCodeElim notin gGlobalOptions and sfDeadCodeElim notin getModule(prc).flags) or ({sfExportc, sfCompilerProc} * prc.flags == {sfExportc}) or diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 3f88e63ee..f63134b66 100644 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -1110,7 +1110,7 @@ proc rawNewModule(module: PSym, filename: string): BModule = proc nullify[T](arr: var T) = for i in low(arr)..high(arr): - arr[i] = nil + arr[i] = Rope(nil) proc resetModule*(m: BModule) = # between two compilations in CAAS mode, we can throw diff --git a/compiler/condsyms.nim b/compiler/condsyms.nim index 31bd85a06..60e8f2826 100644 --- a/compiler/condsyms.nim +++ b/compiler/condsyms.nim @@ -92,3 +92,4 @@ proc initDefines*() = defineSymbol("nimvarargstyped") defineSymbol("nimtypedescfixed") defineSymbol("nimKnowsNimvm") + defineSymbol("nimArrIdx") diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 8b3b11f4a..c5bc44664 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -514,6 +514,7 @@ const {low(TNoteKind)..high(TNoteKind)} - {warnShadowIdent, warnUninit, warnProveField, warnProveIndex, warnGcUnsafe, + hintPath, hintConf, hintDependency, hintExecuting, hintCodeBegin, hintCodeEnd, diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 2f181b5f3..f9fadeec7 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -308,7 +308,10 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode = let gp = finalCallee.ast.sons[genericParamsPos] if gp.kind != nkEmpty: if x.calleeSym.kind notin {skMacro, skTemplate}: - finalCallee = generateInstance(c, x.calleeSym, x.bindings, n.info) + if x.calleeSym.magic in {mArrGet, mArrPut}: + finalCallee = x.calleeSym + else: + finalCallee = generateInstance(c, x.calleeSym, x.bindings, n.info) else: # For macros and templates, the resolved generic params # are added as normal params. diff --git a/compiler/semdata.nim b/compiler/semdata.nim index 345a8c0d1..e6456293c 100644 --- a/compiler/semdata.nim +++ b/compiler/semdata.nim @@ -45,7 +45,8 @@ type TExprFlag* = enum efLValue, efWantIterator, efInTypeof, efWantStmt, efAllowStmt, efDetermineType, - efAllowDestructor, efWantValue, efOperand, efNoSemCheck + efAllowDestructor, efWantValue, efOperand, efNoSemCheck, + efNoProcvarCheck TExprFlags* = set[TExprFlag] TTypeAttachedOp* = enum diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 3ff04a4fc..0e1d52fd4 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -52,7 +52,7 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result.typ = errorType(c) else: # XXX tyGenericInst here? - semProcvarCheck(c, result) + if efNoProcvarCheck notin flags: semProcvarCheck(c, result) if result.typ.kind == tyVar: result = newDeref(result) semDestructorCheck(c, result, flags) @@ -452,18 +452,18 @@ proc changeType(n: PNode, newType: PType, check: bool) = let tup = newType.skipTypes({tyGenericInst}) if tup.kind != tyTuple: if tup.kind == tyObject: return - internalError(n.info, "changeType: no tuple type for constructor") + globalError(n.info, "no tuple type for constructor") elif sonsLen(n) > 0 and n.sons[0].kind == nkExprColonExpr: # named tuple? for i in countup(0, sonsLen(n) - 1): var m = n.sons[i].sons[0] if m.kind != nkSym: - internalError(m.info, "changeType(): invalid tuple constr") + globalError(m.info, "invalid tuple constructor") return if tup.n != nil: var f = getSymFromList(tup.n, m.sym.name) if f == nil: - internalError(m.info, "changeType(): invalid identifier") + globalError(m.info, "unknown identifier: " & m.sym.name.s) return changeType(n.sons[i].sons[1], f.typ, check) else: @@ -1156,7 +1156,7 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = result.add(x[0]) return checkMinSonsLen(n, 2) - n.sons[0] = semExprWithType(c, n.sons[0]) + n.sons[0] = semExprWithType(c, n.sons[0], {efNoProcvarCheck}) let arr = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar, tyPtr, tyRef}) case arr.kind of tyArray, tyOpenArray, tyVarargs, tyArrayConstr, tySequence, tyString, @@ -1196,7 +1196,17 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = localError(n.info, errIndexTypesDoNotMatch) result = n else: - c.p.bracketExpr = n.sons[0] + let s = if n.sons[0].kind == nkSym: n.sons[0].sym + elif n[0].kind in nkSymChoices: n.sons[0][0].sym + else: nil + if s != nil and s.kind in {skProc, skMethod, skConverter}+skIterators: + # type parameters: partial generic specialization + n.sons[0] = semSymGenericInstantiation(c, n.sons[0], s) + result = explicitGenericInstantiation(c, n, s) + elif s != nil and s.kind == skType: + result = symNodeFromType(c, semTypeNode(c, n, nil), n.info) + else: + c.p.bracketExpr = n.sons[0] proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = let oldBracketExpr = c.p.bracketExpr @@ -1250,7 +1260,7 @@ proc asgnToResultVar(c: PContext, n, le, ri: PNode) {.inline.} = template resultTypeIsInferrable(typ: PType): expr = typ.isMetaType and typ.kind != tyTypeDesc -proc semAsgn(c: PContext, n: PNode): PNode = +proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = checkSonsLen(n, 2) var a = n.sons[0] case a.kind @@ -1273,12 +1283,15 @@ proc semAsgn(c: PContext, n: PNode): PNode = # --> `[]=`(a, i, x) let oldBracketExpr = c.p.bracketExpr a = semSubscript(c, a, {efLValue}) - if a == nil: + if a == nil and mode != noOverloadedSubscript: result = buildOverloadedSubscripts(n.sons[0], getIdent"[]=") add(result, n[1]) result = semExprNoType(c, result) c.p.bracketExpr = oldBracketExpr return result + elif a == nil: + localError(n.info, "could not resolve: " & $n[0]) + return n c.p.bracketExpr = oldBracketExpr of nkCurlyExpr: # a{i} = x --> `{}=`(a, i, x) @@ -1323,7 +1336,8 @@ proc semAsgn(c: PContext, n: PNode): PNode = typeMismatch(n, lhs.typ, rhs.typ) n.sons[1] = fitNode(c, le, rhs) - if tfHasAsgn in lhs.typ.flags and not lhsIsResult: + if tfHasAsgn in lhs.typ.flags and not lhsIsResult and + mode != noOverloadedAsgn: return overloadedAsgn(c, lhs, n.sons[1]) fixAbstractType(c, n) @@ -1715,6 +1729,9 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = of mTypeOf: checkSonsLen(n, 2) result = semTypeOf(c, n.sons[1]) + #of mArrGet: result = semArrGet(c, n, flags) + #of mArrPut: result = semArrPut(c, n, flags) + #of mAsgn: result = semAsgnOpr(c, n) of mDefined: result = semDefined(c, setMs(n, s), false) of mDefinedInScope: result = semDefined(c, setMs(n, s), true) of mCompiles: result = semCompiles(c, setMs(n, s), flags) @@ -2066,6 +2083,19 @@ proc semExport(c: PContext, n: PNode): PNode = c.module.ast.add x result = n +proc shouldBeBracketExpr(n: PNode): bool = + assert n.kind in nkCallKinds + let a = n.sons[0] + if a.kind in nkCallKinds: + let b = a[0] + if b.kind in nkSymChoices: + for i in 0..<b.len: + if b[i].sym.magic == mArrGet: + let be = newNodeI(nkBracketExpr, n.info) + for i in 1..<a.len: be.add(a[i]) + n.sons[0] = be + return true + proc setGenericParams(c: PContext, n: PNode) = for i in 1 .. <n.len: n[i].typ = semTypeNode(c, n[i], nil) @@ -2173,7 +2203,8 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = else: #liMessage(n.info, warnUser, renderTree(n)); result = semIndirectOp(c, n, flags) - elif n[0].kind == nkBracketExpr and isSymChoice(n[0][0]): + elif (n[0].kind == nkBracketExpr or shouldBeBracketExpr(n)) and + isSymChoice(n[0][0]): # indirectOp can deal with explicit instantiations; the fixes # the 'newSeq[T](x)' bug setGenericParams(c, n.sons[0]) @@ -2194,16 +2225,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semExpr(c, result, flags) of nkBracketExpr: checkMinSonsLen(n, 1) - var s = qualifiedLookUp(c, n.sons[0], {checkUndeclared}) - if (s != nil and s.kind in {skProc, skMethod, skConverter}+skIterators) or - n[0].kind in nkSymChoices: - # type parameters: partial generic specialization - n.sons[0] = semSymGenericInstantiation(c, n.sons[0], s) - result = explicitGenericInstantiation(c, n, s) - elif s != nil and s.kind in {skType}: - result = symNodeFromType(c, semTypeNode(c, n, nil), n.info) - else: - result = semArrayAccess(c, n, flags) + result = semArrayAccess(c, n, flags) of nkCurlyExpr: result = semExpr(c, buildOverloadedSubscripts(n, getIdent"{}"), flags) of nkPragmaExpr: diff --git a/compiler/semfold.nim b/compiler/semfold.nim index 70276a6d4..5fe4e3299 100644 --- a/compiler/semfold.nim +++ b/compiler/semfold.nim @@ -430,17 +430,10 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode = of mCompileOptionArg: result = newIntNodeT(ord( testCompileOptionArg(getStr(a), getStr(b), n.info)), n) - of mNewString, mNewStringOfCap, - mExit, mInc, ast.mDec, mEcho, mSwap, mAppendStrCh, - mAppendStrStr, mAppendSeqElem, mSetLengthStr, mSetLengthSeq, - mParseExprToAst, mParseStmtToAst, mExpandToAst, mTypeTrait, mDotDot, - mNLen..mNError, mEqRef, mSlurp, mStaticExec, mNGenSym, mSpawn, - mParallel, mPlugin, mGetTypeInfo, mTypeOf: - discard of mEqProc: result = newIntNodeT(ord( exprStructuralEquivalent(a, b, strictSymEquality=true)), n) - else: internalError(a.info, "evalOp(" & $m & ')') + else: discard proc getConstIfExpr(c: PSym, n: PNode): PNode = result = nil diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index e3b598919..ed0244b0c 100644 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -251,6 +251,29 @@ proc semGenericStmt(c: PContext, n: PNode, let flags = if mixinContext: flags+{withinMixin} else: flags for i in countup(first, sonsLen(result) - 1): result.sons[i] = semGenericStmt(c, result.sons[i], flags, ctx) + of nkBracketExpr, nkCurlyExpr: + result = newNodeI(nkCall, n.info) + result.add newIdentNode(getIdent(if n.kind == nkBracketExpr:"[]" else:"{}"), + n.info) + for i in 0 ..< n.len: result.add(n[i]) + result = semGenericStmt(c, result, flags, ctx) + of nkAsgn, nkFastAsgn: + checkSonsLen(n, 2) + let a = n.sons[0] + let b = n.sons[1] + + let k = a.kind + case k + of nkBracketExpr, nkCurlyExpr: + result = newNodeI(nkCall, n.info) + result.add newIdentNode(getIdent(if k == nkBracketExpr:"[]=" else:"{}="), + n.info) + for i in 0 ..< a.len: result.add(a[i]) + result.add(b) + result = semGenericStmt(c, result, flags, ctx) + else: + for i in countup(0, sonsLen(n) - 1): + result.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx) of nkIfStmt: for i in countup(0, sonsLen(n)-1): n.sons[i] = semGenericStmtScope(c, n.sons[i], flags, ctx) diff --git a/compiler/seminst.nim b/compiler/seminst.nim index 42a39d0df..64e3e8cb8 100644 --- a/compiler/seminst.nim +++ b/compiler/seminst.nim @@ -246,6 +246,8 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, inc i pushProcCon(c, result) instantiateProcType(c, pt, result, info) + if tfTriggersCompileTime in result.typ.flags: + incl(result.flags, sfCompileTime) n.sons[genericParamsPos] = ast.emptyNode var oldPrc = genericCacheGet(fn, entry[]) if oldPrc == nil: diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim index 5d16470b0..65185f762 100644 --- a/compiler/semmagic.nim +++ b/compiler/semmagic.nim @@ -26,6 +26,37 @@ proc semTypeOf(c: PContext; n: PNode): PNode = result.add typExpr result.typ = makeTypeDesc(c, typExpr.typ.skipTypes({tyTypeDesc, tyIter})) +type + SemAsgnMode = enum asgnNormal, noOverloadedSubscript, noOverloadedAsgn + +proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode +proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode + +proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode = + result = newNodeI(nkBracketExpr, n.info) + for i in 1..<n.len: result.add(n[i]) + let oldBracketExpr = c.p.bracketExpr + result = semSubscript(c, result, flags) + c.p.bracketExpr = oldBracketExpr + if result.isNil: + localError(n.info, "could not resolve: " & $n) + result = n + +proc semArrPut(c: PContext; n: PNode; flags: TExprFlags): PNode = + # rewrite `[]=`(a, i, x) back to ``a[i] = x``. + let b = newNodeI(nkBracketExpr, n.info) + for i in 1..n.len-2: b.add(n[i]) + result = newNodeI(nkAsgn, n.info, 2) + result.sons[0] = b + result.sons[1] = n.lastSon + result = semAsgn(c, result, noOverloadedSubscript) + +proc semAsgnOpr(c: PContext; n: PNode): PNode = + result = newNodeI(nkAsgn, n.info, 2) + result.sons[0] = n[1] + result.sons[1] = n[2] + result = semAsgn(c, result, noOverloadedAsgn) + proc semIsPartOf(c: PContext, n: PNode, flags: TExprFlags): PNode = var r = isPartOf(n[1], n[2]) result = newIntNodeT(ord(r), n) @@ -125,6 +156,9 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode, of mTypeOf: checkSonsLen(n, 2) result = semTypeOf(c, n.sons[1]) + of mArrGet: result = semArrGet(c, n, flags) + of mArrPut: result = semArrPut(c, n, flags) + of mAsgn: result = semAsgnOpr(c, n) of mIsPartOf: result = semIsPartOf(c, n, flags) of mTypeTrait: result = semTypeTraits(c, n) of mAstToStr: diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 4399c0ab0..f67ee2822 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -1033,6 +1033,7 @@ proc semOverride(c: PContext, s: PSym, n: PNode) = "signature for 'deepCopy' must be proc[T: ptr|ref](x: T): T") incl(s.flags, sfUsed) of "=": + if s.magic == mAsgn: return incl(s.flags, sfUsed) let t = s.typ if t.len == 3 and t.sons[0] == nil and t.sons[1].kind == tyVar: @@ -1131,6 +1132,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind, # semParamList(c, n.sons[ParamsPos], nil, s) else: s.typ = newProcType(c, n.info) + if tfTriggersCompileTime in s.typ.flags: incl(s.flags, sfCompileTime) if n.sons[patternPos].kind != nkEmpty: n.sons[patternPos] = semPattern(c, n.sons[patternPos]) if s.kind in skIterators: diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim index 371abe1e3..fc1af7246 100644 --- a/compiler/semtempl.nim +++ b/compiler/semtempl.nim @@ -281,6 +281,35 @@ proc semTemplBodySons(c: var TemplCtx, n: PNode): PNode = for i in 0.. < n.len: result.sons[i] = semTemplBody(c, n.sons[i]) +proc wrapInBind(c: var TemplCtx; n: PNode; opr: string): PNode = + let ident = getIdent(opr) + if ident.id in c.toInject: return n + + let s = searchInScopes(c.c, ident) + if s != nil: + var callee: PNode + if contains(c.toBind, s.id): + callee = symChoice(c.c, n, s, scClosed) + elif contains(c.toMixin, s.name.id): + callee = symChoice(c.c, n, s, scForceOpen) + elif s.owner == c.owner and sfGenSym in s.flags: + # template tmp[T](x: var seq[T]) = + # var yz: T + incl(s.flags, sfUsed) + callee = newSymNode(s, n.info) + styleCheckUse(n.info, s) + else: + callee = semTemplSymbol(c.c, n, s) + + let call = newNodeI(nkCall, n.info) + call.add(callee) + for i in 0 .. n.len-1: call.add(n[i]) + result = newNodeI(nkBind, n.info, 2) + result.sons[0] = n + result.sons[1] = call + else: + result = n + proc semTemplBody(c: var TemplCtx, n: PNode): PNode = result = n semIdeForTemplateOrGenericCheck(n, c.cursorInBody) @@ -423,6 +452,28 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode = result.sons[1] = semTemplBody(c, n.sons[1]) of nkPragma: result = onlyReplaceParams(c, n) + of nkBracketExpr, nkCurlyExpr: + result = newNodeI(nkCall, n.info) + result.add newIdentNode(getIdent(if n.kind == nkBracketExpr:"[]" else:"{}"), + n.info) + for i in 0 ..< n.len: result.add(n[i]) + result = semTemplBodySons(c, result) + of nkAsgn, nkFastAsgn: + checkSonsLen(n, 2) + let a = n.sons[0] + let b = n.sons[1] + + let k = a.kind + case k + of nkBracketExpr, nkCurlyExpr: + result = newNodeI(nkCall, n.info) + result.add newIdentNode(getIdent(if k == nkBracketExpr:"[]=" else:"{}="), + n.info) + for i in 0 ..< a.len: result.add(a[i]) + result.add(b) + else: + result = n + result = semTemplBodySons(c, result) else: # dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam', # so we use the generic code for nkDotExpr too diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 2ee17fcaf..1cfbc368b 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -718,12 +718,12 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, if paramType == nil: return # (e.g. proc return type) proc addImplicitGenericImpl(typeClass: PType, typId: PIdent): PType = - let finalTypId = if typId != nil: typId - else: getIdent(paramName & ":type") if genericParams == nil: # This happens with anonymous proc types appearing in signatures # XXX: we need to lift these earlier return + let finalTypId = if typId != nil: typId + else: getIdent(paramName & ":type") # is this a bindOnce type class already present in the param list? for i in countup(0, genericParams.len - 1): if genericParams.sons[i].sym.name.id == finalTypId.id: @@ -757,7 +757,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, case paramType.kind: of tyAnything: - result = addImplicitGeneric(newTypeS(tyGenericParam, c)) + result = addImplicitGenericImpl(newTypeS(tyGenericParam, c), nil) of tyStatic: # proc(a: expr{string}, b: expr{nkLambda}) @@ -868,6 +868,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode, of tyExpr: if procKind notin {skMacro, skTemplate}: result = addImplicitGeneric(newTypeS(tyAnything, c)) + #result = addImplicitGenericImpl(newTypeS(tyGenericParam, c), nil) of tyGenericParam: markUsed(info, paramType.sym) @@ -977,7 +978,11 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, # compiler only checks for 'nil': if skipTypes(r, {tyGenericInst}).kind != tyEmpty: # 'auto' as a return type does not imply a generic: - if r.kind != tyExpr: + if r.kind == tyAnything: + # 'p(): auto' and 'p(): expr' are equivalent, but the rest of the + # compiler is hardly aware of 'auto': + r = newTypeS(tyExpr, c) + elif r.kind != tyExpr: if r.sym == nil or sfAnon notin r.sym.flags: let lifted = liftParamType(c, kind, genericParams, r, "result", n.sons[0].info) @@ -1149,7 +1154,17 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = else: result = semAnonTuple(c, n, prev) of nkCallKinds: - if isRange(n): + let x = n[0] + let ident = case x.kind + of nkIdent: x.ident + of nkSym: x.sym.name + of nkClosedSymChoice, nkOpenSymChoice: x[0].sym.name + else: nil + if ident != nil and ident.s == "[]": + let b = newNodeI(nkBracketExpr, n.info) + for i in 1..<n.len: b.add(n[i]) + result = semTypeNode(c, b, prev) + elif ident != nil and ident.id == ord(wDotDot): result = semRangeAux(c, n, prev) elif n[0].kind notin nkIdentKinds: result = semTypeExpr(c, n) @@ -1336,8 +1351,11 @@ proc processMagicType(c: PContext, m: PSym) = of mIntSetBaseType: setMagicType(m, tyRange, intSize) of mNil: setMagicType(m, tyNil, ptrSize) of mExpr: - setMagicType(m, tyExpr, 0) - if m.name.s == "expr": m.typ.flags.incl tfOldSchoolExprStmt + if m.name.s == "auto": + setMagicType(m, tyAnything, 0) + else: + setMagicType(m, tyExpr, 0) + if m.name.s == "expr": m.typ.flags.incl tfOldSchoolExprStmt of mStmt: setMagicType(m, tyStmt, 0) if m.name.s == "stmt": m.typ.flags.incl tfOldSchoolExprStmt @@ -1365,7 +1383,8 @@ proc processMagicType(c: PContext, m: PSym) = of mOrdinal: setMagicType(m, tyOrdinal, 0) rawAddSon(m.typ, newTypeS(tyNone, c)) - of mPNimrodNode: discard + of mPNimrodNode: + incl m.typ.flags, tfTriggersCompileTime of mShared: setMagicType(m, tyObject, 0) m.typ.n = newNodeI(nkRecList, m.info) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 61f1a7444..f6f029936 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1691,6 +1691,10 @@ proc partialMatch*(c: PContext, n, nOrig: PNode, m: var TCandidate) = matchesAux(c, n, nOrig, m, marker) proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) = + if m.calleeSym != nil and m.calleeSym.magic in {mArrGet, mArrPut}: + m.state = csMatch + m.call = n + return var marker = initIntSet() matchesAux(c, n, nOrig, m, marker) if m.state == csNoMatch: return |