@@ -36,6 +36,7 @@ use value::Value;
36
36
37
37
use syntax_pos:: { Span , DUMMY_SP } ;
38
38
39
+ use std:: fmt;
39
40
use std:: ptr;
40
41
41
42
use super :: operand:: { OperandRef , OperandValue } ;
@@ -147,6 +148,12 @@ impl<'tcx> Const<'tcx> {
147
148
}
148
149
}
149
150
151
+ impl < ' tcx > fmt:: Debug for Const < ' tcx > {
152
+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
153
+ write ! ( f, "Const({:?}: {:?})" , Value ( self . llval) , self . ty)
154
+ }
155
+ }
156
+
150
157
#[ derive( Copy , Clone ) ]
151
158
enum Base {
152
159
/// A constant value without an unique address.
@@ -466,7 +473,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
466
473
467
474
fn const_operand ( & self , operand : & mir:: Operand < ' tcx > , span : Span )
468
475
-> Result < Const < ' tcx > , ConstEvalFailure > {
469
- match * operand {
476
+ debug ! ( "const_operand({:?} @ {:?})" , operand, span) ;
477
+ let result = match * operand {
470
478
mir:: Operand :: Consume ( ref lvalue) => {
471
479
Ok ( self . const_lvalue ( lvalue, span) ?. to_const ( span) )
472
480
}
@@ -495,29 +503,41 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
495
503
}
496
504
}
497
505
}
498
- }
506
+ } ;
507
+ debug ! ( "const_operand({:?} @ {:?}) = {:?}" , operand, span,
508
+ result. as_ref( ) . ok( ) ) ;
509
+ result
510
+ }
511
+
512
+ fn const_array ( & self , array_ty : Ty < ' tcx > , fields : & [ ValueRef ] )
513
+ -> Const < ' tcx >
514
+ {
515
+ let elem_ty = array_ty. builtin_index ( ) . unwrap_or_else ( || {
516
+ bug ! ( "bad array type {:?}" , array_ty)
517
+ } ) ;
518
+ let llunitty = type_of:: type_of ( self . ccx , elem_ty) ;
519
+ // If the array contains enums, an LLVM array won't work.
520
+ let val = if fields. iter ( ) . all ( |& f| val_ty ( f) == llunitty) {
521
+ C_array ( llunitty, fields)
522
+ } else {
523
+ C_struct ( self . ccx , fields, false )
524
+ } ;
525
+ Const :: new ( val, array_ty)
499
526
}
500
527
501
528
fn const_rvalue ( & self , rvalue : & mir:: Rvalue < ' tcx > ,
502
529
dest_ty : Ty < ' tcx > , span : Span )
503
530
-> Result < Const < ' tcx > , ConstEvalFailure > {
504
531
let tcx = self . ccx . tcx ( ) ;
532
+ debug ! ( "const_rvalue({:?}: {:?} @ {:?})" , rvalue, dest_ty, span) ;
505
533
let val = match * rvalue {
506
534
mir:: Rvalue :: Use ( ref operand) => self . const_operand ( operand, span) ?,
507
535
508
536
mir:: Rvalue :: Repeat ( ref elem, ref count) => {
509
537
let elem = self . const_operand ( elem, span) ?;
510
538
let size = count. value . as_u64 ( tcx. sess . target . uint_type ) ;
511
539
let fields = vec ! [ elem. llval; size as usize ] ;
512
-
513
- let llunitty = type_of:: type_of ( self . ccx , elem. ty ) ;
514
- // If the array contains enums, an LLVM array won't work.
515
- let val = if val_ty ( elem. llval ) == llunitty {
516
- C_array ( llunitty, & fields)
517
- } else {
518
- C_struct ( self . ccx , & fields, false )
519
- } ;
520
- Const :: new ( val, dest_ty)
540
+ self . const_array ( dest_ty, & fields)
521
541
}
522
542
523
543
mir:: Rvalue :: Aggregate ( ref kind, ref operands) => {
@@ -541,22 +561,26 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
541
561
self . monomorphize ( & substs) ) ;
542
562
}
543
563
544
- let val = if let mir:: AggregateKind :: Adt ( adt_def, index, _) = * kind {
545
- let repr = adt:: represent_type ( self . ccx , dest_ty) ;
546
- let disr = Disr :: from ( adt_def. variants [ index] . disr_val ) ;
547
- adt:: trans_const ( self . ccx , & repr, disr, & fields)
548
- } else if let ty:: TyArray ( elem_ty, _) = dest_ty. sty {
549
- let llunitty = type_of:: type_of ( self . ccx , elem_ty) ;
550
- // If the array contains enums, an LLVM array won't work.
551
- if fields. iter ( ) . all ( |& f| val_ty ( f) == llunitty) {
552
- C_array ( llunitty, & fields)
553
- } else {
554
- C_struct ( self . ccx , & fields, false )
564
+ match * kind {
565
+ mir:: AggregateKind :: Vec => {
566
+ self . const_array ( dest_ty, & fields)
555
567
}
556
- } else {
557
- C_struct ( self . ccx , & fields, false )
558
- } ;
559
- Const :: new ( val, dest_ty)
568
+ mir:: AggregateKind :: Adt ( ..) |
569
+ mir:: AggregateKind :: Closure ( ..) |
570
+ mir:: AggregateKind :: Tuple => {
571
+ let disr = match * kind {
572
+ mir:: AggregateKind :: Adt ( adt_def, index, _) => {
573
+ Disr :: from ( adt_def. variants [ index] . disr_val )
574
+ }
575
+ _ => Disr ( 0 )
576
+ } ;
577
+ let repr = adt:: represent_type ( self . ccx , dest_ty) ;
578
+ Const :: new (
579
+ adt:: trans_const ( self . ccx , & repr, disr, & fields) ,
580
+ dest_ty
581
+ )
582
+ }
583
+ }
560
584
}
561
585
562
586
mir:: Rvalue :: Cast ( ref kind, ref source, cast_ty) => {
@@ -780,6 +804,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
780
804
_ => span_bug ! ( span, "{:?} in constant" , rvalue)
781
805
} ;
782
806
807
+ debug ! ( "const_rvalue({:?}: {:?} @ {:?}) = {:?}" , rvalue, dest_ty, span, val) ;
808
+
783
809
Ok ( val)
784
810
}
785
811
@@ -881,6 +907,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
881
907
constant : & mir:: Constant < ' tcx > )
882
908
-> Const < ' tcx >
883
909
{
910
+ debug ! ( "trans_constant({:?})" , constant) ;
884
911
let ty = bcx. monomorphize ( & constant. ty ) ;
885
912
let result = match constant. literal . clone ( ) {
886
913
mir:: Literal :: Item { def_id, substs } => {
@@ -905,7 +932,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
905
932
}
906
933
} ;
907
934
908
- match result {
935
+ let result = match result {
909
936
Ok ( v) => v,
910
937
Err ( ConstEvalFailure :: Compiletime ( _) ) => {
911
938
// We've errored, so we don't have to produce working code.
@@ -917,7 +944,10 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
917
944
"MIR constant {:?} results in runtime panic: {:?}" ,
918
945
constant, err. description( ) )
919
946
}
920
- }
947
+ } ;
948
+
949
+ debug ! ( "trans_constant({:?}) = {:?}" , constant, result) ;
950
+ result
921
951
}
922
952
}
923
953
0 commit comments