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

[WIP] Also lint Box::new in unused_allocation #97774

Closed
wants to merge 4 commits into from

Conversation

est31
Copy link
Member

@est31 est31 commented Jun 6, 2022

Previously, only box syntax uses would yield in the unused_allocation lint issuing warnings. Now, equivalent unnecessary usage of Box::new also gives a warning. Furthermore, this PR adds a test of the unused_allocation lint which was previously never tested anywhere in the test suite.

With the changes from this pr, this snippet

fn main() {
    let foo = Box::new([1, 2, 3]).len(); //~ ERROR: unnecessary allocation
}

gives

error: unnecessary allocation, use `&` instead
  --> $DIR/unused-allocation.rs:
   |
LL |     let foo = Box::new([1, 2, 3]).len();
   |               ^^^^^^^^

Just like how it lints for the equivalent snippet just with box instead of Box::new.

@rustbot rustbot added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jun 6, 2022
@rust-highfive
Copy link
Collaborator

Hey! It looks like you've submitted a new PR for the library teams!

If this PR contains changes to any rust-lang/rust public library APIs then please comment with r? rust-lang/libs-api @rustbot label +T-libs-api -T-libs to request review from a libs-api team reviewer. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.

Examples of T-libs-api changes:

  • Stabilizing library features
  • Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
  • Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
  • Changing public documentation in ways that create new stability guarantees
  • Changing observable runtime behavior of library APIs

@rust-highfive
Copy link
Collaborator

r? @petrochenkov

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 6, 2022
@rust-log-analyzer

This comment has been minimized.

@est31 est31 force-pushed the unused_allocation_box_new branch 2 times, most recently from 610c923 to 7b94b07 Compare June 6, 2022 01:23
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@est31 est31 force-pushed the unused_allocation_box_new branch from 4423499 to 009228c Compare June 6, 2022 02:23
@est31
Copy link
Member Author

est31 commented Jun 6, 2022

I'm wondering about the last commit, which changed assert!(a == Box::new(8)) into assert!(*a == 8). I'm not sure about the quality of the lint here, because it still suggested adding a & (it suggests & unconditionally). In most cases, it's the right advice, but in this, it's the wrong one, as assert!(a == &8) does not work.

Fundamentally the issue already exists, with & being suggested for assert!(a == box 8):

error: unnecessary allocation, use `&` instead
 --> src/main.rs:6:18
  |
6 |     assert!(a == box 8);
  |                  ^^^^^
  |

But that affects a nightly feature so it does not need to be as polished.

I wonder if the lint needs further improvements before it can be extended to Box::new.

Especially I wonder: a) does the *a trick work all the time? Maybe box/deref patterns are needed? and b) Can you somehow recognize cases where *a should be suggested instead? Is == the only place the issue occurs or are there other places too?

@@ -273,6 +273,7 @@ language_item_table! {
EhCatchTypeinfo, sym::eh_catch_typeinfo, eh_catch_typeinfo, Target::Static, GenericRequirement::None;

OwnedBox, sym::owned_box, owned_box, Target::Struct, GenericRequirement::Minimum(1);
OwnedBoxNew, sym::owned_box_new, owned_box_new, Target::Method(MethodKind::Inherent), GenericRequirement::None;
Copy link
Contributor

Choose a reason for hiding this comment

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

Making it a diagnostic item instead of a lang item would be preferable in this case.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've been planning, as a followup to this PR, to also use this for the #[rustc_box] feature. Right now, #[rustc_box] foobar(foo) is lowered to box foo, irrespective of what foobar is, even if it isn't Box::new. In order to make it error if it's not Box::new, I would be needing something that gives me a def id i suppose. Is a diagnostic item a good choice for such an error as well?

To explain, in a box_syntax free world, some users might still want to use #[rustc_box] over Box::new and they should get a more polished feature.

Copy link
Contributor

Choose a reason for hiding this comment

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

Right now, #[rustc_box] foobar(foo) is lowered to box foo, irrespective of what foobar is, even if it isn't Box::new.

Which seems fine to me, given that #[rustc_box] is an internal feature that is supposed to be removed in the future.

free world, some users might still want to use #[rustc_box] over Box::new and they should get a more polished feature.

If it's supposed to be used by people and be polished, then perhaps it needs a better syntax than #[rustc_box] Box::new(expr), for example box expr, oh wait.

Copy link
Contributor

@petrochenkov petrochenkov Jun 6, 2022

Choose a reason for hiding this comment

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

I didn't follow the story behind #97293 but the state in which you need to write #[rustc_box] Box::new(expr) instead of just Box::new(expr) or box expr (*) seems like the worse from both worlds.

(*) Preferably the former, because whatever made Box::new(expr) slow in #97293 can also make other much more common things like Vec::from()/String::from() slow, so it may be a good win if it's fixed.

Copy link
Member Author

Choose a reason for hiding this comment

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

Box::new(foo) is not slow in most of cases, thanks to LLVM being really good, especially post version 12 (minimum LLVM is 12 now). The issue is just that switching vec![] to Box::new would also switch it for the remaining few cases where it does cause regressions. For these, the PR added #[rustc_box] as an alternative to box foo. My ultimate goal is to remove box foo support from the compiler, this PR is another preparation of it. Eventually this will need a lang team FCP and a "go forward" from them. Anyways, the general future of box syntax is not discussed here but in the tracking issue (still need to make a proposal there).

It might be better if instead of doing empty promises, I add the lang item in a separate PR first that actually needs it, and then switch this PR to it.

compiler/rustc_lint/src/unused.rs Outdated Show resolved Hide resolved
@petrochenkov
Copy link
Contributor

I wonder if the lint needs further improvements before it can be extended to Box::new.

No opinion on this, for that you can try finding some other reviewer who cares more about this case.
@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 6, 2022
@est31 est31 force-pushed the unused_allocation_box_new branch from 009228c to 9500150 Compare June 6, 2022 15:39
@est31 est31 changed the title Also lint Box::new in unused_allocation [WIP] Also lint Box::new in unused_allocation Jun 7, 2022
@est31
Copy link
Member Author

est31 commented Jun 14, 2022

I've marked this as WIP because of: #97774 (comment)

Ideally I'd convert this into a hard error (temporarily for the experiment), run a crater run, and then see what the lint complains about and how many of those cases are not beautiful complaints.

@bors
Copy link
Contributor

bors commented Jul 3, 2022

☔ The latest upstream changes (presumably #98673) made this pull request unmergeable. Please resolve the merge conflicts.

Previously, only (box foo).something() would be linted,
wher something takes &self or &mut self. Now, we also
lint for Box::new(foo).something().
Before the unused_allocation lint has never been tested
outside of its lint documentation.
@rustbot
Copy link
Collaborator

rustbot commented Aug 10, 2022

Hey! It looks like you've submitted a new PR for the library teams!

If this PR contains changes to any rust-lang/rust public library APIs then please comment with @rustbot label +T-libs-api -T-libs to tag it appropriately. If this PR contains changes to any unstable APIs please edit the PR description to add a link to the relevant API Change Proposal or create one if you haven't already. If you're unsure where your change falls no worries, just leave it as is and the reviewer will take a look and make a decision to forward on if necessary.

Examples of T-libs-api changes:

  • Stabilizing library features
  • Introducing insta-stable changes such as new implementations of existing stable traits on existing stable types
  • Introducing new or changing existing unstable library APIs (excluding permanently unstable features / features without a tracking issue)
  • Changing public documentation in ways that create new stability guarantees
  • Changing observable runtime behavior of library APIs

@rust-log-analyzer
Copy link
Collaborator

The job mingw-check failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
    Checking alloc v0.0.0 (/checkout/library/alloc)
    Checking cfg-if v0.1.10
    Checking adler v0.2.3
    Checking rustc-demangle v0.1.21
error[E0522]: definition of an unknown language item: `owned_box_new`
    |
    |
210 |     #[lang = "owned_box_new"]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ definition of unknown language item `owned_box_new`
For more information about this error, try `rustc --explain E0522`.
error: could not compile `alloc` due to previous error
Build completed unsuccessfully in 0:01:17

@bors
Copy link
Contributor

bors commented Oct 1, 2022

☔ The latest upstream changes (presumably #101986) made this pull request unmergeable. Please resolve the merge conflicts.

@JohnCSimon
Copy link
Member

@est31
Ping from triage: I'm closing this due to inactivity, Please reopen when you are ready to continue with this.
Note: if you do please open the PR BEFORE you push to it, else you won't be able to reopen - this is a quirk of github.
Thanks for your contribution.

@rustbot label: +S-inactive

@JohnCSimon JohnCSimon closed this Nov 6, 2022
@rustbot rustbot added the S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. label Nov 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-inactive Status: Inactive and waiting on the author. This is often applied to closed PRs. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants