@@ -15,7 +15,7 @@ use rustc::middle::const_val::{ConstVal, ConstEvalErr, EvalResult, ErrKind};
15
15
use rustc:: hir:: map as hir_map;
16
16
use rustc:: hir:: map:: blocks:: FnLikeNode ;
17
17
use rustc:: traits;
18
- use rustc:: hir:: def:: Def ;
18
+ use rustc:: hir:: def:: { Def , CtorKind } ;
19
19
use rustc:: hir:: def_id:: DefId ;
20
20
use rustc:: ty:: { self , Ty , TyCtxt } ;
21
21
use rustc:: ty:: maps:: Providers ;
@@ -48,28 +48,6 @@ macro_rules! math {
48
48
}
49
49
}
50
50
51
- fn lookup_variant_by_id < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
52
- variant_def : DefId )
53
- -> Option < ( & ' tcx Expr , & ' a ty:: TypeckTables < ' tcx > ) > {
54
- if let Some ( variant_node_id) = tcx. hir . as_local_node_id ( variant_def) {
55
- let enum_node_id = tcx. hir . get_parent ( variant_node_id) ;
56
- if let Some ( hir_map:: NodeItem ( it) ) = tcx. hir . find ( enum_node_id) {
57
- if let hir:: ItemEnum ( ref edef, _) = it. node {
58
- for variant in & edef. variants {
59
- if variant. node . data . id ( ) == variant_node_id {
60
- return variant. node . disr_expr . map ( |e| {
61
- let def_id = tcx. hir . body_owner_def_id ( e) ;
62
- ( & tcx. hir . body ( e) . value ,
63
- tcx. item_tables ( def_id) )
64
- } ) ;
65
- }
66
- }
67
- }
68
- }
69
- }
70
- None
71
- }
72
-
73
51
/// * `def_id` is the id of the constant.
74
52
/// * `substs` is the monomorphized substitutions for the expression.
75
53
///
@@ -289,9 +267,22 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
289
267
}
290
268
}
291
269
hir:: ExprCast ( ref base, _) => {
292
- match cast_const ( tcx, cx. eval ( base) ?, ety) {
293
- Ok ( val) => val,
294
- Err ( kind) => return Err ( ConstEvalErr { span : e. span , kind : kind } ) ,
270
+ let base_val = cx. eval ( base) ?;
271
+ let base_ty = cx. tables . expr_ty ( base) ;
272
+
273
+ // Avoid applying substitutions if they're empty, that'd ICE.
274
+ let base_ty = if cx. substs . is_empty ( ) {
275
+ base_ty
276
+ } else {
277
+ base_ty. subst ( tcx, cx. substs )
278
+ } ;
279
+ if ety == base_ty {
280
+ base_val
281
+ } else {
282
+ match cast_const ( tcx, base_val, ety) {
283
+ Ok ( val) => val,
284
+ Err ( kind) => signal ! ( e, kind) ,
285
+ }
295
286
}
296
287
}
297
288
hir:: ExprPath ( ref qpath) => {
@@ -317,27 +308,20 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
317
308
debug ! ( "bad reference: {:?}, {:?}" , err. description( ) , err. span) ;
318
309
signal ! ( e, ErroneousReferencedConstant ( box err) )
319
310
} ,
311
+ }
320
312
} ,
321
- Def :: VariantCtor ( variant_def, ..) => {
322
- if let Some ( ( expr, tables) ) = lookup_variant_by_id ( tcx, variant_def) {
323
- let cx = ConstContext :: with_tables ( tcx, tables) ;
324
- match cx. eval ( expr) {
325
- Ok ( val) => val,
326
- Err ( ConstEvalErr { kind : TypeckError , .. } ) => {
327
- signal ! ( e, TypeckError ) ;
328
- }
329
- Err ( err) => {
330
- debug ! ( "bad reference: {:?}, {:?}" , err. description( ) , err. span) ;
331
- signal ! ( e, ErroneousReferencedConstant ( box err) )
332
- } ,
333
- }
334
- } else {
335
- signal ! ( e, UnimplementedConstVal ( "enum variants" ) ) ;
336
- }
313
+ Def :: VariantCtor ( variant_def, CtorKind :: Const ) => {
314
+ Variant ( variant_def)
315
+ }
316
+ Def :: VariantCtor ( _, CtorKind :: Fn ) => {
317
+ signal ! ( e, UnimplementedConstVal ( "enum variants" ) ) ;
337
318
}
338
- Def :: StructCtor ( .. ) => {
319
+ Def :: StructCtor ( _ , CtorKind :: Const ) => {
339
320
ConstVal :: Struct ( Default :: default ( ) )
340
321
}
322
+ Def :: StructCtor ( _, CtorKind :: Fn ) => {
323
+ signal ! ( e, UnimplementedConstVal ( "tuple struct constructors" ) )
324
+ }
341
325
Def :: Local ( def_id) => {
342
326
debug ! ( "Def::Local({:?}): {:?}" , def_id, cx. fn_args) ;
343
327
if let Some ( val) = cx. fn_args . as_ref ( ) . and_then ( |args| args. get ( & def_id) ) {
@@ -578,7 +562,7 @@ fn cast_const_int<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
578
562
U8 ( u) => Ok ( Char ( u as char ) ) ,
579
563
_ => bug ! ( ) ,
580
564
} ,
581
- _ => bug ! ( ) ,
565
+ _ => Err ( CannotCast ) ,
582
566
}
583
567
}
584
568
@@ -622,6 +606,11 @@ fn cast_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
622
606
Bool ( b) => cast_const_int ( tcx, U8 ( b as u8 ) , ty) ,
623
607
Float ( f) => cast_const_float ( tcx, f, ty) ,
624
608
Char ( c) => cast_const_int ( tcx, U32 ( c as u32 ) , ty) ,
609
+ Variant ( v) => {
610
+ let adt = tcx. lookup_adt_def ( tcx. parent_def_id ( v) . unwrap ( ) ) ;
611
+ let idx = adt. variant_index_with_id ( v) ;
612
+ cast_const_int ( tcx, adt. discriminant_for_variant ( tcx, idx) , ty)
613
+ }
625
614
Function ( ..) => Err ( UnimplementedConstVal ( "casting fn pointers" ) ) ,
626
615
ByteStr ( b) => match ty. sty {
627
616
ty:: TyRawPtr ( _) => {
0 commit comments