1
1
//! Orphan checker: every impl either implements a trait defined in this
2
2
//! crate or pertains to a type defined in this crate.
3
3
4
- use rustc_data_structures:: fx:: FxHashSet ;
5
- use rustc_errors:: { DelayDm , ErrorGuaranteed } ;
4
+ use rustc_errors:: ErrorGuaranteed ;
6
5
use 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 ;
15
8
use rustc_span:: Span ;
16
9
use rustc_trait_selection:: traits;
17
- use std:: ops:: ControlFlow ;
18
10
19
11
use crate :: errors;
20
12
@@ -26,12 +18,7 @@ pub(crate) fn orphan_check_impl(
26
18
let trait_ref = tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) . instantiate_identity ( ) ;
27
19
trait_ref. error_reported ( ) ?;
28
20
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)
35
22
}
36
23
37
24
fn do_orphan_check_impl < ' tcx > (
@@ -445,146 +432,3 @@ fn emit_orphan_check_error<'tcx>(
445
432
}
446
433
} )
447
434
}
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