@@ -90,7 +90,7 @@ use build::{BlockAnd, BlockAndExtension, Builder};
9090use rustc:: middle:: region:: CodeExtent ;
9191use rustc:: middle:: lang_items;
9292use rustc:: middle:: subst:: Substs ;
93- use rustc:: middle:: ty:: { Ty , Region } ;
93+ use rustc:: middle:: ty:: { self , Ty } ;
9494use rustc:: mir:: repr:: * ;
9595use syntax:: codemap:: { Span , DUMMY_SP } ;
9696use syntax:: parse:: token:: intern_and_get_ident;
@@ -297,27 +297,34 @@ impl<'a,'tcx> Builder<'a,'tcx> {
297297 self . scopes . first ( ) . map ( |scope| scope. extent ) . unwrap ( )
298298 }
299299
300- pub fn panic_bound_check ( & mut self ,
300+ pub fn panic_bounds_check ( & mut self ,
301301 block : BasicBlock ,
302302 index : Operand < ' tcx > ,
303303 len : Operand < ' tcx > ,
304304 span : Span ) {
305+ // fn(&(filename: &'static str, line: u32), index: usize, length: usize) -> !
305306 let func = self . lang_function ( lang_items:: PanicBoundsCheckFnLangItem ) ;
306- let str_ty = self . hir . tcx ( ) . mk_static_str ( ) ;
307- let tup_ty = self . hir . tcx ( ) . mk_tup ( vec ! [ str_ty, self . hir. tcx( ) . types. u32 ] ) ;
308- // FIXME: ReStatic might be wrong here?
309- let ref_region = self . hir . tcx ( ) . mk_region ( Region :: ReStatic ) ;
310- let ref_ty = self . hir . tcx ( ) . mk_imm_ref ( ref_region, tup_ty. clone ( ) ) ;
311- let ( file_arg, line_arg) = self . span_to_fileline_args ( span) ;
307+ let args = func. ty . fn_args ( ) ;
308+ let ref_ty = args. skip_binder ( ) [ 0 ] ;
309+ let ( region, tup_ty) = if let ty:: TyRef ( region, tyandmut) = ref_ty. sty {
310+ ( region, tyandmut. ty )
311+ } else {
312+ self . hir . span_bug ( span, & format ! ( "unexpected panic_bound_check type: {:?}" , func. ty) ) ;
313+ } ;
312314 let ( tuple, tuple_ref) = ( self . temp ( tup_ty) , self . temp ( ref_ty) ) ;
313- self . cfg . push_assign ( block, DUMMY_SP , & tuple, // tuple = (message_arg, file_arg, line_arg);
314- Rvalue :: Aggregate ( AggregateKind :: Tuple , vec ! [ file_arg, line_arg] ) ) ;
315- // FIXME: ReStatic might be wrong here?
315+ let ( file, line) = self . span_to_fileline_args ( span) ;
316+ let elems = vec ! [ Operand :: Constant ( file) , Operand :: Constant ( line) ] ;
317+ // FIXME: We should have this as a constant, rather than a stack variable (to not pollute
318+ // icache with cold branch code), however to achieve that we either have to rely on rvalue
319+ // promotion or have some way, in MIR, to create constants.
320+ self . cfg . push_assign ( block, DUMMY_SP , & tuple, // tuple = (file_arg, line_arg);
321+ Rvalue :: Aggregate ( AggregateKind :: Tuple , elems) ) ;
322+ // FIXME: is this region really correct here?
316323 self . cfg . push_assign ( block, DUMMY_SP , & tuple_ref, // tuple_ref = &tuple;
317- Rvalue :: Ref ( * ref_region , BorrowKind :: Unique , tuple) ) ;
324+ Rvalue :: Ref ( * region , BorrowKind :: Unique , tuple) ) ;
318325 let cleanup = self . diverge_cleanup ( ) ;
319326 self . cfg . terminate ( block, Terminator :: Call {
320- func : func,
327+ func : Operand :: Constant ( func) ,
321328 args : vec ! [ Operand :: Consume ( tuple_ref) , index, len] ,
322329 kind : match cleanup {
323330 None => CallKind :: Diverging ,
@@ -328,31 +335,36 @@ impl<'a,'tcx> Builder<'a,'tcx> {
328335
329336 /// Create diverge cleanup and branch to it from `block`.
330337 pub fn panic ( & mut self , block : BasicBlock , msg : & ' static str , span : Span ) {
338+ // fn(&(msg: &'static str filename: &'static str, line: u32)) -> !
331339 let func = self . lang_function ( lang_items:: PanicFnLangItem ) ;
332-
333- let str_ty = self . hir . tcx ( ) . mk_static_str ( ) ;
334- let tup_ty = self . hir . tcx ( ) . mk_tup ( vec ! [ str_ty, str_ty, self . hir. tcx( ) . types. u32 ] ) ;
335- // FIXME: ReStatic might be wrong here?
336- let ref_region = self . hir . tcx ( ) . mk_region ( Region :: ReStatic ) ;
337- let ref_ty = self . hir . tcx ( ) . mk_imm_ref ( ref_region, tup_ty. clone ( ) ) ;
338- let message_arg = Operand :: Constant ( Constant {
340+ let args = func. ty . fn_args ( ) ;
341+ let ref_ty = args. skip_binder ( ) [ 0 ] ;
342+ let ( region, tup_ty) = if let ty:: TyRef ( region, tyandmut) = ref_ty. sty {
343+ ( region, tyandmut. ty )
344+ } else {
345+ self . hir . span_bug ( span, & format ! ( "unexpected panic type: {:?}" , func. ty) ) ;
346+ } ;
347+ let ( tuple, tuple_ref) = ( self . temp ( tup_ty) , self . temp ( ref_ty) ) ;
348+ let ( file, line) = self . span_to_fileline_args ( span) ;
349+ let message = Constant {
339350 span : DUMMY_SP ,
340- ty : str_ty ,
351+ ty : self . hir . tcx ( ) . mk_static_str ( ) ,
341352 literal : self . hir . str_literal ( intern_and_get_ident ( msg) )
342- } ) ;
343- let ( file_arg, line_arg) = self . span_to_fileline_args ( span) ;
344- let tuple = self . temp ( tup_ty) ;
345- let tuple_ref = self . temp ( ref_ty) ;
353+ } ;
354+ let elems = vec ! [ Operand :: Constant ( message) ,
355+ Operand :: Constant ( file) ,
356+ Operand :: Constant ( line) ] ;
357+ // FIXME: We should have this as a constant, rather than a stack variable (to not pollute
358+ // icache with cold branch code), however to achieve that we either have to rely on rvalue
359+ // promotion or have some way, in MIR, to create constants.
346360 self . cfg . push_assign ( block, DUMMY_SP , & tuple, // tuple = (message_arg, file_arg, line_arg);
347- Rvalue :: Aggregate ( AggregateKind :: Tuple ,
348- vec ! [ message_arg, file_arg, line_arg] )
349- ) ;
350- // FIXME: ReStatic might be wrong here?
361+ Rvalue :: Aggregate ( AggregateKind :: Tuple , elems) ) ;
362+ // FIXME: is this region really correct here?
351363 self . cfg . push_assign ( block, DUMMY_SP , & tuple_ref, // tuple_ref = &tuple;
352- Rvalue :: Ref ( * ref_region , BorrowKind :: Unique , tuple) ) ;
364+ Rvalue :: Ref ( * region , BorrowKind :: Unique , tuple) ) ;
353365 let cleanup = self . diverge_cleanup ( ) ;
354366 self . cfg . terminate ( block, Terminator :: Call {
355- func : func,
367+ func : Operand :: Constant ( func) ,
356368 args : vec ! [ Operand :: Consume ( tuple_ref) ] ,
357369 kind : match cleanup {
358370 None => CallKind :: Diverging ,
@@ -361,34 +373,34 @@ impl<'a,'tcx> Builder<'a,'tcx> {
361373 } ) ;
362374 }
363375
364- fn lang_function ( & mut self , lang_item : lang_items:: LangItem ) -> Operand < ' tcx > {
376+ fn lang_function ( & mut self , lang_item : lang_items:: LangItem ) -> Constant < ' tcx > {
365377 let funcdid = match self . hir . tcx ( ) . lang_items . require ( lang_item) {
366378 Ok ( d) => d,
367379 Err ( m) => {
368380 self . hir . tcx ( ) . sess . fatal ( & * m)
369381 }
370382 } ;
371- Operand :: Constant ( Constant {
383+ Constant {
372384 span : DUMMY_SP ,
373385 ty : self . hir . tcx ( ) . lookup_item_type ( funcdid) . ty ,
374386 literal : Literal :: Item {
375387 def_id : funcdid,
376388 kind : ItemKind :: Function ,
377389 substs : self . hir . tcx ( ) . mk_substs ( Substs :: empty ( ) )
378390 }
379- } )
391+ }
380392 }
381393
382- fn span_to_fileline_args ( & mut self , span : Span ) -> ( Operand < ' tcx > , Operand < ' tcx > ) {
394+ fn span_to_fileline_args ( & mut self , span : Span ) -> ( Constant < ' tcx > , Constant < ' tcx > ) {
383395 let span_lines = self . hir . tcx ( ) . sess . codemap ( ) . lookup_char_pos ( span. lo ) ;
384- ( Operand :: Constant ( Constant {
396+ ( Constant {
385397 span : DUMMY_SP ,
386398 ty : self . hir . tcx ( ) . mk_static_str ( ) ,
387399 literal : self . hir . str_literal ( intern_and_get_ident ( & span_lines. file . name ) )
388- } ) , Operand :: Constant ( Constant {
400+ } , Constant {
389401 span : DUMMY_SP ,
390402 ty : self . hir . tcx ( ) . types . u32 ,
391403 literal : self . hir . usize_literal ( span_lines. line )
392- } ) )
404+ } )
393405 }
394406}
0 commit comments