fixes #2420; negative indexing for slicing is obsolete (breaking change!)
This commit is contained in:
parent
46fb0e0bac
commit
2b80d75aa2
8 changed files with 82 additions and 79 deletions
|
|
@ -12,7 +12,7 @@
|
|||
# included from sem.nim
|
||||
|
||||
# special marker values that indicates that we are
|
||||
# 1) AnalyzingDestructor: currently analyzing the type for destructor
|
||||
# 1) AnalyzingDestructor: currently analyzing the type for destructor
|
||||
# generation (needed for recursive types)
|
||||
# 2) DestructorIsTrivial: completed the analysis before and determined
|
||||
# that the type has a trivial destructor
|
||||
|
|
@ -41,7 +41,7 @@ proc doDestructorStuff(c: PContext, s: PSym, n: PNode) =
|
|||
if t.kind != tyGenericBody:
|
||||
localError(n.info, errDestructorNotGenericEnough)
|
||||
return
|
||||
|
||||
|
||||
t.destructor = s
|
||||
# automatically insert calls to base classes' destructors
|
||||
if n.sons[bodyPos].kind != nkEmpty:
|
||||
|
|
@ -71,17 +71,18 @@ proc destroyCase(c: PContext, n: PNode, holder: PNode): PNode =
|
|||
result.addSon(newNode(nkDotExpr, n.info, @[holder, n.sons[0]]))
|
||||
for i in countup(1, n.len - 1):
|
||||
# of A, B:
|
||||
var caseBranch = newNode(n[i].kind, n[i].info, n[i].sons[0 .. -2])
|
||||
|
||||
let stmt = destroyFieldOrFields(c, n[i].lastSon, holder)
|
||||
let ni = n[i]
|
||||
var caseBranch = newNode(ni.kind, ni.info, ni.sons[0..ni.len-2])
|
||||
|
||||
let stmt = destroyFieldOrFields(c, ni.lastSon, holder)
|
||||
if stmt == nil:
|
||||
caseBranch.addSon(newNode(nkStmtList, n[i].info, @[]))
|
||||
caseBranch.addSon(newNode(nkStmtList, ni.info, @[]))
|
||||
else:
|
||||
caseBranch.addSon(stmt)
|
||||
nonTrivialFields += stmt.len
|
||||
|
||||
|
||||
result.addSon(caseBranch)
|
||||
|
||||
|
||||
# maybe no fields were destroyed?
|
||||
if nonTrivialFields == 0:
|
||||
result = nil
|
||||
|
|
@ -107,7 +108,7 @@ proc destroyFieldOrFields(c: PContext, field: PNode, holder: PNode): PNode =
|
|||
proc generateDestructor(c: PContext, t: PType): PNode =
|
||||
## generate a destructor for a user-defined object or tuple type
|
||||
## returns nil if the destructor turns out to be trivial
|
||||
|
||||
|
||||
# XXX: This may be true for some C-imported types such as
|
||||
# Tposix_spawnattr
|
||||
if t.n == nil or t.n.sons == nil: return
|
||||
|
|
@ -120,13 +121,13 @@ proc generateDestructor(c: PContext, t: PType): PNode =
|
|||
|
||||
proc instantiateDestructor(c: PContext, typ: PType): PType =
|
||||
# returns nil if a variable of type `typ` doesn't require a
|
||||
# destructor. Otherwise, returns the type, which holds the
|
||||
# destructor. Otherwise, returns the type, which holds the
|
||||
# destructor that must be used for the varialbe.
|
||||
# The destructor is either user-defined or automatically
|
||||
# generated by the compiler in a member-wise fashion.
|
||||
var t = skipTypes(typ, {tyConst, tyMutable}).skipGenericAlias
|
||||
let typeHoldingUserDefinition = if t.kind == tyGenericInst: t.base else: t
|
||||
|
||||
|
||||
if typeHoldingUserDefinition.destructor != nil:
|
||||
# XXX: This is not entirely correct for recursive types, but we need
|
||||
# it temporarily to hide the "destroy is already defined" problem
|
||||
|
|
@ -135,7 +136,7 @@ proc instantiateDestructor(c: PContext, typ: PType): PType =
|
|||
return typeHoldingUserDefinition
|
||||
else:
|
||||
return nil
|
||||
|
||||
|
||||
t = t.skipTypes({tyGenericInst})
|
||||
case t.kind
|
||||
of tySequence, tyArray, tyArrayConstr, tyOpenArray, tyVarargs:
|
||||
|
|
@ -200,16 +201,16 @@ proc insertDestructors(c: PContext,
|
|||
varId = varSection[j][0]
|
||||
varTyp = varId.sym.typ
|
||||
info = varId.info
|
||||
|
||||
|
||||
if varTyp == nil or sfGlobal in varId.sym.flags: continue
|
||||
let destructableT = instantiateDestructor(c, varTyp)
|
||||
|
||||
|
||||
if destructableT != nil:
|
||||
var tryStmt = newNodeI(nkTryStmt, info)
|
||||
|
||||
if j < totalVars - 1:
|
||||
var remainingVars = newNodeI(varSection.kind, info)
|
||||
remainingVars.sons = varSection.sons[(j+1)..(-1)]
|
||||
remainingVars.sons = varSection.sons[(j+1)..varSection.len-1]
|
||||
let (outer, inner) = insertDestructors(c, remainingVars)
|
||||
if outer != nil:
|
||||
tryStmt.addSon(outer)
|
||||
|
|
@ -221,7 +222,7 @@ proc insertDestructors(c: PContext,
|
|||
else:
|
||||
result.inner = newNodeI(nkStmtList, info)
|
||||
tryStmt.addSon(result.inner)
|
||||
|
||||
|
||||
tryStmt.addSon(
|
||||
newNode(nkFinally, info, @[
|
||||
semStmt(c, newNode(nkCall, info, @[
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue