summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim4
-rw-r--r--compiler/nim.ini2
-rw-r--r--compiler/nim.nimrod.cfg2
-rw-r--r--compiler/semexprs.nim8
-rw-r--r--compiler/semgnrc.nim11
-rw-r--r--compiler/seminst.nim4
-rw-r--r--compiler/semstmts.nim3
-rw-r--r--compiler/semtypes.nim74
-rw-r--r--compiler/sigmatch.nim31
-rw-r--r--compiler/suggest.nim3
-rw-r--r--compiler/types.nim20
-rw-r--r--copying.txt2
-rw-r--r--doc/backends.txt6
-rw-r--r--doc/nimc.txt52
-rw-r--r--doc/tut1.txt2
-rw-r--r--doc/tut2.txt12
-rw-r--r--koch.nim16
-rw-r--r--lib/impure/osinfo_posix.nim10
-rw-r--r--lib/impure/osinfo_win.nim8
-rw-r--r--lib/posix/posix.nim4
-rw-r--r--lib/pure/rawsockets.nim4
-rw-r--r--lib/system.nim2
-rw-r--r--lib/system/channels.nim7
-rw-r--r--lib/windows/winlean.nim44
-rw-r--r--tests/generics/t1056.nim26
-rw-r--r--tests/generics/t1789.nim44
-rw-r--r--tests/misc/tvarious.nim4
-rw-r--r--tests/threads/ttryrecv.nim35
-rw-r--r--tests/typerel/typedescs.nim7
-rw-r--r--tests/types/tisopr.nim17
-rw-r--r--tools/nimweb.nim20
-rw-r--r--tools/website.tmpl2
-rw-r--r--web/download.txt11
-rw-r--r--web/news.txt13
34 files changed, 323 insertions, 187 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 565bb4353..d85dbf42c 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -1517,8 +1517,8 @@ proc getStr*(a: PNode): string =
 proc getStrOrChar*(a: PNode): string = 
   case a.kind
   of nkStrLit..nkTripleStrLit: result = a.strVal
-  of nkCharLit: result = $chr(int(a.intVal))
-  else: 
+  of nkCharLit..nkUInt64Lit: result = $chr(int(a.intVal))
+  else:
     internalError(a.info, "getStrOrChar")
     result = ""
 
diff --git a/compiler/nim.ini b/compiler/nim.ini
index 576b6d2bb..1f14eb21b 100644
--- a/compiler/nim.ini
+++ b/compiler/nim.ini
@@ -125,7 +125,7 @@ Files: "start.bat"
 BinPath: r"bin;dist\mingw\bin;dist"
 
 ;           Section | dir | zipFile | size hint (in KB) | url | exe start menu entry
-Download: r"Documentation|doc|docs.zip|13824|http://nim-lang.org/download/docs-${version}.zip|doc\overview.html"
+Download: r"Documentation|doc|docs.zip|13824|http://nim-lang.org/download/docs-${version}.zip|overview.html"
 Download: r"C Compiler (MingW)|dist|mingw.zip|82944|http://nim-lang.org/download/${mingw}.zip"
 Download: r"Aporia IDE|dist|aporia.zip|97997|http://nim-lang.org/download/aporia-0.1.3.zip|aporia\bin\aporia.exe"
 ; for now only NSIS supports optional downloads
diff --git a/compiler/nim.nimrod.cfg b/compiler/nim.nimrod.cfg
index ba7697c4c..f4d8b9dcb 100644
--- a/compiler/nim.nimrod.cfg
+++ b/compiler/nim.nimrod.cfg
@@ -1,7 +1,5 @@
 # Special configuration file for the Nim project
 
-# gc:markAndSweep
-
 hint[XDeclaredButNotUsed]:off
 path:"llvm"
 path:"$projectPath/.."
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index ee3391e3e..89110a479 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -219,7 +219,7 @@ proc maybeLiftType(t: var PType, c: PContext, info: TLineInfo) =
   # gnrc. params, then it won't be necessary to open a new scope here
   openScope(c)
   var lifted = liftParamType(c, skType, newNodeI(nkArgList, info),
-                         t, ":anon", info)
+                             t, ":anon", info)
   closeScope(c)
   if lifted != nil: t = lifted
 
@@ -926,7 +926,8 @@ const
 proc readTypeParameter(c: PContext, typ: PType,
                        paramName: PIdent, info: TLineInfo): PNode =
   let ty = if typ.kind == tyGenericInst: typ.skipGenericAlias
-           else: (internalAssert(typ.kind == tyCompositeTypeClass); typ.sons[1])
+           else: (internalAssert(typ.kind == tyCompositeTypeClass);
+                  typ.sons[1].skipGenericAlias)
   #debug ty
   let tbody = ty.sons[0]
   for s in countup(0, tbody.len-2):
@@ -965,6 +966,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
   var ty = n.sons[0].typ
   var f: PSym = nil
   result = nil
+
   if isTypeExpr(n.sons[0]) or (ty.kind == tyTypeDesc and ty.base.kind != tyNone):
     if ty.kind == tyTypeDesc: ty = ty.base
     ty = ty.skipTypes(tyDotOpTransparent)
@@ -985,7 +987,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
     of tyTypeParamsHolders:
       return readTypeParameter(c, ty, i, n.info)
     of tyObject, tyTuple:
-      if ty.n.kind == nkRecList:
+      if ty.n != nil and ty.n.kind == nkRecList:
         for field in ty.n:
           if field.sym.name == i:
             n.typ = newTypeWithSons(c, tyFieldAccessor, @[ty, field.sym.typ])
diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim
index 7c32b0051..1ab4f5989 100644
--- a/compiler/semgnrc.nim
+++ b/compiler/semgnrc.nim
@@ -60,13 +60,20 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
     else:
       result = symChoice(c, n, s, scOpen)
   of skGenericParam: 
-    result = newSymNodeTypeDesc(s, n.info)
+    if s.typ != nil and s.typ.kind == tyStatic:
+      if s.typ.n != nil:
+        result = s.typ.n
+      else:
+        result = n
+    else:
+      result = newSymNodeTypeDesc(s, n.info)
     styleCheckUse(n.info, s)
   of skParam:
     result = n
     styleCheckUse(n.info, s)
   of skType: 
-    if (s.typ != nil) and (s.typ.kind != tyGenericParam): 
+    if (s.typ != nil) and
+       (s.typ.flags * {tfGenericTypeParam, tfImplicitTypeParam} == {}):
       result = newSymNodeTypeDesc(s, n.info)
     else: 
       result = n
diff --git a/compiler/seminst.nim b/compiler/seminst.nim
index 2decb5d0b..81a4465c5 100644
--- a/compiler/seminst.nim
+++ b/compiler/seminst.nim
@@ -21,7 +21,8 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable,
     var q = a.sym
     if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic, tyIter}+tyTypeClasses:
       continue
-    var s = newSym(skType, q.name, getCurrOwner(), q.info)
+    let symKind = if q.typ.kind == tyStatic: skConst else: skType
+    var s = newSym(symKind, q.name, getCurrOwner(), q.info)
     s.flags = s.flags + {sfUsed, sfFromGeneric}
     var t = PType(idTableGet(pt, q.typ))
     if t == nil:
@@ -40,6 +41,7 @@ proc instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable,
       t = generateTypeInstance(c, pt, a, t)
       #t = ReplaceTypeVarsT(cl, t)
     s.typ = t
+    if t.kind == tyStatic: s.ast = t.n
     addDecl(c, s)
     entry.concreteTypes[i] = t
 
diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim
index a7603147c..3b0332939 100644
--- a/compiler/semstmts.nim
+++ b/compiler/semstmts.nim
@@ -653,7 +653,8 @@ proc checkForMetaFields(n: PNode) =
   template checkMeta(t) =
     if t != nil and t.isMetaType and tfGenericTypeParam notin t.flags:
       localError(n.info, errTIsNotAConcreteType, t.typeToString)
-  
+
+  if n.isNil: return
   case n.kind
   of nkRecList, nkRecCase:
     for s in n: checkForMetaFields(s)
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 4305a48e1..eb15c3809 100644
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -214,44 +214,48 @@ proc semRange(c: PContext, n: PNode, prev: PType): PType =
     localError(n.info, errXExpectsOneTypeParam, "range")
     result = newOrPrevType(tyError, prev, c)
 
+proc semArrayIndex(c: PContext, n: PNode): PType =
+  if isRange(n): result = semRangeAux(c, n, nil)
+  else:
+    let e = semExprWithType(c, n, {efDetermineType})
+    if e.typ.kind == tyFromExpr:
+      result = makeRangeWithStaticExpr(c, e.typ.n)
+    elif e.kind in {nkIntLit..nkUInt64Lit}:
+      result = makeRangeType(c, 0, e.intVal-1, n.info, e.typ)
+    elif e.kind == nkSym and e.typ.kind == tyStatic:
+      if e.sym.ast != nil:
+        return semArrayIndex(c, e.sym.ast)
+      internalAssert c.inGenericContext > 0
+      if not isOrdinalType(e.typ.lastSon):
+        localError(n[1].info, errOrdinalTypeExpected)
+      result = makeRangeWithStaticExpr(c, e)
+      result.flags.incl tfUnresolved
+    elif e.kind in nkCallKinds and hasGenericArguments(e):
+      if not isOrdinalType(e.typ):
+        localError(n[1].info, errOrdinalTypeExpected)
+      # This is an int returning call, depending on an
+      # yet unknown generic param (see tgenericshardcases).
+      # We are going to construct a range type that will be
+      # properly filled-out in semtypinst (see how tyStaticExpr
+      # is handled there).
+      result = makeRangeWithStaticExpr(c, e)
+    elif e.kind == nkIdent:
+      result = e.typ.skipTypes({tyTypeDesc})
+    else:
+      let x = semConstExpr(c, e)
+      if x.kind in {nkIntLit..nkUInt64Lit}:
+        result = makeRangeType(c, 0, x.intVal-1, n.info, 
+                             x.typ.skipTypes({tyTypeDesc}))
+      else:
+        result = x.typ.skipTypes({tyTypeDesc})
+        #localError(n[1].info, errConstExprExpected)
+
 proc semArray(c: PContext, n: PNode, prev: PType): PType = 
-  var indx, base: PType
+  var base: PType
   result = newOrPrevType(tyArray, prev, c)
-  if sonsLen(n) == 3: 
+  if sonsLen(n) == 3:
     # 3 = length(array indx base)
-    if isRange(n[1]): indx = semRangeAux(c, n[1], nil)
-    else:
-      let e = semExprWithType(c, n.sons[1], {efDetermineType})
-      if e.typ.kind == tyFromExpr:
-        indx = makeRangeWithStaticExpr(c, e.typ.n)
-      elif e.kind in {nkIntLit..nkUInt64Lit}:
-        indx = makeRangeType(c, 0, e.intVal-1, n.info, e.typ)
-      elif e.kind == nkSym and e.typ.kind == tyStatic:
-        if e.sym.ast != nil: return semArray(c, e.sym.ast, nil)
-        internalAssert c.inGenericContext > 0
-        if not isOrdinalType(e.typ.lastSon):
-          localError(n[1].info, errOrdinalTypeExpected)
-        indx = makeRangeWithStaticExpr(c, e)
-        indx.flags.incl tfUnresolved
-      elif e.kind in nkCallKinds and hasGenericArguments(e):
-        if not isOrdinalType(e.typ):
-          localError(n[1].info, errOrdinalTypeExpected)
-        # This is an int returning call, depending on an
-        # yet unknown generic param (see tgenericshardcases).
-        # We are going to construct a range type that will be
-        # properly filled-out in semtypinst (see how tyStaticExpr
-        # is handled there).
-        indx = makeRangeWithStaticExpr(c, e)
-      elif e.kind == nkIdent:
-        indx = e.typ.skipTypes({tyTypeDesc})
-      else:
-        let x = semConstExpr(c, e)
-        if x.kind in {nkIntLit..nkUInt64Lit}:
-          indx = makeRangeType(c, 0, x.intVal-1, n.info, 
-                               x.typ.skipTypes({tyTypeDesc}))
-        else:
-          indx = x.typ.skipTypes({tyTypeDesc})
-          #localError(n[1].info, errConstExprExpected)
+    var indx = semArrayIndex(c, n[1])
     addSonSkipIntLit(result, indx)
     if indx.kind == tyGenericInst: indx = lastSon(indx)
     if indx.kind notin {tyGenericParam, tyStatic, tyFromExpr}:
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 06f9d58b7..b58818a29 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -517,6 +517,16 @@ proc maybeSkipDistinct(t: PType, callee: PSym): PType =
   else:
     result = t
 
+proc tryResolvingStaticExpr(c: var TCandidate, n: PNode): PNode =
+  # Consider this example:
+  #   type Value[N: static[int]] = object
+  #   proc foo[N](a: Value[N], r: range[0..(N-1)])
+  # Here, N-1 will be initially nkStaticExpr that can be evaluated only after
+  # N is bound to a concrete value during the matching of the first param.
+  # This proc is used to evaluate such static expressions.
+  let instantiated = replaceTypesInBody(c.c, c.bindings, n)
+  result = c.c.semExpr(c.c, instantiated)
+
 proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
   # typeRel can be used to establish various relationships between types:
   #
@@ -620,6 +630,11 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
       # bugfix: accept integer conversions here
       #if result < isGeneric: result = isNone
       if result notin {isNone, isGeneric}:
+        # resolve any late-bound static expressions
+        # that may appear in the range:
+        for i in 0..1:
+          if f.n[i].kind == nkStaticExpr:
+            f.n.sons[i] = tryResolvingStaticExpr(c, f.n[i])
         result = typeRangeRel(f, a)
     else:
       if skipTypes(f, {tyRange}).kind == a.kind:
@@ -964,6 +979,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
   of tyStatic:
     if aOrig.kind == tyStatic:
       result = typeRel(c, f.lastSon, a)
+      if result != isNone and f.n != nil:
+        if not exprStructuralEquivalent(f.n, a.n):
+          result = isNone
       if result != isNone: put(c.bindings, f, aOrig)
     else:
       result = isNone
@@ -1006,15 +1024,14 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
 
   of tyFromExpr:
     # fix the expression, so it contains the already instantiated types
-    let instantiated = replaceTypesInBody(c.c, c.bindings, f.n)
-    let reevaluted = c.c.semExpr(c.c, instantiated)
-    case reevaluted.typ.kind
+    let reevaluated = tryResolvingStaticExpr(c, f.n)
+    case reevaluated.typ.kind
     of tyTypeDesc:
-      result = typeRel(c, a, reevaluted.typ.base)
+      result = typeRel(c, a, reevaluated.typ.base)
     of tyStatic:
-      result = typeRel(c, a, reevaluted.typ.base)
-      if result != isNone and reevaluted.typ.n != nil:
-        if not exprStructuralEquivalent(aOrig.n, reevaluted.typ.n):
+      result = typeRel(c, a, reevaluated.typ.base)
+      if result != isNone and reevaluated.typ.n != nil:
+        if not exprStructuralEquivalent(aOrig.n, reevaluated.typ.n):
           result = isNone
     else:
       localError(f.n.info, errTypeExpected)
diff --git a/compiler/suggest.nim b/compiler/suggest.nim
index c700db323..f7b00c8f8 100644
--- a/compiler/suggest.nim
+++ b/compiler/suggest.nim
@@ -74,9 +74,6 @@ proc suggestField(c: PContext, s: PSym, outputs: var int) =
     suggestWriteln(symToStr(s, isLocal=true, sectionSuggest))
     inc outputs
 
-when not defined(nimhygiene):
-  {.pragma: inject.}
-
 template wholeSymTab(cond, section: expr) {.immediate.} =
   var isLocal = true
   for scope in walkScopes(c.currentScope):
diff --git a/compiler/types.nim b/compiler/types.nim
index f67cd239e..4a77773e6 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -17,7 +17,7 @@ proc lastOrd*(t: PType): BiggestInt
 proc lengthOrd*(t: PType): BiggestInt
 type 
   TPreferedDesc* = enum
-    preferName, preferDesc, preferExported, preferModuleInfo
+    preferName, preferDesc, preferExported, preferModuleInfo, preferGenericArg
 
 proc typeToString*(typ: PType; prefer: TPreferedDesc = preferName): string
 proc base*(t: PType): PType
@@ -411,11 +411,13 @@ const
     "UserTypeClassInst", "CompositeTypeClass",
     "and", "or", "not", "any", "static", "TypeFromExpr", "FieldAccessor"]
 
+const preferToResolveSymbols = {preferName, preferModuleInfo, preferGenericArg}
+
 proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
   var t = typ
   result = ""
   if t == nil: return 
-  if prefer in {preferName, preferModuleInfo} and t.sym != nil and
+  if prefer in preferToResolveSymbols and t.sym != nil and
        sfAnon notin t.sym.flags:
     if t.kind == tyInt and isIntLit(t):
       return t.sym.name.s & " literal(" & $t.n.intVal & ")"
@@ -428,20 +430,26 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
     if not isIntLit(t) or prefer == preferExported:
       result = typeToStr[t.kind]
     else:
-      result = "int literal(" & $t.n.intVal & ")"
+      if prefer == preferGenericArg:
+        result = $t.n.intVal
+      else:
+        result = "int literal(" & $t.n.intVal & ")"
   of tyGenericBody, tyGenericInst, tyGenericInvokation:
     result = typeToString(t.sons[0]) & '['
     for i in countup(1, sonsLen(t) -1 -ord(t.kind != tyGenericInvokation)):
       if i > 1: add(result, ", ")
-      add(result, typeToString(t.sons[i]))
+      add(result, typeToString(t.sons[i], preferGenericArg))
     add(result, ']')
   of tyTypeDesc:
     if t.base.kind == tyNone: result = "typedesc"
     else: result = "typedesc[" & typeToString(t.base) & "]"
   of tyStatic:
     internalAssert t.len > 0
-    result = "static[" & typeToString(t.sons[0]) & "]"
-    if t.n != nil: result.add "(" & renderTree(t.n) & ")"
+    if prefer == preferGenericArg and t.n != nil:
+      result = t.n.renderTree
+    else:
+      result = "static[" & typeToString(t.sons[0]) & "]"
+      if t.n != nil: result.add "(" & renderTree(t.n) & ")"
   of tyUserTypeClass:
     internalAssert t.sym != nil and t.sym.owner != nil
     return t.sym.owner.name.s
diff --git a/copying.txt b/copying.txt
index 254b91c77..908625e18 100644
--- a/copying.txt
+++ b/copying.txt
@@ -1,5 +1,5 @@
 =====================================================
-Nimrod -- a Compiler for Nimrod. http://nimrod-lang.org/
+Nim -- a Compiler for Nim. http://nim-lang.org/
 
 Copyright (C) 2006-2014 Andreas Rumpf. All rights reserved.
  
diff --git a/doc/backends.txt b/doc/backends.txt
index eb16217cd..ffe2d5e88 100644
--- a/doc/backends.txt
+++ b/doc/backends.txt
@@ -456,11 +456,7 @@ can then attach a GC to this thread via
 
 .. code-block:: nim
 
-  setStackBottom(addr(someLocal))
-  initGC()
-
-At the moment this support is still experimental so you need to expose these
-functions yourself or submit patches to request a public API. 
+  system.setupForeignThreadGc()
 
 It is **not** safe to disable the garbage collector and enable it after the
 call from your background thread even if the code you are calling is short
diff --git a/doc/nimc.txt b/doc/nimc.txt
index 92acd3979..a2274febd 100644
--- a/doc/nimc.txt
+++ b/doc/nimc.txt
@@ -550,58 +550,6 @@ in C/C++).
 **Note**: This pragma will not exist for the LLVM backend.

 
 
-Source code style
-=================
-
-Nim allows you to `mix freely case and underscores as identifier separators
-<manual.html#identifiers-keywords>`_, so variables named ``MyPrecioussInt`` and
-``my_preciouss_int`` are equivalent:
-
-.. code-block:: Nim
-  var MyPrecioussInt = 3
-  # Following line compiles fine!
-  echo my_preciouss_int
-
-Since this can lead to many variants of the same source code (you can use
-`nimgrep <nimgrep.html>`_ instead of your typical ``grep`` to ignore style
-problems) the compiler provides the command ``pretty`` to help unifying the
-style of source code.  Running ``nim pretty ugly_test.nim`` with this
-example will generate a secondary file named ``ugly_test.pretty.nim`` with the
-following content:
-
-.. code-block:: Nim
-  var MyPrecioussInt = 3
-  # Following line compiles fine!
-  echo MyPrecioussInt
-
-During execution the ``pretty`` command will also run on Nim's standard
-library, since it doesn't differentiate the standard library as something
-special, and hence will warn of many *errors* which are out of your hand to
-fix, creating respective ``.pretty.nim`` files all the way. You can ignore
-these errors if they don't belong to your source and simply compare your
-original version to the new pretty one. In fact, running ``pretty`` on our test
-file will show the following::
-
-  Hint: ugly_test [Processing]
-  ugly_test.nim(1, 4) Error: name should be: myPrecioussInt
-  ugly_test.nim(1, 4) Error: name should be: myPrecioussInt
-
-At the moment ``pretty`` will homogenize the style of symbols but will leave
-important changes for you to review. In this case the command is warning that a
-variable name should not start with a capital letter, which is usually reserved
-to `object types <tut2.html#objects>`_. To learn about the accepted `camel case
-style <https://en.wikipedia.org/wiki/Camelcase>`_ read `Coding Guidelines in
-the Internals of Nim Compiler <intern.html#coding-guidelines>`_ or `Coding
-Guidelines <https://github.com/Araq/Nim/wiki/Coding-Guidelines>`_ and `NEP 1
-: Style Guide for Nim Code
-<https://github.com/Araq/Nim/wiki/NEP-1-:-Style-Guide-for-Nim-Code>`_
-from the Nim `GitHub wiki<https://github.com/Araq/Nim/wiki>`_.
-
-This command is safe to run because it will never attempt to overwrite your
-existing sources, but the respective ``.pretty.nim`` files **will** be
-overwritten without notice.
-
-
 DynlibOverride
 ==============
 
diff --git a/doc/tut1.txt b/doc/tut1.txt
index 9d75b1ea2..4c32fa0ae 100644
--- a/doc/tut1.txt
+++ b/doc/tut1.txt
@@ -139,7 +139,7 @@ Numbers
 Numerical literals are written as in most other languages. As a special twist,
 underscores are allowed for better readability: ``1_000_000`` (one million).
 A number that contains a dot (or 'e' or 'E') is a floating point literal:
-``1.0e9`` (one million). Hexadecimal literals are prefixed with ``0x``,
+``1.0e9`` (one billion). Hexadecimal literals are prefixed with ``0x``,
 binary literals with ``0b`` and octal literals with ``0o``. A leading zero
 alone does not produce an octal.
 
diff --git a/doc/tut2.txt b/doc/tut2.txt
index 6e239d681..9d3409164 100644
--- a/doc/tut2.txt
+++ b/doc/tut2.txt
@@ -56,7 +56,7 @@ Objects have access to their type at runtime. There is an
 
 .. code-block:: nim
   type
-    TPerson = object of TObject
+    TPerson = object of RootObj
       name*: string  # the * means that `name` is accessible from other modules
       age: int       # no * means that the field is hidden from other modules
 
@@ -76,10 +76,10 @@ never *equivalent*. New object types can only be defined within a type
 section.
 
 Inheritance is done with the ``object of`` syntax. Multiple inheritance is
-currently not supported. If an object type has no suitable ancestor, ``TObject``
+currently not supported. If an object type has no suitable ancestor, ``RootObj``
 can be used as its ancestor, but this is only a convention. Objects that have 
 no ancestor are implicitly ``final``. You can use the ``inheritable`` pragma 
-to introduce new object roots apart from ``system.TObject``. (This is used
+to introduce new object roots apart from ``system.RootObj``. (This is used
 in the GTK wrapper for instance.)
 
 
@@ -228,7 +228,7 @@ is needed:
 .. code-block:: nim
   
   type
-    TSocket* = object of TObject
+    TSocket* = object of RootObj
       FHost: int # cannot be accessed from the outside of the module
                  # the `F` prefix is a convention to avoid clashes since
                  # the accessors are named `host`
@@ -284,7 +284,7 @@ Procedures always use static dispatch. For dynamic dispatch replace the
 
 .. code-block:: nim
   type
-    PExpr = ref object of TObject ## abstract base class for an expression
+    PExpr = ref object of RootObj ## abstract base class for an expression
     PLiteral = ref object of PExpr
       x: int
     PPlusExpr = ref object of PExpr
@@ -313,7 +313,7 @@ dispatching:
 .. code-block:: nim
 
   type
-    TThing = object of TObject
+    TThing = object of RootObj
     TUnit = object of TThing
       x: int
       
diff --git a/koch.nim b/koch.nim
index 79228c1a4..e3831617c 100644
--- a/koch.nim
+++ b/koch.nim
@@ -94,16 +94,16 @@ const
   compileNimInst = "-d:useLibzipSrc tools/niminst/niminst"
 
 proc csource(args: string) = 
-  exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=mingw32 csource compiler/nim.ini $1" %
+  exec("$4 cc $1 -r $3 --var:version=$2 --var:mingw=none csource compiler/nim.ini $1" %
        [args, VersionAsString, compileNimInst, findNim()])
 
 proc zip(args: string) =
-  exec("$3 cc -r $2 --var:version=$1 --var:mingw=mingw32 scripts compiler/nim.ini" %
+  exec("$3 cc -r $2 --var:version=$1 --var:mingw=none scripts compiler/nim.ini" %
        [VersionAsString, compileNimInst, findNim()])
-  exec("$# --var:version=$# --var:mingw=mingw32 zip compiler/nim.ini" %
+  exec("$# --var:version=$# --var:mingw=none zip compiler/nim.ini" %
        ["tools/niminst/niminst".exe, VersionAsString])
-  
-proc buildTool(toolname, args: string) = 
+
+proc buildTool(toolname, args: string) =
   exec("$# cc $# $#" % [findNim(), args, toolname])
   copyFile(dest="bin"/ splitFile(toolname).name.exe, source=toolname.exe)
 
@@ -114,11 +114,11 @@ proc nsis(args: string) =
   # produce 'nimrod_debug.exe':
   exec "nim c compiler" / "nim.nim"
   copyExe("compiler/nim".exe, "bin/nim_debug".exe)
-  exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw32" &
-        " nsis compiler/nim") % VersionAsString)
+  exec(("tools" / "niminst" / "niminst --var:version=$# --var:mingw=mingw$#" &
+        " nsis compiler/nim") % [VersionAsString, $(sizeof(pointer)*8)])
 
 proc install(args: string) = 
-  exec("$# cc -r $# --var:version=$# --var:mingw=mingw32 scripts compiler/nim.ini" %
+  exec("$# cc -r $# --var:version=$# --var:mingw=none scripts compiler/nim.ini" %
        [findNim(), compileNimInst, VersionAsString])
   exec("sh ./install.sh $#" % args)
 
diff --git a/lib/impure/osinfo_posix.nim b/lib/impure/osinfo_posix.nim
index 1baff8c55..0ed4289c4 100644
--- a/lib/impure/osinfo_posix.nim
+++ b/lib/impure/osinfo_posix.nim
@@ -35,7 +35,15 @@ proc getSystemVersion*(): string =
   elif $unix_info.sysname == "Darwin":
     # Darwin
     result.add("Mac OS X ")
-    if "10" in $unix_info.release:
+    if "14" in $unix_info.release:
+      result.add("v10.10 Yosemite")
+    elif "13" in $unix_info.release:
+      result.add("v10.9 Mavericks")
+    elif "12" in $unix_info.release:
+      result.add("v10.8 Mountian Lion")
+    elif "11" in $unix_info.release:
+      result.add("v10.7 Lion")
+    elif "10" in $unix_info.release:
       result.add("v10.6 Snow Leopard")
     elif "9" in $unix_info.release:
       result.add("v10.5 Leopard")
diff --git a/lib/impure/osinfo_win.nim b/lib/impure/osinfo_win.nim
index f423a34a3..becec928e 100644
--- a/lib/impure/osinfo_win.nim
+++ b/lib/impure/osinfo_win.nim
@@ -245,6 +245,14 @@ proc `$`*(osvi: TVersionInfo): string =
         if osvi.ProductType == VER_NT_WORKSTATION:
           result.add("Windows 7 ")
         else: result.add("Windows Server 2008 R2 ")
+      elif osvi.minorVersion == 2:
+        if osvi.ProductType == VER_NT_WORKSTATION:
+          result.add("Windows 8 ")
+        else: result.add("Windows Server 2012 ")
+      elif osvi.minorVersion == 3:
+        if osvi.ProductType == VER_NT_WORKSTATION:
+          result.add("Windows 8.1 ")
+        else: result.add("Windows Server 2012 R2 ")
     
       var dwType = getProductInfo(osvi.majorVersion, osvi.minorVersion, 0, 0)
       case dwType
diff --git a/lib/posix/posix.nim b/lib/posix/posix.nim
index deb120372..0498a0e70 100644
--- a/lib/posix/posix.nim
+++ b/lib/posix/posix.nim
@@ -1570,9 +1570,9 @@ else:
 
 
 when defined(macosx):
+  # We can't use the NOSIGNAL flag in the ``send`` function, it has no effect
   var
-    MSG_HAVEMORE* {.importc, header: "<sys/socket.h>".}: cint
-    MSG_NOSIGNAL* = MSG_HAVEMORE
+    MSG_NOSIGNAL* = 0'i32
 else:
   var
     MSG_NOSIGNAL* {.importc, header: "<sys/socket.h>".}: cint
diff --git a/lib/pure/rawsockets.nim b/lib/pure/rawsockets.nim
index 62a011999..e23deea5b 100644
--- a/lib/pure/rawsockets.nim
+++ b/lib/pure/rawsockets.nim
@@ -428,6 +428,10 @@ proc selectWrite*(writefds: var seq[SocketHandle],
   
   pruneSocketSet(writefds, (wr))
 
+# We ignore signal SIGPIPE on Darwin
+when defined(macosx):
+  signal(SIGPIPE, SIG_IGN)
+
 when defined(Windows):
   var wsa: WSAData
   if wsaStartup(0x0101'i16, addr wsa) != 0: raiseOSError(osLastError())
diff --git a/lib/system.nim b/lib/system.nim
index ca85bf1ad..b7c77e276 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1516,7 +1516,7 @@ const
   NimMinor*: int = 10
     ## is the minor number of Nim's version.
 
-  NimPatch*: int = 2
+  NimPatch*: int = 3
     ## is the patch number of Nim's version.
 
   NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch
diff --git a/lib/system/channels.nim b/lib/system/channels.nim
index 3e5ca0795..d07d6eae1 100644
--- a/lib/system/channels.nim
+++ b/lib/system/channels.nim
@@ -232,9 +232,10 @@ proc tryRecv*[TMsg](c: var TChannel[TMsg]): tuple[dataAvailable: bool,
   ## it returns ``(false, default(msg))``.

   var q = cast[PRawChannel](addr(c))

   if q.mask != ChannelDeadMask:

-    if tryAcquireSys(q.lock):

-      llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg)))

-      result.dataAvailable = true

+    if tryAcquireSys(q.lock):
+      if q.count > 0:

+        llRecv(q, addr(result.msg), cast[PNimType](getTypeInfo(result.msg)))

+        result.dataAvailable = true

       releaseSys(q.lock)

 

 proc peek*[TMsg](c: var TChannel[TMsg]): int =

diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index 76d17bc4a..51a12141b 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -368,32 +368,32 @@ type
 {.deprecated: [TSocketHandle: SocketHandle].}
 
 type
-  WSAData* {.importc: "WSADATA", header: "Winsock2.h".} = object 
+  WSAData* {.importc: "WSADATA", header: "winsock2.h".} = object 
     wVersion, wHighVersion: int16
     szDescription: array[0..WSADESCRIPTION_LEN, char]
     szSystemStatus: array[0..WSASYS_STATUS_LEN, char]
     iMaxSockets, iMaxUdpDg: int16
     lpVendorInfo: cstring
     
-  SockAddr* {.importc: "SOCKADDR", header: "Winsock2.h".} = object 
+  SockAddr* {.importc: "SOCKADDR", header: "winsock2.h".} = object 
     sa_family*: int16 # unsigned
     sa_data: array[0..13, char]
 
-  InAddr* {.importc: "IN_ADDR", header: "Winsock2.h".} = object
+  InAddr* {.importc: "IN_ADDR", header: "winsock2.h".} = object
     s_addr*: int32  # IP address
   
   Sockaddr_in* {.importc: "SOCKADDR_IN", 
-                  header: "Winsock2.h".} = object
+                  header: "winsock2.h".} = object
     sin_family*: int16
     sin_port*: int16 # unsigned
     sin_addr*: InAddr
     sin_zero*: array[0..7, char]
 
-  In6_addr* {.importc: "IN6_ADDR", header: "Winsock2.h".} = object 
+  In6_addr* {.importc: "IN6_ADDR", header: "winsock2.h".} = object 
     bytes*: array[0..15, char]
 
   Sockaddr_in6* {.importc: "SOCKADDR_IN6", 
-                   header: "Winsock2.h".} = object
+                   header: "winsock2.h".} = object
     sin6_family*: int16
     sin6_port*: int16 # unsigned
     sin6_flowinfo*: int32 # unsigned
@@ -450,22 +450,22 @@ type
 
 
 var
-  SOMAXCONN* {.importc, header: "Winsock2.h".}: cint
-  INVALID_SOCKET* {.importc, header: "Winsock2.h".}: SocketHandle
-  SOL_SOCKET* {.importc, header: "Winsock2.h".}: cint
-  SO_DEBUG* {.importc, header: "Winsock2.h".}: cint ## turn on debugging info recording
-  SO_ACCEPTCONN* {.importc, header: "Winsock2.h".}: cint # socket has had listen()
-  SO_REUSEADDR* {.importc, header: "Winsock2.h".}: cint # allow local address reuse
-  SO_KEEPALIVE* {.importc, header: "Winsock2.h".}: cint # keep connections alive
-  SO_DONTROUTE* {.importc, header: "Winsock2.h".}: cint # just use interface addresses
-  SO_BROADCAST* {.importc, header: "Winsock2.h".}: cint # permit sending of broadcast msgs
-  SO_USELOOPBACK* {.importc, header: "Winsock2.h".}: cint # bypass hardware when possible
-  SO_LINGER* {.importc, header: "Winsock2.h".}: cint # linger on close if data present
-  SO_OOBINLINE* {.importc, header: "Winsock2.h".}: cint # leave received OOB data in line
-
-  SO_DONTLINGER* {.importc, header: "Winsock2.h".}: cint
-  SO_EXCLUSIVEADDRUSE* {.importc, header: "Winsock2.h".}: cint # disallow local address reuse
-  SO_ERROR* {.importc, header: "Winsock2.h".}: cint
+  SOMAXCONN* {.importc, header: "winsock2.h".}: cint
+  INVALID_SOCKET* {.importc, header: "winsock2.h".}: SocketHandle
+  SOL_SOCKET* {.importc, header: "winsock2.h".}: cint
+  SO_DEBUG* {.importc, header: "winsock2.h".}: cint ## turn on debugging info recording
+  SO_ACCEPTCONN* {.importc, header: "winsock2.h".}: cint # socket has had listen()
+  SO_REUSEADDR* {.importc, header: "winsock2.h".}: cint # allow local address reuse
+  SO_KEEPALIVE* {.importc, header: "winsock2.h".}: cint # keep connections alive
+  SO_DONTROUTE* {.importc, header: "winsock2.h".}: cint # just use interface addresses
+  SO_BROADCAST* {.importc, header: "winsock2.h".}: cint # permit sending of broadcast msgs
+  SO_USELOOPBACK* {.importc, header: "winsock2.h".}: cint # bypass hardware when possible
+  SO_LINGER* {.importc, header: "winsock2.h".}: cint # linger on close if data present
+  SO_OOBINLINE* {.importc, header: "winsock2.h".}: cint # leave received OOB data in line
+
+  SO_DONTLINGER* {.importc, header: "winsock2.h".}: cint
+  SO_EXCLUSIVEADDRUSE* {.importc, header: "winsock2.h".}: cint # disallow local address reuse
+  SO_ERROR* {.importc, header: "winsock2.h".}: cint
 
 proc `==`*(x, y: SocketHandle): bool {.borrow.}
 
diff --git a/tests/generics/t1056.nim b/tests/generics/t1056.nim
new file mode 100644
index 000000000..73a24a76a
--- /dev/null
+++ b/tests/generics/t1056.nim
@@ -0,0 +1,26 @@
+discard """
+  output: '''TMatrix[3, 3, system.int]
+3
+3'''
+"""
+
+import typetraits
+
+type
+  TMatrix*[N,M: static[int], T] = object
+    data*: array[0..N*M-1, T]
+
+  TMat2[T] = TMatrix[2,2,T]
+
+proc echoMatrix(a: TMatrix) =
+  echo a.type.name
+  echo TMatrix.N
+
+proc echoMat2(a: TMat2) =
+  echo TMat2.M
+  
+var m = TMatrix[3,3,int](data: [1,2,3,4,5,6,7,8,9])
+
+echoMatrix m
+echoMat2 m
+
diff --git a/tests/generics/t1789.nim b/tests/generics/t1789.nim
new file mode 100644
index 000000000..188db88f6
--- /dev/null
+++ b/tests/generics/t1789.nim
@@ -0,0 +1,44 @@
+discard """
+  output: "3\n0"
+"""
+
+# https://github.com/Araq/Nim/issues/1789
+
+type
+  Foo[N: static[int]] = object
+
+proc bindStaticN[N](foo: Foo[N]) =
+  var ar0: array[3, int]
+  var ar1: array[N, int]
+  var ar2: array[1..N, int]
+  var ar3: array[0..(N+10), float]
+  echo N
+
+var f: Foo[3]
+f.bindStaticN
+
+# case 2
+
+type
+  ObjectWithStatic[X, Y: static[int], T] = object
+    bar: array[X * Y, T]   # this one works
+
+  AliasWithStatic[X, Y: static[int], T] = array[X * Y, T]
+
+var
+  x: ObjectWithStatic[1, 2, int]
+  y: AliasWithStatic[2, 3, int]
+
+# case 3
+
+type
+  Bar[N: static[int], T] = object
+    bar: array[N, T]
+
+proc `[]`*[N, T](f: Bar[N, T], n: range[0..(N - 1)]): T =
+  assert high(n) == N-1
+  result = f.bar[n]
+  
+var b: Bar[3, int]
+echo b[2]
+
diff --git a/tests/misc/tvarious.nim b/tests/misc/tvarious.nim
index ed2964cf9..434d25e48 100644
--- a/tests/misc/tvarious.nim
+++ b/tests/misc/tvarious.nim
@@ -62,3 +62,7 @@ when false:
   block:
     var a, b: Bar[int, 0..2]
     discard foo(a, b)
+
+# bug #1788
+
+echo "hello" & char(ord(' ')) & "world"
diff --git a/tests/threads/ttryrecv.nim b/tests/threads/ttryrecv.nim
new file mode 100644
index 000000000..acccf182c
--- /dev/null
+++ b/tests/threads/ttryrecv.nim
@@ -0,0 +1,35 @@
+discard """
+  outputsub: "channel is empty"
+"""
+
+# bug #1816
+
+from math import random
+from os import sleep
+
+type PComm = ptr TChannel[int]
+
+proc doAction(outC: PComm) {.thread.} =
+  for i in 0.. <5:
+    sleep(random(100))
+    send(outC[], i)
+
+var
+  thr: TThread[PComm]
+  chan: TChannel[int]
+
+open(chan)
+createThread[PComm](thr, doAction, addr(chan))
+
+while true:
+  let (flag, x) = tryRecv(chan)
+  if flag:
+    echo("received from chan: " & $x)
+  else:
+    echo "channel is empty"
+    break
+
+echo "Finished listening"
+
+joinThread(thr)                                                       
+close(chan)
diff --git a/tests/typerel/typedescs.nim b/tests/typerel/typedescs.nim
new file mode 100644
index 000000000..23b9ce64f
--- /dev/null
+++ b/tests/typerel/typedescs.nim
@@ -0,0 +1,7 @@
+# bug #1774
+proc p(T: typedesc) = discard
+
+p(type((5, 6)))       # Compiles
+(type((5, 6))).p      # Doesn't compile (SIGSEGV: Illegal storage access.)
+type T = type((5, 6)) # Doesn't compile (SIGSEGV: Illegal storage access.)
+
diff --git a/tests/types/tisopr.nim b/tests/types/tisopr.nim
index 3c2b9ee5e..8b7fe4e46 100644
--- a/tests/types/tisopr.nim
+++ b/tests/types/tisopr.nim
@@ -34,3 +34,20 @@ type
 yes s.items is Iter[TNumber]
 no  s.items is Iter[float]
 
+type
+  Foo[N: static[int], T] = object
+    field: array[1..N, T]
+
+  Bar[T] = Foo[4, T]
+  Baz[N: static[int]] = Foo[N, float]
+
+no Foo[2, float] is Foo[3, float]
+no Foo[2, float] is Foo[2, int]
+
+yes Foo[4, string] is Foo[4, string]
+yes Bar[int] is Foo[4, int]
+yes Foo[4, int] is Bar[int]
+
+no Foo[4, int] is Baz[4]
+yes Foo[4, float] is Baz[4]
+
diff --git a/tools/nimweb.nim b/tools/nimweb.nim
index bbd3776d7..0596076b3 100644
--- a/tools/nimweb.nim
+++ b/tools/nimweb.nim
@@ -47,7 +47,7 @@ proc initConfigData(c: var TConfigData) =
   c.logo = ""
   c.ticker = ""
   c.vars = newStringTable(modeStyleInsensitive)
-  c.gitRepo = "https://github.com/Araq/Nimrod/tree"
+  c.gitRepo = "https://github.com/Araq/Nim/tree"
   c.gitCommit = "master"
   c.numProcessors = countProcessors()
   # Attempts to obtain the git current commit.
@@ -262,24 +262,26 @@ proc buildDocSamples(c: var TConfigData, destPath: string) =
   exec("nim doc2 $# -o:$# $#" %
     [c.nimArgs, destPath / "docgen_sample2.html", src])
 
+proc pathPart(d: string): string = splitFile(d).dir.replace('\\', '/')
+
 proc buildDoc(c: var TConfigData, destPath: string) =
   # call nim for the documentation:
   var
     commands = newSeq[string](len(c.doc) + len(c.srcdoc) + len(c.srcdoc2))
     i = 0
   for d in items(c.doc):
-    commands[i] = "nim rst2html $# --docSeeSrcUrl:$#/$# -o:$# --index:on $#" %
-      [c.nimArgs, c.gitRepo, c.gitCommit,
+    commands[i] = "nim rst2html $# --docSeeSrcUrl:$#/$#/$# -o:$# --index:on $#" %
+      [c.nimArgs, c.gitRepo, c.gitCommit, d.pathPart,
       destPath / changeFileExt(splitFile(d).name, "html"), d]
     i.inc
   for d in items(c.srcdoc):
-    commands[i] = "nim doc $# --docSeeSrcUrl:$#/$# -o:$# --index:on $#" %
-      [c.nimArgs, c.gitRepo, c.gitCommit,
+    commands[i] = "nim doc $# --docSeeSrcUrl:$#/$#/$# -o:$# --index:on $#" %
+      [c.nimArgs, c.gitRepo, c.gitCommit, d.pathPart,
       destPath / changeFileExt(splitFile(d).name, "html"), d]
     i.inc
   for d in items(c.srcdoc2):
-    commands[i] = "nim doc2 $# --docSeeSrcUrl:$#/$# -o:$# --index:on $#" %
-      [c.nimArgs, c.gitRepo, c.gitCommit,
+    commands[i] = "nim doc2 $# --docSeeSrcUrl:$#/$#/$# -o:$# --index:on $#" %
+      [c.nimArgs, c.gitRepo, c.gitCommit, d.pathPart,
       destPath / changeFileExt(splitFile(d).name, "html"), d]
     i.inc
 
@@ -311,8 +313,8 @@ proc buildAddDoc(c: var TConfigData, destPath: string) =
   # build additional documentation (without the index):
   var commands = newSeq[string](c.webdoc.len)
   for i, doc in pairs(c.webdoc):
-    commands[i] = "nim doc $# --docSeeSrcUrl:$#/$# -o:$# $#" %
-      [c.nimArgs, c.gitRepo, c.gitCommit,
+    commands[i] = "nim doc $# --docSeeSrcUrl:$#/$#/$# -o:$# $#" %
+      [c.nimArgs, c.gitRepo, c.gitCommit, doc.pathPart,
       destPath / changeFileExt(splitFile(doc).name, "html"), doc]
   mexec(commands, c.numProcessors)
 
diff --git a/tools/website.tmpl b/tools/website.tmpl
index 6f7a216a5..fed52ac15 100644
--- a/tools/website.tmpl
+++ b/tools/website.tmpl
@@ -63,7 +63,7 @@
 <span class="tab end">  </span>count += <span class="val">1</span>

 

 echo(<span class="val">"Average line length: "</span>,

-  <span class="kwd">if</span> count: sum / count <span class="kwd">else</span>: <span class="val">0</span>)

+  <span class="kwd">if</span> count &gt; <span class="val">0</span>: sum / count <span class="kwd">else</span>: <span class="val">0</span>)

 </pre>

             </div>

             <div>

diff --git a/web/download.txt b/web/download.txt
index 248c0b1bf..497781ad6 100644
--- a/web/download.txt
+++ b/web/download.txt
@@ -9,12 +9,9 @@ and clang on Mac OS X.
 Binaries
 ========
 
-Unfortunately for now we provide no binary builds.
-
-..
-  Unfortunately for now we only provide builds for Windows.
-  * 32 bit: `nim_0.10.2.exe <download/nim_0.10.2.exe>`_
-  * 64 bit: `nim_0.10.2_x64.exe <download/nim_0.10.2_x64.exe>`_
+Unfortunately for now we only provide builds for Windows.
+* 32 bit: `nim-0.10.2_x32.exe <download/nim-0.10.2_x32.exe>`_
+* 64 bit: `nim-0.10.2_x64.exe <download/nim-0.10.2_x64.exe>`_
 
 
 Installation based on generated C code
@@ -24,7 +21,7 @@ This installation method is the preferred way for Linux, Mac OS X, and other Uni
 like systems. Binary packages may be provided later.
 
 
-Download `nim_0.10.2.zip <download/nim_0.10.2.zip>`_, extract it and follow
+Download `nim-0.10.2.zip <download/nim-0.10.2.zip>`_, extract it and follow
 these instructions:
 
 * sh build.sh
diff --git a/web/news.txt b/web/news.txt
index cca2aaeee..ee9ad8837 100644
--- a/web/news.txt
+++ b/web/news.txt
@@ -29,7 +29,10 @@ for lightweight threading through the use of ``spawn``.
 The unpopular "T" and "P" prefixes on types have been deprecated. Nim also
 became more expressive by weakening the distinction between statements and
 expressions. We also added a new and searchable forum, a new website, and our
-documentation generator ``docgen`` has seen major improvements.
+documentation generator ``docgen`` has seen major improvements. Many thanks to
+Nick Greenfield for the much more beautiful documentation!
+
+
 
 What's left to be done
 ~~~~~~~~~~~~~~~~~~~~~~
@@ -120,7 +123,7 @@ Language Additions
 - The builtin ``procCall`` can be used to get ``super``-like functionality
   for multi methods.
 - There is a new pragma ``{.experimental.}`` that enables experimental
-  language features per module, or you can enable this features on a global
+  language features per module, or you can enable these features on a global
   level with the ``--experimental`` command line option.
 
 
@@ -137,9 +140,9 @@ Compiler Additions
 - The following procs are now available at compile-time::
 
     math.sqrt, math.ln, math.log10, math.log2, math.exp, math.round,
-    math.arccos, math.arcsin, math.arctan, math.arctan2, math.cos, math.cosh,
-    math.hypot, math.sinh, math.sin, math.tan, math.tanh, math.pow,
-    math.trunc, math.floor, math.ceil, math.fmod,
+    math.arccos, math.arcsin, math.arctan, math.arctan2, math.cos,
+    math.cosh, math.hypot, math.sinh, math.sin, math.tan, math.tanh,
+    math.pow, math.trunc, math.floor, math.ceil, math.fmod,
     os.getEnv, os.existsEnv, os.dirExists, os.fileExists,
     system.writeFile