Skip to content

Commit

Permalink
Make #[target_feature] Fn trait error message less confusing
Browse files Browse the repository at this point in the history
  • Loading branch information
calebzulawski committed Jun 30, 2020
1 parent 8e899b1 commit 51858da
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 22 deletions.
31 changes: 15 additions & 16 deletions src/librustc_trait_selection/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,18 +286,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
.starts_with("std::convert::From<");
let is_unsize =
{ Some(trait_ref.def_id()) == self.tcx.lang_items().unsize_trait() };
let is_fn_trait = [
self.tcx.lang_items().fn_trait(),
self.tcx.lang_items().fn_mut_trait(),
self.tcx.lang_items().fn_once_trait(),
]
.contains(&Some(trait_ref.def_id()));
let is_target_feature_fn =
if let ty::FnDef(def_id, _) = trait_ref.skip_binder().self_ty().kind {
!self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
} else {
false
};
let (message, note) = if is_try && is_from {
(
Some(format!(
Expand Down Expand Up @@ -439,11 +427,22 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
);
}

let is_fn_trait = [
self.tcx.lang_items().fn_trait(),
self.tcx.lang_items().fn_mut_trait(),
self.tcx.lang_items().fn_once_trait(),
]
.contains(&Some(trait_ref.def_id()));
let is_target_feature_fn =
if let ty::FnDef(def_id, _) = trait_ref.skip_binder().self_ty().kind {
!self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
} else {
false
};
if is_fn_trait && is_target_feature_fn {
err.note(&format!(
"`{}` has `#[target_feature]` and is unsafe to call",
trait_ref.skip_binder().self_ty(),
));
err.note(
"`#[target_feature]` functions do not implement the `Fn` traits",
);
}

// Try to report a help message
Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ LL | call(foo);
|
= help: the trait `std::ops::Fn<()>` is not implemented for `fn() {foo}`
= note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }
= note: `fn() {foo}` has `#[target_feature]` and is unsafe to call
= note: `#[target_feature]` functions do not implement the `Fn` traits

error[E0277]: expected a `std::ops::FnMut<()>` closure, found `fn() {foo}`
--> $DIR/fn-traits.rs:25:14
Expand All @@ -22,7 +22,7 @@ LL | call_mut(foo);
|
= help: the trait `std::ops::FnMut<()>` is not implemented for `fn() {foo}`
= note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }
= note: `fn() {foo}` has `#[target_feature]` and is unsafe to call
= note: `#[target_feature]` functions do not implement the `Fn` traits

error[E0277]: expected a `std::ops::FnOnce<()>` closure, found `fn() {foo}`
--> $DIR/fn-traits.rs:26:15
Expand All @@ -35,7 +35,7 @@ LL | call_once(foo);
|
= help: the trait `std::ops::FnOnce<()>` is not implemented for `fn() {foo}`
= note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }
= note: `fn() {foo}` has `#[target_feature]` and is unsafe to call
= note: `#[target_feature]` functions do not implement the `Fn` traits

error[E0277]: expected a `std::ops::Fn<()>` closure, found `unsafe fn() {foo_unsafe}`
--> $DIR/fn-traits.rs:28:10
Expand All @@ -48,7 +48,7 @@ LL | call(foo_unsafe);
|
= help: the trait `std::ops::Fn<()>` is not implemented for `unsafe fn() {foo_unsafe}`
= note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }
= note: `unsafe fn() {foo_unsafe}` has `#[target_feature]` and is unsafe to call
= note: `#[target_feature]` functions do not implement the `Fn` traits

error[E0277]: expected a `std::ops::FnMut<()>` closure, found `unsafe fn() {foo_unsafe}`
--> $DIR/fn-traits.rs:30:14
Expand All @@ -61,7 +61,7 @@ LL | call_mut(foo_unsafe);
|
= help: the trait `std::ops::FnMut<()>` is not implemented for `unsafe fn() {foo_unsafe}`
= note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }
= note: `unsafe fn() {foo_unsafe}` has `#[target_feature]` and is unsafe to call
= note: `#[target_feature]` functions do not implement the `Fn` traits

error[E0277]: expected a `std::ops::FnOnce<()>` closure, found `unsafe fn() {foo_unsafe}`
--> $DIR/fn-traits.rs:32:15
Expand All @@ -74,7 +74,7 @@ LL | call_once(foo_unsafe);
|
= help: the trait `std::ops::FnOnce<()>` is not implemented for `unsafe fn() {foo_unsafe}`
= note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }
= note: `unsafe fn() {foo_unsafe}` has `#[target_feature]` and is unsafe to call
= note: `#[target_feature]` functions do not implement the `Fn` traits

error: aborting due to 6 previous errors

Expand Down

0 comments on commit 51858da

Please sign in to comment.