Skip to content

Commit 45204c9

Browse files
authored
Recursively traverse let expressions when inferring triggers, not just once (#890)
* Recursively traverse let expressions when inferring triggers, not just once * Filter out triggers that become invalid because of let-replacement * Made check to discard invalid triggers slightly more precise
1 parent ffd042d commit 45204c9

4 files changed

Lines changed: 803 additions & 7 deletions

File tree

src/main/scala/viper/silver/ast/utility/GenericTriggerGenerator.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,10 +167,15 @@ abstract class GenericTriggerGenerator[Node <: AnyRef,
167167
deepCollect(toSearch){ case qe: Quantification => Quantification_vars(qe)}.flatten
168168

169169
val additionalRelevantVars: Seq[Var] = {
170-
val additionalVarFinder = additionalRelevantVariables(vs, nestedBoundVars)
171-
deepCollect(toSearch){
172-
case n if additionalVarFinder.isDefinedAt(n) => additionalVarFinder(n)
173-
}.flatten
170+
var currentRelevantVars = vs
171+
var varFinder = additionalRelevantVariables(currentRelevantVars, nestedBoundVars)
172+
visit(toSearch){
173+
case n if varFinder.isDefinedAt(n) =>
174+
val newVars = varFinder.apply(n)
175+
currentRelevantVars = (currentRelevantVars ++ newVars).distinct
176+
varFinder = additionalRelevantVariables(currentRelevantVars, nestedBoundVars)
177+
}
178+
currentRelevantVars
174179
}
175180
val allRelevantVars = (vs ++ additionalRelevantVars).distinct
176181
val modifyTriggers = modifyPossibleTriggers(allRelevantVars)

src/main/scala/viper/silver/ast/utility/Triggers.scala

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,16 @@ object Triggers {
7575
(ast.LabelledOld(exp, l)(exp.pos, exp.info, exp.errT), t._2, t._3)
7676
})
7777
case ast.Let(v, e, body) => results =>
78-
results.flatten.map(t => {
78+
results.flatten.flatMap(t => {
7979
val exp = t._1
80+
val varIsUsed = body.contains(v.localVar)
8081
val coveredVars = t._2.filter(cv => cv != v.localVar) ++
81-
(if (body.contains(v.localVar)) relevantVars.filter(rv => e.contains(rv)) else Seq())
82-
(exp.replace(v.localVar, e), coveredVars, t._3)
82+
(if (varIsUsed) relevantVars.filter(rv => e.contains(rv)) else Seq())
83+
if (varIsUsed && isForbiddenInTrigger(e)) {
84+
None
85+
} else {
86+
Some((exp.replace(v.localVar, e), coveredVars, t._3))
87+
}
8388
})
8489
}
8590

src/test/resources/all/issues/silicon/0926.vpr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Any copyright is dedicated to the Public Domain.
2+
// http://creativecommons.org/publicdomain/zero/1.0/
3+
14
field f: Int
25

36
function fn(x: Ref, y: Ref): Int

0 commit comments

Comments
 (0)