@@ -39,7 +39,7 @@ use rustc::ty::adjustment::{AdjustUnsafeFnPointer, AdjustMutToConstPointer};
3939use rustc:: ty:: { self , Ty , TyCtxt } ;
4040use rustc:: ty:: cast:: { CastTy , IntTy } ;
4141use util:: nodemap:: NodeMap ;
42- use rustc_const_math:: { ConstInt , ConstMathErr , ConstUsize , ConstIsize } ;
42+ use rustc_const_math:: { ConstInt , ConstUsize , ConstIsize } ;
4343
4444use rustc:: hir;
4545
@@ -48,6 +48,7 @@ use std::borrow::Cow;
4848use libc:: c_uint;
4949use syntax:: ast:: { self , LitKind } ;
5050use syntax:: attr:: { self , AttrMetaMethods } ;
51+ use syntax:: codemap:: Span ;
5152use syntax:: parse:: token;
5253use syntax:: ptr:: P ;
5354
@@ -110,11 +111,11 @@ pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
110111 }
111112}
112113
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 {
118119 unsafe {
119120 // FIXME: this totally needs a better name generation scheme, perhaps a simple global
120121 // counter? Also most other uses of gensym in trans.
@@ -158,13 +159,13 @@ pub fn addr_of(ccx: &CrateContext,
158159}
159160
160161/// 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 {
162163 let v = match cx. const_unsized ( ) . borrow ( ) . get ( & v) {
163164 Some ( & v) => v,
164165 None => v
165166 } ;
166167 let d = unsafe { llvm:: LLVMGetInitializer ( v) } ;
167- if t. is_bool ( ) {
168+ if !d . is_null ( ) && t. is_bool ( ) {
168169 unsafe { llvm:: LLVMConstTrunc ( d, Type :: i1 ( cx) . to_ref ( ) ) }
169170 } else {
170171 d
@@ -466,16 +467,12 @@ fn check_unary_expr_validity(cx: &CrateContext, e: &hir::Expr, t: Ty,
466467 Some ( v) => v,
467468 None => return Ok ( ( ) ) ,
468469 } ;
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) ?;
475471 }
472+ Ok ( ( ) )
476473}
477474
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 > {
479476 match t. sty {
480477 ty:: TyInt ( int_type) => const_to_opt_int ( value) . and_then ( |input| match int_type {
481478 ast:: IntTy :: I8 => {
@@ -523,24 +520,21 @@ fn to_const_int(value: ValueRef, t: Ty, tcx: &TyCtxt) -> Option<ConstInt> {
523520 }
524521}
525522
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 > {
531528 match ( result, trueconst) {
532- ( Ok ( _) , _) => {
533- // We do not actually care about a successful result.
534- Ok ( ( ) )
535- } ,
529+ ( Ok ( x) , _) => Ok ( x) ,
536530 ( 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 ( ) ) ;
539533 Err ( Compiletime ( err) )
540534 } ,
541535 ( 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 ( ) ) ;
544538 Err ( Runtime ( err) )
545539 } ,
546540 }
@@ -564,7 +558,8 @@ fn check_binary_expr_validity(cx: &CrateContext, e: &hir::Expr, t: Ty,
564558 hir:: BiShr => lhs >> rhs,
565559 _ => return Ok ( ( ) ) ,
566560 } ;
567- const_err ( cx, e, result, trueconst)
561+ const_err ( cx, e. span , result. map_err ( ErrKind :: Math ) , trueconst) ?;
562+ Ok ( ( ) )
568563}
569564
570565fn const_expr_unadjusted < ' a , ' tcx > ( cx : & CrateContext < ' a , ' tcx > ,
@@ -719,8 +714,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
719714 if iv >= len {
720715 // FIXME #3170: report this earlier on in the const-eval
721716 // 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) ?;
724718 C_undef ( val_ty ( arr) . element_type ( ) )
725719 } else {
726720 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)
11281122 } ;
11291123
11301124 ccx. instances ( ) . borrow_mut ( ) . insert ( instance, g) ;
1125+ ccx. statics ( ) . borrow_mut ( ) . insert ( g, def_id) ;
11311126 Datum :: new ( g, ty, Lvalue :: new ( "static" ) )
11321127}
11331128
@@ -1147,14 +1142,20 @@ pub fn trans_static(ccx: &CrateContext,
11471142 let def_id = ccx. tcx ( ) . map . local_def_id ( id) ;
11481143 let datum = get_static ( ccx, def_id) ;
11491144
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 ( ) ) ?;
11581159
11591160 // boolean SSA values are i1, but they have to be stored in i8 slots,
11601161 // otherwise some LLVM optimization passes don't work as expected
0 commit comments