mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-29 10:01:39 +00:00
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user