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

@ -136,6 +136,7 @@ proc isCastable(dst, src: PType): bool =
# castableTypeKinds = {tyInt, tyPtr, tyRef, tyCstring, tyString,
# tySequence, tyPointer, tyNil, tyOpenArray,
# tyProc, tySet, tyEnum, tyBool, tyChar}
let src = src.skipTypes(tyUserTypeClasses)
if skipTypes(dst, abstractInst-{tyOpenArray}).kind == tyOpenArray:
return false
if skipTypes(src, abstractInst-{tyTypeDesc}).kind == tyTypeDesc:
@ -301,7 +302,7 @@ proc semOf(c: PContext, n: PNode): PNode =
n.typ = getSysType(tyBool)
result = n
proc isOpImpl(c: PContext, n: PNode): PNode =
proc isOpImpl(c: PContext, n: PNode, flags: TExprFlags): PNode =
internalAssert n.sonsLen == 3 and
n[1].typ != nil and n[1].typ.kind == tyTypeDesc and
n[2].kind in {nkStrLit..nkTripleStrLit, nkType}
@ -318,16 +319,18 @@ proc isOpImpl(c: PContext, n: PNode): PNode =
else:
result = newIntNode(nkIntLit, 0)
else:
var t2 = n[2].typ.skipTypes({tyTypeDesc})
var rhsOrigType = n[2].typ
var t2 = rhsOrigType.skipTypes({tyTypeDesc})
maybeLiftType(t2, c, n.info)
var m: TCandidate
initCandidate(c, m, t2)
if efExplain in flags: m.diagnostics = @[]
let match = typeRel(m, t2, t1) >= isSubtype # isNone
result = newIntNode(nkIntLit, ord(match))
result.typ = n.typ
proc semIs(c: PContext, n: PNode): PNode =
proc semIs(c: PContext, n: PNode, flags: TExprFlags): PNode =
if sonsLen(n) != 3:
localError(n.info, errXExpectsTwoArguments, "is")
@ -347,7 +350,7 @@ proc semIs(c: PContext, n: PNode): PNode =
return
# BUGFIX: don't evaluate this too early: ``T is void``
if not n[1].typ.base.containsGenericType: result = isOpImpl(c, n)
if not n[1].typ.base.containsGenericType: result = isOpImpl(c, n, flags)
proc semOpAux(c: PContext, n: PNode) =
const flags = {efDetermineType}
@ -625,6 +628,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
proc semStaticExpr(c: PContext, n: PNode): PNode =
let a = semExpr(c, n.sons[0])
if a.findUnresolvedStatic != nil: return a
result = evalStaticExpr(c.module, c.cache, a, c.p.owner)
if result.isNil:
localError(n.info, errCannotInterpretNodeX, renderTree(n))
@ -640,10 +644,10 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode,
# for typeof support.
# for ``type(countup(1,3))``, see ``tests/ttoseq``.
result = semOverloadedCall(c, n, nOrig,
{skProc, skMethod, skConverter, skMacro, skTemplate, skIterator})
{skProc, skMethod, skConverter, skMacro, skTemplate, skIterator}, flags)
else:
result = semOverloadedCall(c, n, nOrig,
{skProc, skMethod, skConverter, skMacro, skTemplate})
{skProc, skMethod, skConverter, skMacro, skTemplate}, flags)
if result != nil:
if result.sons[0].kind != nkSym:
@ -751,7 +755,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
# This is a proc variable, apply normal overload resolution
let m = resolveIndirectCall(c, n, nOrig, t)
if m.state != csMatch:
if c.compilesContextId > 0:
if errorOutputs == {}:
# speed up error generation:
globalError(n.info, errTypeMismatch, "")
return emptyNode
@ -912,20 +916,42 @@ 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].skipGenericAlias)
let tbody = ty.sons[0]
for s in countup(0, tbody.len-2):
let tParam = tbody.sons[s]
if tParam.sym.name.id == paramName.id:
let rawTyp = ty.sons[s + 1]
if rawTyp.kind == tyStatic:
return rawTyp.n
if typ.kind in {tyUserTypeClass, tyUserTypeClassInst}:
for statement in typ.n:
case statement.kind
of nkTypeSection:
for def in statement:
if def[0].sym.name.id == paramName.id:
# XXX: Instead of lifting the section type to a typedesc
# here, we could try doing it earlier in semTypeSection.
# This seems semantically correct and then we'll be able
# to return the section symbol directly here
let foundType = makeTypeDesc(c, def[2].typ)
return newSymNode(copySym(def[0].sym).linkTo(foundType), info)
of nkConstSection:
for def in statement:
if def[0].sym.name.id == paramName.id:
return def[2]
else:
let foundTyp = makeTypeDesc(c, rawTyp)
return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info)
#echo "came here: returned nil"
discard
if typ.kind != tyUserTypeClass:
let ty = if typ.kind == tyCompositeTypeClass: typ.sons[1].skipGenericAlias
else: typ.skipGenericAlias
let tbody = ty.sons[0]
for s in countup(0, tbody.len-2):
let tParam = tbody.sons[s]
if tParam.sym.name.id == paramName.id:
let rawTyp = ty.sons[s + 1]
if rawTyp.kind == tyStatic:
return rawTyp.n
else:
let foundTyp = makeTypeDesc(c, rawTyp)
return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info)
return nil
proc semSym(c: PContext, n: PNode, sym: PSym, flags: TExprFlags): PNode =
let s = getGenSym(c, sym)
@ -1080,6 +1106,23 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
var ty = n.sons[0].typ
var f: PSym = nil
result = nil
template tryReadingGenericParam(t: PType) =
case t.kind
of tyTypeParamsHolders:
return readTypeParameter(c, t, i, n.info)
of tyUserTypeClasses:
if t.isResolvedUserTypeClass:
return readTypeParameter(c, t, i, n.info)
else:
n.typ = makeTypeFromExpr(c, copyTree(n))
return n
of tyGenericParam:
n.typ = makeTypeFromExpr(c, copyTree(n))
return n
else:
discard
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)
@ -1097,8 +1140,6 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
markUsed(n.info, f, c.graph.usageSym)
styleCheckUse(n.info, f)
return
of tyTypeParamsHolders:
return readTypeParameter(c, ty, i, n.info)
of tyObject, tyTuple:
if ty.n != nil and ty.n.kind == nkRecList:
let field = lookupInRecord(ty.n, i)
@ -1107,8 +1148,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
n.typ.n = copyTree(n)
return n
else:
# echo "TYPE FIELD ACCESS"
# debug ty
tryReadingGenericParam(ty)
return
# XXX: This is probably not relevant any more
# reset to prevent 'nil' bug: see "tests/reject/tenumitems.nim":
@ -1151,8 +1191,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
# we didn't find any field, let's look for a generic param
if result == nil:
let t = n.sons[0].typ.skipTypes(tyDotOpTransparent)
if t.kind in tyTypeParamsHolders:
result = readTypeParameter(c, t, i, n.info)
tryReadingGenericParam(t)
proc dotTransformation(c: PContext, n: PNode): PNode =
if isSymChoice(n.sons[1]):
@ -1718,7 +1757,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
let oldOwnerLen = len(c.graph.owners)
let oldGenerics = c.generics
let oldErrorOutputs = errorOutputs
errorOutputs = {}
if efExplain notin flags: errorOutputs = {}
let oldContextLen = msgs.getInfoContextLen()
let oldInGenericContext = c.inGenericContext
@ -1731,8 +1770,7 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
result = semExpr(c, n, flags)
if msgs.gErrorCounter != oldErrorCount: result = nil
except ERecoverableError:
if optReportConceptFailures in gGlobalOptions:
err = getCurrentExceptionMsg()
discard
# undo symbol table changes (as far as it's possible):
c.compilesContextId = oldCompilesId
c.generics = oldGenerics
@ -1746,8 +1784,6 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
errorOutputs = oldErrorOutputs
msgs.gErrorCounter = oldErrorCount
msgs.gErrorMax = oldErrorMax
if optReportConceptFailures in gGlobalOptions and not err.isNil:
localError(n.info, err)
proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode =
# we replace this node by a 'true' or 'false' node:
@ -1814,7 +1850,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode =
of mLow: result = semLowHigh(c, setMs(n, s), mLow)
of mHigh: result = semLowHigh(c, setMs(n, s), mHigh)
of mSizeOf: result = semSizeof(c, setMs(n, s))
of mIs: result = semIs(c, setMs(n, s))
of mIs: result = semIs(c, setMs(n, s), flags)
of mOf: result = semOf(c, setMs(n, s))
of mShallowCopy: result = semShallowCopy(c, n, flags)
of mExpandToAst: result = semExpandToAst(c, n, s, flags)
@ -2327,8 +2363,20 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
of nkCurlyExpr:
result = semExpr(c, buildOverloadedSubscripts(n, getIdent"{}"), flags)
of nkPragmaExpr:
# which pragmas are allowed for expressions? `likely`, `unlikely`
internalError(n.info, "semExpr() to implement") # XXX: to implement
var
expr = n[0]
pragma = n[1]
pragmaName = considerQuotedIdent(pragma[0])
flags = flags
case whichKeyword(pragmaName)
of wExplain:
flags.incl efExplain
else:
# what other pragmas are allowed for expressions? `likely`, `unlikely`
invalidPragma(n)
result = semExpr(c, n[0], flags)
of nkPar:
case checkPar(n)
of paNone: result = errorNode(c, n)