@@ -24,20 +24,21 @@ use ty::steal::Steal;
24
24
use ty:: subst:: Substs ;
25
25
use util:: nodemap:: { DefIdSet , NodeSet } ;
26
26
27
- use rustc_data_structures:: fx:: FxHashMap ;
28
27
use rustc_data_structures:: indexed_vec:: IndexVec ;
29
28
use std:: cell:: { RefCell , RefMut } ;
29
+ use std:: option;
30
30
use std:: fmt:: Debug ;
31
31
use std:: hash:: Hash ;
32
32
use std:: iter:: { self , Once } ;
33
33
use std:: mem;
34
34
use std:: collections:: BTreeMap ;
35
35
use std:: ops:: Deref ;
36
36
use std:: rc:: Rc ;
37
+ use std:: vec;
37
38
use syntax_pos:: { Span , DUMMY_SP } ;
38
39
use syntax:: symbol:: Symbol ;
39
40
40
- trait Key : Clone + Hash + Eq + Debug {
41
+ pub trait Key : Clone + Hash + Eq + Debug {
41
42
fn map_crate ( & self ) -> CrateNum ;
42
43
fn default_span ( & self , tcx : TyCtxt ) -> Span ;
43
44
}
@@ -163,27 +164,61 @@ impl<'tcx> Value<'tcx> for ty::SymbolName {
163
164
trait IntoKeyValues < K : Key , V > {
164
165
type KeyValues : IntoIterator < Item =( K , V ) > ;
165
166
166
- fn into_key_values ( tcx : TyCtxt , key : & K , value : Self ) -> Self :: KeyValues ;
167
+ fn into_key_values ( key : & K , value : Self ) -> Self :: KeyValues ;
167
168
}
168
169
169
170
impl < K : Key , V > IntoKeyValues < K , V > for V {
170
171
type KeyValues = Once < ( K , V ) > ;
171
172
172
- fn into_key_values ( _ : TyCtxt , key : & K , value : Self ) -> Self :: KeyValues {
173
+ fn into_key_values ( key : & K , value : Self ) -> Self :: KeyValues {
173
174
iter:: once ( ( key. clone ( ) , value) )
174
175
}
175
176
}
176
177
177
- impl < K : Key , V > IntoKeyValues < K , V > for FxHashMap < K , V > {
178
- type KeyValues = Self ;
178
+ /// Return type for a multi-query, which is a query which may (if it
179
+ /// chooses) return more than one (key, value) pair. Construct a
180
+ /// `Multi` using `Multi::from(...)`.
181
+ pub struct Multi < K : Key , V > {
182
+ single : Option < V > ,
183
+ map : Vec < ( K , V ) > ,
184
+ }
179
185
180
- fn into_key_values ( tcx : TyCtxt , key : & K , value : Self ) -> Self {
181
- if !value. contains_key ( key) {
182
- span_bug ! ( key. default_span( tcx) ,
183
- "multi-generation function for `{:?}` did not generate a value for `{:?}`" ,
184
- key, key)
186
+ impl < K : Key , V > Multi < K , V > {
187
+ pub fn iter < ' a > ( & ' a self , key : & ' a K ) -> impl Iterator < Item = ( & ' a K , & ' a V ) > + ' a {
188
+ self . single . iter ( )
189
+ . map ( move |v| ( key, v) )
190
+ . chain ( self . map . iter ( ) . map ( move |& ( ref k, ref v) | ( k, v) ) )
191
+ }
192
+ }
193
+
194
+ /// Construct a `Multi` from a single value.
195
+ impl < K : Key , V > From < V > for Multi < K , V > {
196
+ fn from ( value : V ) -> Self {
197
+ Multi {
198
+ single : Some ( value) ,
199
+ map : vec ! [ ] ,
185
200
}
186
- value
201
+ }
202
+ }
203
+
204
+ /// Construct a `Multi` from a hashmap of (K, V) pairs.
205
+ impl < K : Key , V > From < Vec < ( K , V ) > > for Multi < K , V > {
206
+ fn from ( value : Vec < ( K , V ) > ) -> Self {
207
+ Multi {
208
+ single : None ,
209
+ map : value
210
+ }
211
+ }
212
+ }
213
+
214
+ impl < K : Key , V > IntoKeyValues < K , V > for Multi < K , V > {
215
+ type KeyValues = iter:: Chain < option:: IntoIter < ( K , V ) > , vec:: IntoIter < ( K , V ) > > ;
216
+
217
+ fn into_key_values ( key : & K , value : Self ) -> Self :: KeyValues {
218
+ value. single
219
+ . map ( |v| ( key. clone ( ) , v) )
220
+ . into_iter ( )
221
+ . chain ( value. map )
187
222
}
188
223
}
189
224
@@ -469,7 +504,7 @@ macro_rules! define_maps {
469
504
470
505
{
471
506
let map = & mut * tcx. maps. $name. borrow_mut( ) ;
472
- for ( k, v) in IntoKeyValues :: <$K, $V>:: into_key_values( tcx , & key, result) {
507
+ for ( k, v) in IntoKeyValues :: <$K, $V>:: into_key_values( & key, result) {
473
508
map. insert( k, v) ;
474
509
}
475
510
}
@@ -545,16 +580,6 @@ macro_rules! define_maps {
545
580
impl <$tcx> Clone for Providers <$tcx> {
546
581
fn clone( & self ) -> Self { * self }
547
582
}
548
-
549
- impl <$tcx> Default for Providers <$tcx> {
550
- fn default ( ) -> Self {
551
- $( fn $name<' a, $tcx>( _: TyCtxt <' a, $tcx, $tcx>, key: $K) -> $V {
552
- bug!( "tcx.maps.{}({:?}) unsupported by its crate" ,
553
- stringify!( $name) , key) ;
554
- } ) *
555
- Providers { $( $name) ,* }
556
- }
557
- }
558
583
}
559
584
}
560
585
@@ -642,34 +667,43 @@ macro_rules! define_provider_struct {
642
667
// Final state:
643
668
( tcx: $tcx: tt,
644
669
input: ( ) ,
645
- output: ( $( $output : tt ) * ) ) => {
670
+ output: ( $( ( [ $name : ident ] [ $K : ty ] [ $R : ty ] ) ) * ) ) => {
646
671
pub struct Providers <$tcx> {
647
- $( $output) *
672
+ $( pub $name: for <' a> fn ( TyCtxt <' a, $tcx, $tcx>, $K) -> $R, ) *
673
+ }
674
+
675
+ impl <$tcx> Default for Providers <$tcx> {
676
+ fn default ( ) -> Self {
677
+ $( fn $name<' a, $tcx>( _: TyCtxt <' a, $tcx, $tcx>, key: $K) -> $R {
678
+ bug!( "tcx.maps.{}({:?}) unsupported by its crate" ,
679
+ stringify!( $name) , key) ;
680
+ } ) *
681
+ Providers { $( $name) ,* }
682
+ }
648
683
}
649
684
} ;
650
685
651
686
// Something ready to shift:
652
687
( tcx: $tcx: tt,
653
- ready: ( [ $name: ident ] [ $K: ty ] [ $R : ty ] ) ,
688
+ ready: ( $name: tt $K: tt $V : tt ) ,
654
689
input: $input: tt,
655
690
output: ( $( $output: tt) * ) ) => {
656
691
define_provider_struct! {
657
692
tcx: $tcx,
658
693
input: $input,
659
- output: ( $( $output) *
660
- pub $name: for <' a> fn ( TyCtxt <' a, $tcx, $tcx>, $K) -> $R, )
694
+ output: ( $( $output) * ( $name $K $V) )
661
695
}
662
696
} ;
663
697
664
698
// The `multi` modifier indicates a **multiquery**, in which case
665
- // the function returns a `FxHashMap <K,V>` instead of just a value
699
+ // the function returns a `Multi <K,V>` instead of just a value
666
700
// `V`.
667
701
( tcx: $tcx: tt,
668
702
input: ( ( [ multi $( $other_modifiers: tt) * ] $name: tt [ $K: ty] [ $V: ty] ) $( $input: tt) * ) ,
669
703
output: $output: tt) => {
670
704
define_provider_struct! {
671
705
tcx: $tcx,
672
- ready: ( $name [ $K] [ FxHashMap <$K, $V>] ) ,
706
+ ready: ( $name [ $K] [ Multi <$K, $V>] ) ,
673
707
input: ( $( $input) * ) ,
674
708
output: $output
675
709
}
@@ -778,7 +812,7 @@ define_maps! { <'tcx>
778
812
/// Fetch the MIR for a given def-id after a given pass has been executed. This is
779
813
/// **only** intended to be used by the `mir_suite` provider -- if you are using it
780
814
/// manually, you're doing it wrong.
781
- [ ] mir_pass: mir_pass( ( MirSuite , MirPassIndex , DefId ) ) -> & ' tcx Steal <mir:: Mir <' tcx>>,
815
+ [ multi ] mir_pass: mir_pass( ( MirSuite , MirPassIndex , DefId ) ) -> & ' tcx Steal <mir:: Mir <' tcx>>,
782
816
783
817
/// MIR after our optimization passes have run. This is MIR that is ready
784
818
/// for trans. This is also the only query that can fetch non-local MIR, at present.
0 commit comments