@@ -86,10 +86,10 @@ impl<'tcx> Children {
86
86
impl_def_id, simplified_self, possible_sibling,
87
87
) ;
88
88
89
- let overlap_error = |overlap : traits:: coherence:: OverlapResult < ' _ > | {
90
- // Found overlap, but no specialization; error out.
89
+ let create_overlap_error = |overlap : traits:: coherence:: OverlapResult < ' _ > | {
91
90
let trait_ref = overlap. impl_header . trait_ref . unwrap ( ) ;
92
91
let self_ty = trait_ref. self_ty ( ) ;
92
+
93
93
OverlapError {
94
94
with_impl : possible_sibling,
95
95
trait_desc : trait_ref. print_only_trait_path ( ) . to_string ( ) ,
@@ -106,21 +106,49 @@ impl<'tcx> Children {
106
106
}
107
107
} ;
108
108
109
- let allowed_to_overlap =
110
- tcx. impls_are_allowed_to_overlap ( impl_def_id, possible_sibling) ;
109
+ let report_overlap_error = |overlap : traits:: coherence:: OverlapResult < ' _ > ,
110
+ last_lint : & mut _ | {
111
+ // Found overlap, but no specialization; error out or report future-compat warning.
112
+
113
+ // Do we *still* get overlap if we disable the future-incompatible modes?
114
+ let should_err = traits:: overlapping_impls (
115
+ tcx,
116
+ possible_sibling,
117
+ impl_def_id,
118
+ traits:: SkipLeakCheck :: default ( ) ,
119
+ |_| true ,
120
+ || false ,
121
+ ) ;
122
+
123
+ let error = create_overlap_error ( overlap) ;
124
+
125
+ if should_err {
126
+ Err ( error)
127
+ } else {
128
+ * last_lint = Some ( FutureCompatOverlapError {
129
+ error,
130
+ kind : FutureCompatOverlapErrorKind :: LeakCheck ,
131
+ } ) ;
132
+
133
+ Ok ( ( false , false ) )
134
+ }
135
+ } ;
111
136
137
+ let last_lint_mut = & mut last_lint;
112
138
let ( le, ge) = traits:: overlapping_impls (
113
139
tcx,
114
140
possible_sibling,
115
141
impl_def_id,
116
- traits:: SkipLeakCheck :: default ( ) ,
142
+ traits:: SkipLeakCheck :: Yes ,
117
143
|overlap| {
118
- if let Some ( overlap_kind) = & allowed_to_overlap {
144
+ if let Some ( overlap_kind) =
145
+ tcx. impls_are_allowed_to_overlap ( impl_def_id, possible_sibling)
146
+ {
119
147
match overlap_kind {
120
148
ty:: ImplOverlapKind :: Permitted { marker : _ } => { }
121
149
ty:: ImplOverlapKind :: Issue33140 => {
122
- last_lint = Some ( FutureCompatOverlapError {
123
- error : overlap_error ( overlap) ,
150
+ * last_lint_mut = Some ( FutureCompatOverlapError {
151
+ error : create_overlap_error ( overlap) ,
124
152
kind : FutureCompatOverlapErrorKind :: Issue33140 ,
125
153
} ) ;
126
154
}
@@ -132,7 +160,11 @@ impl<'tcx> Children {
132
160
let le = tcx. specializes ( ( impl_def_id, possible_sibling) ) ;
133
161
let ge = tcx. specializes ( ( possible_sibling, impl_def_id) ) ;
134
162
135
- if le == ge { Err ( overlap_error ( overlap) ) } else { Ok ( ( le, ge) ) }
163
+ if le == ge {
164
+ report_overlap_error ( overlap, last_lint_mut)
165
+ } else {
166
+ Ok ( ( le, ge) )
167
+ }
136
168
} ,
137
169
|| Ok ( ( false , false ) ) ,
138
170
) ?;
@@ -153,27 +185,8 @@ impl<'tcx> Children {
153
185
154
186
replace_children. push ( possible_sibling) ;
155
187
} else {
156
- if let None = allowed_to_overlap {
157
- // Do future-compat checks for overlap.
158
-
159
- if last_lint. is_none ( ) {
160
- traits:: overlapping_impls (
161
- tcx,
162
- possible_sibling,
163
- impl_def_id,
164
- traits:: SkipLeakCheck :: Yes ,
165
- |overlap| {
166
- last_lint = Some ( FutureCompatOverlapError {
167
- error : overlap_error ( overlap) ,
168
- kind : FutureCompatOverlapErrorKind :: LeakCheck ,
169
- } ) ;
170
- } ,
171
- || ( ) ,
172
- ) ;
173
- }
174
- }
175
-
176
- // no overlap (error bailed already via ?)
188
+ // Either there's no overlap, or the overlap was already reported by
189
+ // `overlap_error`.
177
190
}
178
191
}
179
192
0 commit comments