-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Lint #[inline(always)] closure in #[target_feature] functions #133408
Lint #[inline(always)] closure in #[target_feature] functions #133408
Conversation
This comment has been minimized.
This comment has been minimized.
I am in favor of this lint, but IMO it should get input from some other people as well, so let's r? compiler |
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.
In fact since this is a new lint, we'll need approval from @rust-lang/lang. @calebzulawski can you make the PR description a bit more self-contained so t-lang has the required context here?
&& !tcx.codegen_fn_attrs(owner_id).target_features.is_empty() | ||
{ | ||
if codegen_fn_attrs.inline == InlineAttr::Always { | ||
if let Some(inline_span) = inline_span { |
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.
What if we don't have the span? Something is still wrong, so we should still emit a lint -- it can point at the closure instead of the attribute, maybe?
Given the example at #69098 (comment), I am not sure if we still want to do this. |
Does If for some reason |
That seems like an entirely orthogonal question? I am very confused. |
I'm just suggesting that in this particular example, the closure's inlining might not actually matter, if the Fn trait is not |
@hanna-kruppe indicated that the attribute did help though.
|
Both the example in #96929 and the discussion there suggest to me that it’s a |
For the lang nomination, if someone could perhaps write up a short self-contained code example of this case, that would be helpful to us. |
@hanna-kruppe do you think this minimal example accurately represents your use case? |
Let's de-nominate for now, I am not sure we still want to go ahead with this lint. |
Broadly yes. It’s important that the intermediate non-target-feature function(s), For this specific example you probably want |
This is pretty contrived, but I put together an example that has both inline and non-inline closures: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=58d03317abd8b2fe151e6c8d0bbf2b8d I've written code that looks vaguely like this. I think outside of |
I'm not sure about this lint |
Yeah, I've been convinced we should close this in favor of clearly documenting the current rules for when target features are inherited by closures and when they are not. Those rules are surprising, but it is not clear that forbidding |
I agree. I don't think we want either type of closure to do anything differently, so the existing rules are probably the best we will get. I'm not totally sure where to document it, though. |
Make #108655 a future-incompatible lint as suggested in #69098 (comment)
r? @RalfJung
Some context:
In Rust today, closures don't inherit target features from their enclosing function. This behavior might be surprising to users. The
target_feature_11
feature changes this--otherwise, safe target feature 1.1 calls would still requireunsafe
within a closure.Rust does not allow
#[inline(always)]
to be applied to#[target_feature]
functions, so adding target features to closures causes errors in previously accepted code (#108655). Unfortunately, we can't simply allow both attributes for two reasons. First, it is possible for the closure to "escape" the function (e.g. an indirect call optimization) and attempt to inline into a function that doesn't have the target features, resulting in an ICE when inlining fails. Additionally, there are soundness concerns when combining#[inline(always)]
with#[target_feature]
, see #116573.This leaves us with a few options:
#[inline(always)]
is present. This is the currenttarget_feature_11
behavior. This allows any existing code to still work, but it is potentially confusing for#[inline]
to affect other codegen behavior.#[inline(always)]
on closures in#[target_feature]
functions in a future version of rust.