diff options
| author | bors <bors@rust-lang.org> | 2022-05-17 01:46:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-05-17 01:46:25 +0000 |
| commit | c1d65eaa456d3986e38868e68e6ce25d802f06b4 (patch) | |
| tree | 01aa9fd87338a25a484b612c519982682f11ff15 /compiler/rustc_trait_selection/src | |
| parent | c1cfdd1fb225d64e78b8d8cbab83564ac2dd5ec2 (diff) | |
| parent | 0cefa5fa183fc2ff672d68a4c67009b79ded76e4 (diff) | |
Auto merge of #96892 - oli-obk:🐌_obligation_cause_code_🐌, r=estebank
Clean up derived obligation creation r? `@estebank` working on fixing the perf regression from https://github.com/rust-lang/rust/pull/91030#issuecomment-1083360210
Diffstat (limited to 'compiler/rustc_trait_selection/src')
5 files changed, 56 insertions, 161 deletions
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 7a3579eb1cc..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,42 +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: - DerivedObligationCause { - parent_code, - parent_trait_pred, - }, - .. - }, - ) - | ObligationCauseCode::BuiltinDerivedObligation( - DerivedObligationCause { - parent_code, - parent_trait_pred, - }, - ) - | ObligationCauseCode::DerivedObligation( - DerivedObligationCause { - parent_code, - parent_trait_pred, - }, - ) => { - peeled = true; - code = &parent_code; - 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 { + 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..833e232e636 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; }; @@ -1669,7 +1652,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { debug!("maybe_note_obligation_cause_for_async_await: code={:?}", code); match code { ObligationCauseCode::FunctionArgumentObligation { parent_code, .. } => { - next_code = Some(parent_code.as_ref()); + next_code = Some(parent_code); } ObligationCauseCode::ImplDerivedObligation(cause) => { let ty = cause.derived.parent_trait_pred.skip_binder().self_ty(); @@ -1700,7 +1683,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { _ => {} } - next_code = Some(cause.derived.parent_code.as_ref()); + next_code = Some(&cause.derived.parent_code); } ObligationCauseCode::DerivedObligation(derived_obligation) | ObligationCauseCode::BuiltinDerivedObligation(derived_obligation) => { @@ -1732,7 +1715,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { _ => {} } - next_code = Some(derived_obligation.parent_code.as_ref()); + next_code = Some(&derived_obligation.parent_code); } _ => break, } @@ -2382,8 +2365,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let is_upvar_tys_infer_tuple = if !matches!(ty.kind(), ty::Tuple(..)) { false } else { - if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = - *data.parent_code + if let ObligationCauseCode::BuiltinDerivedObligation(data) = &*data.parent_code { let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred); @@ -2428,7 +2410,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { err, &parent_predicate, param_env, - &cause_code.peel_derives(), + cause_code.peel_derives(), obligated_types, seen_requirements, ) diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index b9025c98fe7..d607f4e7642 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -17,17 +17,15 @@ use rustc_middle::ty::{ToPolyTraitRef, ToPredicate}; use rustc_span::def_id::DefId; use crate::traits::project::{normalize_with_depth, normalize_with_depth_to}; -use crate::traits::select::TraitObligationExt; use crate::traits::util::{self, closure_trait_ref_and_return_type, predicate_for_trait_def}; use crate::traits::{ - BuiltinDerivedObligation, DerivedObligationCause, ImplDerivedObligation, - ImplDerivedObligationCause, ImplSource, ImplSourceAutoImplData, ImplSourceBuiltinData, - ImplSourceClosureData, ImplSourceConstDestructData, ImplSourceDiscriminantKindData, - ImplSourceFnPointerData, ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData, - ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, - ObjectCastObligation, Obligation, ObligationCause, OutputTypeParameterMismatch, - PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, TraitObligation, - Unimplemented, VtblSegment, + BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource, + ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData, + ImplSourceConstDestructData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData, + ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData, ImplSourceTraitAliasData, + ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation, + Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, + SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, VtblSegment, }; use super::BuiltinImplConditions; @@ -1128,21 +1126,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let substs = self.rematch_impl(impl_def_id, &new_obligation); debug!(?substs, "impl substs"); - let derived = DerivedObligationCause { - parent_trait_pred: obligation.predicate, - parent_code: obligation.cause.clone_code(), - }; - let derived_code = ImplDerivedObligation(Box::new(ImplDerivedObligationCause { - derived, - impl_def_id, - span: obligation.cause.span, - })); - - let cause = ObligationCause::new( - obligation.cause.span, - obligation.cause.body_id, - derived_code, - ); + let cause = obligation.derived_cause(|derived| { + ImplDerivedObligation(Box::new(ImplDerivedObligationCause { + derived, + impl_def_id, + span: obligation.cause.span, + })) + }); ensure_sufficient_stack(|| { self.vtable_impl( impl_def_id, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 1c9f83f8f34..a1577a30c91 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -14,9 +14,9 @@ use super::util; use super::util::{closure_trait_ref_and_return_type, predicate_for_trait_def}; use super::wf; use super::{ - DerivedObligationCause, ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause, - Normalized, Obligation, ObligationCause, ObligationCauseCode, Overflow, PredicateObligation, - Selection, SelectionError, SelectionResult, TraitObligation, TraitQueryMode, + ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause, Normalized, Obligation, + ObligationCause, ObligationCauseCode, Overflow, PredicateObligation, Selection, SelectionError, + SelectionResult, TraitObligation, TraitQueryMode, }; use crate::infer::{InferCtxt, InferOk, TypeFreshener}; @@ -2314,17 +2314,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?predicates); assert_eq!(predicates.parent, None); let mut obligations = Vec::with_capacity(predicates.predicates.len()); - let parent_code = cause.clone_code(); for (predicate, span) in predicates.predicates { let span = *span; - let derived = - DerivedObligationCause { parent_trait_pred, parent_code: parent_code.clone() }; - let code = ImplDerivedObligation(Box::new(ImplDerivedObligationCause { - derived, - impl_def_id: def_id, - span, - })); - let cause = ObligationCause::new(cause.span, cause.body_id, code); + let cause = cause.clone().derived_cause(parent_trait_pred, |derived| { + ImplDerivedObligation(Box::new(ImplDerivedObligationCause { + derived, + impl_def_id: def_id, + span, + })) + }); let predicate = normalize_with_depth_to( self, param_env, @@ -2340,42 +2338,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } -trait TraitObligationExt<'tcx> { - fn derived_cause( - &self, - variant: fn(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>, - ) -> ObligationCause<'tcx>; -} - -impl<'tcx> TraitObligationExt<'tcx> for TraitObligation<'tcx> { - fn derived_cause( - &self, - variant: fn(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>, - ) -> ObligationCause<'tcx> { - /*! - * Creates a cause for obligations that are derived from - * `obligation` by a recursive search (e.g., for a builtin - * bound, or eventually a `auto trait Foo`). If `obligation` - * is itself a derived obligation, this is just a clone, but - * otherwise we create a "derived obligation" cause so as to - * keep track of the original root obligation for error - * reporting. - */ - - let obligation = self; - - // NOTE(flaper87): As of now, it keeps track of the whole error - // chain. Ideally, we should have a way to configure this either - // by using -Z verbose or just a CLI argument. - let derived_cause = DerivedObligationCause { - parent_trait_pred: obligation.predicate, - parent_code: obligation.cause.clone_code(), - }; - let derived_code = variant(derived_cause); - ObligationCause::new(obligation.cause.span, obligation.cause.body_id, derived_code) - } -} - impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> { fn list(&'o self) -> TraitObligationStackList<'o, 'tcx> { TraitObligationStackList::with(self) diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index ca40c3452e2..0379b16334c 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -294,30 +294,22 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.substs); debug!("compute_trait_ref obligations {:?}", obligations); - let cause = self.cause(traits::MiscObligation); let param_env = self.param_env; let depth = self.recursion_depth; let item = self.item; - let extend = |obligation: traits::PredicateObligation<'tcx>| { - let mut cause = cause.clone(); - if let Some(parent_trait_pred) = obligation.predicate.to_opt_poly_trait_pred() { - let derived_cause = traits::DerivedObligationCause { + let extend = |traits::PredicateObligation { predicate, mut cause, .. }| { + if let Some(parent_trait_pred) = predicate.to_opt_poly_trait_pred() { + cause = cause.derived_cause( parent_trait_pred, - parent_code: obligation.cause.clone_code(), - }; - *cause.make_mut_code() = - traits::ObligationCauseCode::DerivedObligation(derived_cause); + traits::ObligationCauseCode::DerivedObligation, + ); } extend_cause_with_original_assoc_item_obligation( - tcx, - trait_ref, - item, - &mut cause, - obligation.predicate, + tcx, trait_ref, item, &mut cause, predicate, ); - traits::Obligation::with_depth(cause, depth, param_env, obligation.predicate) + traits::Obligation::with_depth(cause, depth, param_env, predicate) }; if let Elaborate::All = elaborate { @@ -339,17 +331,17 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { }) .filter(|(_, arg)| !arg.has_escaping_bound_vars()) .map(|(i, arg)| { - let mut new_cause = cause.clone(); + let mut cause = traits::ObligationCause::misc(self.span, self.body_id); // The first subst is the self ty - use the correct span for it. if i == 0 { if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) = item.map(|i| &i.kind) { - new_cause.span = self_ty.span; + cause.span = self_ty.span; } } traits::Obligation::with_depth( - new_cause, + cause, depth, param_env, ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx), |
