@@ -10,8 +10,9 @@ use rustc_type_ir::solve::{
1010 RerunReason , RerunResultExt , SizedTraitKind ,
1111} ;
1212use rustc_type_ir:: {
13- self as ty, FieldInfo , Interner , MayBeErased , Movability , PredicatePolarity , TraitPredicate ,
14- TraitRef , TypeVisitableExt as _, TypingMode , Unnormalized , Upcast as _, elaborate,
13+ self as ty, ExistentialPredicate , FieldInfo , Interner , MayBeErased , Movability ,
14+ PredicatePolarity , TraitPredicate , TraitRef , TypeVisitableExt as _, TypingMode , Unnormalized ,
15+ Upcast as _, elaborate,
1516} ;
1617use tracing:: { debug, instrument, trace, warn} ;
1718
@@ -87,12 +88,17 @@ where
8788 // Impl matches polarity
8889 ( ty:: ImplPolarity :: Positive , ty:: PredicatePolarity :: Positive )
8990 | ( ty:: ImplPolarity :: Negative , ty:: PredicatePolarity :: Negative ) => {
90- if let TypingMode :: Reflection = ecx. typing_mode ( )
91- && !cx. is_fully_generic_for_reflection ( impl_def_id)
92- {
93- return Err ( NoSolution . into ( ) ) ;
94- } else {
95- Certainty :: Yes
91+ match ecx. typing_mode ( ) {
92+ TypingMode :: Reflection if !cx. is_fully_generic_for_reflection ( impl_def_id) => {
93+ return Err ( NoSolution . into ( ) ) ;
94+ }
95+ TypingMode :: Coherence
96+ | TypingMode :: ErasedNotCoherence ( _)
97+ | TypingMode :: Analysis { .. }
98+ | TypingMode :: Borrowck { .. }
99+ | TypingMode :: PostBorrowckAnalysis { .. }
100+ | TypingMode :: PostAnalysis
101+ | TypingMode :: Reflection => Certainty :: Yes ,
96102 }
97103 }
98104
@@ -873,6 +879,49 @@ where
873879 }
874880 }
875881
882+ fn consider_builtin_try_as_dyn_candidate (
883+ ecx : & mut EvalCtxt < ' _ , D > ,
884+ goal : Goal < I , Self > ,
885+ ) -> Result < Candidate < I > , NoSolutionOrRerunNonErased > {
886+ if goal. predicate . polarity != ty:: PredicatePolarity :: Positive {
887+ return Err ( NoSolution . into ( ) ) ;
888+ }
889+ let cx = ecx. cx ( ) ;
890+
891+ ecx. probe_builtin_trait_candidate ( BuiltinImplSource :: Misc ) . enter ( |ecx| {
892+ let self_ty = goal. predicate . self_ty ( ) ;
893+ let ty_lifetime = goal. predicate . trait_ref . args . region_at ( 1 ) ;
894+ match self_ty. kind ( ) {
895+ ty:: Dynamic ( bounds, lifetime) => {
896+ for bound in bounds. iter ( ) {
897+ match bound. skip_binder ( ) {
898+ ExistentialPredicate :: Trait ( _) => { }
899+ // FIXME(try_as_dyn): check what kind of projections we can allow
900+ ExistentialPredicate :: Projection ( _) => return Err ( NoSolution . into ( ) ) ,
901+ // Auto traits do not affect lifetimes outside of specialization,
902+ // which is disabled in reflection.
903+ ExistentialPredicate :: AutoTrait ( _) => { }
904+ }
905+ }
906+ ecx. add_goal (
907+ GoalSource :: Misc ,
908+ goal. with ( cx, ty:: OutlivesPredicate ( ty_lifetime, lifetime) ) ,
909+ ) ;
910+ ecx. evaluate_added_goals_and_make_canonical_response ( Certainty :: Yes )
911+ }
912+
913+ ty:: Bound ( ..)
914+ | ty:: Infer (
915+ ty:: TyVar ( _) | ty:: FreshTy ( _) | ty:: FreshIntTy ( _) | ty:: FreshFloatTy ( _) ,
916+ ) => {
917+ panic ! ( "unexpected type `{self_ty:?}`" )
918+ }
919+
920+ _ => Err ( NoSolution . into ( ) ) ,
921+ }
922+ } )
923+ }
924+
876925 fn consider_builtin_field_candidate (
877926 ecx : & mut EvalCtxt < ' _ , D > ,
878927 goal : Goal < I , Self > ,
0 commit comments