-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
accept String
in span_lint*
functions directly to avoid unnecessary clones
#12453
Conversation
(To be fair, I don't think an unnecessary clone is going to make any noticeable difference on the |
☔ The latest upstream changes (presumably #12445) made this pull request unmergeable. Please resolve the merge conflicts. |
I'll wait with fixing conflicts since there will be many more. About this:
It looks like the span_bug I ran into (here) was added in rust-lang/rust#121382. @nnethercote since you created that PR, do you think that it'd make sense to add a way to "allow" it in some way? I'm not too sure what exactly it's asserting, but it seems somewhat specific to rustc and translatable diagnostics, which clippy doesn't have anyway |
FWIW, the compiler isn't ICEing (i.e. crashing due to a bug), rather a compiler-internal lint is giving an error. There's no fundamental reason for the restriction on the number of |
I'm thinking that having our own trait for things that can be turned into diagnostic messages wouldn't be so bad of an idea anyway (like it currently does as a workaround), since it allows us to implement it for other clippy-specific types (which normally wouldn't work b/c of orphan rules). For example, we could implement it for the |
Oh wait no, we should totally be able to |
The internal diagnostic lint currently only allows one, because that was all that occurred in practice. But rust-lang/rust-clippy/pull/12453 wants to introduce functions with more than one, and this limitation is getting in the way.
My mistake, it is an ICE.
Done in rust-lang/rust/pull/122315. |
Nice, thanks for getting to it so quickly! |
The internal diagnostic lint currently only allows one, because that was all that occurred in practice. But rust-lang/rust-clippy/pull/12453 wants to introduce functions with more than one, and this limitation is getting in the way.
…sage, r=Nilstrieb Allow multiple `impl Into<{D,Subd}iagMessage>` parameters in a function. The internal diagnostic lint currently only allows one, because that was all that occurred in practice. But rust-lang/rust-clippy/pull/12453 wants to introduce functions with more than one, and this limitation is getting in the way. r? `@Nilstrieb`
Rollup merge of rust-lang#122315 - nnethercote:multiple-into-diag-message, r=Nilstrieb Allow multiple `impl Into<{D,Subd}iagMessage>` parameters in a function. The internal diagnostic lint currently only allows one, because that was all that occurred in practice. But rust-lang/rust-clippy/pull/12453 wants to introduce functions with more than one, and this limitation is getting in the way. r? `@Nilstrieb`
@y21 Meow meow, meow I think that the wisest course of action now would be to wait until the sync, and then undo the workaround (it isn't necessary anymore thanks to nnethercote's fix) |
…ilstrieb Allow multiple `impl Into<{D,Subd}iagMessage>` parameters in a function. The internal diagnostic lint currently only allows one, because that was all that occurred in practice. But rust-lang/rust-clippy/pull/12453 wants to introduce functions with more than one, and this limitation is getting in the way. r? `@Nilstrieb`
fwiw, this might have a bigger impact than would first seem (haven't done a benchmark tho). It doesn't do anything else before checking the lint level, so is definitely pretty good for that case. |
I'll do a benchmark soon, maybe this is even better than expected! |
Okis, the sync has been done today =^w^= |
5bebbf3
to
9fc88bc
Compare
Alright, I removed the workaround. The functions now accept the real |
I'll benchmark this PR right now (from the server, while working on other issues) |
It probably makes sense to run the benchmark on a crate/crates that emit a lot of lints. Maybe the Even in such an extreme case with 250k diagnostics though, with a "guess" that an allocation takes maybe 20ns, that would still be 5 milliseconds, which I'm not sure if that's noticeable. |
I would be very skeptical of that guess since allocating on the heap is usually thousands of instructions, is it not? (and a disassembler does show this, even with the system allocator). There's a lot involved, even just in the kernel (excluding any tricks the allocator does - idk if clippy uses the default [system] global allocator, unlike rustc) A single cycle should be ~0.4ns for me excluding any other factors, so e.g., fetching from RAM, caching instructions, failed branch prediction, etc..., But regardless, this has absolutely been discussed many times before. A simple benchmark does take <20ns (sometimes 5ns with jemalloc) but I don't think that's applicable in practice. It wouldn't need to search for long to find free memory for instance, or maybe it takes a different branch in that case. Who knows, really |
|
I've been trying to benchmark this for days. It's ridiculous how much a patch can resist to being benchmarked. |
Yea, fair points. I realize now that the number could be totally wrong so I take that part of my message back. I guess real benchmarks are the only source of truth we can trust :) |
Okis, the benchmarks are finally done. Yeah, it has some small improvements. |
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, thanks! ❤️
clippy_utils/src/diagnostics.rs
Outdated
)* | ||
} | ||
} | ||
impl_into_message!(&'static str, String, std::borrow::Cow<'static, str>); |
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.
impl_into_message!(&'static str, String, std::borrow::Cow<'static, str>); | |
impl_into_message![ | |
&'static str, | |
String, | |
std::borrow::Cow<'static, str> | |
]; |
@bors r+ |
accept `String` in `span_lint*` functions directly to avoid unnecessary clones context: https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Accepting.20.60Into.3C.7BSub.7DdiagMessage.3E.60.20in.20.60span_lint*.60.20functions/near/425703273 tldr: the `span_lint*` functions now accept both `String`s, which are then reused and not recloned like before, and also `&'static str`, in which case it [doesn't need to allocate](https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_error_messages/lib.rs.html#359). Previously, it accepted `&str` and would always call `.to_string()`, which is worse in any case: it allocates for `&'static str` and forces a clone even if the caller already has a `String`. --------- This PR has a massive diff, but the only interesting change is in the first commit, which changes the message/help/note parameter in the `span_lint*` functions to not take a `&str`, but an `impl Into<DiagMessage>`. The second commit changes all of the errors that now occur: - `&format!(...)` cannot be passed to `span_lint` anymore. Instead, we now simply pass `format!()` directly. - `Into<DiagMessage>` can be `&'static str`, but not any `&str`. So this requires changing a bunch of other `&str` to `&'static str` at call sites as well. - Added [`Sugg::into_string`](https://github.com/y21/rust-clippy/blob/9fc88bc2851fbb287d89f65b78fb67af504f8362/clippy_utils/src/sugg.rs#L362), which, as opposed to `Sugg::to_string`, can take advantage of the fact that it takes ownership and is able to reuse the `String` changelog: none
💔 Test failed - checks-action_dev_test |
9fc88bc
to
a6881b0
Compare
Looks like the |
@bors retry |
?? |
accept `String` in `span_lint*` functions directly to avoid unnecessary clones context: https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Accepting.20.60Into.3C.7BSub.7DdiagMessage.3E.60.20in.20.60span_lint*.60.20functions/near/425703273 tldr: the `span_lint*` functions now accept both `String`s, which are then reused and not recloned like before, and also `&'static str`, in which case it [doesn't need to allocate](https://doc.rust-lang.org/nightly/nightly-rustc/src/rustc_error_messages/lib.rs.html#359). Previously, it accepted `&str` and would always call `.to_string()`, which is worse in any case: it allocates for `&'static str` and forces a clone even if the caller already has a `String`. --------- This PR has a massive diff, but the only interesting change is in the first commit, which changes the message/help/note parameter in the `span_lint*` functions to not take a `&str`, but an `impl Into<DiagMessage>`. The second commit changes all of the errors that now occur: - `&format!(...)` cannot be passed to `span_lint` anymore. Instead, we now simply pass `format!()` directly. - `Into<DiagMessage>` can be `&'static str`, but not any `&str`. So this requires changing a bunch of other `&str` to `&'static str` at call sites as well. - Added [`Sugg::into_string`](https://github.com/y21/rust-clippy/blob/9fc88bc2851fbb287d89f65b78fb67af504f8362/clippy_utils/src/sugg.rs#L362), which, as opposed to `Sugg::to_string`, can take advantage of the fact that it takes ownership and is able to reuse the `String` changelog: none
💔 Test failed - checks-action_dev_test |
Oh I thought you fixed it in the latest push 😅 |
oh well, another lint was changed to use |
@bors r+ |
☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test |
context: https://rust-lang.zulipchat.com/#narrow/stream/257328-clippy/topic/Accepting.20.60Into.3C.7BSub.7DdiagMessage.3E.60.20in.20.60span_lint*.60.20functions/near/425703273
tldr: the
span_lint*
functions now accept bothString
s, which are then reused and not recloned like before, and also&'static str
, in which case it doesn't need to allocate.Previously, it accepted
&str
and would always call.to_string()
, which is worse in any case: it allocates for&'static str
and forces a clone even if the caller already has aString
.This PR has a massive diff, but the only interesting change is in the first commit, which changes the message/help/note parameter in the
span_lint*
functions to not take a&str
, but animpl Into<DiagMessage>
.The second commit changes all of the errors that now occur:
&format!(...)
cannot be passed tospan_lint
anymore. Instead, we now simply passformat!()
directly.Into<DiagMessage>
can be&'static str
, but not any&str
. So this requires changing a bunch of other&str
to&'static str
at call sites as well.Sugg::into_string
, which, as opposed toSugg::to_string
, can take advantage of the fact that it takes ownership and is able to reuse theString
changelog: none