-
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
Treat safe target_feature functions as unsafe by default [less invasive variant] #134353
base: master
Are you sure you want to change the base?
Treat safe target_feature functions as unsafe by default [less invasive variant] #134353
Conversation
r? @chenyukang rustbot has assigned @chenyukang. Use |
Some changes occurred in src/tools/clippy cc @rust-lang/clippy |
if sig.target_feature { hir::Safety::Unsafe } else { hir::Safety::Safe }, | ||
&[], |
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.
This is a bit hacky, I'll add a comment
let Some(sig) = tcx.hir_node_by_def_id(did).fn_sig() else { | ||
tcx.dcx().span_delayed_bug(attr.span, "target_feature applied to non-fn"); | ||
continue; | ||
}; |
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.
This hides some follow-up errors when applying the attribute to items that shouldn't have it
// Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396). | ||
// Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396), | ||
// report a better error than a safety mismatch. | ||
// FIXME(target_feature): do this inside `coerce_from_safe_fn` |
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.
the fixme should say that this should be safe, as it can just be emulated by wrapping in a closure, and in contrast to normal unsafe fns, this can't be unsound as you're already executing code that is satisfying the target feature constraints
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.
hold up, is that true? are there maybe ways around this with TAITs or some other shenanigans that never actually execute the code at runtime, but obtain the closure anyway and then execute that
@@ -1112,7 +1120,11 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) { | |||
|
|||
let hir_id = tcx.local_def_id_to_hir_id(def); | |||
let safety_context = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| { | |||
if fn_sig.header.safety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe } | |||
if matches!(fn_sig.header.safety, Some(hir::Safety::Unsafe)) { |
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.
add a comment explaining why this is the way it is (target_feature is the reason, but explain the details)
| | ||
LL | let foo: fn() = foo as fn(); | ||
| ~~~~~~~~~~~ | ||
= note: unsafe functions cannot be coerced into safe function pointers |
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.
shuold probably avoid this note
@@ -26,6 +26,9 @@ LL | Quux.avx_bmi2(); | |||
error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block | |||
--> $DIR/safe-calls.rs:38:5 | |||
| | |||
LL | fn bar() { | |||
| -------- items do not inherit unsafety from separate enclosing items |
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.
lol what, look into this
= note: expected signature `fn(&Bar)` | ||
found signature `unsafe fn(&Bar)` |
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.
this is still wrong... why are we repeating the same logic in 50 3 places... go fix this
This comment has been minimized.
This comment has been minimized.
9bd90ce
to
273c6c5
Compare
…ler-errors Handle fndef rendering together with signature rendering Pulled out of rust-lang#134353 Changes some highlighting in type mismatch errors around fndefs
…ler-errors Handle fndef rendering together with signature rendering Pulled out of rust-lang#134353 Changes some highlighting in type mismatch errors around fndefs
…ler-errors Handle fndef rendering together with signature rendering Pulled out of rust-lang#134353 Changes some highlighting in type mismatch errors around fndefs
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.
This is the less (imo) invasive variant of #134317, as it doesn't require changing the Safety enum, so it only affects FnDefs and nothing else, as it should.
TODO before landing:
Option<Safety>
hack with a proper enum around that.