3
3
4
4
use crate :: errors:: {
5
5
SimdShuffleMissingLength , UnrecognizedAtomicOperation , UnrecognizedIntrinsicFunction ,
6
- WrongNumberOfTypeArgumentsToInstrinsic ,
6
+ WrongNumberOfGenericArgumentsToIntrinsic ,
7
7
} ;
8
8
use crate :: require_same_types;
9
9
10
- use rustc_errors:: struct_span_err;
10
+ use rustc_errors:: { pluralize , struct_span_err} ;
11
11
use rustc_hir as hir;
12
12
use rustc_middle:: traits:: { ObligationCause , ObligationCauseCode } ;
13
13
use rustc_middle:: ty:: subst:: Subst ;
@@ -21,36 +21,45 @@ fn equate_intrinsic_type<'tcx>(
21
21
tcx : TyCtxt < ' tcx > ,
22
22
it : & hir:: ForeignItem < ' _ > ,
23
23
n_tps : usize ,
24
+ n_lts : usize ,
24
25
sig : ty:: PolyFnSig < ' tcx > ,
25
26
) {
26
- match it. kind {
27
- hir:: ForeignItemKind :: Fn ( ..) => { }
27
+ let ( own_counts, span) = match & it. kind {
28
+ hir:: ForeignItemKind :: Fn ( .., generics) => {
29
+ let own_counts = tcx. generics_of ( it. def_id . to_def_id ( ) ) . own_counts ( ) ;
30
+ ( own_counts, generics. span )
31
+ }
28
32
_ => {
29
33
struct_span_err ! ( tcx. sess, it. span, E0622 , "intrinsic must be a function" )
30
34
. span_label ( it. span , "expected a function" )
31
35
. emit ( ) ;
32
36
return ;
33
37
}
34
- }
38
+ } ;
35
39
36
- let i_n_tps = tcx. generics_of ( it. def_id ) . own_counts ( ) . types ;
37
- if i_n_tps != n_tps {
38
- let span = match it. kind {
39
- hir:: ForeignItemKind :: Fn ( _, _, ref generics) => generics. span ,
40
- _ => bug ! ( ) ,
41
- } ;
40
+ let gen_count_ok = |found : usize , expected : usize , descr : & str | -> bool {
41
+ if found != expected {
42
+ tcx. sess . emit_err ( WrongNumberOfGenericArgumentsToIntrinsic {
43
+ span,
44
+ found,
45
+ expected,
46
+ expected_pluralize : pluralize ! ( expected) ,
47
+ descr,
48
+ } ) ;
49
+ false
50
+ } else {
51
+ true
52
+ }
53
+ } ;
42
54
43
- tcx. sess . emit_err ( WrongNumberOfTypeArgumentsToInstrinsic {
44
- span,
45
- found : i_n_tps,
46
- expected : n_tps,
47
- } ) ;
48
- return ;
55
+ if gen_count_ok ( own_counts. lifetimes , n_lts, "lifetime" )
56
+ && gen_count_ok ( own_counts. types , n_tps, "type" )
57
+ && gen_count_ok ( own_counts. consts , 0 , "const" )
58
+ {
59
+ let fty = tcx. mk_fn_ptr ( sig) ;
60
+ let cause = ObligationCause :: new ( it. span , it. hir_id ( ) , ObligationCauseCode :: IntrinsicType ) ;
61
+ require_same_types ( tcx, & cause, tcx. mk_fn_ptr ( tcx. fn_sig ( it. def_id ) ) , fty) ;
49
62
}
50
-
51
- let fty = tcx. mk_fn_ptr ( sig) ;
52
- let cause = ObligationCause :: new ( it. span , it. hir_id ( ) , ObligationCauseCode :: IntrinsicType ) ;
53
- require_same_types ( tcx, & cause, tcx. mk_fn_ptr ( tcx. fn_sig ( it. def_id ) ) , fty) ;
54
63
}
55
64
56
65
/// Returns the unsafety of the given intrinsic.
@@ -121,7 +130,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
121
130
} )
122
131
} ;
123
132
124
- let ( n_tps, inputs, output, unsafety) = if name_str. starts_with ( "atomic_" ) {
133
+ let ( n_tps, n_lts , inputs, output, unsafety) = if name_str. starts_with ( "atomic_" ) {
125
134
let split: Vec < & str > = name_str. split ( '_' ) . collect ( ) ;
126
135
assert ! ( split. len( ) >= 2 , "Atomic intrinsic in an incorrect format" ) ;
127
136
@@ -143,7 +152,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
143
152
return ;
144
153
}
145
154
} ;
146
- ( n_tps, inputs, output, hir:: Unsafety :: Unsafe )
155
+ ( n_tps, 0 , inputs, output, hir:: Unsafety :: Unsafe )
147
156
} else {
148
157
let unsafety = intrinsic_operation_unsafety ( intrinsic_name) ;
149
158
let ( n_tps, inputs, output) = match intrinsic_name {
@@ -372,11 +381,11 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
372
381
return ;
373
382
}
374
383
} ;
375
- ( n_tps, inputs, output, unsafety)
384
+ ( n_tps, 0 , inputs, output, unsafety)
376
385
} ;
377
386
let sig = tcx. mk_fn_sig ( inputs. into_iter ( ) , output, false , unsafety, Abi :: RustIntrinsic ) ;
378
387
let sig = ty:: Binder :: bind_with_vars ( sig, bound_vars) ;
379
- equate_intrinsic_type ( tcx, it, n_tps, sig)
388
+ equate_intrinsic_type ( tcx, it, n_tps, n_lts , sig)
380
389
}
381
390
382
391
/// Type-check `extern "platform-intrinsic" { ... }` functions.
@@ -472,5 +481,5 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
472
481
Abi :: PlatformIntrinsic ,
473
482
) ;
474
483
let sig = ty:: Binder :: dummy ( sig) ;
475
- equate_intrinsic_type ( tcx, it, n_tps, sig)
484
+ equate_intrinsic_type ( tcx, it, n_tps, 0 , sig)
476
485
}
0 commit comments