@@ -179,6 +179,10 @@ trait EffectsAnalyzer extends oo.CachingPhase {
179179 def asString (implicit ctx : inox.Context ) = s " MutableMapAccessor( ${index.asString}) "
180180 }
181181
182+ case class TupleFieldAccessor (index : Int ) extends Accessor {
183+ def asString (implicit ctx : inox.Context ) = s " TupleFieldAccessor( $index) "
184+ }
185+
182186 case class Path (path : Seq [Accessor ]) {
183187 def :+ (elem : Accessor ): Path = Path (path :+ elem)
184188 def +: (elem : Accessor ): Path = Path (elem +: path)
@@ -210,6 +214,8 @@ trait EffectsAnalyzer extends oo.CachingPhase {
210214 rec(xs1, xs2)
211215 case (ClassFieldAccessor (id1) +: xs1, ClassFieldAccessor (id2) +: xs2) if id1 == id2 =>
212216 rec(xs1, xs2)
217+ case (TupleFieldAccessor (id1) +: xs1, TupleFieldAccessor (id2) +: xs2) if id1 == id2 =>
218+ rec(xs1, xs2)
213219 case (MutableMapAccessor (_) +: xs1, MutableMapAccessor (_) +: xs2) =>
214220 rec(xs1, xs2)
215221 case _ => false
@@ -225,6 +231,7 @@ trait EffectsAnalyzer extends oo.CachingPhase {
225231 else path.map {
226232 case ADTFieldAccessor (id) => s " . ${id.asString}"
227233 case ClassFieldAccessor (id) => s " . ${id.asString}"
234+ case TupleFieldAccessor (idx) => s " ._ $idx"
228235 case ArrayAccessor (idx) => s " ( ${idx.asString}) "
229236 case MutableMapAccessor (idx) => s " ( ${idx.asString}) "
230237 }.mkString(" " )
@@ -239,6 +246,9 @@ trait EffectsAnalyzer extends oo.CachingPhase {
239246 case ADTFieldAccessor (id) +: xs =>
240247 wrap(ADTSelector (expr, id), xs)
241248
249+ case TupleFieldAccessor (idx) +: xs =>
250+ wrap(TupleSelect (expr, idx), xs)
251+
242252 case ClassFieldAccessor (id) +: xs =>
243253 def asClassType (tpe : Type ): Option [ClassType ] = tpe match {
244254 case ct : ClassType => Some (ct)
@@ -297,6 +307,9 @@ trait EffectsAnalyzer extends oo.CachingPhase {
297307 val field = syms.classForField(ct, id).flatMap(_.fields.find(_.id == id))
298308 field.isDefined && rec(field.get.getType, xs)
299309
310+ case (tt : TupleType , TupleFieldAccessor (idx) +: xs) =>
311+ 0 < idx && idx <= tt.dimension && rec(tt.bases(idx - 1 ), xs)
312+
300313 case (ArrayType (base), ArrayAccessor (idx) +: xs) =>
301314 rec(base, xs)
302315
@@ -331,11 +344,14 @@ trait EffectsAnalyzer extends oo.CachingPhase {
331344 override def toString : String = asString
332345 }
333346
347+ // getTargets(expr, Seq()) returns the set of targets such that after `var x = expr`,
348+ // the modifications on `x` will result in modifications on these targets
334349 def getTargets (expr : Expr , path : Seq [Accessor ])(implicit symbols : Symbols ): Set [Target ] = expr match {
335350 case _ if variablesOf(expr).forall(v => ! symbols.isMutableType(v.tpe)) => Set .empty
336351 case v : Variable => Set (Target (v, None , Path (path)))
337352 case ADTSelector (e, id) => getTargets(e, ADTFieldAccessor (id) +: path)
338353 case ClassSelector (e, id) => getTargets(e, ClassFieldAccessor (id) +: path)
354+ case TupleSelect (e, idx) => getTargets(e, TupleFieldAccessor (idx) +: path)
339355 case ArraySelect (a, idx) => getTargets(a, ArrayAccessor (idx) +: path)
340356 case MutableMapApply (a, idx) => getTargets(a, MutableMapAccessor (idx) +: path)
341357 case MutableMapDuplicate (m) => getTargets(m, path)
@@ -354,6 +370,13 @@ trait EffectsAnalyzer extends oo.CachingPhase {
354370 Set .empty
355371 }
356372
373+ case Tuple (exprs) => path match {
374+ case TupleFieldAccessor (idx) +: rest =>
375+ getTargets(exprs(idx - 1 ), rest)
376+ case _ =>
377+ Set .empty
378+ }
379+
357380 case FiniteArray (elems, _) => path match {
358381 case ArrayAccessor (bv : BVLiteral ) +: rest =>
359382 val i = bv.toBigInt.toInt
@@ -390,7 +413,8 @@ trait EffectsAnalyzer extends oo.CachingPhase {
390413 } yield target
391414
392415 case fi : FunctionInvocation if ! symbols.isRecursive(fi.id) =>
393- BodyWithSpecs (symbols.simplifyLets(fi.inlined))
416+ if (fi.tfd.flags.contains(IsPure )) Set .empty
417+ else BodyWithSpecs (symbols.simplifyLets(fi.inlined))
394418 .bodyOpt
395419 .map(getTargets(_, path))
396420 .getOrElse(Set .empty)
@@ -403,6 +427,7 @@ trait EffectsAnalyzer extends oo.CachingPhase {
403427 case AsInstanceOf (e, _) => getTargets(e, path)
404428 case Old (_) => Set .empty
405429 case Snapshot (_) => Set .empty
430+ case FreshCopy (_) => Set .empty
406431
407432 case ArrayLength (_) => Set .empty
408433
0 commit comments