Skip to content

Commit b43c5d3

Browse files
committed
Fix unnecessary restrictions in struct-target-features.
Allow using struct-tf with functions with non-Rust ABI. Also allow converting struct-tf functions to function pointers / let them implement function traits.
1 parent 72cebcc commit b43c5d3

File tree

4 files changed

+12
-19
lines changed

4 files changed

+12
-19
lines changed

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

-7
Original file line numberDiff line numberDiff line change
@@ -611,13 +611,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
611611
&mut additional_tf,
612612
)
613613
}
614-
// FIXME(struct_target_features): is this really necessary?
615-
if !additional_tf.is_empty() && sig.skip_binder().abi() != abi::Abi::Rust {
616-
tcx.dcx().span_err(
617-
tcx.hir().span(tcx.local_def_id_to_hir_id(did)),
618-
"cannot use a struct with target features in a function with non-Rust ABI",
619-
);
620-
}
621614
if !additional_tf.is_empty() && codegen_fn_attrs.inline == InlineAttr::Always {
622615
tcx.dcx().span_err(
623616
tcx.hir().span(tcx.local_def_id_to_hir_id(did)),

compiler/rustc_hir_typeck/src/coercion.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -909,12 +909,15 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
909909
return Err(TypeError::IntrinsicCast);
910910
}
911911

912-
// Safe `#[target_feature]` functions are not assignable to safe fn pointers (RFC 2396).
913-
// FIXME(struct_target_features): should this be true also for functions that inherit
914-
// target features from structs?
915-
912+
// Safe functions with explicit `#[target_feature]` attributes are not
913+
// assignable to safe fn pointers (RFC 2396).
916914
if b_hdr.safety == hir::Safety::Safe
917-
&& !self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
915+
&& self
916+
.tcx
917+
.codegen_fn_attrs(def_id)
918+
.target_features
919+
.iter()
920+
.any(|x| !x.implied)
918921
{
919922
return Err(TypeError::TargetFeatureCast(def_id));
920923
}

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -464,9 +464,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
464464
let is_target_feature_fn = if let ty::FnDef(def_id, _) =
465465
*leaf_trait_ref.skip_binder().self_ty().kind()
466466
{
467-
// FIXME(struct_target_features): should a function that inherits
468-
// target_features through arguments implement Fn traits?
469-
!self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
467+
self.tcx.codegen_fn_attrs(def_id).target_features.iter().any(|x| !x.implied)
470468
} else {
471469
false
472470
};

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -546,13 +546,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
546546
.push(FnPointerCandidate { fn_host_effect: self.tcx().consts.true_ });
547547
}
548548
}
549-
// Provide an impl for suitable functions, rejecting `#[target_feature]` functions (RFC 2396).
549+
// Provide an impl for suitable functions, rejecting functions with explicit
550+
// `#[target_feature]` attributes (RFC 2396).
550551
ty::FnDef(def_id, args) => {
551552
let tcx = self.tcx();
552-
// FIXME(struct_target_features): should a function that inherits target_features
553-
// through an argument implement Fn traits?
554553
if tcx.fn_sig(def_id).skip_binder().is_fn_trait_compatible()
555-
&& tcx.codegen_fn_attrs(def_id).target_features.is_empty()
554+
&& !tcx.codegen_fn_attrs(def_id).target_features.iter().any(|x| !x.implied)
556555
{
557556
candidates.vec.push(FnPointerCandidate {
558557
fn_host_effect: tcx

0 commit comments

Comments
 (0)