@@ -60,7 +60,7 @@ use crate::dep_graph::{DepGraph, DepKindStruct};
6060use crate :: infer:: canonical:: { CanonicalParamEnvCache , CanonicalVarInfo , CanonicalVarInfos } ;
6161use crate :: lint:: lint_level;
6262use crate :: metadata:: ModChild ;
63- use crate :: middle:: codegen_fn_attrs:: CodegenFnAttrs ;
63+ use crate :: middle:: codegen_fn_attrs:: { CodegenFnAttrs , TargetFeature } ;
6464use crate :: middle:: { resolve_bound_vars, stability} ;
6565use crate :: mir:: interpret:: { self , Allocation , ConstAllocation } ;
6666use crate :: mir:: { Body , Local , Place , PlaceElem , ProjectionKind , Promoted } ;
@@ -1776,6 +1776,37 @@ impl<'tcx> TyCtxt<'tcx> {
17761776 pub fn dcx ( self ) -> DiagCtxtHandle < ' tcx > {
17771777 self . sess . dcx ( )
17781778 }
1779+
1780+ pub fn is_target_feature_call_safe (
1781+ self ,
1782+ callee_features : & [ TargetFeature ] ,
1783+ body_features : & [ TargetFeature ] ,
1784+ ) -> bool {
1785+ // If the called function has target features the calling function hasn't,
1786+ // the call requires `unsafe`. Don't check this on wasm
1787+ // targets, though. For more information on wasm see the
1788+ // is_like_wasm check in hir_analysis/src/collect.rs
1789+ self . sess . target . options . is_like_wasm
1790+ || callee_features
1791+ . iter ( )
1792+ . all ( |feature| body_features. iter ( ) . any ( |f| f. name == feature. name ) )
1793+ }
1794+
1795+ /// Returns the safe version of the signature of the given function, if calling it
1796+ /// would be safe in the context of the given caller.
1797+ pub fn adjust_target_feature_sig (
1798+ self ,
1799+ fun_def : DefId ,
1800+ fun_sig : ty:: Binder < ' tcx , ty:: FnSig < ' tcx > > ,
1801+ caller : DefId ,
1802+ ) -> Option < ty:: Binder < ' tcx , ty:: FnSig < ' tcx > > > {
1803+ let fun_features = & self . codegen_fn_attrs ( fun_def) . target_features ;
1804+ let callee_features = & self . codegen_fn_attrs ( caller) . target_features ;
1805+ if self . is_target_feature_call_safe ( & fun_features, & callee_features) {
1806+ return Some ( fun_sig. map_bound ( |sig| ty:: FnSig { safety : hir:: Safety :: Safe , ..sig } ) ) ;
1807+ }
1808+ None
1809+ }
17791810}
17801811
17811812impl < ' tcx > TyCtxtAt < ' tcx > {
0 commit comments