summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2018-08-23 11:30:55 +0200
committerAraq <rumpf_a@web.de>2018-08-23 11:30:55 +0200
commit30597e643fe8818ef1bb6cc93a5c573f92a28ea9 (patch)
treeea6de7aabdbfc5db583e2dfbaf9f792c8240a63e /compiler
parentcb9e9297fba72c812913376311ca4b7ebd7e007f (diff)
parent55a86497491586dc1b5ad2f6303d53992b999ab5 (diff)
downloadNim-30597e643fe8818ef1bb6cc93a5c573f92a28ea9.tar.gz
fixes merge conflict
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ast.nim1
-rw-r--r--compiler/docgen.nim7
-rw-r--r--compiler/importer.nim26
-rw-r--r--compiler/lexer.nim2
-rw-r--r--compiler/lookups.nim4
-rw-r--r--compiler/modulepaths.nim7
-rw-r--r--compiler/parser.nim2
-rw-r--r--compiler/pragmas.nim10
-rw-r--r--compiler/rodutils.nim4
-rw-r--r--compiler/semcall.nim11
-rw-r--r--compiler/semexprs.nim5
-rw-r--r--compiler/semfold.nim54
-rw-r--r--compiler/semtypes.nim4
-rw-r--r--compiler/sigmatch.nim3
-rw-r--r--compiler/suggest.nim23
-rw-r--r--compiler/types.nim2
16 files changed, 104 insertions, 61 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 832463bd5..6591105d4 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -506,6 +506,7 @@ type
     tfGenericTypeParam
     tfImplicitTypeParam
     tfInferrableStatic
+    tfConceptMatchedTypeSym
     tfExplicit        # for typedescs, marks types explicitly prefixed with the
                       # `type` operator (e.g. type int)
     tfWildcard        # consider a proc like foo[T, I](x: Type[T, I])
diff --git a/compiler/docgen.nim b/compiler/docgen.nim
index b35452365..3842f0ad4 100644
--- a/compiler/docgen.nim
+++ b/compiler/docgen.nim
@@ -787,14 +787,13 @@ proc getOutFile2(conf: ConfigRef; filename, ext, dir: string): string =
 
 proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) =
   var content = genOutFile(d)
-  var success = true
   if optStdout in d.conf.globalOptions:
     writeRope(stdout, content)
   else:
     let outfile = getOutFile2(d.conf, filename, outExt, "htmldocs")
-    success = writeRope(content, outfile)
-  if not success:
-    rawMessage(d.conf, if useWarning: warnCannotOpenFile else: errCannotOpenFile, filename)
+    createDir(outfile.parentDir)
+    if not writeRope(content, outfile):
+      rawMessage(d.conf, if useWarning: warnCannotOpenFile else: errCannotOpenFile, outfile)
 
 proc writeOutputJson*(d: PDoc, filename, outExt: string,
                       useWarning = false) =
diff --git a/compiler/importer.nim b/compiler/importer.nim
index c013b93ab..acc3d26d2 100644
--- a/compiler/importer.nim
+++ b/compiler/importer.nim
@@ -174,20 +174,32 @@ proc impMod(c: PContext; it: PNode; importStmtResult: PNode) =
     #importForwarded(c, m.ast, emptySet)
 
 proc evalImport(c: PContext, n: PNode): PNode =
-  #result = n
   result = newNodeI(nkImportStmt, n.info)
   for i in countup(0, sonsLen(n) - 1):
     let it = n.sons[i]
     if it.kind == nkInfix and it.len == 3 and it[2].kind == nkBracket:
       let sep = it[0]
       let dir = it[1]
-      let a = newNodeI(nkInfix, it.info)
-      a.add sep
-      a.add dir
-      a.add sep # dummy entry, replaced in the loop
+      var imp = newNodeI(nkInfix, it.info)
+      imp.add sep
+      imp.add dir
+      imp.add sep # dummy entry, replaced in the loop
       for x in it[2]:
-        a.sons[2] = x
-        impMod(c, a, result)
+        if x.kind == nkInfix and x.sons[0].ident.s == "as":
+          imp.sons[2] = x.sons[1]
+          let impAs = newNodeI(nkImportAs, it.info)
+          impAs.add imp
+          impAs.add x.sons[2]
+          imp = impAs
+          impMod(c, imp, result)
+        else:
+          imp.sons[2] = x
+          impMod(c, imp, result)
+    elif it.kind == nkInfix and it.sons[0].ident.s == "as":
+      let imp = newNodeI(nkImportAs, it.info)
+      imp.add it.sons[1]
+      imp.add it.sons[2]
+      impMod(c, imp, result)
     else:
       impMod(c, it, result)
 
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index 9727d16a7..6ad1d9fc6 100644
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -1209,7 +1209,7 @@ proc rawGetTok*(L: var TLexer, tok: var TToken) =
         tok.tokType = tkInvalid
         lexMessage(L, errGenerated, "invalid token: " & c & " (\\" & $(ord(c)) & ')')
     of '\"':
-      # check for extended raw string literal:
+      # check for generalized raw string literal:
       var rawMode = L.bufpos > 0 and L.buf[L.bufpos-1] in SymChars
       getString(L, tok, rawMode)
       if rawMode:
diff --git a/compiler/lookups.nim b/compiler/lookups.nim
index 1e9d963fa..7f0882754 100644
--- a/compiler/lookups.nim
+++ b/compiler/lookups.nim
@@ -161,7 +161,7 @@ proc ensureNoMissingOrUnusedSymbols(c: PContext; scope: PScope) =
   var s = initTabIter(it, scope.symbols)
   var missingImpls = 0
   while s != nil:
-    if sfForward in s.flags and s.kind != skType:
+    if sfForward in s.flags and s.kind notin {skType, skModule}:
       # too many 'implementation of X' errors are annoying
       # and slow 'suggest' down:
       if missingImpls == 0:
@@ -259,7 +259,7 @@ proc errorUseQualifier*(c: PContext; info: TLineInfo; s: PSym) =
 proc errorUndeclaredIdentifier*(c: PContext; info: TLineInfo; name: string) =
   var err = "undeclared identifier: '" & name & "'"
   if c.recursiveDep.len > 0:
-    err.add "\nThis might be caused by a recursive module dependency: "
+    err.add "\nThis might be caused by a recursive module dependency:\n"
     err.add c.recursiveDep
     # prevent excessive errors for 'nim check'
     c.recursiveDep = ""
diff --git a/compiler/modulepaths.nim b/compiler/modulepaths.nim
index e5cbf3a2c..118002fcf 100644
--- a/compiler/modulepaths.nim
+++ b/compiler/modulepaths.nim
@@ -126,13 +126,6 @@ proc getModuleName*(conf: ConfigRef; n: PNode): string =
   of nkInfix:
     let n0 = n[0]
     let n1 = n[1]
-    if n0.kind == nkIdent and n0.ident.s == "as":
-      # XXX hack ahead:
-      n.kind = nkImportAs
-      n.sons[0] = n.sons[1]
-      n.sons[1] = n.sons[2]
-      n.sons.setLen(2)
-      return getModuleName(conf, n.sons[0])
     when false:
       if n1.kind == nkPrefix and n1[0].kind == nkIdent and n1[0].ident.s == "$":
         if n0.kind == nkIdent and n0.ident.s == "/":
diff --git a/compiler/parser.nim b/compiler/parser.nim
index 98ccb05b9..246dcb814 100644
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -1638,7 +1638,7 @@ proc parseStaticOrDefer(p: var TParser; k: TNodeKind): PNode =
   addSon(result, parseStmt(p))
 
 proc parseAsm(p: var TParser): PNode =
-  #| asmStmt = 'asm' pragma? (STR_LIT | RSTR_LIT | TRIPLE_STR_LIT)
+  #| asmStmt = 'asm' pragma? (STR_LIT | RSTR_LIT | TRIPLESTR_LIT)
   result = newNodeP(nkAsmStmt, p)
   getTokNoInd(p)
   if p.tok.tokType == tkCurlyDotLe: addSon(result, parsePragma(p))
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index a067f2074..263068344 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -868,11 +868,17 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int,
       of wExplain:
         sym.flags.incl sfExplain
       of wDeprecated:
-        if sym != nil and sym.kind in routineKinds:
+        if sym != nil and sym.kind in routineKinds + {skType}:
           if it.kind in nkPragmaCallKinds: discard getStrLitNode(c, it)
           incl(sym.flags, sfDeprecated)
+        elif sym != nil and sym.kind != skModule:
+          # We don't support the extra annotation field
+          if it.kind in nkPragmaCallKinds:
+            localError(c.config, it.info, "annotation to deprecated not supported here")
+          incl(sym.flags, sfDeprecated)
+        # At this point we're quite sure this is a statement and applies to the
+        # whole module
         elif it.kind in nkPragmaCallKinds: deprecatedStmt(c, it)
-        elif sym != nil: incl(sym.flags, sfDeprecated)
         else: incl(c.module.flags, sfDeprecated)
       of wVarargs:
         noVal(c, it)
diff --git a/compiler/rodutils.nim b/compiler/rodutils.nim
index a774cdba7..90431999a 100644
--- a/compiler/rodutils.nim
+++ b/compiler/rodutils.nim
@@ -10,8 +10,8 @@
 ## Serialization utilities for the compiler.
 import strutils, math
 
-# MSVC prior to 2013 doesn't have C99 functions
-when defined(windows) and (defined(vcc) or defined(bcc)):
+# bcc on windows doesn't have C99 functions
+when defined(windows) and defined(bcc):
   {.emit: """#if defined(_MSC_VER) && _MSC_VER < 1900
   #include <stdarg.h>
   static int c99_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) {
diff --git a/compiler/semcall.nim b/compiler/semcall.nim
index ef452fcdc..dc71f2567 100644
--- a/compiler/semcall.nim
+++ b/compiler/semcall.nim
@@ -399,12 +399,11 @@ proc updateDefaultParams(call: PNode) =
   # the default params with `nfDefaultParam` and `instantiateProcType`
   # computes correctly the default values for each instantiation.
   let calleeParams = call[0].sym.typ.n
-  for i in countdown(call.len - 1, 1):
-    if nfDefaultParam notin call[i].flags:
-      return
-    let def = calleeParams[i].sym.ast
-    if nfDefaultRefsParam in def.flags: call.flags.incl nfDefaultRefsParam
-    call[i] = def
+  for i in 1..<call.len:
+    if nfDefaultParam in call[i].flags:
+      let def = calleeParams[i].sym.ast
+      if nfDefaultRefsParam in def.flags: call.flags.incl nfDefaultRefsParam
+      call[i] = def
 
 proc semResolvedCall(c: PContext, x: TCandidate,
                      n: PNode, flags: TExprFlags): PNode =
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 895920310..5a8c76216 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -352,6 +352,11 @@ proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode =
       res = t.kind == tyProc and
             t.callConv == ccClosure and
             tfIterator notin t.flags
+    of "iterator":
+      let t = skipTypes(t1, abstractRange)
+      res = t.kind == tyProc and
+            t.callConv == ccClosure and
+            tfIterator in t.flags
     else:
       res = false
   else:
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index a6c185fdc..444940144 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -69,9 +69,13 @@ proc foldSub*(a, b: BiggestInt, n: PNode; g: ModuleGraph): PNode =
       checkInRange(g.config, n, res):
     result = newIntNodeT(res, n, g)
 
+proc foldUnarySub(a: BiggestInt, n: PNode, g: ModuleGraph): PNode =
+  if a != firstOrd(g.config, n.typ):
+    result = newIntNodeT(-a, n, g)
+
 proc foldAbs*(a: BiggestInt, n: PNode; g: ModuleGraph): PNode =
   if a != firstOrd(g.config, n.typ):
-    result = newIntNodeT(a, n, g)
+    result = newIntNodeT(abs(a), n, g)
 
 proc foldMod*(a, b: BiggestInt, n: PNode; g: ModuleGraph): PNode =
   if b != 0'i64:
@@ -173,32 +177,41 @@ proc makeRangeF(typ: PType, first, last: BiggestFloat; g: ModuleGraph): PType =
   result.n = n
   addSonSkipIntLit(result, skipTypes(typ, {tyRange}))
 
-proc evalIs(n, a: PNode): PNode =
+proc evalIs(n: PNode, lhs: PSym, g: ModuleGraph): PNode =
   # XXX: This should use the standard isOpImpl
-  #internalAssert a.kind == nkSym and a.sym.kind == skType
-  #internalAssert n.sonsLen == 3 and
-  #  n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
+  internalAssert g.config,
+    n.sonsLen == 3 and
+    lhs.typ != nil and
+    n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
 
-  let t1 = a.sym.typ
+  var
+    res = false
+    t1 = lhs.typ
+    t2 = n[2].typ
+
+  if t1.kind == tyTypeDesc and t2.kind != tyTypeDesc:
+    t1 = t1.base
 
   if n[2].kind in {nkStrLit..nkTripleStrLit}:
     case n[2].strVal.normalize
     of "closure":
       let t = skipTypes(t1, abstractRange)
-      result = newIntNode(nkIntLit, ord(t.kind == tyProc and
-                                        t.callConv == ccClosure and
-                                        tfIterator notin t.flags))
+      res = t.kind == tyProc and
+            t.callConv == ccClosure and
+            tfIterator notin t.flags
     of "iterator":
       let t = skipTypes(t1, abstractRange)
-      result = newIntNode(nkIntLit, ord(t.kind == tyProc and
-                                        t.callConv == ccClosure and
-                                        tfIterator in t.flags))
-    else: discard
+      res = t.kind == tyProc and
+            t.callConv == ccClosure and
+            tfIterator in t.flags
+    else:
+      res = false
   else:
     # XXX semexprs.isOpImpl is slightly different and requires a context. yay.
     let t2 = n[2].typ
-    var match = sameType(t1, t2)
-    result = newIntNode(nkIntLit, ord(match))
+    res = sameType(t1, t2)
+
+  result = newIntNode(nkIntLit, ord(res))
   result.typ = n.typ
 
 proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
@@ -207,7 +220,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
   case m
   of mOrd: result = newIntNodeT(getOrdValue(a), n, g)
   of mChr: result = newIntNodeT(getInt(a), n, g)
-  of mUnaryMinusI, mUnaryMinusI64: result = newIntNodeT(- getInt(a), n, g)
+  of mUnaryMinusI, mUnaryMinusI64: result = foldUnarySub(getInt(a), n, g)
   of mUnaryMinusF64: result = newFloatNodeT(- getFloat(a), n, g)
   of mNot: result = newIntNodeT(1 - getInt(a), n, g)
   of mCard: result = newIntNodeT(nimsets.cardSet(g.config, a), n, g)
@@ -584,6 +597,9 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
         result = copyTree(s.ast)
     of skProc, skFunc, skMethod:
       result = n
+    of skParam:
+      if s.typ != nil and s.typ.kind == tyTypeDesc:
+        result = newSymNodeTypeDesc(s, n.info)
     of skType:
       # XXX gensym'ed symbols can come here and cannot be resolved. This is
       # dirty, but correct.
@@ -651,9 +667,9 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
       of mConStrStr:
         result = foldConStrStr(m, n, g)
       of mIs:
-        let a = getConstExpr(m, n[1], g)
-        if a != nil and a.kind == nkSym and a.sym.kind == skType:
-          result = evalIs(n, a)
+        let lhs = getConstExpr(m, n[1], g)
+        if lhs != nil and lhs.kind == nkSym:
+          result = evalIs(n, lhs.sym, g)
       else:
         result = magicCall(m, n, g)
     except OverflowError:
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 1669a7707..86f3a17ab 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -372,7 +372,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
   if n.kind == nkSym:
     result = getGenSym(c, n.sym)
   else:
-    result = pickSym(c, n, {skType, skGenericParam})
+    result = pickSym(c, n, {skType, skGenericParam, skParam})
     if result.isNil:
       result = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared})
     if result != nil:
@@ -1345,7 +1345,7 @@ proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
     if modifier != tyNone:
       dummyName = param[0]
       dummyType = c.makeTypeWithModifier(modifier, candidateTypeSlot)
-      if modifier == tyTypeDesc: dummyType.flags.incl tfExplicit
+      if modifier == tyTypeDesc: dummyType.flags.incl tfConceptMatchedTypeSym
     else:
       dummyName = param
       dummyType = candidateTypeSlot
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index f206119ec..932163055 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -993,7 +993,8 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
     useTypeLoweringRuleInTypeClass = c.c.matchedConcept != nil and
                                      not c.isNoCall and
                                      f.kind != tyTypeDesc and
-                                     tfExplicit notin aOrig.flags
+                                     tfExplicit notin aOrig.flags and
+                                     tfConceptMatchedTypeSym notin aOrig.flags
 
     aOrig = if useTypeLoweringRuleInTypeClass:
           aOrig.skipTypes({tyTypeDesc})
diff --git a/compiler/suggest.nim b/compiler/suggest.nim
index 3d3cd2484..770bf25e6 100644
--- a/compiler/suggest.nim
+++ b/compiler/suggest.nim
@@ -454,14 +454,23 @@ proc suggestSym*(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym;
       suggestResult(conf, symToSuggest(conf, s, isLocal=false, ideOutline, info, 100, PrefixMatch.None, false, 0))
 
 proc warnAboutDeprecated(conf: ConfigRef; info: TLineInfo; s: PSym) =
+  var pragmaNode: PNode
+
   if s.kind in routineKinds:
-    let n = s.ast[pragmasPos]
-    if n.kind != nkEmpty:
-      for it in n:
-        if whichPragma(it) == wDeprecated and it.safeLen == 2 and
-            it[1].kind in {nkStrLit..nkTripleStrLit}:
-          message(conf, info, warnDeprecated, it[1].strVal & "; " & s.name.s)
-          return
+    pragmaNode = s.ast[pragmasPos]
+  elif s.kind in {skType}:
+    # s.ast = nkTypedef / nkPragmaExpr / [nkSym, nkPragma]
+    pragmaNode = s.ast[0][1]
+
+  doAssert pragmaNode == nil or pragmaNode.kind == nkPragma
+
+  if pragmaNode != nil:
+    for it in pragmaNode:
+      if whichPragma(it) == wDeprecated and it.safeLen == 2 and
+        it[1].kind in {nkStrLit..nkTripleStrLit}:
+        message(conf, info, warnDeprecated, it[1].strVal & "; " & s.name.s)
+        return
+
   message(conf, info, warnDeprecated, s.name.s)
 
 proc markUsed(conf: ConfigRef; info: TLineInfo; s: PSym; usageSym: var PSym) =
diff --git a/compiler/types.nim b/compiler/types.nim
index 4a16e7207..d0eec35cf 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -428,6 +428,8 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
        sfAnon notin t.sym.flags:
     if t.kind == tyInt and isIntLit(t):
       result = t.sym.name.s & " literal(" & $t.n.intVal & ")"
+    elif t.kind == tyAlias:
+      result = typeToString(t.sons[0])
     elif prefer in {preferName, preferTypeName} or t.sym.owner.isNil:
       result = t.sym.name.s
       if t.kind == tyGenericParam and t.sonsLen > 0: