-
Notifications
You must be signed in to change notification settings - Fork 242
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
analyze: add NON_NULL rewrites #1095
Conversation
I realized while writing the PR that I never tested field projections ( |
4776e2e
to
7b13770
Compare
Left a couple of comments. This is a large PR, it will take me a while to get through. |
for (i, mir_rw) in mir_rws.iter().enumerate() { | ||
match mir_rw.rw { | ||
// Bail out if we see nested delimiters. | ||
mir_op::RewriteKind::OptionMapBegin => return None, |
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.
Should we log this, somewhere in the call chain? It might be useful for users to know that this case is not supported, and where it occurs.
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.
Added some clarification to the comment in ff20263. Bailing out here is not a hard error - it is legal, but suboptimal, to rewrite OptionMapBegin
as p
-> p.unwrap()
. Also, currently mir_op
should never generate rewrites that trigger this.
|
||
mir_op::RewriteKind::OptionMapBegin => { | ||
// `p` -> `p.unwrap()` | ||
Rewrite::MethodCall("unwrap /*map_begin*/".to_string(), Box::new(hir_rw), vec![]) |
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.
Is this a TODO?
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.
I initially added the /*map_begin*/
comment for debugging, and I think it's actually useful to leave it in place to help us catch any cases where the Option::map
rewrite is not working properly.
We previously used the syntax `[[[var]] ..]`, which should expand to `[value ..]`, but FileCheck-7 parses the first part as `[[ [var ]]` and reports a syntax error.
ff20263
to
8aa58bf
Compare
8aa58bf
to
73652be
Compare
@ahomescu I've addressed all the previous feedback - any objections to merging this now? |
This branch implements rewriting of nullable pointers (those lacking
PermissionSet::NON_NULL
) toOption
. This includes the following kinds of rewrites:Option<&mut T>
instead of&mut T
p.unwrap()
andSome(p)
. For most permissions, we implement only one direction because the other is invalid/nonsensical, but here we implement both in order to support "unsound" rewrites involving overriddenNON_NULL
flags (as in analyze: allow overriding dataflow for specific permissions #1088).p: Option<&mut T>
, we usep.as_deref_mut().unwrap()
instead ofp.unwrap()
to avoid consuming the originalp
. (In the code, this is called a "downgrade", since it allows borrowingOption<Box<T>>
asOption<&T>
and similar.)NON_NULL
pointers would use&p[0]
, nullable ones usep.map(|ptr| &ptr[0])
. Internally, this is represented similar toSome(&p.unwrap()[0])
, but it's handled specially byrewrite::expr::convert
to produce amap
call instead, which passes throughNone
without a panic.unwrap()
calls on derefs.*p
is rewritten to*p.unwrap()
, or to*p.as_deref().unwrap()
if a downgrade/borrow is necessary to avoid movingp
.ptr::null()
and0 as *const _
toNone
, andp.is_null()
top.is_none()
.The new
non_null_rewrites.rs
test case passes, and the rewritten code compiles.This might be easier to review commit-by-commit.