borrow checking (#15282)

* refactoring: move procs to typeallowed.nim
* frontend preparations for first class openArray support
* prepare the code generator for first class openArray
* code generation for first class openArray; WIP
* code generation for open arrays, progress
* added isViewType proc
* preparations for borrow checking
* added borrow checking to the front end
This commit is contained in:
Andreas Rumpf
2020-09-09 07:32:03 +02:00
committed by GitHub
parent c49b88163c
commit 10988d4840
18 changed files with 554 additions and 311 deletions

View File

@@ -178,7 +178,7 @@ proc checkConvertible(c: PContext, targetTyp: PType, src: PNode): TConvStatus =
else:
discard
proc isCastable(conf: ConfigRef; dst, src: PType): bool =
proc isCastable(c: PContext; dst, src: PType): bool =
## Checks whether the source type can be cast to the destination type.
## Casting is very unrestrictive; casts are allowed as long as
## castDest.size >= src.size, and typeAllowed(dst, skParam)
@@ -193,6 +193,7 @@ proc isCastable(conf: ConfigRef; dst, src: PType): bool =
return false
if skipTypes(dst, abstractInst).kind == tyBuiltInTypeClass:
return false
let conf = c.config
if conf.selectedGC in {gcArc, gcOrc}:
let d = skipTypes(dst, abstractInst)
let s = skipTypes(src, abstractInst)
@@ -210,7 +211,7 @@ proc isCastable(conf: ConfigRef; dst, src: PType): bool =
result = false
elif srcSize < 0:
result = false
elif typeAllowed(dst, skParam) != nil:
elif typeAllowed(dst, skParam, c) != nil:
result = false
elif dst.kind == tyProc and dst.callConv == ccClosure:
result = src.kind == tyProc and src.callConv == ccClosure
@@ -338,7 +339,7 @@ proc semCast(c: PContext, n: PNode): PNode =
let castedExpr = semExprWithType(c, n[1])
if tfHasMeta in targetType.flags:
localError(c.config, n[0].info, "cannot cast to a non concrete type: '$1'" % $targetType)
if not isCastable(c.config, targetType, castedExpr.typ):
if not isCastable(c, targetType, castedExpr.typ):
let tar = $targetType
let alt = typeToString(targetType, preferDesc)
let msg = if tar != alt: tar & "=" & alt else: tar
@@ -794,7 +795,7 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
if callee.kind notin {skProc, skFunc, skConverter, skConst} or callee.isGenericRoutine:
return
if n.typ != nil and typeAllowed(n.typ, skConst) != nil: return
if n.typ != nil and typeAllowed(n.typ, skConst, c) != nil: return
var call = newNodeIT(nkCall, n.info, n.typ)
call.add(n[0])
@@ -962,9 +963,9 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode =
# t.sym != nil
# sfAnon notin t.sym.flags
# t.kind != tySequence(It is tyProc)
if typ.sym != nil and sfAnon notin typ.sym.flags and
if typ.sym != nil and sfAnon notin typ.sym.flags and
typ.kind == tyProc:
msg.add(" = " &
msg.add(" = " &
typeToString(typ, preferDesc))
localError(c.config, n.info, msg)
return errorNode(c, n)
@@ -1600,7 +1601,7 @@ proc takeImplicitAddr(c: PContext, n: PNode; isLent: bool): PNode =
proc asgnToResultVar(c: PContext, n, le, ri: PNode) {.inline.} =
if le.kind == nkHiddenDeref:
var x = le[0]
if x.typ.kind in {tyVar, tyLent} and x.kind == nkSym and x.sym.kind == skResult:
if (x.typ.kind in {tyVar, tyLent} or isViewType(x.typ)) and x.kind == nkSym and x.sym.kind == skResult:
n[0] = x # 'result[]' --> 'result'
n[1] = takeImplicitAddr(c, ri, x.typ.kind == tyLent)
x.typ.flags.incl tfVarIsPtr
@@ -1732,7 +1733,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
if cmpTypes(c, lhs.typ, rhsTyp) in {isGeneric, isEqual}:
internalAssert c.config, c.p.resultSym != nil
# Make sure the type is valid for the result variable
typeAllowedCheck(c.config, n.info, rhsTyp, skResult)
typeAllowedCheck(c, n.info, rhsTyp, skResult)
lhs.typ = rhsTyp
c.p.resultSym.typ = rhsTyp
c.p.owner.typ[0] = rhsTyp
@@ -1825,7 +1826,9 @@ proc semYieldVarResult(c: PContext, n: PNode, restype: PType) =
tupleConstr[i] = takeImplicitAddr(c, tupleConstr[i], e.kind == tyLent)
else:
localError(c.config, n[0].info, errXExpected, "tuple constructor")
else: discard
else:
if isViewType(t):
n[0] = takeImplicitAddr(c, n[0], false)
proc semYield(c: PContext, n: PNode): PNode =
result = n