Skip to content

Commit 75dbd5b

Browse files
committed
Auto merge of #102931 - camsteffen:inline-overlapping-impls, r=cjgillot
Make `overlapping_impls` not generic Trying to win back perf from #101632.
2 parents ddc7fd9 + c4068c7 commit 75dbd5b

File tree

3 files changed

+34
-47
lines changed

3 files changed

+34
-47
lines changed

compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,11 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
148148
// inherent impls without warning.
149149
SkipLeakCheck::Yes,
150150
overlap_mode,
151-
|overlap| {
152-
self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap);
153-
false
154-
},
155-
|| true,
156-
);
151+
)
152+
.map_or(true, |overlap| {
153+
self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap);
154+
false
155+
});
157156
}
158157

159158
fn check_item(&mut self, id: hir::ItemId) {

compiler/rustc_trait_selection/src/traits/coherence.rs

+8-14
Original file line numberDiff line numberDiff line change
@@ -60,23 +60,17 @@ pub fn add_placeholder_note(err: &mut Diagnostic) {
6060
);
6161
}
6262

63-
/// If there are types that satisfy both impls, invokes `on_overlap`
63+
/// If there are types that satisfy both impls, returns `Some`
6464
/// with a suitably-freshened `ImplHeader` with those types
65-
/// substituted. Otherwise, invokes `no_overlap`.
66-
#[instrument(skip(tcx, skip_leak_check, on_overlap, no_overlap), level = "debug")]
67-
pub fn overlapping_impls<F1, F2, R>(
65+
/// substituted. Otherwise, returns `None`.
66+
#[instrument(skip(tcx, skip_leak_check), level = "debug")]
67+
pub fn overlapping_impls(
6868
tcx: TyCtxt<'_>,
6969
impl1_def_id: DefId,
7070
impl2_def_id: DefId,
7171
skip_leak_check: SkipLeakCheck,
7272
overlap_mode: OverlapMode,
73-
on_overlap: F1,
74-
no_overlap: F2,
75-
) -> R
76-
where
77-
F1: FnOnce(OverlapResult<'_>) -> R,
78-
F2: FnOnce() -> R,
79-
{
73+
) -> Option<OverlapResult<'_>> {
8074
// Before doing expensive operations like entering an inference context, do
8175
// a quick check via fast_reject to tell if the impl headers could possibly
8276
// unify.
@@ -97,15 +91,15 @@ where
9791
if !may_overlap {
9892
// Some types involved are definitely different, so the impls couldn't possibly overlap.
9993
debug!("overlapping_impls: fast_reject early-exit");
100-
return no_overlap();
94+
return None;
10195
}
10296

10397
let infcx = tcx.infer_ctxt().build();
10498
let selcx = &mut SelectionContext::intercrate(&infcx);
10599
let overlaps =
106100
overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some();
107101
if !overlaps {
108-
return no_overlap();
102+
return None;
109103
}
110104

111105
// In the case where we detect an error, run the check again, but
@@ -114,7 +108,7 @@ where
114108
let infcx = tcx.infer_ctxt().build();
115109
let selcx = &mut SelectionContext::intercrate(&infcx);
116110
selcx.enable_tracking_intercrate_ambiguity_causes();
117-
on_overlap(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap())
111+
Some(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap())
118112
}
119113

120114
fn with_fresh_ty_vars<'cx, 'tcx>(

compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs

+21-27
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,8 @@ impl ChildrenExt<'_> for Children {
137137
impl_def_id,
138138
traits::SkipLeakCheck::default(),
139139
overlap_mode,
140-
|_| true,
141-
|| false,
142-
);
140+
)
141+
.is_some();
143142

144143
let error = create_overlap_error(overlap);
145144

@@ -162,34 +161,29 @@ impl ChildrenExt<'_> for Children {
162161
impl_def_id,
163162
traits::SkipLeakCheck::Yes,
164163
overlap_mode,
165-
|overlap| {
166-
if let Some(overlap_kind) =
167-
tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling)
168-
{
169-
match overlap_kind {
170-
ty::ImplOverlapKind::Permitted { marker: _ } => {}
171-
ty::ImplOverlapKind::Issue33140 => {
172-
*last_lint_mut = Some(FutureCompatOverlapError {
173-
error: create_overlap_error(overlap),
174-
kind: FutureCompatOverlapErrorKind::Issue33140,
175-
});
176-
}
164+
)
165+
.map_or(Ok((false, false)), |overlap| {
166+
if let Some(overlap_kind) =
167+
tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling)
168+
{
169+
match overlap_kind {
170+
ty::ImplOverlapKind::Permitted { marker: _ } => {}
171+
ty::ImplOverlapKind::Issue33140 => {
172+
*last_lint_mut = Some(FutureCompatOverlapError {
173+
error: create_overlap_error(overlap),
174+
kind: FutureCompatOverlapErrorKind::Issue33140,
175+
});
177176
}
178-
179-
return Ok((false, false));
180177
}
181178

182-
let le = tcx.specializes((impl_def_id, possible_sibling));
183-
let ge = tcx.specializes((possible_sibling, impl_def_id));
179+
return Ok((false, false));
180+
}
184181

185-
if le == ge {
186-
report_overlap_error(overlap, last_lint_mut)
187-
} else {
188-
Ok((le, ge))
189-
}
190-
},
191-
|| Ok((false, false)),
192-
)?;
182+
let le = tcx.specializes((impl_def_id, possible_sibling));
183+
let ge = tcx.specializes((possible_sibling, impl_def_id));
184+
185+
if le == ge { report_overlap_error(overlap, last_lint_mut) } else { Ok((le, ge)) }
186+
})?;
193187

194188
if le && !ge {
195189
debug!(

0 commit comments

Comments
 (0)