@@ -28,10 +28,18 @@ use crate::{
2828
2929pub struct Interners {
3030 goals : Interner < ( Hash64 , ResultIdx ) , GoalIdx , GoalData > ,
31+ implementors : Interner < DefId , ImplementorsIdx , Implementors > ,
3132 candidates : Interner < CanKey , CandidateIdx , CandidateData > ,
3233 results : Interner < EvaluationResult , ResultIdx , ResultData > ,
3334}
3435
36+ pub struct InternedData {
37+ pub goals : IndexVec < GoalIdx , GoalData > ,
38+ pub implementors : IndexVec < ImplementorsIdx , Implementors > ,
39+ pub candidates : IndexVec < CandidateIdx , CandidateData > ,
40+ pub results : IndexVec < ResultIdx , ResultData > ,
41+ }
42+
3543#[ derive( PartialEq , Eq , Hash ) ]
3644enum CanKey {
3745 Impl ( DefId ) ,
@@ -43,23 +51,19 @@ impl Interners {
4351 pub fn default ( ) -> Self {
4452 Self {
4553 goals : Interner :: default ( ) ,
54+ implementors : Interner :: default ( ) ,
4655 candidates : Interner :: default ( ) ,
4756 results : Interner :: default ( ) ,
4857 }
4958 }
5059
51- pub fn take (
52- self ,
53- ) -> (
54- IndexVec < GoalIdx , GoalData > ,
55- IndexVec < CandidateIdx , CandidateData > ,
56- IndexVec < ResultIdx , ResultData > ,
57- ) {
58- (
59- self . goals . consume ( ) ,
60- self . candidates . consume ( ) ,
61- self . results . consume ( ) ,
62- )
60+ pub fn take ( self ) -> InternedData {
61+ InternedData {
62+ goals : self . goals . consume ( ) ,
63+ implementors : self . implementors . consume ( ) ,
64+ candidates : self . candidates . consume ( ) ,
65+ results : self . results . consume ( ) ,
66+ }
6367 }
6468
6569 // NOTE: used in `test_utils`.
@@ -74,10 +78,6 @@ impl Interners {
7478 self . candidates . get_data ( & c) . expect ( "missing candidate idx" )
7579 }
7680
77- pub fn mk_result_node ( & mut self , result : EvaluationResult ) -> ProofNode {
78- ProofNode :: pack ( ProofNodeUnpacked :: Result ( self . intern_result ( result) ) )
79- }
80-
8181 pub fn mk_goal_node ( & mut self , goal : & InspectGoal ) -> ProofNode {
8282 let infcx = goal. infcx ( ) ;
8383 let result_idx = self . intern_result ( goal. result ( ) ) ;
@@ -213,4 +213,63 @@ impl Interners {
213213
214214 self . candidates . insert_no_key ( CandidateData :: from ( string) )
215215 }
216+
217+ pub ( super ) fn intern_implementors (
218+ & mut self ,
219+ infcx : & InferCtxt ,
220+ def_id : DefId ,
221+ tp : ty:: PolyTraitPredicate ,
222+ ) -> ImplementorsIdx {
223+ use argus_ext:: { rustc:: InferCtxtExt , ty:: ImplCandidateExt } ;
224+
225+ if let Some ( i) = self . implementors . get_idx ( & def_id) {
226+ return i;
227+ }
228+
229+ let identity_trait_ref =
230+ ty:: TraitRef :: identity ( infcx. tcx , tp. skip_binder ( ) . trait_ref . def_id ) ;
231+
232+ let trait_ = ser:: TraitRefPrintOnlyTraitPathDef ( identity_trait_ref) ;
233+ let trait_ = tls:: unsafe_access_interner ( |ty_interner| {
234+ ser:: to_value_expect ( infcx, ty_interner, & trait_)
235+ } ) ;
236+
237+ // Gather all impls
238+ let mut impls = vec ! [ ] ;
239+ let mut inductive_impls = vec ! [ ] ;
240+
241+ let mut impl_candidates = infcx. all_impls ( tp. def_id ( ) ) ;
242+
243+ // HACK: Sort the `impl_candidates` by the number of *type* parameters. We use this
244+ // as a proxy for complexity, that is, complexity of reading the impl, we want
245+ // to show Argus users "simpler" impls first.
246+ // This probably shouldn't happen here, as it's a concern of the frontend, but this is
247+ // the last place we have all that information.
248+ macro_rules! sort_by_count {
249+ ( $field: ident, $vec: expr) => {
250+ $vec. sort_by_key( |c| {
251+ infcx. tcx. generics_of( c. impl_def_id) . own_counts( ) . $field
252+ } )
253+ } ;
254+ }
255+ sort_by_count ! ( types, impl_candidates) ;
256+ sort_by_count ! ( lifetimes, impl_candidates) ;
257+
258+ for can in impl_candidates {
259+ let can_idx = self . intern_impl ( infcx, can. impl_def_id ) ;
260+ if can. is_inductive ( infcx. tcx ) {
261+ inductive_impls. push ( can_idx) ;
262+ } else {
263+ impls. push ( can_idx) ;
264+ }
265+ }
266+
267+ let impls = Implementors {
268+ trait_,
269+ impls,
270+ inductive_impls,
271+ } ;
272+
273+ self . implementors . insert ( def_id, impls)
274+ }
216275}
0 commit comments