@@ -11,10 +11,11 @@ use crate::traits::SkipLeakCheck;
11
11
use crate :: traits:: { self , Normalized , Obligation , ObligationCause , SelectionContext } ;
12
12
use crate :: ty:: fold:: TypeFoldable ;
13
13
use crate :: ty:: subst:: Subst ;
14
- use crate :: ty:: { self , Ty , TyCtxt } ;
14
+ use crate :: ty:: { self , fast_reject , Ty , TyCtxt } ;
15
15
use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
16
16
use rustc_span:: symbol:: sym;
17
17
use rustc_span:: DUMMY_SP ;
18
+ use std:: iter;
18
19
19
20
/// Whether we do the orphan check relative to this crate or
20
21
/// to some remote crate.
70
71
impl1_def_id, impl2_def_id, intercrate_mode
71
72
) ;
72
73
74
+ // Before doing expensive operations like entering an inference context, do
75
+ // a quick check via fast_reject to tell if the impl headers could possibly
76
+ // unify.
77
+ let impl1_self = tcx. type_of ( impl1_def_id) ;
78
+ let impl2_self = tcx. type_of ( impl2_def_id) ;
79
+ let impl1_ref = tcx. impl_trait_ref ( impl1_def_id) ;
80
+ let impl2_ref = tcx. impl_trait_ref ( impl2_def_id) ;
81
+
82
+ // Check if any of the input types definitely mismatch.
83
+ if impl1_ref
84
+ . iter ( )
85
+ . flat_map ( |tref| tref. input_types ( ) )
86
+ . zip ( impl2_ref. iter ( ) . flat_map ( |tref| tref. input_types ( ) ) )
87
+ . chain ( iter:: once ( ( impl1_self, impl2_self) ) )
88
+ . any ( |( ty1, ty2) | {
89
+ let ty1 = fast_reject:: simplify_type ( tcx, ty1, false ) ;
90
+ let ty2 = fast_reject:: simplify_type ( tcx, ty2, false ) ;
91
+ if let ( Some ( ty1) , Some ( ty2) ) = ( ty1, ty2) {
92
+ // Simplified successfully
93
+ ty1 != ty2
94
+ } else {
95
+ // Types might unify
96
+ false
97
+ }
98
+ } )
99
+ {
100
+ // Some types involved are definitely different, so the impls couldn't possibly overlap.
101
+ debug ! ( "overlapping_impls: fast_reject early-exit" ) ;
102
+ return no_overlap ( ) ;
103
+ }
104
+
73
105
let overlaps = tcx. infer_ctxt ( ) . enter ( |infcx| {
74
106
let selcx = & mut SelectionContext :: intercrate ( & infcx, intercrate_mode) ;
75
107
overlap ( selcx, skip_leak_check, impl1_def_id, impl2_def_id) . is_some ( )
0 commit comments