Consider the following example:
field f: Int
predicate P(x: Ref, y: Ref) {
acc(x.f) && x.f > 0 && (x.f > 0 ==> y != null) // Is well-defined
}
method test(x: Ref, y: Ref) {
inhale acc(P(x, y), none)
unfold acc(P(x, y), none) // Permission-scaled predicate body is no longer well-defined
assert y != null
}
Silicon reports insufficient permissions to x.f at the unfold statement (because it can't find a heap chunk with non-zero permissions that would allow reading x.f).
Carbon happily verifies the program, although, I would argue, y != null should not be implied if x.f can't even be read.
I would suggest to simply disallow unfolding with no permissions.
Consider the following example:
Silicon reports insufficient permissions to
x.fat theunfoldstatement (because it can't find a heap chunk with non-zero permissions that would allow readingx.f).Carbon happily verifies the program, although, I would argue,
y != nullshould not be implied ifx.fcan't even be read.I would suggest to simply disallow unfolding with no permissions.