@@ -29,6 +29,41 @@ use syntax::ast_util::local_def;
29
29
use syntax:: codemap:: Span ;
30
30
use syntax:: parse:: token;
31
31
32
+ fn equate_intrinsic_type < ' a , ' tcx > ( tcx : & ty:: ctxt < ' tcx > , it : & ast:: ForeignItem ,
33
+ maybe_infcx : Option < & infer:: InferCtxt < ' a , ' tcx > > ,
34
+ n_tps : usize ,
35
+ abi : abi:: Abi ,
36
+ inputs : Vec < ty:: Ty < ' tcx > > ,
37
+ output : ty:: FnOutput < ' tcx > ) {
38
+ let fty = tcx. mk_fn ( None , tcx. mk_bare_fn ( ty:: BareFnTy {
39
+ unsafety : ast:: Unsafety :: Unsafe ,
40
+ abi : abi,
41
+ sig : ty:: Binder ( FnSig {
42
+ inputs : inputs,
43
+ output : output,
44
+ variadic : false ,
45
+ } ) ,
46
+ } ) ) ;
47
+ let i_ty = tcx. lookup_item_type ( local_def ( it. id ) ) ;
48
+ let i_n_tps = i_ty. generics . types . len ( subst:: FnSpace ) ;
49
+ if i_n_tps != n_tps {
50
+ span_err ! ( tcx. sess, it. span, E0094 ,
51
+ "intrinsic has wrong number of type \
52
+ parameters: found {}, expected {}",
53
+ i_n_tps, n_tps) ;
54
+ } else {
55
+ require_same_types ( tcx,
56
+ maybe_infcx,
57
+ false ,
58
+ it. span ,
59
+ i_ty. ty ,
60
+ fty,
61
+ || {
62
+ format ! ( "intrinsic has wrong type: expected `{}`" ,
63
+ fty)
64
+ } ) ;
65
+ }
66
+ }
32
67
33
68
/// Remember to add all intrinsics here, in librustc_trans/trans/intrinsic.rs,
34
69
/// and in libcore/intrinsics.rs
@@ -312,34 +347,15 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
312
347
} ;
313
348
( n_tps, inputs, ty:: FnConverging ( output) )
314
349
} ;
315
- let fty = tcx. mk_fn ( None , tcx. mk_bare_fn ( ty:: BareFnTy {
316
- unsafety : ast:: Unsafety :: Unsafe ,
317
- abi : abi:: RustIntrinsic ,
318
- sig : ty:: Binder ( FnSig {
319
- inputs : inputs,
320
- output : output,
321
- variadic : false ,
322
- } ) ,
323
- } ) ) ;
324
- let i_ty = ccx. tcx . lookup_item_type ( local_def ( it. id ) ) ;
325
- let i_n_tps = i_ty. generics . types . len ( subst:: FnSpace ) ;
326
- if i_n_tps != n_tps {
327
- span_err ! ( tcx. sess, it. span, E0094 ,
328
- "intrinsic has wrong number of type \
329
- parameters: found {}, expected {}",
330
- i_n_tps, n_tps) ;
331
- } else {
332
- require_same_types ( tcx,
333
- None ,
334
- false ,
335
- it. span ,
336
- i_ty. ty ,
337
- fty,
338
- || {
339
- format ! ( "intrinsic has wrong type: expected `{}`" ,
340
- fty)
341
- } ) ;
342
- }
350
+ equate_intrinsic_type (
351
+ tcx,
352
+ it,
353
+ None ,
354
+ n_tps,
355
+ abi:: RustIntrinsic ,
356
+ inputs,
357
+ output
358
+ )
343
359
}
344
360
345
361
/// Type-check `extern "platform-intrinsic" { ... }` functions.
@@ -391,10 +407,10 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt,
391
407
Some ( intr) => {
392
408
// this function is a platform specific intrinsic
393
409
if i_n_tps != 0 {
394
- tcx. sess . span_err ( it. span ,
395
- & format ! ( " intrinsic has wrong number of type parameters: \
396
- found {}, expected 0",
397
- i_n_tps) ) ;
410
+ span_err ! ( tcx. sess, it. span, E0440 ,
411
+ "platform-specific intrinsic has wrong number of type \
412
+ parameters: found {}, expected 0",
413
+ i_n_tps) ;
398
414
return
399
415
}
400
416
@@ -412,40 +428,23 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt,
412
428
return
413
429
}
414
430
None => {
415
- tcx. sess . span_err ( it. span ,
416
- & format ! ( "unrecognized intrinsic function: `{}`" , name) ) ;
431
+ span_err ! ( tcx. sess, it. span, E0441 ,
432
+ "unrecognized platform-specific intrinsic function: `{}`" , name) ;
417
433
return ;
418
434
}
419
435
}
420
436
}
421
437
} ;
422
438
423
- let fty = tcx. mk_fn ( None , tcx. mk_bare_fn ( ty:: BareFnTy {
424
- unsafety : ast:: Unsafety :: Unsafe ,
425
- abi : abi:: PlatformIntrinsic ,
426
- sig : ty:: Binder ( FnSig {
427
- inputs : inputs,
428
- output : ty:: FnConverging ( output) ,
429
- variadic : false ,
430
- } ) ,
431
- } ) ) ;
432
- if i_n_tps != n_tps {
433
- span_err ! ( tcx. sess, it. span, E0094 ,
434
- "intrinsic has wrong number of type \
435
- parameters: found {}, expected {}",
436
- i_n_tps, n_tps) ;
437
- } else {
438
- require_same_types ( tcx,
439
- infer_ctxt. as_ref ( ) ,
440
- false ,
441
- it. span ,
442
- i_ty. ty ,
443
- fty,
444
- || {
445
- format ! ( "intrinsic has wrong type: expected `{}`" ,
446
- fty)
447
- } ) ;
448
- }
439
+ equate_intrinsic_type (
440
+ tcx,
441
+ it,
442
+ infer_ctxt. as_ref ( ) ,
443
+ n_tps,
444
+ abi:: PlatformIntrinsic ,
445
+ inputs,
446
+ ty:: FnConverging ( output)
447
+ )
449
448
}
450
449
451
450
// walk the expected type and the actual type in lock step, checking they're
@@ -459,53 +458,53 @@ fn match_intrinsic_type_to_type<'tcx, 'a>(
459
458
expected : & ' a intrinsics:: Type , t : ty:: Ty < ' tcx > )
460
459
{
461
460
use intrinsics:: Type :: * ;
461
+
462
+ let simple_error = |real : & str , expected : & str | {
463
+ span_err ! ( tcx. sess, span, E0442 ,
464
+ "intrinsic {} has wrong type: found {}, expected {}" ,
465
+ position, real, expected)
466
+ } ;
467
+
462
468
match * expected {
463
469
Integer ( bits) => match ( bits, & t. sty ) {
464
470
( 8 , & ty:: TyInt ( ast:: TyI8 ) ) | ( 8 , & ty:: TyUint ( ast:: TyU8 ) ) |
465
471
( 16 , & ty:: TyInt ( ast:: TyI16 ) ) | ( 16 , & ty:: TyUint ( ast:: TyU16 ) ) |
466
472
( 32 , & ty:: TyInt ( ast:: TyI32 ) ) | ( 32 , & ty:: TyUint ( ast:: TyU32 ) ) |
467
473
( 64 , & ty:: TyInt ( ast:: TyI64 ) ) | ( 64 , & ty:: TyUint ( ast:: TyU64 ) ) => { } ,
468
- _ => tcx. sess . span_err ( span,
469
- & format ! ( "intrinsic {} has wrong type: found `{}`, \
470
- expected `i{n}` or `u{n}`",
471
- position,
472
- t, n = bits) ) ,
474
+ _ => simple_error ( & format ! ( "`{}`" , t) ,
475
+ & format ! ( "`i{n}` or `u{n}`" , n = bits) ) ,
473
476
} ,
474
477
Float ( bits) => match ( bits, & t. sty ) {
475
478
( 32 , & ty:: TyFloat ( ast:: TyF32 ) ) |
476
479
( 64 , & ty:: TyFloat ( ast:: TyF64 ) ) => { } ,
477
- _ => tcx. sess . span_err ( span,
478
- & format ! ( "intrinsic {} has wrong type: found `{}`, \
479
- expected `f{n}`",
480
- position,
481
- t, n = bits) ) ,
480
+ _ => simple_error ( & format ! ( "`{}`" , t) ,
481
+ & format ! ( "`f{n}`" , n = bits) ) ,
482
482
} ,
483
483
Pointer ( _) => unimplemented ! ( ) ,
484
484
Vector ( ref inner_expected, len) => {
485
485
if !t. is_simd ( tcx) {
486
- tcx. sess . span_err ( span,
487
- & format ! ( "intrinsic {} has wrong type: found non-simd type {}, \
488
- expected simd type",
489
- position, t) ) ;
486
+ simple_error ( & format ! ( "non-simd type `{}`" , t) ,
487
+ "simd type" ) ;
490
488
return ;
491
489
}
492
490
let t_len = t. simd_size ( tcx) ;
493
491
if len as usize != t_len {
494
- tcx. sess . span_err ( span,
495
- & format ! ( "intrinsic {} has wrong type: found \
496
- vector with length {}, expected length {}",
497
- position,
498
- t_len, len) ) ;
492
+ simple_error ( & format ! ( "vector with length {}" , t_len) ,
493
+ & format ! ( "length {}" , len) ) ;
499
494
return ;
500
495
}
501
496
let t_ty = t. simd_type ( tcx) ;
502
497
{
498
+ // check that a given structural type always has the same an intrinsic definition
503
499
let previous = structural_to_nominal. entry ( expected) . or_insert ( t) ;
504
500
if * previous != t {
505
- tcx. sess . span_err ( span,
506
- & format ! ( "intrinsic {} has wrong type: found `{}`, \
507
- but already seen this vector type as `{}`",
508
- position, t, previous) ) ;
501
+ // this gets its own error code because it is non-trivial
502
+ span_err ! ( tcx. sess, span, E0443 ,
503
+ "intrinsic {} has wrong type: found `{}`, expected `{}` which \
504
+ was used for this vector type previously in this signature",
505
+ position,
506
+ t,
507
+ * previous) ;
509
508
return ;
510
509
}
511
510
}
0 commit comments