-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Experiment: Less duplication, more aggressive let simplification #860
base: scala-2
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,10 +10,12 @@ package verification | |
*/ | ||
trait AssertionInjector extends transformers.TreeTransformer { | ||
val s: ast.Trees | ||
val t: ast.Trees | ||
val t: s.type | ||
|
||
implicit val symbols: s.Symbols | ||
|
||
import t.dsl._ | ||
|
||
val strictArithmetic: Boolean | ||
|
||
private[this] var inWrappingMode: Boolean = false | ||
|
@@ -53,11 +55,33 @@ trait AssertionInjector extends transformers.TreeTransformer { | |
).copiedFrom(i), transform(v)).copiedFrom(e) | ||
|
||
case sel @ s.ADTSelector(expr, _) => | ||
t.Assert( | ||
t.IsConstructor(transform(expr), sel.constructor.id).copiedFrom(e), | ||
Some("Cast error"), | ||
super.transform(e) | ||
).copiedFrom(e) | ||
def isIndexedType(tpe: s.Type) = | ||
tpe match { | ||
case _: s.RecursiveType => true | ||
case _ => false | ||
} | ||
val hasIndexedType = expr match { | ||
case v: s.Variable => isIndexedType(v.tpe) | ||
case fi: s.FunctionInvocation => isIndexedType(fi.tfd.returnType) | ||
case _ => false | ||
} | ||
|
||
// NOTE(gsps): Keeping the old, code-duplicating behavior here, since index annotations on | ||
// types are not propagated through `expr.getType`, breaking the Streams example. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess an alternative would be to replicate part of the type inference logic from the type checker. In the long run, it probably makes more sense to move all the assertion checks there anyway. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean add the assertion check for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, all of the assertion checks injected in this class, really. It's not quite as good in terms of separation of concerns, but it makes sense to centralize all the checking. Using let-bindings with type inference would also be reasonable and possibly not that difficult to implement. Actually, it would be great if we could add a simple locale type inference phrase to Stainless to compensate a bit for the lack of dependent types in Scala. |
||
if (hasIndexedType) | ||
t.Assert( | ||
t.IsConstructor(transform(expr), sel.constructor.id).copiedFrom(e), | ||
Some("Cast error"), | ||
super.transform(e) | ||
).copiedFrom(e) | ||
else | ||
let("recv" :: expr.getType, transform(expr)) { recv => | ||
t.Assert( | ||
t.IsConstructor(recv, sel.constructor.id).copiedFrom(e), | ||
Some("Cast error"), | ||
super.transform(sel.copy(adt = recv).copiedFrom(e)) | ||
).copiedFrom(e) | ||
}.copiedFrom(e) | ||
|
||
case BVTyped(true, size, e0 @ s.Plus(lhs0, rhs0)) if checkOverflow => | ||
val lhs = transform(lhs0) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We usually try not to simplify within the Deconstructor to make sure transformations are as predictable as possible. You could add the corresponding transformation within one of the various simplify procedures.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I'll see if I can find some simplification that's already applied anyways. I guess I'd still like to add an assertion in
AnnotatedType
that ensures we never end up with an empty list of annotations (which is impossible to spot in the pretty-printed tree!).