11//! Orphan checker: every impl either implements a trait defined in this 
22//! crate or pertains to a type defined in this crate. 
33
4- use  rustc_data_structures:: fx:: FxHashSet ; 
5- use  rustc_errors:: { DelayDm ,  ErrorGuaranteed } ; 
4+ use  rustc_errors:: ErrorGuaranteed ; 
65use  rustc_hir as  hir; 
7- use  rustc_middle:: ty:: util:: CheckRegions ; 
8- use  rustc_middle:: ty:: GenericArgs ; 
9- use  rustc_middle:: ty:: { 
10-     self ,  AliasKind ,  ImplPolarity ,  Ty ,  TyCtxt ,  TypeSuperVisitable ,  TypeVisitable ,  TypeVisitableExt , 
11-     TypeVisitor , 
12- } ; 
13- use  rustc_session:: lint; 
14- use  rustc_span:: def_id:: { DefId ,  LocalDefId } ; 
6+ use  rustc_middle:: ty:: { self ,  AliasKind ,  Ty ,  TyCtxt ,  TypeVisitableExt } ; 
7+ use  rustc_span:: def_id:: LocalDefId ; 
158use  rustc_span:: Span ; 
169use  rustc_trait_selection:: traits; 
17- use  std:: ops:: ControlFlow ; 
1810
1911use  crate :: errors; 
2012
@@ -26,30 +18,17 @@ pub(crate) fn orphan_check_impl(
2618    let  trait_ref = tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) . instantiate_identity ( ) ; 
2719    trait_ref. error_reported ( ) ?; 
2820
29-     let  ret = do_orphan_check_impl ( tcx,  trait_ref,  impl_def_id) ; 
30-     if  tcx. trait_is_auto ( trait_ref. def_id )  { 
31-         lint_auto_trait_impl ( tcx,  trait_ref,  impl_def_id) ; 
32-     } 
33- 
34-     ret
35- } 
36- 
37- fn  do_orphan_check_impl < ' tcx > ( 
38-     tcx :  TyCtxt < ' tcx > , 
39-     trait_ref :  ty:: TraitRef < ' tcx > , 
40-     def_id :  LocalDefId , 
41- )  -> Result < ( ) ,  ErrorGuaranteed >  { 
4221    let  trait_def_id = trait_ref. def_id ; 
4322
44-     match  traits:: orphan_check ( tcx,  def_id . to_def_id ( ) )  { 
23+     match  traits:: orphan_check ( tcx,  impl_def_id . to_def_id ( ) )  { 
4524        Ok ( ( ) )  => { } 
4625        Err ( err)  => { 
47-             let  item = tcx. hir ( ) . expect_item ( def_id ) ; 
26+             let  item = tcx. hir ( ) . expect_item ( impl_def_id ) ; 
4827            let  hir:: ItemKind :: Impl ( impl_)  = item. kind  else  { 
49-                 bug ! ( "{:?} is not an impl: {:?}" ,  def_id ,  item) ; 
28+                 bug ! ( "{:?} is not an impl: {:?}" ,  impl_def_id ,  item) ; 
5029            } ; 
5130            let  tr = impl_. of_trait . as_ref ( ) . unwrap ( ) ; 
52-             let  sp = tcx. def_span ( def_id ) ; 
31+             let  sp = tcx. def_span ( impl_def_id ) ; 
5332
5433            emit_orphan_check_error ( 
5534                tcx, 
@@ -193,7 +172,7 @@ fn do_orphan_check_impl<'tcx>(
193172            // impl<T> AutoTrait for T {} 
194173            // impl<T: ?Sized> AutoTrait for T {} 
195174            ty:: Param ( ..)  => ( 
196-                 if  self_ty. is_sized ( tcx,  tcx. param_env ( def_id ) )  { 
175+                 if  self_ty. is_sized ( tcx,  tcx. param_env ( impl_def_id ) )  { 
197176                    LocalImpl :: Allow 
198177                }  else  { 
199178                    LocalImpl :: Disallow  {  problematic_kind :  "generic type"  } 
@@ -250,7 +229,7 @@ fn do_orphan_check_impl<'tcx>(
250229            | ty:: Bound ( ..) 
251230            | ty:: Placeholder ( ..) 
252231            | ty:: Infer ( ..)  => { 
253-                 let  sp = tcx. def_span ( def_id ) ; 
232+                 let  sp = tcx. def_span ( impl_def_id ) ; 
254233                span_bug ! ( sp,  "weird self type for autotrait impl" ) 
255234            } 
256235
@@ -262,7 +241,7 @@ fn do_orphan_check_impl<'tcx>(
262241                LocalImpl :: Allow  => { } 
263242                LocalImpl :: Disallow  {  problematic_kind }  => { 
264243                    return  Err ( tcx. dcx ( ) . emit_err ( errors:: TraitsWithDefaultImpl  { 
265-                         span :  tcx. def_span ( def_id ) , 
244+                         span :  tcx. def_span ( impl_def_id ) , 
266245                        traits :  tcx. def_path_str ( trait_def_id) , 
267246                        problematic_kind, 
268247                        self_ty, 
@@ -274,13 +253,13 @@ fn do_orphan_check_impl<'tcx>(
274253                NonlocalImpl :: Allow  => { } 
275254                NonlocalImpl :: DisallowBecauseNonlocal  => { 
276255                    return  Err ( tcx. dcx ( ) . emit_err ( errors:: CrossCrateTraitsDefined  { 
277-                         span :  tcx. def_span ( def_id ) , 
256+                         span :  tcx. def_span ( impl_def_id ) , 
278257                        traits :  tcx. def_path_str ( trait_def_id) , 
279258                    } ) ) ; 
280259                } 
281260                NonlocalImpl :: DisallowOther  => { 
282261                    return  Err ( tcx. dcx ( ) . emit_err ( errors:: CrossCrateTraits  { 
283-                         span :  tcx. def_span ( def_id ) , 
262+                         span :  tcx. def_span ( impl_def_id ) , 
284263                        traits :  tcx. def_path_str ( trait_def_id) , 
285264                        self_ty, 
286265                    } ) ) ; 
@@ -445,146 +424,3 @@ fn emit_orphan_check_error<'tcx>(
445424        } 
446425    } ) 
447426} 
448- 
449- /// Lint impls of auto traits if they are likely to have 
450- /// unsound or surprising effects on auto impls. 
451- fn  lint_auto_trait_impl < ' tcx > ( 
452-     tcx :  TyCtxt < ' tcx > , 
453-     trait_ref :  ty:: TraitRef < ' tcx > , 
454-     impl_def_id :  LocalDefId , 
455- )  { 
456-     if  trait_ref. args . len ( )  != 1  { 
457-         tcx. dcx ( ) . span_delayed_bug ( 
458-             tcx. def_span ( impl_def_id) , 
459-             "auto traits cannot have generic parameters" , 
460-         ) ; 
461-         return ; 
462-     } 
463-     let  self_ty = trait_ref. self_ty ( ) ; 
464-     let  ( self_type_did,  args)  = match  self_ty. kind ( )  { 
465-         ty:: Adt ( def,  args)  => ( def. did ( ) ,  args) , 
466-         _ => { 
467-             // FIXME: should also lint for stuff like `&i32` but 
468-             // considering that auto traits are unstable, that 
469-             // isn't too important for now as this only affects 
470-             // crates using `nightly`, and std. 
471-             return ; 
472-         } 
473-     } ; 
474- 
475-     // Impls which completely cover a given root type are fine as they 
476-     // disable auto impls entirely. So only lint if the args 
477-     // are not a permutation of the identity args. 
478-     let  Err ( arg)  = tcx. uses_unique_generic_params ( args,  CheckRegions :: No )  else  { 
479-         // ok 
480-         return ; 
481-     } ; 
482- 
483-     // Ideally: 
484-     // 
485-     // - compute the requirements for the auto impl candidate 
486-     // - check whether these are implied by the non covering impls 
487-     // - if not, emit the lint 
488-     // 
489-     // What we do here is a bit simpler: 
490-     // 
491-     // - badly check if an auto impl candidate definitely does not apply 
492-     //   for the given simplified type 
493-     // - if so, do not lint 
494-     if  fast_reject_auto_impl ( tcx,  trait_ref. def_id ,  self_ty)  { 
495-         // ok 
496-         return ; 
497-     } 
498- 
499-     tcx. node_span_lint ( 
500-         lint:: builtin:: SUSPICIOUS_AUTO_TRAIT_IMPLS , 
501-         tcx. local_def_id_to_hir_id ( impl_def_id) , 
502-         tcx. def_span ( impl_def_id) , 
503-         DelayDm ( || { 
504-             format ! ( 
505-                 "cross-crate traits with a default impl, like `{}`, \  
506- , 
507-                 tcx. def_path_str( trait_ref. def_id) , 
508-             ) 
509-         } ) , 
510-         |lint| { 
511-             let  item_span = tcx. def_span ( self_type_did) ; 
512-             let  self_descr = tcx. def_descr ( self_type_did) ; 
513-             match  arg { 
514-                 ty:: util:: NotUniqueParam :: DuplicateParam ( arg)  => { 
515-                     lint. note ( format ! ( "`{arg}` is mentioned multiple times" ) ) ; 
516-                 } 
517-                 ty:: util:: NotUniqueParam :: NotParam ( arg)  => { 
518-                     lint. note ( format ! ( "`{arg}` is not a generic parameter" ) ) ; 
519-                 } 
520-             } 
521-             lint. span_note ( 
522-                 item_span, 
523-                 format ! ( 
524-                     "try using the same sequence of generic parameters as the {self_descr} definition" , 
525-                 ) , 
526-             ) ; 
527-         } , 
528-     ) ; 
529- } 
530- 
531- fn  fast_reject_auto_impl < ' tcx > ( tcx :  TyCtxt < ' tcx > ,  trait_def_id :  DefId ,  self_ty :  Ty < ' tcx > )  -> bool  { 
532-     struct  DisableAutoTraitVisitor < ' tcx >  { 
533-         tcx :  TyCtxt < ' tcx > , 
534-         trait_def_id :  DefId , 
535-         self_ty_root :  Ty < ' tcx > , 
536-         seen :  FxHashSet < DefId > , 
537-     } 
538- 
539-     impl < ' tcx >  TypeVisitor < TyCtxt < ' tcx > >  for  DisableAutoTraitVisitor < ' tcx >  { 
540-         type  BreakTy  = ( ) ; 
541-         fn  visit_ty ( & mut  self ,  ty :  Ty < ' tcx > )  -> ControlFlow < Self :: BreakTy >  { 
542-             let  tcx = self . tcx ; 
543-             if  ty != self . self_ty_root  { 
544-                 for  impl_def_id in  tcx. non_blanket_impls_for_ty ( self . trait_def_id ,  ty)  { 
545-                     match  tcx. impl_polarity ( impl_def_id)  { 
546-                         ImplPolarity :: Negative  => return  ControlFlow :: Break ( ( ) ) , 
547-                         ImplPolarity :: Reservation  => { } 
548-                         // FIXME(@lcnr): That's probably not good enough, idk 
549-                         // 
550-                         // We might just want to take the rustdoc code and somehow avoid 
551-                         // explicit impls for `Self`. 
552-                         ImplPolarity :: Positive  => return  ControlFlow :: Continue ( ( ) ) , 
553-                     } 
554-                 } 
555-             } 
556- 
557-             match  ty. kind ( )  { 
558-                 ty:: Adt ( def,  args)  if  def. is_phantom_data ( )  => args. visit_with ( self ) , 
559-                 ty:: Adt ( def,  args)  => { 
560-                     // @lcnr: This is the only place where cycles can happen. We avoid this 
561-                     // by only visiting each `DefId` once. 
562-                     // 
563-                     // This will be is incorrect in subtle cases, but I don't care :) 
564-                     if  self . seen . insert ( def. did ( ) )  { 
565-                         for  ty in  def. all_fields ( ) . map ( |field| field. ty ( tcx,  args) )  { 
566-                             ty. visit_with ( self ) ?; 
567-                         } 
568-                     } 
569- 
570-                     ControlFlow :: Continue ( ( ) ) 
571-                 } 
572-                 _ => ty. super_visit_with ( self ) , 
573-             } 
574-         } 
575-     } 
576- 
577-     let  self_ty_root = match  self_ty. kind ( )  { 
578-         ty:: Adt ( def,  _)  => Ty :: new_adt ( tcx,  * def,  GenericArgs :: identity_for_item ( tcx,  def. did ( ) ) ) , 
579-         _ => unimplemented ! ( "unexpected self ty {:?}" ,  self_ty) , 
580-     } ; 
581- 
582-     self_ty_root
583-         . visit_with ( & mut  DisableAutoTraitVisitor  { 
584-             tcx, 
585-             self_ty_root, 
586-             trait_def_id, 
587-             seen :  FxHashSet :: default ( ) , 
588-         } ) 
589-         . is_break ( ) 
590- } 
0 commit comments