diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index c634a57b0b534..130eb8005b069 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -148,12 +148,11 @@ impl<'tcx> InherentOverlapChecker<'tcx> { // inherent impls without warning. SkipLeakCheck::Yes, overlap_mode, - |overlap| { - self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap); - false - }, - || true, - ); + ) + .map_or(true, |overlap| { + self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap); + false + }); } fn check_item(&mut self, id: hir::ItemId) { diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 7715874743192..8aab75490a81b 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -60,23 +60,17 @@ pub fn add_placeholder_note(err: &mut Diagnostic) { ); } -/// If there are types that satisfy both impls, invokes `on_overlap` +/// If there are types that satisfy both impls, returns `Some` /// with a suitably-freshened `ImplHeader` with those types -/// substituted. Otherwise, invokes `no_overlap`. -#[instrument(skip(tcx, skip_leak_check, on_overlap, no_overlap), level = "debug")] -pub fn overlapping_impls( +/// substituted. Otherwise, returns `None`. +#[instrument(skip(tcx, skip_leak_check), level = "debug")] +pub fn overlapping_impls( tcx: TyCtxt<'_>, impl1_def_id: DefId, impl2_def_id: DefId, skip_leak_check: SkipLeakCheck, overlap_mode: OverlapMode, - on_overlap: F1, - no_overlap: F2, -) -> R -where - F1: FnOnce(OverlapResult<'_>) -> R, - F2: FnOnce() -> R, -{ +) -> Option> { // Before doing expensive operations like entering an inference context, do // a quick check via fast_reject to tell if the impl headers could possibly // unify. @@ -97,7 +91,7 @@ where if !may_overlap { // Some types involved are definitely different, so the impls couldn't possibly overlap. debug!("overlapping_impls: fast_reject early-exit"); - return no_overlap(); + return None; } let infcx = tcx.infer_ctxt().build(); @@ -105,7 +99,7 @@ where let overlaps = overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some(); if !overlaps { - return no_overlap(); + return None; } // In the case where we detect an error, run the check again, but @@ -114,7 +108,7 @@ where let infcx = tcx.infer_ctxt().build(); let selcx = &mut SelectionContext::intercrate(&infcx); selcx.enable_tracking_intercrate_ambiguity_causes(); - on_overlap(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap()) + Some(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap()) } fn with_fresh_ty_vars<'cx, 'tcx>( diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index fcb73b43fa8a1..63f89a33e8adc 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -137,9 +137,8 @@ impl ChildrenExt<'_> for Children { impl_def_id, traits::SkipLeakCheck::default(), overlap_mode, - |_| true, - || false, - ); + ) + .is_some(); let error = create_overlap_error(overlap); @@ -162,34 +161,29 @@ impl ChildrenExt<'_> for Children { impl_def_id, traits::SkipLeakCheck::Yes, overlap_mode, - |overlap| { - if let Some(overlap_kind) = - tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) - { - match overlap_kind { - ty::ImplOverlapKind::Permitted { marker: _ } => {} - ty::ImplOverlapKind::Issue33140 => { - *last_lint_mut = Some(FutureCompatOverlapError { - error: create_overlap_error(overlap), - kind: FutureCompatOverlapErrorKind::Issue33140, - }); - } + ) + .map_or(Ok((false, false)), |overlap| { + if let Some(overlap_kind) = + tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) + { + match overlap_kind { + ty::ImplOverlapKind::Permitted { marker: _ } => {} + ty::ImplOverlapKind::Issue33140 => { + *last_lint_mut = Some(FutureCompatOverlapError { + error: create_overlap_error(overlap), + kind: FutureCompatOverlapErrorKind::Issue33140, + }); } - - return Ok((false, false)); } - let le = tcx.specializes((impl_def_id, possible_sibling)); - let ge = tcx.specializes((possible_sibling, impl_def_id)); + return Ok((false, false)); + } - if le == ge { - report_overlap_error(overlap, last_lint_mut) - } else { - Ok((le, ge)) - } - }, - || Ok((false, false)), - )?; + let le = tcx.specializes((impl_def_id, possible_sibling)); + let ge = tcx.specializes((possible_sibling, impl_def_id)); + + if le == ge { report_overlap_error(overlap, last_lint_mut) } else { Ok((le, ge)) } + })?; if le && !ge { debug!(