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

Treat safe target_feature functions as unsafe by default #134317

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented Dec 14, 2024

This unblocks

As I stated in #134090 (comment) I think the previous impl was too easy to get wrong, as by default it treated safe target feature functions as safe and had to add additional checks for when they weren't. Now the logic is inverted. By default they are unsafe and you have to explicitly handle safe target feature functions.

I will make another version of this PR that doesn't modify the safety enum but just checks the attrs. Should be less invasive

@rustbot
Copy link
Collaborator

rustbot commented Dec 14, 2024

r? @BoxyUwU

rustbot has assigned @BoxyUwU.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added A-rustdoc-json Area: Rustdoc JSON backend S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Dec 14, 2024
@rustbot
Copy link
Collaborator

rustbot commented Dec 14, 2024

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

Some changes occurred to the CTFE machinery

cc @rust-lang/wg-const-eval

if b_hdr.safety == hir::Safety::Safe
&& !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
if b_hdr.safety.is_safe()
&& matches!(a_sig.safety(), hir::Safety::Unsafe { target_feature: true })
Copy link
Contributor

Choose a reason for hiding this comment

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

As mentioned in #134090 (comment), we might want to make this actually safe if the function this happens in has the required features.
We probably shouldn't change it now, but we might want to modify the comment/FIXME accordingly

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If the features are also set via target information that can't differ between crates linked together?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if doing so is supposed to be ok...

Anyway, I guess the point of the comment is that if you can call a function, then you also ought to be able to take a safe fn pointer to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But safe pointers can be passed around to code where it's not safe to use them.

With the change I made (plus encoding the actually used target features) we can in theory start creating safe target feature pointers by keeping the target feature information on the function pointer type.

Copy link
Contributor

Choose a reason for hiding this comment

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

target_feature_11 enables this:

#[target_feature(enable = "avx2")]
fn bar() -> fn() {
    || avx2()
}

which is not particularly different from allowing coercion of avx2 to a fn pointer. If you have concerns about this, the stabilization PR is probably the better place to discuss it (the stabilization report mentions why it's OK to do this)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh right, yea that makes sense. You already had to call an unsafe function to get here, and it's not a footgun, because it's global informatiom, not local

@@ -2521,8 +2521,14 @@ impl<'tcx> TyCtxt<'tcx> {
/// that is, a `fn` type that is equivalent in every way for being
/// unsafe.
pub fn safe_to_unsafe_fn_ty(self, sig: PolyFnSig<'tcx>) -> Ty<'tcx> {
assert_eq!(sig.safety(), hir::Safety::Safe);
Ty::new_fn_ptr(self, sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Unsafe, ..sig }))
matches!(sig.safety(), hir::Safety::Safe | hir::Safety::Unsafe { target_feature: true });
Copy link
Contributor

Choose a reason for hiding this comment

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

Didn't this drop an assertion?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh huh

@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)
   |                 ^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
   |
help: the struct variant's field is being ignored
   |
36 |         (false, Safety::Unsafe { target_feature: _ }) => span_lint(

    Checking crossbeam-channel v0.5.13
error[E0533]: expected unit struct, unit variant or constant, found struct variant `Safety::Unsafe`
   --> src/tools/clippy/clippy_lints/src/doc/mod.rs:634:33
   --> src/tools/clippy/clippy_lints/src/doc/mod.rs:634:33
    |
634 |                         (false, Safety::Unsafe) => span_lint(
    |                                 ^^^^^^^^^^^^^^ not a unit struct, unit variant or constant
    |
help: the struct variant's field is being ignored
    |
634 |                         (false, Safety::Unsafe { target_feature: _ }) => span_lint(

    Checking quote v1.0.37
    Checking parking_lot_core v0.9.10
    Checking rustfix v0.8.1

@oli-obk oli-obk added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Dec 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rustdoc-json Area: Rustdoc JSON backend S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants