Uh oh!
There was an error while loading. Please reload this page.
Value visitors for miri - #55549
Conversation
rust-highfive
commented
Oct 31, 2018
r? @oli-obk (rust_highfive has picked a reviewer for you, use r? to override) |
rust-highfive
commented
Oct 31, 2018
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
RalfJung
commented
Oct 31, 2018
Wtf, this compiled fine in stage 2... NLL bug or so? |
oli-obk
left a comment
There was a problem hiding this comment.
Preliminary review. I think reviewing the rest only makes sense with the review questions addressed
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
I dislike the self mutation. It does not feel right. I think these downcast functions should be recursing via visit_value.
There was a problem hiding this comment.
downcast_dyn_trait is gone in a later commit.
For downcast_enum I will do this, but it actually makes the interface larger overall (i.e., one more method to implement).
There was a problem hiding this comment.
Oh and then there is an extra hook I need to keep the nice error reporting... of the validity check :/
There was a problem hiding this comment.
Okay I did something. Thanks for making me do it, it is now better than it was before. :) Let me know what you think.
There was a problem hiding this comment.
I am aware this is a bad error message. Fixing this will be fairly easy once #55293 lands: Use ScalarMaybeUndef in EvalErrorKind::InvalidDiscriminant.
oli-obk
left a comment
There was a problem hiding this comment.
oh damn, I never pressed the submit review button :/
Anyway, yes, this is getting closer to what I'm imagining.
Take the comments with a grain of salt, because I've not checked how obsolete they have become with your changes
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
What do you mean by replace? changing a function argument does not persist outside the function call.
I would have assumed this to just forward to visit_value by default, ignoring all the other arguments.
There was a problem hiding this comment.
The visitor has in its internal state the current value we are visiting. This function makes it change that state to another value.
I know this is a somewhat strange architecture for a visitor, but it's the best I could come up with so far in terms of code reuse. But the original design also did not have the Value trait; now that I got that maybe I can separate the value from the rest of the visitor state. However, I actually found it quite nice that they are connected because the ValidationVisitor uses that to keep track of its stack.
There was a problem hiding this comment.
So I think I fundamentally misunderstood the nature of this visitor. I thought it was like the visitor for Mir, which just gives you mutable references to rustc::mir::* types and by default calls walk_*, which destructures the value and calls visit_* on all the values obtainable.
I am not sure what this "visitor" is doing anymore. Would it be possible to write a visitor of the following form, still support your use cases and still copy/allocate as little intermediate state as possible?
traitValueVisitor<'a,'mir,'tcx,M:Machine<'a,'mir,'tcx>>: fmt::Debug + Sized{typeV:Value<'tcx,M>;fnecx(&mutself) -> &mutEvalContext<'a,'mir,'tcx,M>)fnvisit(&mutself,value:&mutV) -> EvalResult<'tcx>{walk_value(self, value)}fnvisit_array(&mutself,elements:implIterator<Item = &mutV>) -> EvalResult<'tcx>{walk_array(self, elements)}fnvisit_enum(&mutself,value:&mutValue) -> EvalResutl<'tcx>{walk_enum(self, value)}// leafsfnvisit_scalar(&mutself,_scalar:&mutScalar,_layout:&layout::Scalar) -> EvalResult<'tcx>{Ok(())}// ...}fn walk_value....
fn walk_array<VIS:ValueVisitor>(visitor:&mut VIS, elements:implIterator<Item = &mutVIS::V>) -> EvalResult<'tcx> {for element in elements {
visitor.visit(element)?;}Ok(())}
fn walk_enum<VIS:ValueVisitor>(visitor:&mut VIS, value:&mut VIS::V) -> EvalResult<'tcx> {let variant = value.read_discriminant(self.ecx())?.1;
visitor.visit(value.downcast(self.ecx(), variant)?)}This will increase the amount of recursion happening, but it has a much nicer feel to me, because fewer things are entangled with each other.
bors
commented
Nov 1, 2018
☔ The latest upstream changes (presumably #55579) made this pull request unmergeable. Please resolve the merge conflicts. |
oli-obk
left a comment
There was a problem hiding this comment.
The visitor as it is (except for the visit_scalar method as mentioned in the comments) looks good to me now. I'll review the rest of the code independently now
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
| /// Visit the given value as a union. | |
| /// Visit the given value as a union. Does not recurse unless overwritten to do so. |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
how can an uninhabited type have fields?
There was a problem hiding this comment.
I think the default impl should be calling a walk_scalar method then. Pass all arguments needed to recurse. Implementing a visit_* function as Ok(()) should stop recursion right there.
There was a problem hiding this comment.
That does not match the structure we used for the validation visitor, and I think it is the wrong structure. The point is that being a scalar and being an aggregate are orthogonal properties, a value can be neither or both or any combination. Some scalars are primitives, some are not - -we'd have to duplicate all the primitive-vs-aggregate handling. I don't think that would be a good idea.
There was a problem hiding this comment.
Oh right. Add a comment that it's not really recursing into the scalar, but the value, so one should overwrite visit_value if they want to not recurse into this case
RalfJung
commented
Nov 2, 2018
I added the iterator-based |
Uh oh!
There was an error while loading. Please reload this page.
RalfJung
commented
Nov 2, 2018
My plan is to ask for perf once #55316 lands, so that we can see just the impact of this refactor. |
09e4551 to
7f93557CompareRalfJung
commented
Nov 2, 2018
Rebased onto master; now this PR can stand for itself. |
RalfJung
commented
Nov 2, 2018
@bors try |
bors
commented
Nov 2, 2018
Value visitors for miri Generalize the traversal part of validation to a `ValueVisitor`. ~~This includes #55316, [click here](RalfJung/rust@retagging...RalfJung:miri-visitor) for just the new commits.~~ This PR does not change the interface to miri, so I use the opportunity to update miri.
bors
commented
Nov 2, 2018
☀️ Test successful - status-travis |
oli-obk
commented
Nov 2, 2018
@rust-timer build 5f8bd0a |
rust-timer
commented
Nov 2, 2018
Success: Queued 5f8bd0a with parent e53a5ff, comparison URL. |
| ScalarMaybeUndef::Scalar(Scalar::Bits { bits, .. }) => | ||
| bits.to_string(), | ||
| struct ValidityVisitor<'rt, 'a: 'rt, 'mir: 'rt, 'tcx: 'a+'rt+'mir, M: Machine<'a, 'mir, 'tcx>+'rt> { | ||
| /// The `path` may be pushed to, but the part that is present when a function |
There was a problem hiding this comment.
we really need to start using the im crate in the compiler
Uh oh!
There was an error while loading. Please reload this page.
This comment has been minimized.
This comment has been minimized.
rust-timer
commented
Nov 6, 2018
Finished benchmarking try commit 5f8bd0a |
RalfJung
commented
Nov 6, 2018
Seems like something went wrong? There is no benchmark data. Cc @rust-lang/infra Maybe we should just try again. |
bors
commented
Nov 6, 2018
⌛ Trying commit 3538532cb617bcb6c97e304459c2135a5e2240b9 with merge ad5b1b390d95a7a68786df120aefae5118043810... |
kennytm
commented
Nov 6, 2018
@RalfJung the parent commit e53a5ff is still being benchmarked (see https://perf.rust-lang.org/status.html). There's no need to retry. |
RalfJung
commented
Nov 6, 2018
Oh, so the bot was just wrong telling me that everything is done? Curious. |
kennytm
commented
Nov 6, 2018
bors
commented
Nov 6, 2018
☀️ Test successful - status-travis |
RalfJung
commented
Nov 6, 2018
Some small losses, some small gains... @oli-obk seems acceptable? |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
oli-obk
commented
Nov 6, 2018
@bors r+ |
bors
commented
Nov 6, 2018
📌 Commit 7b7c6ce has been approved by |
bors
commented
Nov 7, 2018
Value visitors for miri Generalize the traversal part of validation to a `ValueVisitor`. ~~This includes #55316, [click here](RalfJung/rust@retagging...RalfJung:miri-visitor) for just the new commits.~~
bors
commented
Nov 7, 2018
☀️ Test successful - status-appveyor, status-travis |
Add escape-to-raw MIR statement Add a new MIR "ghost state statement": Escaping a ptr to permit raw accesses. ~~This includes #55549, [click here](RalfJung/rust@miri-visitor...RalfJung:escape-to-raw) for just the new commits.~~
Generalize the traversal part of validation to a
ValueVisitor.This includes #55316, click here for just the new commits.