@@ -11,8 +11,9 @@ use rustc_type_ir::lang_items::SolverTraitLangItem;
1111use rustc_type_ir:: search_graph:: CandidateHeadUsages ;
1212use rustc_type_ir:: solve:: SizedTraitKind ;
1313use rustc_type_ir:: {
14- self as ty, Interner , TypeFlags , TypeFoldable , TypeSuperVisitable , TypeVisitable ,
15- TypeVisitableExt as _, TypeVisitor , TypingMode , Upcast as _, elaborate,
14+ self as ty, Interner , TypeFlags , TypeFoldable , TypeFolder , TypeSuperFoldable ,
15+ TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor , TypingMode , Upcast ,
16+ elaborate,
1617} ;
1718use tracing:: { debug, instrument} ;
1819
@@ -399,12 +400,17 @@ where
399400
400401 if normalized_self_ty. is_ty_var ( ) {
401402 debug ! ( "self type has been normalized to infer" ) ;
402- candidates. extend ( self . forced_ambiguity ( MaybeCause :: Ambiguity ) ) ;
403+ self . try_assemble_bounds_via_registered_opaque (
404+ goal,
405+ normalized_self_ty,
406+ & mut candidates,
407+ ) ;
403408 return ( candidates, failed_candidate_info) ;
404409 }
405410
406411 let goal: Goal < I , G > = goal
407412 . with ( self . cx ( ) , goal. predicate . with_replaced_self_ty ( self . cx ( ) , normalized_self_ty) ) ;
413+
408414 // Vars that show up in the rest of the goal substs may have been constrained by
409415 // normalizing the self type as well, since type variables are not uniquified.
410416 let goal = self . resolve_vars_if_possible ( goal) ;
@@ -943,6 +949,61 @@ where
943949 }
944950 }
945951
952+ /// If the self type is the hidden type of an opaque, try to assemble
953+ /// candidates for it by consider its item bounds. This is used to
954+ /// incompletely guide type inference when handling non-defining uses
955+ /// in the defining scope.
956+ fn try_assemble_bounds_via_registered_opaque < G : GoalKind < D > > (
957+ & mut self ,
958+ goal : Goal < I , G > ,
959+ self_ty : I :: Ty ,
960+ candidates : & mut Vec < Candidate < I > > ,
961+ ) {
962+ for alias_ty in self . find_sup_as_registered_opaque ( self_ty) {
963+ for item_bound in self
964+ . cx ( )
965+ . item_self_bounds ( alias_ty. def_id )
966+ . iter_instantiated ( self . cx ( ) , alias_ty. args )
967+ {
968+ // TODO: comment
969+ let assumption =
970+ item_bound. fold_with ( & mut ReplaceOpaque { cx : self . cx ( ) , alias_ty, self_ty } ) ;
971+ candidates. extend ( G :: probe_and_match_goal_against_assumption (
972+ self ,
973+ CandidateSource :: AliasBound ,
974+ goal,
975+ assumption,
976+ |ecx| {
977+ ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: AMBIGUOUS )
978+ } ,
979+ ) ) ;
980+ }
981+
982+ struct ReplaceOpaque < I : Interner > {
983+ cx : I ,
984+ alias_ty : ty:: AliasTy < I > ,
985+ self_ty : I :: Ty ,
986+ }
987+ impl < I : Interner > TypeFolder < I > for ReplaceOpaque < I > {
988+ fn cx ( & self ) -> I {
989+ self . cx
990+ }
991+ fn fold_ty ( & mut self , ty : I :: Ty ) -> I :: Ty {
992+ if let ty:: Alias ( ty:: Opaque , alias_ty) = ty. kind ( ) {
993+ if alias_ty == self . alias_ty {
994+ return self . self_ty ;
995+ }
996+ }
997+ ty. super_fold_with ( self )
998+ }
999+ }
1000+ }
1001+
1002+ if candidates. is_empty ( ) {
1003+ candidates. extend ( self . forced_ambiguity ( MaybeCause :: Ambiguity ) ) ;
1004+ }
1005+ }
1006+
9461007 /// Assemble and merge candidates for goals which are related to an underlying trait
9471008 /// goal. Right now, this is normalizes-to and host effect goals.
9481009 ///
0 commit comments