Skip to content
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

Clippy pointer cast lint experiment #75098

Merged
merged 23 commits into from
Aug 11, 2020

Conversation

Ryan1729
Copy link
Contributor

@Ryan1729 Ryan1729 commented Aug 3, 2020

This PR is an experiment about exposing more parts of rustc_typeck for use in clippy. In particular, the code that checks where a cast is valid or not was exposed, which necessitated exposing FnCtxt, and figuring out how to create an instance of that type inside clippy.

This was prompted by this clippy issue.

r? @oli-obk

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @oli-obk (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 3, 2020
.ok()
// do_check's documentation says that it might return Ok and create
// errors in the fcx instead of returing Err in some cases.
.filter(|_| !fn_ctxt.errors_reported_since_creation())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems bad... won't we start emitting errors for weird transmutes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My intention was that if errors happened, we would return None. As far as I understand, that filter achieves that since I negated the boolean. So if error happen in the FnCtxt, this code should be treating it the same as an Err result, unless I've missed something.

I assumed that if any errors happened in the FnCtxt, some other check, probably from rustc itself, would catch the problem and report it. Does that seem like a reasonable assumption, and does that fit with your expectations?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My worry is that the errors have already been emitted. I haven't checked how errors could be emitted, so... I guess look for these errors and try to use the arguments on which they'd error for a cast on a transmute and see how the tests fare.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of all the functions called from inside do_check, check_ref_cast is the one that most clearly has a case where errors are emitted. This is because it calls demand_eqtype which clearly can emit an error.

The following functions clearly do not emit errors:

  • CheckCast::check_ptr_ptr_cast
  • CheckCast::check_ptr_addr_cast
  • CheckCast::check_addr_ptr_cast
  • CheckCast::check_fptr_ptr_cast

I haven't confirmed whether or not the other functions called in do_check emit errors though.

I also had a look at the commit the introduced do_check and the doc comment on it I mentioned above, and check_ref_cast was already called within do_check at that time, so I suspect that is what the doc comment originally referred to.

So, my next step is to add code to the tests that triggers demand_eqtype to emit an error, and see what happens.

Copy link
Contributor Author

@Ryan1729 Ryan1729 Aug 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried adding a dbg! call into demand_eqtype so that if the error case was called, the tests would definitely fail, (due to the extra stdout output.) That way, we would know that the new tests would actually hit that case, so we would know whether or not we got an extra error message.

The existing tests for the new lint did not hit that case, but from looking at the code leading from do_check to demand_eqtype, it seems like a transmute from an array reference to a pointer to a different type should trigger the lint to call do_check in a way that should trigger it. For example, &[i32; 1] to *const u8. So I added such a transmute to the tests, but I got an error from a different transmute lint.

While the other lint seems to prevent any issues at the moment, if that lint, or the ordering was changed in the future that could lead to a surprising bug, so it seems prudent to understand whether the do_check call will cause an extra error or not.

So, I temporarily placed the new lint at the top of the big match inside the check_expr implementation inside transmute.rs. Doing that lead to an ICE with the following error message:

thread 'rustc' panicked at 'assertion failed: self.find(parent).map_or(false, |n| is_body_owner(n, hir_id))', src/librustc_middle/hir/map/mod.rs:352:9

So without digging into what the failed assert means exactly, I would guess that something is wrong with the way that the FnCtxt was created inside clippy in this PR. But I'm not really sure. Does anyone else have more context around what that assert failing suggests?

(In case anyone cares, here's a link to the commit that had the ICE, on a different branch)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but I got an error from a different transmute lint.

If that other lint is allowed, would the error occur? Or is it part of this big match, so we never reach your new lint if the other lint is emitted? I'd be fine to just leave sufficient comments (and add a test that will fail horribly if the order is changed).

Copy link
Contributor Author

@Ryan1729 Ryan1729 Aug 6, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it part of this big match, so we never reach your new lint if the other lint is emitted?

That is the case.

Some other tests were already failing whenever I observed the ICE, but better safe than sorry. I've added a the transmute from &[i32; 1] to *const u8 case to the lint-specific test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok great! I think you can now just make this an assert instead of filtering

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. I added a not about the panics to the comments too. All that is in this commit

@oli-obk
Copy link
Contributor

oli-obk commented Aug 6, 2020

@rust-lang/clippy we're doing a clippy PR against rustc, because it also requires rustc changes. Now that the rustc changes work, we could also split it and move the clippy changes to a clippy PR, or we review it here and then sync afterwards. Opinions?

@Ryan1729 please rebase and ensure that none of your commits contain submodule changes

@Ryan1729 Ryan1729 force-pushed the clippy-pointer-cast-lint-experiment branch from 421434a to 5447247 Compare August 6, 2020 10:24
// fall through into `do_check`.
fn trigger_do_check_to_emit_error(in_param: &[i32; 1]) -> *const u8 {
unsafe { transmute::<&[i32; 1], *const u8>(in_param) }
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing a newline at the end of the file

@oli-obk
Copy link
Contributor

oli-obk commented Aug 6, 2020

You need to run ./x.py fmt before CI even starts building the PR

This seemed to overdo it a bit, affecting multiple submodules, and changing a file I didn't touch, so I didn't commit those changes
@flip1995
Copy link
Member

flip1995 commented Aug 6, 2020

I can review the Clippy changes in this PR and we can sync afterwards. I don't think it is worth to go back and forth with syncs for changes that affect rustc and clippy (to avoid this we switched to subtree in the first place)

@Ryan1729
Copy link
Contributor Author

Ryan1729 commented Aug 8, 2020

Here’s a snippet from the bottom of the raw log linked above that suggests the failure was caused by a network issue.

2020-08-07T17:55:39.4818196Z Caused by:
2020-08-07T17:55:39.4818413Z   failed to get 200 response from `https://crates.io/api/v1/crates/maplit/1.0.1/download`, got 502

@oli-obk
Copy link
Contributor

oli-obk commented Aug 8, 2020

@bors retry

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 8, 2020
@bors
Copy link
Contributor

bors commented Aug 8, 2020

⌛ Testing commit c04c4cb with merge d72af5f4695cbd0c3d565eb53c4cdb50a5370e6b...

@bors
Copy link
Contributor

bors commented Aug 8, 2020

💔 Test failed - checks-actions

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Aug 8, 2020
@oli-obk
Copy link
Contributor

oli-obk commented Aug 8, 2020

clippy's stderr files need updating again, you may need to rebase first

@Ryan1729
Copy link
Contributor Author

Ryan1729 commented Aug 9, 2020

After several small changes, this is passing again, locally.

Two changes are most notable:
The fixed code wasn't compiling because I was getting a warning about use std::mem::transmute being unused after the fixes removed all calls to it. I noticed then that a situation where no suggestion should happen was not part of the tests. So I added a new test that containing a transmute call that should not and does not get removed by the fixer.

The other notable change was that I changed the use of -1isize in the new tests to usize::MAX since otherwise the fixed version resulted in -1 as *const i32 which does not compile since the 1 ia inferred to be a usize. I couldn't find an easy way to change the suggestion to include the type suffix, so since actually wanting to use a unary minus to write a number to be cast as a pointer seems rather niche, (I only used -1 here so if something went wrong it would be obvious), I just changed the type to be a usize and kept the same value.

@oli-obk
Copy link
Contributor

oli-obk commented Aug 10, 2020

@bors r+

@bors
Copy link
Contributor

bors commented Aug 10, 2020

📌 Commit d2e7293 has been approved by oli-obk

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 10, 2020
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 11, 2020
Rollup of 10 pull requests

Successful merges:

 - rust-lang#75098 (Clippy pointer cast lint experiment)
 - rust-lang#75249 (Only add a border for the rust logo)
 - rust-lang#75315 (Avoid deleting temporary files on error)
 - rust-lang#75316 (Don't try to use wasm intrinsics on vectors)
 - rust-lang#75337 (instance: only polymorphize upvar substs)
 - rust-lang#75339 (evaluate required_consts when pushing stack frame in Miri engine)
 - rust-lang#75363 (Use existing `infcx` when emitting trait impl diagnostic)
 - rust-lang#75366 (Add help button)
 - rust-lang#75369 (Move to intra-doc links in /library/core/src/borrow.rs)
 - rust-lang#75379 (Use intra-doc links in /library/core/src/cmp.rs)

Failed merges:

r? @ghost
@bors bors merged commit 63d1e37 into rust-lang:master Aug 11, 2020
bors added a commit to rust-lang/rust-clippy that referenced this pull request Aug 11, 2020
flip1995 pushed a commit to flip1995/rust that referenced this pull request Aug 11, 2020
…xperiment, r=oli-obk

Clippy pointer cast lint experiment

This PR is an experiment about exposing more parts of `rustc_typeck` for use in `clippy`. In particular, the code that checks where a cast is valid or not was exposed, which necessitated exposing [`FnCtxt`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/check/struct.FnCtxt.html), and figuring out how to create an instance of that type inside `clippy`.

This was prompted by [this clippy issue](rust-lang/rust-clippy#2064).

r? @oli-obk
@flip1995 flip1995 mentioned this pull request Aug 11, 2020
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 12, 2020
Update Clippy

Biweekly Clippy update (2 days late, since I wanted to wait for rust-lang#75098)

r? @Manishearth
flip1995 pushed a commit to flip1995/rust-clippy that referenced this pull request Aug 12, 2020
Update Clippy

Biweekly Clippy update (2 days late, since I wanted to wait for rust-lang/rust#75098)

r? @Manishearth
@cuviper cuviper added this to the 1.47.0 milestone May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants