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 ;
13
+ use super :: { Normalized , SelectionContext } ;
14
+ use super :: { Obligation , ObligationCause , PredicateObligation } ;
17
15
use super :: project;
18
16
use super :: util;
19
17
20
18
use middle:: cstore:: LOCAL_CRATE ;
21
19
use middle:: def_id:: DefId ;
22
20
use middle:: subst:: { Subst , Substs , TypeSpace } ;
23
21
use middle:: ty:: { self , Ty , TyCtxt } ;
22
+ use middle:: ty:: error:: TypeError ;
24
23
use middle:: infer:: { self , InferCtxt , TypeOrigin } ;
25
24
use syntax:: codemap:: { DUMMY_SP , Span } ;
26
25
27
26
#[ derive( Copy , Clone ) ]
28
27
struct InferIsLocal ( bool ) ;
29
28
30
- /// If there are types that satisfy both impls, returns a `TraitRef `
29
+ /// If there are types that satisfy both impls, returns an `ImplTy `
31
30
/// with those types substituted (by updating the given `infcx`)
32
31
pub fn overlapping_impls < ' cx , ' tcx > ( infcx : & InferCtxt < ' cx , ' tcx > ,
33
32
impl1_def_id : DefId ,
34
33
impl2_def_id : DefId )
35
- -> Option < ty :: TraitRef < ' tcx > >
34
+ -> Option < ImplTy < ' tcx > >
36
35
{
37
36
debug ! ( "impl_can_satisfy(\
38
37
impl1_def_id={:?}, \
@@ -45,34 +44,28 @@ pub fn overlapping_impls<'cx, 'tcx>(infcx: &InferCtxt<'cx, 'tcx>,
45
44
}
46
45
47
46
/// 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.
47
+ /// `where` clauses)? If so, returns an `ImplHeader ` that unifies the two impls.
49
48
fn overlap < ' cx , ' tcx > ( selcx : & mut SelectionContext < ' cx , ' tcx > ,
50
49
a_def_id : DefId ,
51
50
b_def_id : DefId )
52
- -> Option < ty :: TraitRef < ' tcx > >
51
+ -> Option < ImplHeader < ' tcx > >
53
52
{
54
53
debug ! ( "overlap(a_def_id={:?}, b_def_id={:?})" ,
55
54
a_def_id,
56
55
b_def_id) ;
57
56
58
- let ( a_trait_ref, a_obligations) = impl_trait_ref_and_oblig ( selcx,
59
- a_def_id,
60
- util:: fresh_type_vars_for_impl) ;
57
+ let a_impl_header = ty:: ImplHeader :: with_fresh_ty_vars ( selcx, a_def_id) ;
58
+ let b_impl_header = ty:: ImplHeader :: with_fresh_ty_vars ( selcx, b_def_id) ;
61
59
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) ;
60
+ debug ! ( "overlap: a_impl_header={:?}" , a_impl_header) ;
61
+ debug ! ( "overlap: b_impl_header={:?}" , b_impl_header) ;
69
62
70
63
// 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 ) {
64
+ if let Err ( _) = infer:: mk_eq_impl_headers ( selcx. infcx ( ) ,
65
+ true ,
66
+ TypeOrigin :: Misc ( DUMMY_SP ) ,
67
+ a_impl_header ,
68
+ b_impl_header ) {
76
69
return None ;
77
70
}
78
71
@@ -81,17 +74,21 @@ fn overlap<'cx, 'tcx>(selcx: &mut SelectionContext<'cx, 'tcx>,
81
74
// Are any of the obligations unsatisfiable? If so, no overlap.
82
75
let infcx = selcx. infcx ( ) ;
83
76
let opt_failing_obligation =
84
- a_obligations. iter ( )
85
- . chain ( & b_obligations)
86
- . map ( |o| infcx. resolve_type_vars_if_possible ( o) )
77
+ a_impl_header. prediates
78
+ . iter ( )
79
+ . chain ( & b_impl_header. predicates )
80
+ . map ( |p| infcx. resolve_type_vars_if_possible ( p) )
81
+ . map ( |p| Obligation { cause : ObligationCause :: dummy ( ) ,
82
+ recursion_depth : 0 ,
83
+ predicate : p } )
87
84
. find ( |o| !selcx. evaluate_obligation ( o) ) ;
88
85
89
86
if let Some ( failing_obligation) = opt_failing_obligation {
90
87
debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
91
88
return None
92
89
}
93
90
94
- Some ( selcx. infcx ( ) . resolve_type_vars_if_possible ( & a_trait_ref ) )
91
+ Some ( selcx. infcx ( ) . resolve_type_vars_if_possible ( & a_impl_header ) )
95
92
}
96
93
97
94
pub fn trait_ref_is_knowable < ' tcx > ( tcx : & TyCtxt < ' tcx > , trait_ref : & ty:: TraitRef < ' tcx > ) -> bool
@@ -125,44 +122,6 @@ pub fn trait_ref_is_knowable<'tcx>(tcx: &TyCtxt<'tcx>, trait_ref: &ty::TraitRef<
125
122
orphan_check_trait_ref ( tcx, trait_ref, InferIsLocal ( true ) ) . is_err ( )
126
123
}
127
124
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
125
pub enum OrphanCheckErr < ' tcx > {
167
126
NoLocalInputType ,
168
127
UncoveredTy ( Ty < ' tcx > ) ,
0 commit comments