diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 2 | ||||
-rw-r--r-- | compiler/astalgo.nim | 17 | ||||
-rw-r--r-- | compiler/evaltempl.nim | 5 | ||||
-rw-r--r-- | compiler/lexer.nim | 2 | ||||
-rw-r--r-- | compiler/msgs.nim | 8 | ||||
-rw-r--r-- | compiler/options.nim | 5 | ||||
-rw-r--r-- | compiler/sem.nim | 7 | ||||
-rw-r--r-- | compiler/semcall.nim | 1 | ||||
-rw-r--r-- | compiler/semexprs.nim | 15 | ||||
-rw-r--r-- | compiler/semstmts.nim | 2 | ||||
-rw-r--r-- | compiler/semtypes.nim | 5 | ||||
-rw-r--r-- | compiler/sigmatch.nim | 5 | ||||
-rw-r--r-- | compiler/types.nim | 5 |
13 files changed, 64 insertions, 15 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 177def594..137cc12f1 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -460,6 +460,8 @@ type # proc foo(T: typedesc, list: seq[T]): var T # proc foo(L: static[int]): array[L, int] # can be attached to ranges to indicate that the range + # can be attached to generic procs with free standing + # type parameters: e.g. proc foo[T]() # depends on unresolved static params. tfRetType, # marks return types in proc (used to detect type classes # used as return types for return type inference) diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim index 226d5ee42..161e4d637 100644 --- a/compiler/astalgo.nim +++ b/compiler/astalgo.nim @@ -67,6 +67,23 @@ proc debug*(n: PSym) {.deprecated.} proc debug*(n: PType) {.deprecated.} proc debug*(n: PNode) {.deprecated.} +template mdbg*: bool {.dirty.} = + when compiles(c.module): + c.module.fileIdx == gProjectMainIdx + elif compiles(m.c.module): + m.c.module.fileIdx == gProjectMainIdx + elif compiles(cl.c.module): + cl.c.module.fileIdx == gProjectMainIdx + elif compiles(p): + when compiles(p.lex): + p.lex.fileIdx == gProjectMainIdx + else: + p.module.module.fileIdx == gProjectMainIdx + elif compiles(L.fileIdx): + L.fileIdx == gProjectMainIdx + else: + false + # --------------------------- ident tables ---------------------------------- proc idTableGet*(t: TIdTable, key: PIdObj): RootRef proc idTableGet*(t: TIdTable, key: int): RootRef diff --git a/compiler/evaltempl.nim b/compiler/evaltempl.nim index 318254a80..5bd274a3e 100644 --- a/compiler/evaltempl.nim +++ b/compiler/evaltempl.nim @@ -80,9 +80,14 @@ proc evalTemplateArgs(n: PNode, s: PSym; fromHlo: bool): PNode = expectedRegularParams = <s.typ.len givenRegularParams = totalParams - genericParams if givenRegularParams < 0: givenRegularParams = 0 + if totalParams > expectedRegularParams + genericParams: globalError(n.info, errWrongNumberOfArguments) + if totalParams < genericParams: + globalError(n.info, errMissingGenericParamsForTemplate, + n.renderTree) + result = newNodeI(nkArgList, n.info) for i in 1 .. givenRegularParams: result.addSon n.sons[i] diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 2bb228f41..7e54a30e2 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -1080,7 +1080,7 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) = inc(L.bufpos) of '.': when defined(nimsuggest): - if L.fileIdx == gTrackPos.fileIndex and tok.col+1 == gTrackPos.col and + if L.fileIdx == gTrackPos.fileIndex and tok.col == gTrackPos.col and tok.line == gTrackPos.line and gIdeCmd == ideSug: tok.tokType = tkDot L.cursor = CursorPosition.InToken diff --git a/compiler/msgs.nim b/compiler/msgs.nim index b89b4ee93..2db3646b5 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -64,6 +64,8 @@ type errVarForOutParamNeeded, errPureTypeMismatch, errTypeMismatch, errButExpected, errButExpectedX, errAmbiguousCallXYZ, errWrongNumberOfArguments, + errWrongNumberOfArgumentsInCall, + errMissingGenericParamsForTemplate, errXCannotBePassedToProcVar, errXCannotBeInParamDecl, errPragmaOnlyInHeaderOfProcX, errImplOfXNotAllowed, errImplOfXexpected, errNoSymbolToBorrowFromFound, errDiscardValueX, @@ -89,6 +91,7 @@ type errMainModuleMustBeSpecified, errXExpected, errTIsNotAConcreteType, + errCastToANonConcreteType, errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError, errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile, errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitly, @@ -107,6 +110,7 @@ type errCannotInferTypeOfTheLiteral, errCannotInferReturnType, errGenericLambdaNotAllowed, + errProcHasNoConcreteType, errCompilerDoesntSupportTarget, errUser, warnCannotOpenFile, @@ -269,6 +273,8 @@ const errButExpectedX: "but expected \'$1\'", errAmbiguousCallXYZ: "ambiguous call; both $1 and $2 match for: $3", errWrongNumberOfArguments: "wrong number of arguments", + errWrongNumberOfArgumentsInCall: "wrong number of arguments in call to '$1'", + errMissingGenericParamsForTemplate: "'$1' has unspecified generic parameters", errXCannotBePassedToProcVar: "\'$1\' cannot be passed to a procvar", errXCannotBeInParamDecl: "$1 cannot be declared in parameter declaration", errPragmaOnlyInHeaderOfProcX: "pragmas are only allowed in the header of a proc; redefinition of $1", @@ -326,6 +332,7 @@ const errMainModuleMustBeSpecified: "please, specify a main module in the project configuration file", errXExpected: "\'$1\' expected", errTIsNotAConcreteType: "\'$1\' is not a concrete type.", + errCastToANonConcreteType: "cannot cast to a non concrete type: \'$1\'", errInvalidSectionStart: "invalid section start", errGridTableNotImplemented: "grid table is not implemented", errGeneralParseError: "general parse error", @@ -369,6 +376,7 @@ const errGenericLambdaNotAllowed: "A nested proc can have generic parameters only when " & "it is used as an operand to another routine and the types " & "of the generic paramers can be inferred from the expected signature.", + errProcHasNoConcreteType: "'$1' doesn't have a concrete type, due to unspecified generic parameters.", errCompilerDoesntSupportTarget: "The current compiler \'$1\' doesn't support the requested compilation target", errUser: "$1", warnCannotOpenFile: "cannot open \'$1\'", diff --git a/compiler/options.nim b/compiler/options.nim index c6d016095..349f9dae1 100644 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -420,11 +420,6 @@ proc binaryStrSearch*(x: openArray[string], y: string): int = return mid result = - 1 -template nimdbg*: untyped = c.module.fileIdx == gProjectMainIdx -template cnimdbg*: untyped = p.module.module.fileIdx == gProjectMainIdx -template pnimdbg*: untyped = p.lex.fileIdx == gProjectMainIdx -template lnimdbg*: untyped = L.fileIdx == gProjectMainIdx - proc parseIdeCmd*(s: string): IdeCmd = case s: of "sug": ideSug diff --git a/compiler/sem.nim b/compiler/sem.nim index 2ad506b41..6ad77e3fb 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -385,6 +385,13 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, if sym == c.p.owner: globalError(n.info, errRecursiveDependencyX, sym.name.s) + let genericParams = if sfImmediate in sym.flags: 0 + else: sym.ast[genericParamsPos].len + let suppliedParams = max(n.safeLen - 1, 0) + + if suppliedParams < genericParams: + globalError(n.info, errMissingGenericParamsForTemplate, n.renderTree) + #if c.evalContext == nil: # c.evalContext = c.createEvalContext(emStatic) result = evalMacroCall(c.module, c.cache, n, nOrig, sym) diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 98667b085..3a43c63b2 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -411,6 +411,7 @@ proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = let tm = typeRel(m, formal, arg, true) if tm in {isNone, isConvertible}: return nil var newInst = generateInstance(c, s, m.bindings, n.info) + newInst.typ.flags.excl tfUnresolved markUsed(n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) result = newSymNode(newInst, n.info) diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 3dc174527..8f1362691 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -30,6 +30,8 @@ proc semOperand(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # result = errorNode(c, n) if result.typ != nil: # XXX tyGenericInst here? + if result.typ.kind == tyProc and tfUnresolved in result.typ.flags: + localError(n.info, errProcHasNoConcreteType, n.renderTree) if result.typ.kind == tyVar: result = newDeref(result) elif {efWantStmt, efAllowStmt} * flags != {}: result.typ = newTypeS(tyVoid, c) @@ -218,13 +220,16 @@ proc semConv(c: PContext, n: PNode): PNode = proc semCast(c: PContext, n: PNode): PNode = ## Semantically analyze a casting ("cast[type](param)") checkSonsLen(n, 2) + let targetType = semTypeNode(c, n.sons[0], nil) + let castedExpr = semExprWithType(c, n.sons[1]) + if tfHasMeta in targetType.flags: + localError(n.sons[0].info, errCastToANonConcreteType, $targetType) + if not isCastable(targetType, castedExpr.typ): + localError(n.info, errExprCannotBeCastToX, $targetType) result = newNodeI(nkCast, n.info) - result.typ = semTypeNode(c, n.sons[0], nil) + result.typ = targetType addSon(result, copyTree(n.sons[0])) - addSon(result, semExprWithType(c, n.sons[1])) - if not isCastable(result.typ, result.sons[1].typ): - localError(result.info, errExprCannotBeCastToX, - typeToString(result.typ)) + addSon(result, castedExpr) proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = const diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 6d0190257..069ece6a6 100644 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -503,6 +503,8 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = if hasEmpty(typ): localError(def.info, errCannotInferTypeOfTheLiteral, ($typ.kind).substr(2).toLowerAscii) + elif typ.kind == tyProc and tfUnresolved in typ.flags: + localError(def.info, errProcHasNoConcreteType, def.renderTree) else: if symkind == skLet: localError(a.info, errLetNeedsInit) diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index 83d0c83b2..7877a26a9 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -1009,8 +1009,11 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode, result.sons[0] = r result.n.typ = r - if genericParams != nil: + if genericParams != nil and genericParams.len > 0: for n in genericParams: + if {sfUsed, sfAnon} * n.sym.flags == {}: + result.flags.incl tfUnresolved + if tfWildcard in n.sym.typ.flags: n.sym.kind = skType n.sym.typ.flags.excl tfWildcard diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index f2caab41f..bc9888df9 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -1514,6 +1514,7 @@ proc paramTypesMatch*(m: var TCandidate, f, a: PType, if arg.sons[i].sym.kind in {skProc, skMethod, skConverter, skIterator}: copyCandidate(z, m) z.callee = arg.sons[i].typ + if tfUnresolved in z.callee.flags: continue z.calleeSym = arg.sons[i].sym #if arg.sons[i].sym.name.s == "cmp": # ggDebug = true @@ -1650,7 +1651,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, if a >= formalLen-1 and formal != nil and formal.typ.isVarargsUntyped: incl(marker, formal.position) if container.isNil: - container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, n.info)) + container = newNodeIT(nkArgList, n.sons[a].info, arrayConstr(c, n.info)) setSon(m.call, formal.position + 1, container) else: incrIndexType(container.typ) @@ -1738,7 +1739,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode, if formal.typ.isVarargsUntyped: if container.isNil: - container = newNodeIT(nkBracket, n.sons[a].info, arrayConstr(c, n.info)) + container = newNodeIT(nkArgList, n.sons[a].info, arrayConstr(c, n.info)) setSon(m.call, formal.position + 1, container) else: incrIndexType(container.typ) diff --git a/compiler/types.nim b/compiler/types.nim index df1d3e3ca..f4ef75094 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -20,6 +20,7 @@ type preferName, preferDesc, preferExported, preferModuleInfo, preferGenericArg proc typeToString*(typ: PType; prefer: TPreferedDesc = preferName): string +template `$`*(typ: PType): string = typeToString(typ) proc base*(t: PType): PType = result = t.sons[0] @@ -547,7 +548,9 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string = if prefer != preferExported: result.add("(" & typeToString(t.sons[0]) & ")") of tyProc: - result = if tfIterator in t.flags: "iterator (" else: "proc (" + result = if tfIterator in t.flags: "iterator " else: "proc " + if tfUnresolved in t.flags: result.add "[*missing parameters*]" + result.add "(" for i in countup(1, sonsLen(t) - 1): if t.n != nil and i < t.n.len and t.n[i].kind == nkSym: add(result, t.n[i].sym.name.s) |