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,12 +18,7 @@ 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
21+ do_orphan_check_impl ( tcx, trait_ref, impl_def_id)
3522}
3623
3724fn do_orphan_check_impl < ' tcx > (
@@ -445,146 +432,3 @@ fn emit_orphan_check_error<'tcx>(
445432 }
446433 } )
447434}
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- should not be specialized",
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