merge devel

This commit is contained in:
cooldome 2018-06-12 21:19:30 +01:00
commit 37aa488f99
136 changed files with 4276 additions and 5649 deletions

View file

@ -13,9 +13,9 @@
import
intsets, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
magicsys, condsyms, idents, lexer, options, parampatterns, strutils, trees,
nimfix.pretty
nimfix / pretty, lineinfos
when not defined(noDocgen):
when defined(booting) or defined(nimsuggest):
import docgen
type
@ -253,7 +253,7 @@ proc complexDisambiguation(a, b: PType): int =
result = x - y
proc writeMatches*(c: TCandidate) =
echo "Candidate '", c.calleeSym.name.s, "' at ", c.calleeSym.info
echo "Candidate '", c.calleeSym.name.s, "' at ", c.c.config $ c.calleeSym.info
echo " exact matches: ", c.exactMatches
echo " generic matches: ", c.genericMatches
echo " subtype matches: ", c.subtypeMatches
@ -376,8 +376,10 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
if k == f.kind: result = isSubrange
elif k == tyInt and f.kind in {tyRange, tyInt8..tyInt64,
tyUInt..tyUInt64} and
isIntLit(ab) and ab.n.intVal >= firstOrd(f) and
ab.n.intVal <= lastOrd(f):
isIntLit(ab) and ab.n.intVal >= firstOrd(nil, f) and
ab.n.intVal <= lastOrd(nil, f):
# passing 'nil' to firstOrd/lastOrd here as type checking rules should
# not depent on the target integer size configurations!
# integer literal in the proper range; we want ``i16 + 4`` to stay an
# ``int16`` operation so we declare the ``4`` pseudo-equal to int16
result = isFromIntLit
@ -387,8 +389,10 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
result = isConvertible
elif a.kind == tyRange and a.sons[0].kind in {tyInt..tyInt64,
tyUInt8..tyUInt32} and
a.n[0].intVal >= firstOrd(f) and
a.n[1].intVal <= lastOrd(f):
a.n[0].intVal >= firstOrd(nil, f) and
a.n[1].intVal <= lastOrd(nil, f):
# passing 'nil' to firstOrd/lastOrd here as type checking rules should
# not depent on the target integer size configurations!
result = isConvertible
else: result = isNone
#elif f.kind == tyInt and k in {tyInt..tyInt32}: result = isIntConv
@ -720,7 +724,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
addDecl(c, param)
var
oldWriteHook: type(writelnHook)
oldWriteHook: type(m.c.config.writelnHook)
diagnostics: seq[string]
errorPrefix: string
flags: TExprFlags = {}
@ -728,12 +732,12 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
sfExplain in typeClass.sym.flags
if collectDiagnostics:
oldWriteHook = writelnHook
oldWriteHook = m.c.config.writelnHook
# XXX: we can't write to m.diagnostics directly, because
# Nim doesn't support capturing var params in closures
diagnostics = @[]
flags = {efExplain}
writelnHook = proc (s: string) =
m.c.config.writelnHook = proc (s: string) =
if errorPrefix == nil: errorPrefix = typeClass.sym.name.s & ":"
let msg = s.replace("Error:", errorPrefix)
if oldWriteHook != nil: oldWriteHook msg
@ -742,7 +746,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
var checkedBody = c.semTryExpr(c, body.copyTree, flags)
if collectDiagnostics:
writelnHook = oldWriteHook
m.c.config.writelnHook = oldWriteHook
for msg in diagnostics:
m.diagnostics.safeAdd msg
m.diagnosticsEnabled = true
@ -766,11 +770,11 @@ proc shouldSkipDistinct(m: TCandidate; rules: PNode, callIdent: PIdent): bool =
# XXX This is bad as 'considerQuotedIdent' can produce an error!
if rules.kind == nkWith:
for r in rules:
if considerQuotedIdent(m.c.graph.config, r) == callIdent: return true
if considerQuotedIdent(m.c, r) == callIdent: return true
return false
else:
for r in rules:
if considerQuotedIdent(m.c.graph.config, r) == callIdent: return false
if considerQuotedIdent(m.c, r) == callIdent: return false
return true
proc maybeSkipDistinct(m: TCandidate; t: PType, callee: PSym): PType =
@ -889,17 +893,17 @@ proc inferStaticsInRange(c: var TCandidate,
if inferStaticParam(c, exp, rhs):
return isGeneric
else:
failureToInferStaticParam(c.c.graph.config, exp)
failureToInferStaticParam(c.c.config, exp)
if lowerBound.kind == nkIntLit:
if upperBound.kind == nkIntLit:
if lengthOrd(concrete) == upperBound.intVal - lowerBound.intVal + 1:
if lengthOrd(c.c.config, concrete) == upperBound.intVal - lowerBound.intVal + 1:
return isGeneric
else:
return isNone
doInferStatic(upperBound, lengthOrd(concrete) + lowerBound.intVal - 1)
doInferStatic(upperBound, lengthOrd(c.c.config, concrete) + lowerBound.intVal - 1)
elif upperBound.kind == nkIntLit:
doInferStatic(lowerBound, upperBound.intVal + 1 - lengthOrd(concrete))
doInferStatic(lowerBound, upperBound.intVal + 1 - lengthOrd(c.c.config, concrete))
template subtypeCheck() =
if result <= isSubrange and f.lastSon.skipTypes(abstractInst).kind in {tyRef, tyPtr, tyVar, tyLent}:
@ -1178,7 +1182,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
elif c.c.matchedConcept != nil and aRange.rangeHasUnresolvedStatic:
return inferStaticsInRange(c, aRange, f)
else:
if lengthOrd(fRange) != lengthOrd(aRange):
if lengthOrd(c.c.config, fRange) != lengthOrd(c.c.config, aRange):
result = isNone
else: discard
of tyOpenArray, tyVarargs:
@ -1344,7 +1348,7 @@ proc typeRelImpl(c: var TCandidate, f, aOrig: PType,
if a.len == 1:
let pointsTo = a.sons[0].skipTypes(abstractInst)
if pointsTo.kind == tyChar: result = isConvertible
elif pointsTo.kind == tyArray and firstOrd(pointsTo.sons[0]) == 0 and
elif pointsTo.kind == tyArray and firstOrd(nil, pointsTo.sons[0]) == 0 and
skipTypes(pointsTo.sons[0], {tyRange}).kind in {tyInt..tyInt64} and
pointsTo.sons[1].kind == tyChar:
result = isConvertible
@ -1776,7 +1780,7 @@ proc implicitConv(kind: TNodeKind, f: PType, arg: PNode, m: TCandidate,
else:
result.typ = f
if result.typ == nil: internalError(c.graph.config, arg.info, "implicitConv")
addSon(result, ast.emptyNode)
addSon(result, c.graph.emptyNode)
addSon(result, arg)
proc userConvMatch(c: PContext, m: var TCandidate, f, a: PType,
@ -1995,7 +1999,10 @@ proc paramTypesMatchAux(m: var TCandidate, f, a: PType,
return arg
elif a.kind == tyVoid and f.matchesVoidProc and argOrig.kind == nkStmtList:
# lift do blocks without params to lambdas
let lifted = c.semExpr(c, newProcNode(nkDo, argOrig.info, argOrig), {})
let p = c.graph
let lifted = c.semExpr(c, newProcNode(nkDo, argOrig.info, body = argOrig,
params = p.emptyNode, name = p.emptyNode, pattern = p.emptyNode,
genericParams = p.emptyNode, pragmas = p.emptyNode, exceptions = p.emptyNode), {})
if f.kind == tyBuiltInTypeClass:
inc m.genericMatches
put(m, f, lifted.typ)
@ -2129,10 +2136,10 @@ proc prepareOperand(c: PContext; a: PNode): PNode =
result = a
considerGenSyms(c, result)
proc prepareNamedParam(a: PNode; conf: ConfigRef) =
proc prepareNamedParam(a: PNode; c: PContext) =
if a.sons[0].kind != nkIdent:
var info = a.sons[0].info
a.sons[0] = newIdentNode(considerQuotedIdent(conf, a.sons[0]), info)
a.sons[0] = newIdentNode(considerQuotedIdent(c, a.sons[0]), info)
proc arrayConstr(c: PContext, n: PNode): PType =
result = newTypeS(tyArray, c)
@ -2197,7 +2204,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
elif n.sons[a].kind == nkExprEqExpr:
# named param
# check if m.callee has such a param:
prepareNamedParam(n.sons[a], c.config)
prepareNamedParam(n.sons[a], c)
if n.sons[a].sons[0].kind != nkIdent:
localError(c.config, n.sons[a].info, "named parameter has to be an identifier")
m.state = csNoMatch
@ -2361,14 +2368,18 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
for t in m.inferredTypes:
if t.sonsLen > 1: t.sons.setLen 1
proc argtypeMatches*(c: PContext, f, a: PType): bool =
proc argtypeMatches*(c: PContext, f, a: PType, fromHlo = false): bool =
var m: TCandidate
initCandidate(c, m, f)
let res = paramTypesMatch(m, f, a, ast.emptyNode, nil)
let res = paramTypesMatch(m, f, a, c.graph.emptyNode, nil)
#instantiateGenericConverters(c, res, m)
# XXX this is used by patterns.nim too; I think it's better to not
# instantiate generic converters for that
result = res != nil
if not fromHlo:
res != nil
else:
# pattern templates do not allow for conversions except from int literal
res != nil and m.convMatches == 0 and m.intConvMatches in [0, 256]
proc instTypeBoundOp*(c: PContext; dc: PSym; t: PType; info: TLineInfo;
op: TTypeAttachedOp; col: int): PSym {.procvar.} =