10
10
11
11
//! See `README.md` for high-level documentation
12
12
13
- use super :: Normalized ;
14
- use super :: SelectionContext ;
15
- use super :: ObligationCause ;
16
- use super :: PredicateObligation ;
17
- use super :: project;
18
- use super :: util;
13
+ use super :: { SelectionContext } ;
14
+ use super :: { Obligation , ObligationCause } ;
19
15
20
16
use middle:: cstore:: LOCAL_CRATE ;
21
17
use middle:: def_id:: DefId ;
22
- use middle:: subst:: { Subst , Substs , TypeSpace } ;
18
+ use middle:: subst:: TypeSpace ;
23
19
use middle:: ty:: { self , Ty , TyCtxt } ;
24
20
use middle:: infer:: { self , InferCtxt , TypeOrigin } ;
25
- use syntax:: codemap:: { DUMMY_SP , Span } ;
21
+ use syntax:: codemap:: DUMMY_SP ;
26
22
27
23
#[ derive( Copy , Clone ) ]
28
24
struct InferIsLocal ( bool ) ;
29
25
30
- /// If there are types that satisfy both impls, returns a `TraitRef `
26
+ /// If there are types that satisfy both impls, returns an `ImplTy `
31
27
/// with those types substituted (by updating the given `infcx`)
32
28
pub fn overlapping_impls < ' cx , ' tcx > ( infcx : & InferCtxt < ' cx , ' tcx > ,
33
29
impl1_def_id : DefId ,
34
30
impl2_def_id : DefId )
35
- -> Option < ty:: TraitRef < ' tcx > >
31
+ -> Option < ty:: ImplHeader < ' tcx > >
36
32
{
37
33
debug ! ( "impl_can_satisfy(\
38
34
impl1_def_id={:?}, \
@@ -45,34 +41,28 @@ pub fn overlapping_impls<'cx, 'tcx>(infcx: &InferCtxt<'cx, 'tcx>,
45
41
}
46
42
47
43
/// Can both impl `a` and impl `b` be satisfied by a common type (including
48
- /// `where` clauses)? If so, returns a `TraitRef ` that unifies the two impls.
44
+ /// `where` clauses)? If so, returns an `ImplHeader ` that unifies the two impls.
49
45
fn overlap < ' cx , ' tcx > ( selcx : & mut SelectionContext < ' cx , ' tcx > ,
50
46
a_def_id : DefId ,
51
47
b_def_id : DefId )
52
- -> Option < ty:: TraitRef < ' tcx > >
48
+ -> Option < ty:: ImplHeader < ' tcx > >
53
49
{
54
50
debug ! ( "overlap(a_def_id={:?}, b_def_id={:?})" ,
55
51
a_def_id,
56
52
b_def_id) ;
57
53
58
- let ( a_trait_ref, a_obligations) = impl_trait_ref_and_oblig ( selcx,
59
- a_def_id,
60
- util:: fresh_type_vars_for_impl) ;
54
+ let a_impl_header = ty:: ImplHeader :: with_fresh_ty_vars ( selcx, a_def_id) ;
55
+ let b_impl_header = ty:: ImplHeader :: with_fresh_ty_vars ( selcx, b_def_id) ;
61
56
62
- let ( b_trait_ref, b_obligations) = impl_trait_ref_and_oblig ( selcx,
63
- b_def_id,
64
- util:: fresh_type_vars_for_impl) ;
65
-
66
- debug ! ( "overlap: a_trait_ref={:?} a_obligations={:?}" , a_trait_ref, a_obligations) ;
67
-
68
- debug ! ( "overlap: b_trait_ref={:?} b_obligations={:?}" , b_trait_ref, b_obligations) ;
57
+ debug ! ( "overlap: a_impl_header={:?}" , a_impl_header) ;
58
+ debug ! ( "overlap: b_impl_header={:?}" , b_impl_header) ;
69
59
70
60
// Do `a` and `b` unify? If not, no overlap.
71
- if let Err ( _) = infer:: mk_eq_trait_refs ( selcx. infcx ( ) ,
72
- true ,
73
- TypeOrigin :: Misc ( DUMMY_SP ) ,
74
- a_trait_ref ,
75
- b_trait_ref ) {
61
+ if let Err ( _) = infer:: mk_eq_impl_headers ( selcx. infcx ( ) ,
62
+ true ,
63
+ TypeOrigin :: Misc ( DUMMY_SP ) ,
64
+ & a_impl_header ,
65
+ & b_impl_header ) {
76
66
return None ;
77
67
}
78
68
@@ -81,17 +71,21 @@ fn overlap<'cx, 'tcx>(selcx: &mut SelectionContext<'cx, 'tcx>,
81
71
// Are any of the obligations unsatisfiable? If so, no overlap.
82
72
let infcx = selcx. infcx ( ) ;
83
73
let opt_failing_obligation =
84
- a_obligations. iter ( )
85
- . chain ( & b_obligations)
86
- . map ( |o| infcx. resolve_type_vars_if_possible ( o) )
74
+ a_impl_header. predicates
75
+ . iter ( )
76
+ . chain ( & b_impl_header. predicates )
77
+ . map ( |p| infcx. resolve_type_vars_if_possible ( p) )
78
+ . map ( |p| Obligation { cause : ObligationCause :: dummy ( ) ,
79
+ recursion_depth : 0 ,
80
+ predicate : p } )
87
81
. find ( |o| !selcx. evaluate_obligation ( o) ) ;
88
82
89
83
if let Some ( failing_obligation) = opt_failing_obligation {
90
84
debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
91
85
return None
92
86
}
93
87
94
- Some ( selcx. infcx ( ) . resolve_type_vars_if_possible ( & a_trait_ref ) )
88
+ Some ( selcx. infcx ( ) . resolve_type_vars_if_possible ( & a_impl_header ) )
95
89
}
96
90
97
91
pub fn trait_ref_is_knowable < ' tcx > ( tcx : & TyCtxt < ' tcx > , trait_ref : & ty:: TraitRef < ' tcx > ) -> bool
@@ -125,44 +119,6 @@ pub fn trait_ref_is_knowable<'tcx>(tcx: &TyCtxt<'tcx>, trait_ref: &ty::TraitRef<
125
119
orphan_check_trait_ref ( tcx, trait_ref, InferIsLocal ( true ) ) . is_err ( )
126
120
}
127
121
128
- type SubstsFn = for <' a , ' tcx > fn ( infcx : & InferCtxt < ' a , ' tcx > ,
129
- span : Span ,
130
- impl_def_id : DefId )
131
- -> Substs < ' tcx > ;
132
-
133
- /// Instantiate fresh variables for all bound parameters of the impl
134
- /// and return the impl trait ref with those variables substituted.
135
- fn impl_trait_ref_and_oblig < ' a , ' tcx > ( selcx : & mut SelectionContext < ' a , ' tcx > ,
136
- impl_def_id : DefId ,
137
- substs_fn : SubstsFn )
138
- -> ( ty:: TraitRef < ' tcx > ,
139
- Vec < PredicateObligation < ' tcx > > )
140
- {
141
- let impl_substs =
142
- & substs_fn ( selcx. infcx ( ) , DUMMY_SP , impl_def_id) ;
143
- let impl_trait_ref =
144
- selcx. tcx ( ) . impl_trait_ref ( impl_def_id) . unwrap ( ) ;
145
- let impl_trait_ref =
146
- impl_trait_ref. subst ( selcx. tcx ( ) , impl_substs) ;
147
- let Normalized { value : impl_trait_ref, obligations : normalization_obligations1 } =
148
- project:: normalize ( selcx, ObligationCause :: dummy ( ) , & impl_trait_ref) ;
149
-
150
- let predicates = selcx. tcx ( ) . lookup_predicates ( impl_def_id) ;
151
- let predicates = predicates. instantiate ( selcx. tcx ( ) , impl_substs) ;
152
- let Normalized { value : predicates, obligations : normalization_obligations2 } =
153
- project:: normalize ( selcx, ObligationCause :: dummy ( ) , & predicates) ;
154
- let impl_obligations =
155
- util:: predicates_for_generics ( ObligationCause :: dummy ( ) , 0 , & predicates) ;
156
-
157
- let impl_obligations: Vec < _ > =
158
- impl_obligations. into_iter ( )
159
- . chain ( normalization_obligations1)
160
- . chain ( normalization_obligations2)
161
- . collect ( ) ;
162
-
163
- ( impl_trait_ref, impl_obligations)
164
- }
165
-
166
122
pub enum OrphanCheckErr < ' tcx > {
167
123
NoLocalInputType ,
168
124
UncoveredTy ( Ty < ' tcx > ) ,
0 commit comments