-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Ruby: Fix spurious flow through reverse stores #10574
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
Conversation
5740f22
to
212d112
Compare
212d112
to
34fb0d3
Compare
The tests highlight the differences between `(With|Without)?Element[1]` and `(With|Without)?Element[1!]`.
34fb0d3
to
31806b8
Compare
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.
LGTM. This conflicts with #10375 but it's probably easier for me to update my PR than the other way around, so feel free to merge first.
Thanks. Sorry for introducing yet another merge conflict on your PR. |
This only fixes superficial conflicts with github#10574 semantic conflicts will be addressed in later commits
Commit-by-commit review is encouraged.
In Ruby, reads with known indices, such as
give rise to two read steps; one that reads
TSingletonContent(TKnownElementContent(0))
and one that readsTSingletonContent(TUnknownElementContent())
(if data is stored at an unknown index, it might be0
).Since
[]
is just a method call, it means we have two flow summaries for[]
:This works well for reads, however for reverse stores
it means that we will get store steps into
a
with bothTSingletonContent(TKnownElementContent(0))
andTSingletonContent(TUnknownElementContent())
, which allows for spurious flow:The solution in this PR is to add a new
ContentSet
branchwhich can read from both
TKnownElementContent(c)
andTUnknownElementContent()
, but which can only store intoTKnownElementContent(c)
. We can then reducea[0]
to just a single read step, which reads fromTKnownOrUnknownElementContent(TKnownElementContent(0))
.In order to distinguish
TKnownOrUnknownElementContent(c)
fromTSingletonContent(TKnownElementContent(c))
in models-as-data specifications, we use the following syntaxContentSet
Element[0]
TKnownOrUnknownElementContent(0)
Element[0!]
TSingletonContent(TKnownElementContent(0))
and similarly for
With(out)Element
and rangesElement[0..]
. This means that the flow summary for[]
is just a single row:Note also that using
Element[0]
vsElement[0!]
in output specifications makes no differences, since the former also stores only intoTSingletonContent(TKnownElementContent(0))
.