1+ use  std:: ops:: ControlFlow ; 
2+ 
13use  rustc_abi:: { FieldIdx ,  VariantIdx } ; 
24use  rustc_apfloat:: Float ; 
35use  rustc_data_structures:: fx:: FxHashSet ; 
@@ -187,7 +189,7 @@ impl<'tcx> ConstToPat<'tcx> {
187189
188190        if  !inlined_const_as_pat. references_error ( )  { 
189191            // Always check for `PartialEq` if we had no other errors yet. 
190-             if  !type_has_partial_eq_impl ( self . tcx ,  typing_env,  ty) . 0  { 
192+             if  !type_has_partial_eq_impl ( self . tcx ,  typing_env,  ty) . has_impl  { 
191193                let  mut  err = self . tcx . dcx ( ) . create_err ( TypeNotPartialEq  {  span :  self . span ,  ty } ) ; 
192194                extend_type_not_partial_eq ( self . tcx ,  typing_env,  ty,  & mut  err) ; 
193195                return  self . mk_err ( err,  ty) ; 
@@ -221,12 +223,13 @@ impl<'tcx> ConstToPat<'tcx> {
221223                // Extremely important check for all ADTs! Make sure they opted-in to be used in 
222224                // patterns. 
223225                debug ! ( "adt_def {:?} has !type_marked_structural for cv.ty: {:?}" ,  adt_def,  ty) ; 
224-                 let  ( _impls_partial_eq,  derived,  structural,  impl_def_id)  =
225-                     type_has_partial_eq_impl ( self . tcx ,  self . typing_env ,  ty) ; 
226+                 let  PartialEqImplStatus  { 
227+                     is_derived,  structural_partial_eq,  non_blanket_impl,  ..
228+                 }  = type_has_partial_eq_impl ( self . tcx ,  self . typing_env ,  ty) ; 
226229                let  ( manual_partialeq_impl_span,  manual_partialeq_impl_note)  =
227-                     match  ( structural ,  impl_def_id )  { 
230+                     match  ( structural_partial_eq ,  non_blanket_impl )  { 
228231                        ( true ,  _)  => ( None ,  false ) , 
229-                         ( _,  Some ( def_id) )  if  def_id. is_local ( )  && !derived  => { 
232+                         ( _,  Some ( def_id) )  if  def_id. is_local ( )  && !is_derived  => { 
230233                            ( Some ( tcx. def_span ( def_id) ) ,  false ) 
231234                        } 
232235                        _ => ( None ,  true ) , 
@@ -390,15 +393,24 @@ fn extend_type_not_partial_eq<'tcx>(
390393    } 
391394
392395    impl < ' tcx >  TypeVisitor < TyCtxt < ' tcx > >  for  UsedParamsNeedInstantiationVisitor < ' tcx >  { 
393-         fn  visit_ty ( & mut  self ,  ty :  Ty < ' tcx > )  -> Self :: Result  { 
396+         type  Result  = ControlFlow < ( ) > ; 
397+         fn  visit_ty ( & mut  self ,  ty :  Ty < ' tcx > )  -> ControlFlow < ( ) >  { 
394398            if  ty. has_escaping_bound_vars ( )  { 
395399                self . has_escaping_bound_vars  = true ; 
400+                 return  ControlFlow :: Break ( ( ) ) ; 
401+             }  else  if  let  ty:: Dynamic ( ..)  = ty. kind ( )  { 
402+                 self . has_escaping_bound_vars  = true ; 
403+                 return  ControlFlow :: Break ( ( ) ) ; 
396404            }  else  if  let  ty:: Adt ( def,  _args)  = ty. kind ( )  { 
397405                let  ty_def_id = def. did ( ) ; 
398406                let  ty_def_span = self . tcx . def_span ( ty_def_id) ; 
399-                 let  ( impls_partial_eq,  derived,  structural,  impl_def_id)  =
400-                     type_has_partial_eq_impl ( self . tcx ,  self . typing_env ,  ty) ; 
401-                 match  ( impls_partial_eq,  derived,  structural,  impl_def_id)  { 
407+                 let  PartialEqImplStatus  { 
408+                     has_impl, 
409+                     is_derived, 
410+                     structural_partial_eq, 
411+                     non_blanket_impl, 
412+                 }  = type_has_partial_eq_impl ( self . tcx ,  self . typing_env ,  ty) ; 
413+                 match  ( has_impl,  is_derived,  structural_partial_eq,  non_blanket_impl)  { 
402414                    ( _,  _,  true ,  _)  => { } 
403415                    ( true ,  false ,  _,  Some ( def_id) )  if  def_id. is_local ( )  => { 
404416                        self . adts_with_manual_partialeq . insert ( self . tcx . def_span ( def_id) ) ; 
@@ -459,17 +471,20 @@ fn extend_type_not_partial_eq<'tcx>(
459471    } 
460472} 
461473
474+ #[ derive( Debug ) ]  
475+ struct  PartialEqImplStatus  { 
476+     has_impl :  bool , 
477+     is_derived :  bool , 
478+     structural_partial_eq :  bool , 
479+     non_blanket_impl :  Option < DefId > , 
480+ } 
481+ 
462482#[ instrument( level = "trace" ,  skip( tcx) ,  ret) ]  
463483fn  type_has_partial_eq_impl < ' tcx > ( 
464484    tcx :  TyCtxt < ' tcx > , 
465485    typing_env :  ty:: TypingEnv < ' tcx > , 
466486    ty :  Ty < ' tcx > , 
467- )  -> ( 
468-     /* has impl */  bool , 
469-     /* is derived */  bool , 
470-     /* structural partial eq */  bool , 
471-     /* non-blanket impl */  Option < DefId > , 
472- )  { 
487+ )  -> PartialEqImplStatus  { 
473488    let  ( infcx,  param_env)  = tcx. infer_ctxt ( ) . build_with_typing_env ( typing_env) ; 
474489    // double-check there even *is* a semantic `PartialEq` to dispatch to. 
475490    // 
@@ -479,10 +494,6 @@ fn type_has_partial_eq_impl<'tcx>(
479494    let  partial_eq_trait_id = tcx. require_lang_item ( hir:: LangItem :: PartialEq ,  None ) ; 
480495    let  structural_partial_eq_trait_id = tcx. require_lang_item ( hir:: LangItem :: StructuralPeq ,  None ) ; 
481496
482-     if  ty. has_escaping_bound_vars ( )  { 
483-         return  ( false ,  false ,  false ,  None ) ; 
484-     } 
485- 
486497    let  partial_eq_obligation = Obligation :: new ( 
487498        tcx, 
488499        ObligationCause :: dummy ( ) , 
@@ -510,10 +521,10 @@ fn type_has_partial_eq_impl<'tcx>(
510521    // that patterns can only do things that the code could also do without patterns, but it is 
511522    // needed for backwards compatibility. The actual pattern matching compares primitive values, 
512523    // `PartialEq::eq` never gets invoked, so there's no risk of us running non-const code. 
513-     ( 
514-         infcx. predicate_must_hold_modulo_regions ( & partial_eq_obligation) , 
515-         automatically_derived, 
516-         structural_peq, 
517-         impl_def_id, 
518-     ) 
524+     PartialEqImplStatus   { 
525+         has_impl :   infcx. predicate_must_hold_modulo_regions ( & partial_eq_obligation) , 
526+         is_derived :   automatically_derived, 
527+         structural_partial_eq :   structural_peq, 
528+         non_blanket_impl :   impl_def_id, 
529+     } 
519530} 
0 commit comments