From 1e72c7f536bbdf3ed8a0071d28824c071c3722b5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 2 Jun 2024 18:36:11 -0400 Subject: [PATCH] Add cycle errors to ScrubbedTraitError to remove a couple more calls to new_with_diagnostics --- .../src/type_check/constraint_conversion.rs | 2 +- .../src/coherence/orphan.rs | 3 ++- compiler/rustc_trait_selection/src/infer.rs | 14 ++++-------- compiler/rustc_trait_selection/src/regions.rs | 2 +- .../src/solve/fulfill.rs | 2 +- .../src/solve/normalize.rs | 4 ++-- .../src/traits/engine.rs | 13 ++--------- .../src/traits/fulfill.rs | 7 +++--- .../rustc_trait_selection/src/traits/mod.rs | 12 +++++----- .../src/traits/query/normalize.rs | 2 +- .../query/type_op/implied_outlives_bounds.rs | 2 +- compiler/rustc_traits/src/codegen.rs | 8 +++---- .../src/normalize_projection_ty.rs | 13 +++++------ compiler/rustc_traits/src/type_op.rs | 22 +++++++------------ 14 files changed, 42 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 210532e56a5..266a80187c5 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -287,7 +287,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { ocx.infcx.at(&ObligationCause::dummy_with_span(self.span), self.param_env), ty, ) - .map_err(|_: Vec| NoSolution) + .map_err(|_: Vec>| NoSolution) }, "normalize type outlives obligation", ) diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index d2eb0cb5a7b..1e7bb63e6ea 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -319,7 +319,8 @@ fn orphan_check<'tcx>( } let ty = if infcx.next_trait_solver() { - let mut fulfill_cx = >::new(&infcx); + let mut fulfill_cx = + >>::new(&infcx); infcx .at(&cause, ty::ParamEnv::empty()) .structurally_normalize(ty, &mut *fulfill_cx) diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index f5d78430c97..c95649e2ffb 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -1,9 +1,5 @@ -use crate::solve::NextSolverError; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; -use crate::traits::{ - self, FromSolverError, Obligation, ObligationCause, ObligationCtxt, OldSolverError, - SelectionContext, -}; +use crate::traits::{self, Obligation, ObligationCause, ObligationCtxt, SelectionContext}; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; @@ -124,21 +120,19 @@ impl<'tcx> InferCtxtBuilder<'tcx> { /// bound for the closure and in part because it is convenient to /// have `'tcx` be free on this function so that we can talk about /// `K: TypeFoldable>`.) - fn enter_canonical_trait_query( + fn enter_canonical_trait_query( self, canonical_key: &Canonical<'tcx, K>, - operation: impl FnOnce(&ObligationCtxt<'_, 'tcx, E>, K) -> Result, + operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result, ) -> Result, NoSolution> where K: TypeFoldable>, R: Debug + TypeFoldable>, Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>, - E: FromSolverError<'tcx, NextSolverError<'tcx>> - + FromSolverError<'tcx, OldSolverError<'tcx>>, { let (infcx, key, canonical_inference_vars) = self.build_with_canonical(DUMMY_SP, canonical_key); - let ocx = ObligationCtxt::new_generic(&infcx); + let ocx = ObligationCtxt::new(&infcx); let value = operation(&ocx, key)?; ocx.make_canonicalized_query_response(canonical_inference_vars, value) } diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs index 3ef3f9ef358..5f986e22f51 100644 --- a/compiler/rustc_trait_selection/src/regions.rs +++ b/compiler/rustc_trait_selection/src/regions.rs @@ -28,7 +28,7 @@ impl<'tcx> InferCtxt<'tcx> { ), ty, ) - .map_err(|_: Vec| NoSolution) + .map_err(|_: Vec>| NoSolution) } else { Ok(ty) } diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs index b644f70eee4..3de4aee0927 100644 --- a/compiler/rustc_trait_selection/src/solve/fulfill.rs +++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs @@ -225,7 +225,7 @@ impl<'tcx> FromSolverError<'tcx, NextSolverError<'tcx>> for FulfillmentError<'tc } } -impl<'tcx> FromSolverError<'tcx, NextSolverError<'tcx>> for ScrubbedTraitError { +impl<'tcx> FromSolverError<'tcx, NextSolverError<'tcx>> for ScrubbedTraitError<'tcx> { fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: NextSolverError<'tcx>) -> Self { match error { NextSolverError::TrueError(_) => ScrubbedTraitError::TrueError, diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs index 5e41e8e8ba9..4211129a4e1 100644 --- a/compiler/rustc_trait_selection/src/solve/normalize.rs +++ b/compiler/rustc_trait_selection/src/solve/normalize.rs @@ -253,7 +253,7 @@ impl<'tcx> TypeFolder> for DeeplyNormalizeForDiagnosticsFolder<'_, ty, vec![None; ty.outer_exclusive_binder().as_usize()], ) - .unwrap_or_else(|_: Vec| ty.super_fold_with(self)) + .unwrap_or_else(|_: Vec>| ty.super_fold_with(self)) } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { @@ -262,6 +262,6 @@ impl<'tcx> TypeFolder> for DeeplyNormalizeForDiagnosticsFolder<'_, ct, vec![None; ct.outer_exclusive_binder().as_usize()], ) - .unwrap_or_else(|_: Vec| ct.super_fold_with(self)) + .unwrap_or_else(|_: Vec>| ct.super_fold_with(self)) } } diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 333fd4556e3..397f9cf2638 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -54,7 +54,7 @@ impl< /// Used if you want to have pleasant experience when dealing /// with obligations outside of hir or mir typeck. -pub struct ObligationCtxt<'a, 'tcx, E = ScrubbedTraitError> { +pub struct ObligationCtxt<'a, 'tcx, E = ScrubbedTraitError<'tcx>> { pub infcx: &'a InferCtxt<'tcx>, engine: RefCell>>, } @@ -65,21 +65,12 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>> { } } -impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, ScrubbedTraitError> { +impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, ScrubbedTraitError<'tcx>> { pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self { Self { infcx, engine: RefCell::new(>::new(infcx)) } } } -impl<'a, 'tcx, E> ObligationCtxt<'a, 'tcx, E> -where - E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>, -{ - pub fn new_generic(infcx: &'a InferCtxt<'tcx>) -> Self { - Self { infcx, engine: RefCell::new(>::new(infcx)) } - } -} - impl<'a, 'tcx, E> ObligationCtxt<'a, 'tcx, E> where E: FulfillmentErrorLike<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 8746cfa37e2..59802a26043 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -856,16 +856,15 @@ impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for FulfillmentError<'tcx } } -impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for ScrubbedTraitError { +impl<'tcx> FromSolverError<'tcx, OldSolverError<'tcx>> for ScrubbedTraitError<'tcx> { fn from_solver_error(_infcx: &InferCtxt<'tcx>, error: OldSolverError<'tcx>) -> Self { match error.error { FulfillmentErrorCode::Select(_) | FulfillmentErrorCode::Project(_) | FulfillmentErrorCode::Subtype(_, _) | FulfillmentErrorCode::ConstEquate(_, _) => ScrubbedTraitError::TrueError, - FulfillmentErrorCode::Cycle(_) | FulfillmentErrorCode::Ambiguity { overflow: _ } => { - ScrubbedTraitError::Ambiguity - } + FulfillmentErrorCode::Ambiguity { overflow: _ } => ScrubbedTraitError::Ambiguity, + FulfillmentErrorCode::Cycle(cycle) => ScrubbedTraitError::Cycle(cycle), } } } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 8fdf9c61c49..9aaa8adbd67 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -77,24 +77,26 @@ pub use rustc_infer::traits::*; /// error itself (except for if it's an ambiguity or true error). /// /// use [`ObligationCtxt::new_with_diagnostics`] to get a [`FulfillmentError`]. -#[derive(Copy, Clone, Debug)] -pub enum ScrubbedTraitError { +#[derive(Clone, Debug)] +pub enum ScrubbedTraitError<'tcx> { /// A real error. This goal definitely does not hold. TrueError, /// An ambiguity. This goal may hold if further inference is done. Ambiguity, + /// An old-solver-style cycle error, which will fatal. + Cycle(Vec>), } -impl ScrubbedTraitError { +impl<'tcx> ScrubbedTraitError<'tcx> { fn is_true_error(&self) -> bool { match self { ScrubbedTraitError::TrueError => true, - ScrubbedTraitError::Ambiguity => false, + ScrubbedTraitError::Ambiguity | ScrubbedTraitError::Cycle(_) => false, } } } -impl<'tcx> FulfillmentErrorLike<'tcx> for ScrubbedTraitError { +impl<'tcx> FulfillmentErrorLike<'tcx> for ScrubbedTraitError<'tcx> { fn is_true_error(&self) -> bool { self.is_true_error() } diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 860f50888a5..e170d7cae93 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -76,7 +76,7 @@ impl<'cx, 'tcx> At<'cx, 'tcx> { }; if self.infcx.next_trait_solver() { - match crate::solve::deeply_normalize_with_skipped_universes::<_, ScrubbedTraitError>( + match crate::solve::deeply_normalize_with_skipped_universes::<_, ScrubbedTraitError<'tcx>>( self, value, universes, ) { Ok(value) => return Ok(Normalized { value, obligations: vec![] }), diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index e4d0a541219..54fa0749618 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -267,7 +267,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>( ocx.infcx.at(&ObligationCause::dummy(), param_env), ty_a, ) - .map_err(|_errs: Vec| NoSolution)?; + .map_err(|_errs: Vec>| NoSolution)?; } let mut components = smallvec![]; push_outlives_components(tcx, ty_a, &mut components); diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs index 5defb817271..c73ececd1d1 100644 --- a/compiler/rustc_traits/src/codegen.rs +++ b/compiler/rustc_traits/src/codegen.rs @@ -9,8 +9,8 @@ use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::{ - FulfillmentErrorCode, ImplSource, Obligation, ObligationCause, ObligationCtxt, - SelectionContext, Unimplemented, + ImplSource, Obligation, ObligationCause, ObligationCtxt, ScrubbedTraitError, SelectionContext, + Unimplemented, }; use tracing::debug; @@ -51,7 +51,7 @@ pub fn codegen_select_candidate<'tcx>( // all nested obligations. This is because they can inform the // inference of the impl's type parameters. // FIXME(-Znext-solver): Doesn't need diagnostics if new solver. - let ocx = ObligationCtxt::new_with_diagnostics(&infcx); + let ocx = ObligationCtxt::new(&infcx); let impl_source = selection.map(|obligation| { ocx.register_obligation(obligation); }); @@ -65,7 +65,7 @@ pub fn codegen_select_candidate<'tcx>( // Cycle errors are the only post-monomorphization errors possible; emit them now so // `rustc_ty_utils::resolve_associated_item` doesn't return `None` post-monomorphization. for err in errors { - if let FulfillmentErrorCode::Cycle(cycle) = err.code { + if let ScrubbedTraitError::Cycle(cycle) = err { infcx.err_ctxt().report_overflow_obligation_cycle(&cycle); } } diff --git a/compiler/rustc_traits/src/normalize_projection_ty.rs b/compiler/rustc_traits/src/normalize_projection_ty.rs index 712abf6fcb3..b0a93b62dbf 100644 --- a/compiler/rustc_traits/src/normalize_projection_ty.rs +++ b/compiler/rustc_traits/src/normalize_projection_ty.rs @@ -7,9 +7,7 @@ use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::query::{ normalize::NormalizationResult, CanonicalAliasGoal, NoSolution, }; -use rustc_trait_selection::traits::{ - self, FulfillmentError, FulfillmentErrorCode, ObligationCause, ObligationCtxt, SelectionContext, -}; +use rustc_trait_selection::traits::{self, ObligationCause, ScrubbedTraitError, SelectionContext}; use tracing::debug; pub(crate) fn provide(p: &mut Providers) { @@ -29,8 +27,7 @@ fn normalize_canonicalized_projection_ty<'tcx>( tcx.infer_ctxt().enter_canonical_trait_query( &goal, - |ocx: &ObligationCtxt<'_, 'tcx, FulfillmentError<'tcx>>, - ParamEnvAnd { param_env, value: goal }| { + |ocx, ParamEnvAnd { param_env, value: goal }| { debug_assert!(!ocx.infcx.next_trait_solver()); let selcx = &mut SelectionContext::new(ocx.infcx); let cause = ObligationCause::dummy(); @@ -50,7 +47,7 @@ fn normalize_canonicalized_projection_ty<'tcx>( // that impl vars are constrained by the signature, for example). if !tcx.sess.opts.actually_rustdoc { for error in &errors { - if let FulfillmentErrorCode::Cycle(cycle) = &error.code { + if let ScrubbedTraitError::Cycle(cycle) = &error { ocx.infcx.err_ctxt().report_overflow_obligation_cycle(cycle); } } @@ -74,7 +71,7 @@ fn normalize_canonicalized_weak_ty<'tcx>( tcx.infer_ctxt().enter_canonical_trait_query( &goal, - |ocx: &ObligationCtxt<'_, 'tcx>, ParamEnvAnd { param_env, value: goal }| { + |ocx, ParamEnvAnd { param_env, value: goal }| { let obligations = tcx.predicates_of(goal.def_id).instantiate_own(tcx, goal.args).map( |(predicate, span)| { traits::Obligation::new( @@ -100,7 +97,7 @@ fn normalize_canonicalized_inherent_projection_ty<'tcx>( tcx.infer_ctxt().enter_canonical_trait_query( &goal, - |ocx: &ObligationCtxt<'_, 'tcx>, ParamEnvAnd { param_env, value: goal }| { + |ocx, ParamEnvAnd { param_env, value: goal }| { let selcx = &mut SelectionContext::new(ocx.infcx); let cause = ObligationCause::dummy(); let mut obligations = vec![]; diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index 35b0ede9a2e..b6a59a4ad3a 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -43,13 +43,10 @@ fn type_op_eq<'tcx>( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Eq<'tcx>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { - tcx.infer_ctxt().enter_canonical_trait_query( - &canonicalized, - |ocx: &ObligationCtxt<'_, 'tcx>, key| { - let (param_env, Eq { a, b }) = key.into_parts(); - Ok(ocx.eq(&ObligationCause::dummy(), param_env, a, b)?) - }, - ) + tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| { + let (param_env, Eq { a, b }) = key.into_parts(); + Ok(ocx.eq(&ObligationCause::dummy(), param_env, a, b)?) + }) } fn type_op_normalize<'tcx, T>( @@ -98,13 +95,10 @@ fn type_op_subtype<'tcx>( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Subtype<'tcx>>>, ) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, NoSolution> { - tcx.infer_ctxt().enter_canonical_trait_query( - &canonicalized, - |ocx: &ObligationCtxt<'_, 'tcx>, key| { - let (param_env, Subtype { sub, sup }) = key.into_parts(); - Ok(ocx.sup(&ObligationCause::dummy(), param_env, sup, sub)?) - }, - ) + tcx.infer_ctxt().enter_canonical_trait_query(&canonicalized, |ocx, key| { + let (param_env, Subtype { sub, sup }) = key.into_parts(); + Ok(ocx.sup(&ObligationCause::dummy(), param_env, sup, sub)?) + }) } fn type_op_prove_predicate<'tcx>(