@@ -29,6 +29,41 @@ use syntax::ast_util::local_def;
2929use syntax:: codemap:: Span ;
3030use syntax:: parse:: token;
3131
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+ }
3267
3368/// Remember to add all intrinsics here, in librustc_trans/trans/intrinsic.rs,
3469/// and in libcore/intrinsics.rs
@@ -312,34 +347,15 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
312347 } ;
313348 ( n_tps, inputs, ty:: FnConverging ( output) )
314349 } ;
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+ )
343359}
344360
345361/// Type-check `extern "platform-intrinsic" { ... }` functions.
@@ -391,10 +407,10 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt,
391407 Some ( intr) => {
392408 // this function is a platform specific intrinsic
393409 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) ;
398414 return
399415 }
400416
@@ -412,40 +428,23 @@ pub fn check_platform_intrinsic_type(ccx: &CrateCtxt,
412428 return
413429 }
414430 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) ;
417433 return ;
418434 }
419435 }
420436 }
421437 } ;
422438
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+ )
449448}
450449
451450// 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>(
459458 expected : & ' a intrinsics:: Type , t : ty:: Ty < ' tcx > )
460459{
461460 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+
462468 match * expected {
463469 Integer ( bits) => match ( bits, & t. sty ) {
464470 ( 8 , & ty:: TyInt ( ast:: TyI8 ) ) | ( 8 , & ty:: TyUint ( ast:: TyU8 ) ) |
465471 ( 16 , & ty:: TyInt ( ast:: TyI16 ) ) | ( 16 , & ty:: TyUint ( ast:: TyU16 ) ) |
466472 ( 32 , & ty:: TyInt ( ast:: TyI32 ) ) | ( 32 , & ty:: TyUint ( ast:: TyU32 ) ) |
467473 ( 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) ) ,
473476 } ,
474477 Float ( bits) => match ( bits, & t. sty ) {
475478 ( 32 , & ty:: TyFloat ( ast:: TyF32 ) ) |
476479 ( 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) ) ,
482482 } ,
483483 Pointer ( _) => unimplemented ! ( ) ,
484484 Vector ( ref inner_expected, len) => {
485485 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" ) ;
490488 return ;
491489 }
492490 let t_len = t. simd_size ( tcx) ;
493491 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) ) ;
499494 return ;
500495 }
501496 let t_ty = t. simd_type ( tcx) ;
502497 {
498+ // check that a given structural type always has the same an intrinsic definition
503499 let previous = structural_to_nominal. entry ( expected) . or_insert ( t) ;
504500 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) ;
509508 return ;
510509 }
511510 }
0 commit comments