@@ -60,7 +60,7 @@ use crate::dep_graph::{DepGraph, DepKindStruct};
60
60
use crate :: infer:: canonical:: { CanonicalParamEnvCache , CanonicalVarInfo , CanonicalVarInfos } ;
61
61
use crate :: lint:: lint_level;
62
62
use crate :: metadata:: ModChild ;
63
- use crate :: middle:: codegen_fn_attrs:: CodegenFnAttrs ;
63
+ use crate :: middle:: codegen_fn_attrs:: { CodegenFnAttrs , TargetFeature } ;
64
64
use crate :: middle:: { resolve_bound_vars, stability} ;
65
65
use crate :: mir:: interpret:: { self , Allocation , ConstAllocation } ;
66
66
use crate :: mir:: { Body , Local , Place , PlaceElem , ProjectionKind , Promoted } ;
@@ -1776,6 +1776,37 @@ impl<'tcx> TyCtxt<'tcx> {
1776
1776
pub fn dcx ( self ) -> DiagCtxtHandle < ' tcx > {
1777
1777
self . sess . dcx ( )
1778
1778
}
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
+ }
1779
1810
}
1780
1811
1781
1812
impl < ' tcx > TyCtxtAt < ' tcx > {
0 commit comments