1
Fork 0

Rollup merge of #135504 - veluca93:target-feature-cast-to-fn-ptr, r=oli-obk

Allow coercing safe-to-call target_feature functions to safe fn pointers

r? oli-obk

`@oli-obk:` this is based on your PR #134353 :-)

See https://github.com/rust-lang/rust/pull/134090#issuecomment-2539422624 for the motivation behind this change.
This commit is contained in:
Matthias Krüger 2025-01-16 18:46:09 +01:00 committed by GitHub
commit bbc6d16ad6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 114 additions and 23 deletions

View file

@ -60,7 +60,7 @@ use crate::dep_graph::{DepGraph, DepKindStruct};
use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos};
use crate::lint::lint_level;
use crate::metadata::ModChild;
use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
use crate::middle::codegen_fn_attrs::{CodegenFnAttrs, TargetFeature};
use crate::middle::{resolve_bound_vars, stability};
use crate::mir::interpret::{self, Allocation, ConstAllocation};
use crate::mir::{Body, Local, Place, PlaceElem, ProjectionKind, Promoted};
@ -1776,6 +1776,37 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn dcx(self) -> DiagCtxtHandle<'tcx> {
self.sess.dcx()
}
pub fn is_target_feature_call_safe(
self,
callee_features: &[TargetFeature],
body_features: &[TargetFeature],
) -> bool {
// If the called function has target features the calling function hasn't,
// the call requires `unsafe`. Don't check this on wasm
// targets, though. For more information on wasm see the
// is_like_wasm check in hir_analysis/src/collect.rs
self.sess.target.options.is_like_wasm
|| callee_features
.iter()
.all(|feature| body_features.iter().any(|f| f.name == feature.name))
}
/// Returns the safe version of the signature of the given function, if calling it
/// would be safe in the context of the given caller.
pub fn adjust_target_feature_sig(
self,
fun_def: DefId,
fun_sig: ty::Binder<'tcx, ty::FnSig<'tcx>>,
caller: DefId,
) -> Option<ty::Binder<'tcx, ty::FnSig<'tcx>>> {
let fun_features = &self.codegen_fn_attrs(fun_def).target_features;
let callee_features = &self.codegen_fn_attrs(caller).target_features;
if self.is_target_feature_call_safe(&fun_features, &callee_features) {
return Some(fun_sig.map_bound(|sig| ty::FnSig { safety: hir::Safety::Safe, ..sig }));
}
None
}
}
impl<'tcx> TyCtxtAt<'tcx> {