@@ -17,7 +17,7 @@ use rustc::mir::{Constant, Literal, Location, Place, Mir, Operand, Rvalue, Local
17
17
use rustc:: mir:: { NullOp , StatementKind , Statement , BasicBlock , LocalKind } ;
18
18
use rustc:: mir:: { TerminatorKind , ClearCrossCrate , SourceInfo , BinOp , ProjectionElem } ;
19
19
use rustc:: mir:: visit:: { Visitor , PlaceContext } ;
20
- use rustc:: mir:: interpret:: ConstEvalErr ;
20
+ use rustc:: mir:: interpret:: { ConstEvalErr , EvalErrorKind } ;
21
21
use rustc:: ty:: { TyCtxt , self , Instance } ;
22
22
use rustc:: mir:: interpret:: { Value , Scalar , GlobalId , EvalResult } ;
23
23
use interpret:: EvalContext ;
@@ -145,17 +145,23 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
145
145
let r = match f ( self ) {
146
146
Ok ( val) => Some ( val) ,
147
147
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
+ }
159
165
None
160
166
} ,
161
167
} ;
@@ -257,10 +263,25 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
257
263
} ,
258
264
Rvalue :: Repeat ( ..) |
259
265
Rvalue :: Ref ( ..) |
260
- Rvalue :: Cast ( ..) |
261
266
Rvalue :: Aggregate ( ..) |
262
267
Rvalue :: NullaryOp ( NullOp :: Box , _) |
263
268
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
+
264
285
// FIXME(oli-obk): evaluate static/constant slice lengths
265
286
Rvalue :: Len ( _) => None ,
266
287
Rvalue :: NullaryOp ( NullOp :: SizeOf , ty) => {
@@ -354,7 +375,6 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
354
375
)
355
376
} else {
356
377
if overflow {
357
- use rustc:: mir:: interpret:: EvalErrorKind ;
358
378
let err = EvalErrorKind :: Overflow ( op) . into ( ) ;
359
379
let _: Option < ( ) > = self . use_ecx ( source_info, |_| Err ( err) ) ;
360
380
return None ;
0 commit comments