diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2025-01-16 18:46:09 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-16 18:46:09 +0100 |
| commit | bbc6d16ad6d6f5a644b04cf60a3ac90fb1f1ad7b (patch) | |
| tree | 491ecb455bfbafa876a8918071f97c53ed0b8d51 /compiler/rustc_middle/src | |
| parent | 4aae8d15d6cc95c13e3d8dfbda5212e7f547d920 (diff) | |
| parent | 8fee6a77394ffda819e58a648d4b44e1e566f34b (diff) | |
| download | rust-bbc6d16ad6d6f5a644b04cf60a3ac90fb1f1ad7b.tar.gz rust-bbc6d16ad6d6f5a644b04cf60a3ac90fb1f1ad7b.zip | |
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.
Diffstat (limited to 'compiler/rustc_middle/src')
| -rw-r--r-- | compiler/rustc_middle/src/ty/context.rs | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index fab0047babf..7035e641f39 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -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> { |
