@@ -3,11 +3,13 @@ use rustc_ast::ast;
3
3
use rustc_errors:: { pluralize, Applicability , DiagnosticBuilder } ;
4
4
use rustc_hir as hir;
5
5
use rustc_hir:: def_id:: DefId ;
6
+ use rustc_span:: symbol:: sym;
6
7
use rustc_span:: Span ;
7
8
use rustc_target:: spec:: abi;
8
9
9
10
use std:: borrow:: Cow ;
10
11
use std:: fmt;
12
+ use std:: ops:: Deref ;
11
13
12
14
#[ derive( Clone , Copy , Debug , PartialEq , Eq , TypeFoldable ) ]
13
15
pub struct ExpectedFound < T > {
@@ -58,6 +60,8 @@ pub enum TypeError<'tcx> {
58
60
ConstMismatch ( ExpectedFound < & ' tcx ty:: Const < ' tcx > > ) ,
59
61
60
62
IntrinsicCast ,
63
+ /// Safe `#[target_feature]` functions are not assignable to safe function pointers.
64
+ TargetFeatureCast ( DefId ) ,
61
65
}
62
66
63
67
pub enum UnconstrainedNumeric {
@@ -183,6 +187,10 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
183
187
write ! ( f, "expected `{}`, found `{}`" , values. expected, values. found)
184
188
}
185
189
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
+ ) ,
186
194
ObjectUnsafeCoercion ( _) => write ! ( f, "coercion to object-unsafe trait object" ) ,
187
195
}
188
196
}
@@ -193,7 +201,8 @@ impl<'tcx> TypeError<'tcx> {
193
201
use self :: TypeError :: * ;
194
202
match self {
195
203
CyclicTy ( _) | UnsafetyMismatch ( _) | Mismatch | AbiMismatch ( _) | FixedArraySize ( _)
196
- | Sorts ( _) | IntMismatch ( _) | FloatMismatch ( _) | VariadicMismatch ( _) => false ,
204
+ | Sorts ( _) | IntMismatch ( _) | FloatMismatch ( _) | VariadicMismatch ( _)
205
+ | TargetFeatureCast ( _) => false ,
197
206
198
207
Mutability
199
208
| TupleSize ( _)
@@ -489,6 +498,18 @@ impl Trait for X {
489
498
) ;
490
499
}
491
500
}
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
+ }
492
513
_ => { }
493
514
}
494
515
}
0 commit comments