From 5b5b54958022911b5ba9afc85b7f58d69e0842f8 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 10 May 2022 11:03:52 +0000 Subject: [PATCH] Add a helper function for a common piece of code --- compiler/rustc_middle/src/traits/mod.rs | 28 +++++++------ .../src/traits/error_reporting/mod.rs | 41 +++++-------------- .../src/traits/error_reporting/suggestions.rs | 31 ++++---------- 3 files changed, 32 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 31744671d3a..d28605fc26f 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -427,25 +427,27 @@ pub struct ImplDerivedObligationCause<'tcx> { pub span: Span, } -impl ObligationCauseCode<'_> { +impl<'tcx> ObligationCauseCode<'tcx> { // Return the base obligation, ignoring derived obligations. pub fn peel_derives(&self) -> &Self { let mut base_cause = self; - loop { - match base_cause { - BuiltinDerivedObligation(DerivedObligationCause { parent_code, .. }) - | DerivedObligation(DerivedObligationCause { parent_code, .. }) - | FunctionArgumentObligation { parent_code, .. } => { - base_cause = &parent_code; - } - ImplDerivedObligation(obligation_cause) => { - base_cause = &*obligation_cause.derived.parent_code; - } - _ => break, - } + while let Some((parent_code, _)) = base_cause.parent() { + base_cause = parent_code; } base_cause } + + pub fn parent(&self) -> Option<(&Self, Option>)> { + match self { + FunctionArgumentObligation { parent_code, .. } => Some((parent_code, None)), + BuiltinDerivedObligation(derived) + | DerivedObligation(derived) + | ImplDerivedObligation(box ImplDerivedObligationCause { derived, .. }) => { + Some((&derived.parent_code, Some(derived.parent_trait_pred))) + } + _ => None, + } + } } // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger. diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 8f4383b728d..6082d7529c3 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -2,11 +2,10 @@ pub mod on_unimplemented; pub mod suggestions; use super::{ - DerivedObligationCause, EvaluationResult, FulfillmentContext, FulfillmentError, - FulfillmentErrorCode, ImplDerivedObligationCause, MismatchedProjectionTypes, Obligation, - ObligationCause, ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote, - OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionContext, SelectionError, - TraitNotObjectSafe, + EvaluationResult, FulfillmentContext, FulfillmentError, FulfillmentErrorCode, + MismatchedProjectionTypes, Obligation, ObligationCause, ObligationCauseCode, + OnUnimplementedDirective, OnUnimplementedNote, OutputTypeParameterMismatch, Overflow, + PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe, }; use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; @@ -684,32 +683,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let mut code = obligation.cause.code(); let mut trait_pred = trait_predicate; let mut peeled = false; - loop { - match &*code { - ObligationCauseCode::FunctionArgumentObligation { - parent_code, - .. - } => { - code = &parent_code; - } - ObligationCauseCode::ImplDerivedObligation( - box ImplDerivedObligationCause { - derived, - .. - }, - ) - | ObligationCauseCode::BuiltinDerivedObligation( - derived, - ) - | ObligationCauseCode::DerivedObligation( - derived, - ) => { - peeled = true; - code = &derived.parent_code; - trait_pred = derived.parent_trait_pred; - } - _ => break, - }; + while let Some((parent_code, parent_trait_pred)) = code.parent() { + code = parent_code; + if let Some(parent_trait_pred) = parent_trait_pred { + trait_pred = parent_trait_pred; + peeled = true; + } } let def_id = trait_pred.def_id(); // Mention *all* the `impl`s for the *top most* obligation, the diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index d20ba99ebc9..e4060d1ee5b 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1,6 +1,6 @@ use super::{ - DerivedObligationCause, EvaluationResult, ImplDerivedObligationCause, Obligation, - ObligationCause, ObligationCauseCode, PredicateObligation, SelectionContext, + EvaluationResult, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation, + SelectionContext, }; use crate::autoderef::Autoderef; @@ -623,28 +623,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let span = obligation.cause.span; let mut real_trait_pred = trait_pred; let mut code = obligation.cause.code(); - loop { - match &code { - ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => { - code = &parent_code; - } - ObligationCauseCode::ImplDerivedObligation(box ImplDerivedObligationCause { - derived: DerivedObligationCause { parent_code, parent_trait_pred }, - .. - }) - | ObligationCauseCode::BuiltinDerivedObligation(DerivedObligationCause { - parent_code, - parent_trait_pred, - }) - | ObligationCauseCode::DerivedObligation(DerivedObligationCause { - parent_code, - parent_trait_pred, - }) => { - code = &parent_code; - real_trait_pred = *parent_trait_pred; - } - _ => break, - }; + while let Some((parent_code, parent_trait_pred)) = code.parent() { + code = parent_code; + if let Some(parent_trait_pred) = parent_trait_pred { + real_trait_pred = parent_trait_pred; + } let Some(real_ty) = real_trait_pred.self_ty().no_bound_vars() else { continue; };