@@ -3,11 +3,13 @@ use rustc_ast::ast;
33use rustc_errors:: { pluralize, Applicability , DiagnosticBuilder } ;
44use rustc_hir as hir;
55use rustc_hir:: def_id:: DefId ;
6+ use rustc_span:: symbol:: sym;
67use rustc_span:: Span ;
78use rustc_target:: spec:: abi;
89
910use std:: borrow:: Cow ;
1011use std:: fmt;
12+ use std:: ops:: Deref ;
1113
1214#[ derive( Clone , Copy , Debug , PartialEq , Eq , TypeFoldable ) ]
1315pub struct ExpectedFound < T > {
@@ -58,6 +60,8 @@ pub enum TypeError<'tcx> {
5860 ConstMismatch ( ExpectedFound < & ' tcx ty:: Const < ' tcx > > ) ,
5961
6062 IntrinsicCast ,
63+ /// Safe `#[target_feature]` functions are not assignable to safe function pointers.
64+ TargetFeatureCast ( DefId ) ,
6165}
6266
6367pub enum UnconstrainedNumeric {
@@ -183,6 +187,10 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
183187 write ! ( f, "expected `{}`, found `{}`" , values. expected, values. found)
184188 }
185189 IntrinsicCast => write ! ( f, "cannot coerce intrinsics to function pointers" ) ,
190+ TargetFeatureCast ( _) => write ! (
191+ f,
192+ "cannot coerce functions with `#[target_feature]` to safe function pointers"
193+ ) ,
186194 ObjectUnsafeCoercion ( _) => write ! ( f, "coercion to object-unsafe trait object" ) ,
187195 }
188196 }
@@ -193,7 +201,8 @@ impl<'tcx> TypeError<'tcx> {
193201 use self :: TypeError :: * ;
194202 match self {
195203 CyclicTy ( _) | UnsafetyMismatch ( _) | Mismatch | AbiMismatch ( _) | FixedArraySize ( _)
196- | Sorts ( _) | IntMismatch ( _) | FloatMismatch ( _) | VariadicMismatch ( _) => false ,
204+ | Sorts ( _) | IntMismatch ( _) | FloatMismatch ( _) | VariadicMismatch ( _)
205+ | TargetFeatureCast ( _) => false ,
197206
198207 Mutability
199208 | TupleSize ( _)
@@ -489,6 +498,18 @@ impl Trait for X {
489498 ) ;
490499 }
491500 }
501+ TargetFeatureCast ( def_id) => {
502+ let attrs = self . get_attrs ( * def_id) ;
503+ let target_spans = attrs
504+ . deref ( )
505+ . iter ( )
506+ . filter ( |attr| attr. has_name ( sym:: target_feature) )
507+ . map ( |attr| attr. span ) ;
508+ db. note (
509+ "functions with `#[target_feature]` can only be coerced to `unsafe` function pointers"
510+ ) ;
511+ db. span_labels ( target_spans, "`#[target_feature]` added here" ) ;
512+ }
492513 _ => { }
493514 }
494515 }
0 commit comments