@@ -39,7 +39,7 @@ use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
39
39
use rustc:: ty:: { self , Ty , TyCtxt } ;
40
40
use rustc:: ty:: cast:: { CastTy , IntTy } ;
41
41
use util:: nodemap:: NodeMap ;
42
- use rustc_const_math:: { ConstInt , ConstMathErr , ConstUsize , ConstIsize } ;
42
+ use rustc_const_math:: { ConstInt , ConstUsize , ConstIsize } ;
43
43
44
44
use rustc:: hir;
45
45
@@ -48,6 +48,7 @@ use std::borrow::Cow;
48
48
use libc:: c_uint;
49
49
use syntax:: ast:: { self , LitKind } ;
50
50
use syntax:: attr:: { self , AttrMetaMethods } ;
51
+ use syntax:: codemap:: Span ;
51
52
use syntax:: parse:: token;
52
53
use syntax:: ptr:: P ;
53
54
@@ -110,11 +111,11 @@ pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
110
111
}
111
112
}
112
113
113
- fn addr_of_mut ( ccx : & CrateContext ,
114
- cv : ValueRef ,
115
- align : machine:: llalign ,
116
- kind : & str )
117
- -> ValueRef {
114
+ pub fn addr_of_mut ( ccx : & CrateContext ,
115
+ cv : ValueRef ,
116
+ align : machine:: llalign ,
117
+ kind : & str )
118
+ -> ValueRef {
118
119
unsafe {
119
120
// FIXME: this totally needs a better name generation scheme, perhaps a simple global
120
121
// counter? Also most other uses of gensym in trans.
@@ -158,13 +159,13 @@ pub fn addr_of(ccx: &CrateContext,
158
159
}
159
160
160
161
/// Deref a constant pointer
161
- fn load_const ( cx : & CrateContext , v : ValueRef , t : Ty ) -> ValueRef {
162
+ pub fn load_const ( cx : & CrateContext , v : ValueRef , t : Ty ) -> ValueRef {
162
163
let v = match cx. const_unsized ( ) . borrow ( ) . get ( & v) {
163
164
Some ( & v) => v,
164
165
None => v
165
166
} ;
166
167
let d = unsafe { llvm:: LLVMGetInitializer ( v) } ;
167
- if t. is_bool ( ) {
168
+ if !d . is_null ( ) && t. is_bool ( ) {
168
169
unsafe { llvm:: LLVMConstTrunc ( d, Type :: i1 ( cx) . to_ref ( ) ) }
169
170
} else {
170
171
d
@@ -466,16 +467,12 @@ fn check_unary_expr_validity(cx: &CrateContext, e: &hir::Expr, t: Ty,
466
467
Some ( v) => v,
467
468
None => return Ok ( ( ) ) ,
468
469
} ;
469
- match -cval {
470
- Ok ( _) => return Ok ( ( ) ) ,
471
- Err ( err) => const_err ( cx, e, Err ( err) , trueconst) ,
472
- }
473
- } else {
474
- Ok ( ( ) )
470
+ const_err ( cx, e. span , ( -cval) . map_err ( ErrKind :: Math ) , trueconst) ?;
475
471
}
472
+ Ok ( ( ) )
476
473
}
477
474
478
- fn to_const_int ( value : ValueRef , t : Ty , tcx : & TyCtxt ) -> Option < ConstInt > {
475
+ pub fn to_const_int ( value : ValueRef , t : Ty , tcx : & TyCtxt ) -> Option < ConstInt > {
479
476
match t. sty {
480
477
ty:: TyInt ( int_type) => const_to_opt_int ( value) . and_then ( |input| match int_type {
481
478
ast:: IntTy :: I8 => {
@@ -523,24 +520,21 @@ fn to_const_int(value: ValueRef, t: Ty, tcx: &TyCtxt) -> Option<ConstInt> {
523
520
}
524
521
}
525
522
526
- fn const_err ( cx : & CrateContext ,
527
- e : & hir :: Expr ,
528
- result : Result < ConstInt , ConstMathErr > ,
529
- trueconst : TrueConst )
530
- -> Result < ( ) , ConstEvalFailure > {
523
+ pub fn const_err < T > ( cx : & CrateContext ,
524
+ span : Span ,
525
+ result : Result < T , ErrKind > ,
526
+ trueconst : TrueConst )
527
+ -> Result < T , ConstEvalFailure > {
531
528
match ( result, trueconst) {
532
- ( Ok ( _) , _) => {
533
- // We do not actually care about a successful result.
534
- Ok ( ( ) )
535
- } ,
529
+ ( Ok ( x) , _) => Ok ( x) ,
536
530
( Err ( err) , TrueConst :: Yes ) => {
537
- let err = ConstEvalErr { span : e . span , kind : ErrKind :: Math ( err) } ;
538
- cx. tcx ( ) . sess . span_err ( e . span , & err. description ( ) ) ;
531
+ let err = ConstEvalErr { span : span, kind : err } ;
532
+ cx. tcx ( ) . sess . span_err ( span, & err. description ( ) ) ;
539
533
Err ( Compiletime ( err) )
540
534
} ,
541
535
( Err ( err) , TrueConst :: No ) => {
542
- let err = ConstEvalErr { span : e . span , kind : ErrKind :: Math ( err) } ;
543
- cx. tcx ( ) . sess . span_warn ( e . span , & err. description ( ) ) ;
536
+ let err = ConstEvalErr { span : span, kind : err } ;
537
+ cx. tcx ( ) . sess . span_warn ( span, & err. description ( ) ) ;
544
538
Err ( Runtime ( err) )
545
539
} ,
546
540
}
@@ -564,7 +558,8 @@ fn check_binary_expr_validity(cx: &CrateContext, e: &hir::Expr, t: Ty,
564
558
hir:: BiShr => lhs >> rhs,
565
559
_ => return Ok ( ( ) ) ,
566
560
} ;
567
- const_err ( cx, e, result, trueconst)
561
+ const_err ( cx, e. span , result. map_err ( ErrKind :: Math ) , trueconst) ?;
562
+ Ok ( ( ) )
568
563
}
569
564
570
565
fn const_expr_unadjusted < ' a , ' tcx > ( cx : & CrateContext < ' a , ' tcx > ,
@@ -719,8 +714,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
719
714
if iv >= len {
720
715
// FIXME #3170: report this earlier on in the const-eval
721
716
// pass. Reporting here is a bit late.
722
- span_err ! ( cx. sess( ) , e. span, E0515 ,
723
- "const index-expr is out of bounds" ) ;
717
+ const_err ( cx, e. span , Err ( ErrKind :: IndexOutOfBounds ) , trueconst) ?;
724
718
C_undef ( val_ty ( arr) . element_type ( ) )
725
719
} else {
726
720
const_get_elt ( arr, & [ iv as c_uint ] )
@@ -1128,6 +1122,7 @@ pub fn get_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, def_id: DefId)
1128
1122
} ;
1129
1123
1130
1124
ccx. instances ( ) . borrow_mut ( ) . insert ( instance, g) ;
1125
+ ccx. statics ( ) . borrow_mut ( ) . insert ( g, def_id) ;
1131
1126
Datum :: new ( g, ty, Lvalue :: new ( "static" ) )
1132
1127
}
1133
1128
@@ -1147,14 +1142,20 @@ pub fn trans_static(ccx: &CrateContext,
1147
1142
let def_id = ccx. tcx ( ) . map . local_def_id ( id) ;
1148
1143
let datum = get_static ( ccx, def_id) ;
1149
1144
1150
- let empty_substs = ccx. tcx ( ) . mk_substs ( Substs :: empty ( ) ) ;
1151
- let ( v, _) = const_expr (
1152
- ccx,
1153
- expr,
1154
- empty_substs,
1155
- None ,
1156
- TrueConst :: Yes ,
1157
- ) . map_err ( |e| e. into_inner ( ) ) ?;
1145
+ let check_attrs = |attrs : & [ ast:: Attribute ] | {
1146
+ let default_to_mir = ccx. sess ( ) . opts . debugging_opts . orbit ;
1147
+ let invert = if default_to_mir { "rustc_no_mir" } else { "rustc_mir" } ;
1148
+ default_to_mir ^ attrs. iter ( ) . any ( |item| item. check_name ( invert) )
1149
+ } ;
1150
+ let use_mir = check_attrs ( ccx. tcx ( ) . map . attrs ( id) ) ;
1151
+
1152
+ let v = if use_mir {
1153
+ :: mir:: trans_static_initializer ( ccx, def_id)
1154
+ } else {
1155
+ let empty_substs = ccx. tcx ( ) . mk_substs ( Substs :: empty ( ) ) ;
1156
+ const_expr ( ccx, expr, empty_substs, None , TrueConst :: Yes )
1157
+ . map ( |( v, _) | v)
1158
+ } . map_err ( |e| e. into_inner ( ) ) ?;
1158
1159
1159
1160
// boolean SSA values are i1, but they have to be stored in i8 slots,
1160
1161
// otherwise some LLVM optimization passes don't work as expected
0 commit comments