@@ -108,13 +108,11 @@ use rustc_ast::LitKind;
108
108
use rustc_data_structures:: fx:: FxHashMap ;
109
109
use rustc_data_structures:: sync:: { HashMapExt , Lock } ;
110
110
use rustc_data_structures:: tiny_list:: TinyList ;
111
- use rustc_hir as hir;
112
111
use rustc_hir:: def_id:: DefId ;
113
- use rustc_hir:: definitions:: DefPathData ;
114
112
use rustc_middle:: traits:: Reveal ;
115
113
use rustc_middle:: ty:: print:: with_no_trimmed_paths;
116
114
use rustc_serialize:: { Decodable , Encodable } ;
117
- use rustc_span:: { Pos , Span } ;
115
+ use rustc_span:: Span ;
118
116
use rustc_target:: abi:: Endian ;
119
117
120
118
use crate :: mir;
@@ -451,40 +449,6 @@ impl<'tcx> AllocMap<'tcx> {
451
449
}
452
450
}
453
451
454
- /// What we store about a frame in an interpreter backtrace.
455
- #[ derive( Debug ) ]
456
- pub struct FrameInfo < ' tcx > {
457
- pub instance : ty:: Instance < ' tcx > ,
458
- pub span : Span ,
459
- pub lint_root : Option < hir:: HirId > ,
460
- }
461
-
462
- impl < ' tcx > fmt:: Display for FrameInfo < ' tcx > {
463
- fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
464
- ty:: tls:: with ( |tcx| {
465
- if tcx. def_key ( self . instance . def_id ( ) ) . disambiguated_data . data
466
- == DefPathData :: ClosureExpr
467
- {
468
- write ! ( f, "inside closure" ) ?;
469
- } else {
470
- write ! ( f, "inside `{}`" , self . instance) ?;
471
- }
472
- if !self . span . is_dummy ( ) {
473
- let sm = tcx. sess . source_map ( ) ;
474
- let lo = sm. lookup_char_pos ( self . span . lo ( ) ) ;
475
- write ! (
476
- f,
477
- " at {}:{}:{}" ,
478
- sm. filename_for_diagnostics( & lo. file. name) ,
479
- lo. line,
480
- lo. col. to_usize( ) + 1
481
- ) ?;
482
- }
483
- Ok ( ( ) )
484
- } )
485
- }
486
- }
487
-
488
452
/// Used to store results of calls to `eval_to_allocation_raw` and
489
453
/// `eval_to_const_value_raw`.
490
454
#[ derive( Debug ) ]
@@ -650,88 +614,13 @@ impl<'tcx> TyCtxt<'tcx> {
650
614
key : ty:: ParamEnvAnd < ' tcx , GlobalId < ' tcx > > ,
651
615
opt_span : Option < Span > ,
652
616
) -> EvalToAllocationRawResult < ' tcx > {
653
- let ( param_env, id) = key. into_parts ( ) ;
654
- let dedup_const_map = self . dedup_const_map . lock ( ) ;
655
- debug ! ( "dedup_const_map: {:#?}" , dedup_const_map) ;
656
- let alloc_map = dedup_const_map. alloc_map . borrow ( ) ;
657
- debug ! ( "alloc_map: {:#?}" , alloc_map) ;
658
-
659
- let dedup_reveal = alloc_map. get ( & id) ;
660
- debug ! ( ?dedup_reveal) ;
661
-
662
- match param_env. reveal ( ) {
663
- Reveal :: Selection => match dedup_reveal {
664
- Some ( Reveal :: Selection ) => {
665
- drop ( alloc_map) ;
666
- drop ( dedup_const_map) ;
667
-
668
- // Use cached result of query
669
- return self . eval_to_allocation_raw ( key) ;
670
- }
671
- Some ( Reveal :: UserFacing ) => {
672
- drop ( alloc_map) ;
673
- drop ( dedup_const_map) ;
674
-
675
- // can deduplicate query with Reveal::Selection from Reveal::UserFacing
676
- // since these only differ in the way errors are reported, but successful
677
- // query calls are equivalent.
678
- let new_key = param_env. with_user_facing ( ) . and ( id) ;
679
- return self . eval_to_allocation_raw ( new_key) ;
680
- }
681
- _ => { }
682
- } ,
683
- Reveal :: UserFacing => match dedup_reveal {
684
- Some ( Reveal :: UserFacing ) => {
685
- drop ( alloc_map) ;
686
- drop ( dedup_const_map) ;
687
-
688
- return self . eval_to_allocation_raw ( key) ;
689
- }
690
- Some ( Reveal :: Selection ) => {
691
- drop ( alloc_map) ;
692
- drop ( dedup_const_map) ;
693
-
694
- let new_key = param_env. with_reveal_selection ( ) . and ( id) ;
695
- return self . eval_to_allocation_raw ( new_key) ;
696
- }
697
- _ => { }
698
- } ,
699
- Reveal :: All => match dedup_reveal {
700
- Some ( Reveal :: Selection ) => {
701
- drop ( alloc_map) ;
702
- drop ( dedup_const_map) ;
703
-
704
- let new_key = param_env. with_reveal_selection ( ) . and ( id) ;
705
- return self . eval_to_allocation_raw ( new_key) ;
706
- }
707
- Some ( Reveal :: UserFacing ) => {
708
- drop ( alloc_map) ;
709
- drop ( dedup_const_map) ;
710
-
711
- let new_key = param_env. with_user_facing ( ) . and ( id) ;
712
- return self . eval_to_allocation_raw ( new_key) ;
713
- }
714
- Some ( Reveal :: All ) => {
715
- drop ( alloc_map) ;
716
- drop ( dedup_const_map) ;
717
-
718
- return self . eval_to_allocation_raw ( key) ;
719
- }
720
- _ => { }
721
- } ,
722
- }
723
-
724
- // Important to drop the lock here
725
- drop ( alloc_map) ;
726
- drop ( dedup_const_map) ;
727
-
728
- debug ! ( "unable to deduplicate" ) ;
729
-
730
- // We weren't able to deduplicate
731
- match opt_span {
732
- Some ( span) => self . at ( span) . eval_to_allocation_raw ( key) ,
733
- None => self . eval_to_allocation_raw ( key) ,
734
- }
617
+ self . dedup_eval (
618
+ key,
619
+ opt_span,
620
+ EvalCtxt :: Alloc ,
621
+ |key| self . eval_to_allocation_raw ( key) ,
622
+ |key, span| self . at ( span) . eval_to_allocation_raw ( key) ,
623
+ )
735
624
}
736
625
737
626
/// Tries to deduplicate a call to `eval_to_const_value_raw`. If deduplication isn't
@@ -742,91 +631,128 @@ impl<'tcx> TyCtxt<'tcx> {
742
631
key : ty:: ParamEnvAnd < ' tcx , GlobalId < ' tcx > > ,
743
632
opt_span : Option < Span > ,
744
633
) -> EvalToConstValueResult < ' tcx > {
634
+ self . dedup_eval (
635
+ key,
636
+ opt_span,
637
+ EvalCtxt :: ConstVal ,
638
+ |key| self . eval_to_const_value_raw ( key) ,
639
+ |key, span| self . at ( span) . eval_to_const_value_raw ( key) ,
640
+ )
641
+ }
642
+
643
+ /// Deduplicates the result of a query call.
644
+ ///
645
+ /// Explanation for why we can deduplicate query calls in certain situations:
646
+ ///
647
+ /// If we have stored a successful query result with `Reveal::Selection` then we can
648
+ /// deduplicate that result on calls of the `dedup` version of the query with both
649
+ /// `Reveal::Selection` and `Reveal::UserFacing` (since `Selection` and `UserFacing`
650
+ /// only differ in that we keep certain errors silent with `Selection`, but successful
651
+ /// allocations are always equivalent). This is also the reason why we can deduplicate
652
+ /// from saved calls with `UserFacing`on calls with both `Selection` and `UserFacing`.
653
+ ///
654
+ /// If we try to deduplicate with `Reveal::All` we are able to deduplicate
655
+ /// from saved query results with both `Selection` and `UserFacing`, since `All`
656
+ /// will always succeed if either `UserFacing` or `Selection` have succeeded.
657
+ /// On the other hand if we have a saved result with `Reveal::All`, it's not
658
+ /// guaranteed that query calls with `Reveal::Selection` or `Reveal::UserFacing`
659
+ /// succeed, so we can't deduplicate from those.
660
+ fn dedup_eval < T : Copy > (
661
+ self ,
662
+ key : ty:: ParamEnvAnd < ' tcx , GlobalId < ' tcx > > ,
663
+ opt_span : Option < Span > ,
664
+ eval_ctxt : EvalCtxt ,
665
+ query_call : impl Fn ( ty:: ParamEnvAnd < ' tcx , GlobalId < ' tcx > > ) -> T ,
666
+ query_call_span : impl Fn ( ty:: ParamEnvAnd < ' tcx , GlobalId < ' tcx > > , Span ) -> T ,
667
+ ) -> T {
745
668
let ( param_env, id) = key. into_parts ( ) ;
746
669
let dedup_const_map = self . dedup_const_map . lock ( ) ;
747
- debug ! ( "dedup_const_map: {:#?}" , dedup_const_map) ;
748
- let const_val_map = dedup_const_map. const_val_map . borrow ( ) ;
749
- debug ! ( "const_val_map: {:#?}" , const_val_map) ;
670
+ let dedup_query_map = match eval_ctxt {
671
+ EvalCtxt :: Alloc => dedup_const_map. alloc_map . borrow ( ) ,
672
+ EvalCtxt :: ConstVal => dedup_const_map. const_val_map . borrow ( ) ,
673
+ } ;
750
674
751
- let dedup_reveal = const_val_map . get ( & id) ;
675
+ let dedup_reveal = dedup_query_map . get ( & id) ;
752
676
debug ! ( ?dedup_reveal) ;
753
677
754
678
match param_env. reveal ( ) {
755
679
Reveal :: Selection => match dedup_reveal {
756
680
Some ( Reveal :: Selection ) => {
757
- drop ( const_val_map ) ;
681
+ drop ( dedup_query_map ) ;
758
682
drop ( dedup_const_map) ;
759
683
760
684
// Use cached result of query
761
- return self . eval_to_const_value_raw ( key) ;
685
+ return query_call ( key) ;
762
686
}
763
687
Some ( Reveal :: UserFacing ) => {
764
- drop ( const_val_map ) ;
688
+ drop ( dedup_query_map ) ;
765
689
drop ( dedup_const_map) ;
766
690
767
- // can deduplicate query with Reveal::Selection from Reveal::UserFacing
768
- // since these only differ in the way errors are reported, but successful
769
- // query calls are equivalent.
770
691
let new_key = param_env. with_user_facing ( ) . and ( id) ;
771
- return self . eval_to_const_value_raw ( new_key) ;
692
+ return query_call ( new_key) ;
772
693
}
773
694
_ => { }
774
695
} ,
775
696
Reveal :: UserFacing => match dedup_reveal {
776
697
Some ( Reveal :: UserFacing ) => {
777
- drop ( const_val_map ) ;
698
+ drop ( dedup_query_map ) ;
778
699
drop ( dedup_const_map) ;
779
700
780
- return self . eval_to_const_value_raw ( key) ;
701
+ return query_call ( key) ;
781
702
}
782
703
Some ( Reveal :: Selection ) => {
783
- drop ( const_val_map ) ;
704
+ drop ( dedup_query_map ) ;
784
705
drop ( dedup_const_map) ;
785
706
786
707
let new_key = param_env. with_reveal_selection ( ) . and ( id) ;
787
- return self . eval_to_const_value_raw ( new_key) ;
708
+ return query_call ( new_key) ;
788
709
}
789
710
_ => { }
790
711
} ,
791
712
Reveal :: All => match dedup_reveal {
792
713
Some ( Reveal :: Selection ) => {
793
- drop ( const_val_map ) ;
714
+ drop ( dedup_query_map ) ;
794
715
drop ( dedup_const_map) ;
795
716
796
717
let new_key = param_env. with_reveal_selection ( ) . and ( id) ;
797
- return self . eval_to_const_value_raw ( new_key) ;
718
+ return query_call ( new_key) ;
798
719
}
799
720
Some ( Reveal :: UserFacing ) => {
800
- drop ( const_val_map ) ;
721
+ drop ( dedup_query_map ) ;
801
722
drop ( dedup_const_map) ;
802
723
803
724
let new_key = param_env. with_user_facing ( ) . and ( id) ;
804
- return self . eval_to_const_value_raw ( new_key) ;
725
+ return query_call ( new_key) ;
805
726
}
806
727
Some ( Reveal :: All ) => {
807
- drop ( const_val_map ) ;
728
+ drop ( dedup_query_map ) ;
808
729
drop ( dedup_const_map) ;
809
730
810
- return self . eval_to_const_value_raw ( key) ;
731
+ return query_call ( key) ;
811
732
}
812
733
_ => { }
813
734
} ,
814
735
}
815
736
816
737
// Important to drop the lock here
817
- drop ( const_val_map ) ;
738
+ drop ( dedup_query_map ) ;
818
739
drop ( dedup_const_map) ;
819
740
820
741
debug ! ( "unable to deduplicate" ) ;
821
742
822
743
// We weren't able to deduplicate
823
744
match opt_span {
824
- Some ( span) => self . at ( span ) . eval_to_const_value_raw ( key) ,
825
- None => self . eval_to_const_value_raw ( key) ,
745
+ Some ( span) => query_call_span ( key, span ) ,
746
+ None => query_call ( key) ,
826
747
}
827
748
}
828
749
}
829
750
751
+ enum EvalCtxt {
752
+ Alloc ,
753
+ ConstVal ,
754
+ }
755
+
830
756
////////////////////////////////////////////////////////////////////////////////
831
757
// Methods to access integers in the target endianness
832
758
////////////////////////////////////////////////////////////////////////////////
0 commit comments