@@ -17,7 +17,7 @@ use rustc::mir::{Constant, Literal, Location, Place, Mir, Operand, Rvalue, Local
1717use rustc:: mir:: { NullOp , StatementKind , Statement , BasicBlock , LocalKind } ;
1818use rustc:: mir:: { TerminatorKind , ClearCrossCrate , SourceInfo , BinOp , ProjectionElem } ;
1919use rustc:: mir:: visit:: { Visitor , PlaceContext } ;
20- use rustc:: mir:: interpret:: ConstEvalErr ;
20+ use rustc:: mir:: interpret:: { ConstEvalErr , EvalErrorKind } ;
2121use rustc:: ty:: { TyCtxt , self , Instance } ;
2222use rustc:: mir:: interpret:: { Value , Scalar , GlobalId , EvalResult } ;
2323use interpret:: EvalContext ;
@@ -145,17 +145,23 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
145145 let r = match f ( self ) {
146146 Ok ( val) => Some ( val) ,
147147 Err ( err) => {
148- let ( frames, span) = self . ecx . generate_stacktrace ( None ) ;
149- let err = ConstEvalErr {
150- span,
151- error : err,
152- stacktrace : frames,
153- } ;
154- err. report_as_lint (
155- self . ecx . tcx ,
156- "this expression will panic at runtime" ,
157- lint_root,
158- ) ;
148+ match err. kind {
149+ // don't report these, they make no sense in a const prop context
150+ EvalErrorKind :: MachineError ( _) => { } ,
151+ _ => {
152+ let ( frames, span) = self . ecx . generate_stacktrace ( None ) ;
153+ let err = ConstEvalErr {
154+ span,
155+ error : err,
156+ stacktrace : frames,
157+ } ;
158+ err. report_as_lint (
159+ self . ecx . tcx ,
160+ "this expression will panic at runtime" ,
161+ lint_root,
162+ ) ;
163+ }
164+ }
159165 None
160166 } ,
161167 } ;
@@ -257,10 +263,25 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
257263 } ,
258264 Rvalue :: Repeat ( ..) |
259265 Rvalue :: Ref ( ..) |
260- Rvalue :: Cast ( ..) |
261266 Rvalue :: Aggregate ( ..) |
262267 Rvalue :: NullaryOp ( NullOp :: Box , _) |
263268 Rvalue :: Discriminant ( ..) => None ,
269+
270+ Rvalue :: Cast ( kind, ref operand, _) => {
271+ let ( value, ty, span) = self . eval_operand ( operand, source_info) ?;
272+ self . use_ecx ( source_info, |this| {
273+ let dest_ptr = this. ecx . alloc_ptr ( place_ty) ?;
274+ let place_align = this. ecx . layout_of ( place_ty) ?. align ;
275+ let dest = :: interpret:: Place :: from_ptr ( dest_ptr, place_align) ;
276+ this. ecx . cast ( ValTy { value, ty } , kind, place_ty, dest) ?;
277+ Ok ( (
278+ Value :: ByRef ( dest_ptr. into ( ) , place_align) ,
279+ place_ty,
280+ span,
281+ ) )
282+ } )
283+ }
284+
264285 // FIXME(oli-obk): evaluate static/constant slice lengths
265286 Rvalue :: Len ( _) => None ,
266287 Rvalue :: NullaryOp ( NullOp :: SizeOf , ty) => {
@@ -354,7 +375,6 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
354375 )
355376 } else {
356377 if overflow {
357- use rustc:: mir:: interpret:: EvalErrorKind ;
358378 let err = EvalErrorKind :: Overflow ( op) . into ( ) ;
359379 let _: Option < ( ) > = self . use_ecx ( source_info, |_| Err ( err) ) ;
360380 return None ;
0 commit comments