Merge remote-tracking branch 'origin/concepts-rebased' into araq

This commit is contained in:
Andreas Rumpf 2017-03-31 16:40:21 +02:00
commit 529609f7ed
47 changed files with 2038 additions and 345 deletions

View file

@ -501,6 +501,8 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
#changeType(def.skipConv, typ, check=true)
else:
typ = skipIntLit(def.typ)
if typ.kind in tyUserTypeClasses and typ.isResolvedUserTypeClass:
typ = typ.lastSon
if hasEmpty(typ):
localError(def.info, errCannotInferTypeOfTheLiteral,
($typ.kind).substr(2).toLowerAscii)
@ -1554,6 +1556,16 @@ proc usesResult(n: PNode): bool =
for c in n:
if usesResult(c): return true
proc inferConceptStaticParam(c: PContext, inferred, n: PNode) =
var typ = inferred.typ
let res = semConstExpr(c, n)
if not sameType(res.typ, typ.base):
localError(n.info,
"cannot infer the concept parameter '%s', due to a type mismatch. " &
"attempt to equate '%s' and '%s'.",
[inferred.renderTree, $res.typ, $typ.base])
typ.n = res
proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
# these must be last statements in a block:
const
@ -1605,10 +1617,21 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
n.typ = n.sons[i].typ
return
else:
n.sons[i] = semExpr(c, n.sons[i])
if c.inTypeClass > 0 and n[i].typ != nil:
case n[i].typ.kind
var expr = semExpr(c, n.sons[i], flags)
n.sons[i] = expr
if c.inTypeClass > 0 and expr.typ != nil:
case expr.typ.kind
of tyBool:
if expr.kind == nkInfix and
expr[0].kind == nkSym and
expr[0].sym.name.s == "==":
if expr[1].typ.isUnresolvedStatic:
inferConceptStaticParam(c, expr[1], expr[2])
continue
elif expr[2].typ.isUnresolvedStatic:
inferConceptStaticParam(c, expr[2], expr[1])
continue
let verdict = semConstExpr(c, n[i])
if verdict.intVal == 0:
localError(result.info, "type class predicate failed")
@ -1632,8 +1655,12 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
of nkPragma, nkCommentStmt, nkNilLit, nkEmpty: discard
else: localError(n.sons[j].info, errStmtInvalidAfterReturn)
else: discard
if result.len == 1 and result.sons[0].kind != nkDefer:
if result.len == 1 and
c.inTypeClass == 0 and # concept bodies should be preserved as a stmt list
result.sons[0].kind != nkDefer:
result = result.sons[0]
when defined(nimfix):
if result.kind == nkCommentStmt and not result.comment.isNil and
not (result.comment[0] == '#' and result.comment[1] == '#'):