@@ -90,7 +90,7 @@ use build::{BlockAnd, BlockAndExtension, Builder};
90
90
use rustc:: middle:: region:: CodeExtent ;
91
91
use rustc:: middle:: lang_items;
92
92
use rustc:: middle:: subst:: Substs ;
93
- use rustc:: middle:: ty:: { Ty , Region } ;
93
+ use rustc:: middle:: ty:: { self , Ty } ;
94
94
use rustc:: mir:: repr:: * ;
95
95
use syntax:: codemap:: { Span , DUMMY_SP } ;
96
96
use syntax:: parse:: token:: intern_and_get_ident;
@@ -297,27 +297,34 @@ impl<'a,'tcx> Builder<'a,'tcx> {
297
297
self . scopes . first ( ) . map ( |scope| scope. extent ) . unwrap ( )
298
298
}
299
299
300
- pub fn panic_bound_check ( & mut self ,
300
+ pub fn panic_bounds_check ( & mut self ,
301
301
block : BasicBlock ,
302
302
index : Operand < ' tcx > ,
303
303
len : Operand < ' tcx > ,
304
304
span : Span ) {
305
+ // fn(&(filename: &'static str, line: u32), index: usize, length: usize) -> !
305
306
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
+ } ;
312
314
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?
316
323
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) ) ;
318
325
let cleanup = self . diverge_cleanup ( ) ;
319
326
self . cfg . terminate ( block, Terminator :: Call {
320
- func : func,
327
+ func : Operand :: Constant ( func) ,
321
328
args : vec ! [ Operand :: Consume ( tuple_ref) , index, len] ,
322
329
kind : match cleanup {
323
330
None => CallKind :: Diverging ,
@@ -328,31 +335,36 @@ impl<'a,'tcx> Builder<'a,'tcx> {
328
335
329
336
/// Create diverge cleanup and branch to it from `block`.
330
337
pub fn panic ( & mut self , block : BasicBlock , msg : & ' static str , span : Span ) {
338
+ // fn(&(msg: &'static str filename: &'static str, line: u32)) -> !
331
339
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 {
339
350
span : DUMMY_SP ,
340
- ty : str_ty ,
351
+ ty : self . hir . tcx ( ) . mk_static_str ( ) ,
341
352
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.
346
360
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?
351
363
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) ) ;
353
365
let cleanup = self . diverge_cleanup ( ) ;
354
366
self . cfg . terminate ( block, Terminator :: Call {
355
- func : func,
367
+ func : Operand :: Constant ( func) ,
356
368
args : vec ! [ Operand :: Consume ( tuple_ref) ] ,
357
369
kind : match cleanup {
358
370
None => CallKind :: Diverging ,
@@ -361,34 +373,34 @@ impl<'a,'tcx> Builder<'a,'tcx> {
361
373
} ) ;
362
374
}
363
375
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 > {
365
377
let funcdid = match self . hir . tcx ( ) . lang_items . require ( lang_item) {
366
378
Ok ( d) => d,
367
379
Err ( m) => {
368
380
self . hir . tcx ( ) . sess . fatal ( & * m)
369
381
}
370
382
} ;
371
- Operand :: Constant ( Constant {
383
+ Constant {
372
384
span : DUMMY_SP ,
373
385
ty : self . hir . tcx ( ) . lookup_item_type ( funcdid) . ty ,
374
386
literal : Literal :: Item {
375
387
def_id : funcdid,
376
388
kind : ItemKind :: Function ,
377
389
substs : self . hir . tcx ( ) . mk_substs ( Substs :: empty ( ) )
378
390
}
379
- } )
391
+ }
380
392
}
381
393
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 > ) {
383
395
let span_lines = self . hir . tcx ( ) . sess . codemap ( ) . lookup_char_pos ( span. lo ) ;
384
- ( Operand :: Constant ( Constant {
396
+ ( Constant {
385
397
span : DUMMY_SP ,
386
398
ty : self . hir . tcx ( ) . mk_static_str ( ) ,
387
399
literal : self . hir . str_literal ( intern_and_get_ident ( & span_lines. file . name ) )
388
- } ) , Operand :: Constant ( Constant {
400
+ } , Constant {
389
401
span : DUMMY_SP ,
390
402
ty : self . hir . tcx ( ) . types . u32 ,
391
403
literal : self . hir . usize_literal ( span_lines. line )
392
- } ) )
404
+ } )
393
405
}
394
406
}
0 commit comments