fixes destructor tuple regression #10940 (#10941)

* fixes #10940

* bug fixes

* fix spacing
This commit is contained in:
cooldome 2019-04-04 20:46:02 +01:00 • committed by GitHub
commit 795de374fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 3 deletions

View file

@ -610,7 +610,7 @@ proc createTypeBoundOps*(c: PContext; orig: PType; info: TLineInfo) =
## In the semantic pass this is called in strategic places
## to ensure we lift assignment, destructors and moves properly.
## The later 'injectdestructors' pass depends on it.
if orig == nil or {tfCheckedForDestructor, tfHasMeta} * orig.flags != {}: return
if orig == nil or {tfCheckedForDestructor, tfHasMeta} * orig.skipTypes({tyAlias}).flags != {}: return
incl orig.flags, tfCheckedForDestructor
let h = sighashes.hashType(orig, {CoType, CoConsiderOwned})

View file

@ -776,7 +776,12 @@ proc track(tracked: PEffects, n: PNode) =
let last = lastSon(child)
if last.kind != nkEmpty: track(tracked, last)
if tracked.owner.kind != skMacro:
createTypeBoundOps(tracked.c, child[0].typ, child.info)
if child.kind == nkVarTuple:
createTypeBoundOps(tracked.c, child[^1].typ, child.info)
for i in 0..child.len-3:
createTypeBoundOps(tracked.c, child[i].typ, child.info)
else:
createTypeBoundOps(tracked.c, child[0].typ, child.info)
if child.kind == nkIdentDefs and last.kind != nkEmpty:
for i in 0 .. child.len-3:
initVar(tracked, child.sons[i], volatileCheck=false)

View file

@ -2120,7 +2120,7 @@ proc semStmtList(c: PContext, n: PNode, flags: TExprFlags): PNode =
continue
let verdict = semConstExpr(c, n[i])
if verdict.intVal == 0:
if verdict == nil or verdict.kind != nkIntLit or verdict.intVal == 0:
localError(c.config, result.info, "concept predicate failed")
of tyUnknown: continue
else: discard

View file

@ -0,0 +1,48 @@
discard """
output: '''5.0 10.0'''
"""
type
MyOpt[T] = object
case has: bool:
of true: val: T
of false: nil
MyVal = object
f: ptr float
proc `=destroy`(x: var MyVal) =
if x.f != nil:
dealloc(x.f)
proc `=sink`(x1: var MyVal, x2: Myval) =
if x1.f != x2.f:
`=destroy`(x1)
x1.f = x2.f
proc `=`(x1: var MyVal, x2: Myval) =
if x1.f != x2.f:
`=destroy`(x1)
x1.f = create(float)
x1.f[] = x2.f[]
proc newVal(x: float): MyVal =
result.f = create(float)
result.f[] = x
template getIt[T, R](self: MyOpt[T], body: untyped, default: R): R =
if self.has:
template it: untyped {.inject.} = self.val
body
else:
default
proc myproc(h: MyOpt[float]) =
let (a, b) = h.getIt((newVal(it), newVal(it * 2)), (newVal(1.0), newVal(1.0)))
echo a.f[], " ", b.f[]
let h = MyOpt[float](has: true, val: 5.0)
myproc(h)