@@ -872,3 +872,61 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>(
872872 . filter_map ( |( ty, exprs) | ty. could_unify_with_deeply ( db, & ctx. goal ) . then_some ( exprs) )
873873 . flatten ( )
874874}
875+
876+ /// # Make tuple tactic
877+ ///
878+ /// Attempts to create tuple types if any are listed in types wishlist
879+ ///
880+ /// Updates lookup by new types reached and returns iterator that yields
881+ /// elements that unify with `goal`.
882+ ///
883+ /// # Arguments
884+ /// * `ctx` - Context for the term search
885+ /// * `defs` - Set of items in scope at term search target location
886+ /// * `lookup` - Lookup table for types
887+ pub ( super ) fn make_tuple < ' a , DB : HirDatabase > (
888+ ctx : & ' a TermSearchCtx < ' a , DB > ,
889+ _defs : & ' a FxHashSet < ScopeDef > ,
890+ lookup : & ' a mut LookupTable ,
891+ ) -> impl Iterator < Item = Expr > + ' a {
892+ let db = ctx. sema . db ;
893+ let module = ctx. scope . module ( ) ;
894+
895+ lookup
896+ . types_wishlist ( )
897+ . clone ( )
898+ . into_iter ( )
899+ . filter ( |ty| ty. is_tuple ( ) )
900+ . filter_map ( move |ty| {
901+ // Double check to not contain unknown
902+ if ty. contains_unknown ( ) {
903+ return None ;
904+ }
905+
906+ // Ignore types that have something to do with lifetimes
907+ if ctx. config . enable_borrowcheck && ty. contains_reference ( db) {
908+ return None ;
909+ }
910+
911+ // Early exit if some param cannot be filled from lookup
912+ let param_exprs: Vec < Vec < Expr > > =
913+ ty. type_arguments ( ) . map ( |field| lookup. find ( db, & field) ) . collect :: < Option < _ > > ( ) ?;
914+
915+ let exprs: Vec < Expr > = param_exprs
916+ . into_iter ( )
917+ . multi_cartesian_product ( )
918+ . map ( |params| {
919+ let tys: Vec < Type > = params. iter ( ) . map ( |it| it. ty ( db) ) . collect ( ) ;
920+ let tuple_ty = Type :: new_tuple ( module. krate ( ) . into ( ) , & tys) ;
921+
922+ let expr = Expr :: Tuple { ty : tuple_ty. clone ( ) , params } ;
923+ lookup. insert ( tuple_ty, iter:: once ( expr. clone ( ) ) ) ;
924+ expr
925+ } )
926+ . collect ( ) ;
927+
928+ Some ( exprs)
929+ } )
930+ . flatten ( )
931+ . filter_map ( |expr| expr. ty ( db) . could_unify_with_deeply ( db, & ctx. goal ) . then_some ( expr) )
932+ }
0 commit comments