@@ -500,53 +500,62 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
500500 _ => bx. new_fn_type ( sig, & extra_args)
501501 } ;
502502
503- // emit a panic instead of instantiating an uninhabited type
504- if ( intrinsic == Some ( "init" ) || intrinsic == Some ( "uninit" ) ) &&
505- fn_ty. ret . layout . abi . is_uninhabited ( )
506- {
507- let loc = bx. sess ( ) . source_map ( ) . lookup_char_pos ( span. lo ( ) ) ;
508- let filename = Symbol :: intern ( & loc. file . name . to_string ( ) ) . as_str ( ) ;
509- let filename = bx. const_str_slice ( filename) ;
510- let line = bx. const_u32 ( loc. line as u32 ) ;
511- let col = bx. const_u32 ( loc. col . to_usize ( ) as u32 + 1 ) ;
512- let align = tcx. data_layout . aggregate_align . abi
513- . max ( tcx. data_layout . i32_align . abi )
514- . max ( tcx. data_layout . pointer_align . abi ) ;
515-
516- let str = format ! (
517- "Attempted to instantiate uninhabited type {} using mem::{}" ,
518- sig. output( ) ,
519- if intrinsic == Some ( "init" ) { "zeroed" } else { "uninitialized" }
520- ) ;
521- let msg_str = Symbol :: intern ( & str) . as_str ( ) ;
522- let msg_str = bx. const_str_slice ( msg_str) ;
523- let msg_file_line_col = bx. const_struct (
524- & [ msg_str, filename, line, col] ,
525- false ,
526- ) ;
527- let msg_file_line_col = bx. static_addr_of (
528- msg_file_line_col,
529- align,
530- Some ( "panic_loc" ) ,
531- ) ;
503+ // emit a panic or a NOP for `panic_if_uninhabited`
504+ if intrinsic == Some ( "panic_if_uninhabited" ) {
505+ let ty = match callee. layout . ty . sty {
506+ ty:: FnDef ( _, substs) => {
507+ substs. type_at ( 0 )
508+ }
509+ _ => bug ! ( "{} is not callable as intrinsic" , callee. layout. ty)
510+ } ;
511+ let layout = bx. layout_of ( ty) ;
512+ if layout. abi . is_uninhabited ( ) {
513+ let loc = bx. sess ( ) . source_map ( ) . lookup_char_pos ( span. lo ( ) ) ;
514+ let filename = Symbol :: intern ( & loc. file . name . to_string ( ) ) . as_str ( ) ;
515+ let filename = bx. const_str_slice ( filename) ;
516+ let line = bx. const_u32 ( loc. line as u32 ) ;
517+ let col = bx. const_u32 ( loc. col . to_usize ( ) as u32 + 1 ) ;
518+ let align = tcx. data_layout . aggregate_align . abi
519+ . max ( tcx. data_layout . i32_align . abi )
520+ . max ( tcx. data_layout . pointer_align . abi ) ;
521+
522+ let str = format ! (
523+ "Attempted to instantiate uninhabited type {}" ,
524+ ty
525+ ) ;
526+ let msg_str = Symbol :: intern ( & str) . as_str ( ) ;
527+ let msg_str = bx. const_str_slice ( msg_str) ;
528+ let msg_file_line_col = bx. const_struct (
529+ & [ msg_str, filename, line, col] ,
530+ false ,
531+ ) ;
532+ let msg_file_line_col = bx. static_addr_of (
533+ msg_file_line_col,
534+ align,
535+ Some ( "panic_loc" ) ,
536+ ) ;
532537
533- // Obtain the panic entry point.
534- let def_id =
535- common:: langcall ( bx. tcx ( ) , Some ( span) , "" , lang_items:: PanicFnLangItem ) ;
536- let instance = ty:: Instance :: mono ( bx. tcx ( ) , def_id) ;
537- let fn_ty = bx. fn_type_of_instance ( & instance) ;
538- let llfn = bx. get_fn ( instance) ;
539-
540- // Codegen the actual panic invoke/call.
541- do_call (
542- self ,
543- & mut bx,
544- fn_ty,
545- llfn,
546- & [ msg_file_line_col] ,
547- destination. as_ref ( ) . map ( |( _, bb) | ( ReturnDest :: Nothing , * bb) ) ,
548- cleanup,
549- ) ;
538+ // Obtain the panic entry point.
539+ let def_id =
540+ common:: langcall ( bx. tcx ( ) , Some ( span) , "" , lang_items:: PanicFnLangItem ) ;
541+ let instance = ty:: Instance :: mono ( bx. tcx ( ) , def_id) ;
542+ let fn_ty = bx. fn_type_of_instance ( & instance) ;
543+ let llfn = bx. get_fn ( instance) ;
544+
545+ // Codegen the actual panic invoke/call.
546+ do_call (
547+ self ,
548+ & mut bx,
549+ fn_ty,
550+ llfn,
551+ & [ msg_file_line_col] ,
552+ destination. as_ref ( ) . map ( |( _, bb) | ( ReturnDest :: Nothing , * bb) ) ,
553+ cleanup,
554+ ) ;
555+ } else {
556+ // a NOP
557+ funclet_br ( self , & mut bx, destination. as_ref ( ) . unwrap ( ) . 1 ) ;
558+ }
550559 return ;
551560 }
552561
0 commit comments