From 91525a43243e088abb34fca3d43fd8588b8667e0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 24 May 2023 17:11:40 +0000 Subject: [PATCH 1/2] Use ErrorGuaranteed more in MIR type ops --- .../src/type_check/canonical.rs | 45 +++++----------- .../src/type_check/free_region_relations.rs | 21 +++----- .../src/type_check/liveness/trace.rs | 16 ++++-- compiler/rustc_borrowck/src/type_check/mod.rs | 54 +++++++++++-------- .../src/type_check/relate_tys.rs | 15 ++---- .../src/traits/outlives_bounds.rs | 12 ++--- .../src/traits/query/type_op/custom.rs | 24 ++++++--- .../src/traits/query/type_op/mod.rs | 24 +++++++-- 8 files changed, 104 insertions(+), 107 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 95dcc8d4b1916..f527eee7bda05 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -1,12 +1,12 @@ use std::fmt; +use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::canonical::Canonical; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_span::def_id::DefId; use rustc_span::Span; use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput}; -use rustc_trait_selection::traits::query::{Fallible, NoSolution}; use rustc_trait_selection::traits::ObligationCause; use crate::diagnostics::{ToUniverseInfo, UniverseInfo}; @@ -30,14 +30,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { locations: Locations, category: ConstraintCategory<'tcx>, op: Op, - ) -> Fallible + ) -> Result where Op: type_op::TypeOp<'tcx, Output = R>, Op::ErrorInfo: ToUniverseInfo<'tcx>, { let old_universe = self.infcx.universe(); - let TypeOpOutput { output, constraints, error_info } = op.fully_perform(self.infcx)?; + let TypeOpOutput { output, constraints, error_info } = + op.fully_perform(self.infcx, locations.span(self.body))?; debug!(?output, ?constraints); @@ -135,14 +136,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ) { let param_env = self.param_env; let predicate = predicate.to_predicate(self.tcx()); - self.fully_perform_op( + let _: Result<_, ErrorGuaranteed> = self.fully_perform_op( locations, category, param_env.and(type_op::prove_predicate::ProvePredicate::new(predicate)), - ) - .unwrap_or_else(|NoSolution| { - span_mirbug!(self, NoSolution, "could not prove {:?}", predicate); - }) + ); } pub(super) fn normalize(&mut self, value: T, location: impl NormalizeLocation) -> T @@ -163,15 +161,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx, { let param_env = self.param_env; - self.fully_perform_op( + let result: Result<_, ErrorGuaranteed> = self.fully_perform_op( location.to_locations(), category, param_env.and(type_op::normalize::Normalize::new(value)), - ) - .unwrap_or_else(|NoSolution| { - span_mirbug!(self, NoSolution, "failed to normalize `{:?}`", value); - value - }) + ); + result.unwrap_or(value) } #[instrument(skip(self), level = "debug")] @@ -181,18 +176,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { user_ty: ty::UserType<'tcx>, span: Span, ) { - self.fully_perform_op( + let _: Result<_, ErrorGuaranteed> = self.fully_perform_op( Locations::All(span), ConstraintCategory::Boring, self.param_env.and(type_op::ascribe_user_type::AscribeUserType::new(mir_ty, user_ty)), - ) - .unwrap_or_else(|err| { - span_mirbug!( - self, - span, - "ascribe_user_type `{mir_ty:?}=={user_ty:?}` failed with `{err:?}`", - ); - }); + ); } /// *Incorrectly* skips the WF checks we normally do in `ascribe_user_type`. @@ -219,7 +207,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let cause = ObligationCause::dummy_with_span(span); let param_env = self.param_env; - self.fully_perform_op( + let _: Result<_, ErrorGuaranteed> = self.fully_perform_op( Locations::All(span), ConstraintCategory::Boring, type_op::custom::CustomTypeOp::new( @@ -230,13 +218,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { }, "ascribe_user_type_skip_wf", ), - ) - .unwrap_or_else(|err| { - span_mirbug!( - self, - span, - "ascribe_user_type_skip_wf `{mir_ty:?}=={user_ty:?}` failed with `{err:?}`", - ); - }); + ); } } diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index bd01c0b504cb5..c8ec1257d376e 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -8,7 +8,7 @@ use rustc_infer::infer::InferCtxt; use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::query::OutlivesBound; use rustc_middle::ty::{self, RegionVid, Ty}; -use rustc_span::Span; +use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::traits::query::type_op::{self, TypeOp}; use std::rc::Rc; use type_op::TypeOpOutput; @@ -243,18 +243,11 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { let TypeOpOutput { output: norm_ty, constraints: constraints_normalize, .. } = self .param_env .and(type_op::normalize::Normalize::new(ty)) - .fully_perform(self.infcx) - .unwrap_or_else(|_| { - let guar = self - .infcx - .tcx - .sess - .delay_span_bug(span, format!("failed to normalize {:?}", ty)); - TypeOpOutput { - output: self.infcx.tcx.ty_error(guar), - constraints: None, - error_info: None, - } + .fully_perform(self.infcx, span) + .unwrap_or_else(|guar| TypeOpOutput { + output: self.infcx.tcx.ty_error(guar), + constraints: None, + error_info: None, }); if let Some(c) = constraints_normalize { constraints.push(c) @@ -324,7 +317,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { let TypeOpOutput { output: bounds, constraints, .. } = self .param_env .and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty }) - .fully_perform(self.infcx) + .fully_perform(self.infcx, DUMMY_SP) .unwrap_or_else(|_| bug!("failed to compute implied bounds {:?}", ty)); debug!(?bounds, ?constraints); self.add_outlives_bounds(bounds); diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 9731b10aa99d9..fd94ac86d7dc2 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -4,6 +4,7 @@ use rustc_index::interval::IntervalSet; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location}; use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt}; +use rustc_span::DUMMY_SP; use rustc_trait_selection::traits::query::dropck_outlives::DropckOutlivesResult; use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; @@ -568,10 +569,15 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { ) -> DropData<'tcx> { debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,); - let param_env = typeck.param_env; - let TypeOpOutput { output, constraints, .. } = - param_env.and(DropckOutlives::new(dropped_ty)).fully_perform(typeck.infcx).unwrap(); - - DropData { dropck_result: output, region_constraint_data: constraints } + match typeck + .param_env + .and(DropckOutlives::new(dropped_ty)) + .fully_perform(typeck.infcx, DUMMY_SP) + { + Ok(TypeOpOutput { output, constraints, .. }) => { + DropData { dropck_result: output, region_constraint_data: constraints } + } + Err(_) => DropData { dropck_result: Default::default(), region_constraint_data: None }, + } } } diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index cf204cff6b3a7..b2693e6054674 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -10,6 +10,7 @@ use either::Either; use hir::OpaqueTyOrigin; use rustc_data_structures::frozen::Frozen; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; +use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; @@ -216,24 +217,22 @@ pub(crate) fn type_check<'mir, 'tcx>( let opaque_type_values = opaque_type_values .into_iter() .map(|(opaque_type_key, decl)| { - checker - .fully_perform_op( - Locations::All(body.span), - ConstraintCategory::OpaqueType, - CustomTypeOp::new( - |ocx| { - ocx.infcx.register_member_constraints( - param_env, - opaque_type_key, - decl.hidden_type.ty, - decl.hidden_type.span, - ); - Ok(()) - }, - "opaque_type_map", - ), - ) - .unwrap(); + let _: Result<_, ErrorGuaranteed> = checker.fully_perform_op( + Locations::All(body.span), + ConstraintCategory::OpaqueType, + CustomTypeOp::new( + |ocx| { + ocx.infcx.register_member_constraints( + param_env, + opaque_type_key, + decl.hidden_type.ty, + decl.hidden_type.span, + ); + Ok(()) + }, + "opaque_type_map", + ), + ); let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type); trace!("finalized opaque type {:?} to {:#?}", opaque_type_key, hidden_type.ty.kind()); if hidden_type.has_non_region_infer() { @@ -2755,11 +2754,20 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> { /// constraints in our `InferCtxt` type ErrorInfo = InstantiateOpaqueType<'tcx>; - fn fully_perform(mut self, infcx: &InferCtxt<'tcx>) -> Fallible> { - let (mut output, region_constraints) = scrape_region_constraints(infcx, |ocx| { - ocx.register_obligations(self.obligations.clone()); - Ok(()) - })?; + fn fully_perform( + mut self, + infcx: &InferCtxt<'tcx>, + span: Span, + ) -> Result, ErrorGuaranteed> { + let (mut output, region_constraints) = scrape_region_constraints( + infcx, + |ocx| { + ocx.register_obligations(self.obligations.clone()); + Ok(()) + }, + "InstantiateOpaqueType", + span, + )?; self.region_constraints = Some(region_constraints); output.error_info = Some(self); Ok(output) diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index dd1f89e5b9157..6f3451d56574e 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -1,3 +1,4 @@ +use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::nll_relate::{TypeRelating, TypeRelatingDelegate}; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::traits::PredicateObligations; @@ -185,7 +186,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> } fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { - match self.type_checker.fully_perform_op( + let _: Result<_, ErrorGuaranteed> = self.type_checker.fully_perform_op( self.locations, self.category, InstantiateOpaqueType { @@ -194,16 +195,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> base_universe: None, region_constraints: None, }, - ) { - Ok(()) => {} - Err(_) => { - // It's a bit redundant to delay a bug here, but I'd rather - // delay more bugs than accidentally not delay a bug at all. - self.type_checker.tcx().sess.delay_span_bug( - self.locations.span(self.type_checker.body), - "errors selecting obligation during MIR typeck", - ); - } - }; + ); } } diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 0db8023289127..0e797a1cb60d5 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -1,8 +1,8 @@ use crate::infer::InferCtxt; use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput}; -use crate::traits::query::NoSolution; use crate::traits::{ObligationCause, ObligationCtxt}; use rustc_data_structures::fx::FxIndexSet; +use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt}; use rustc_span::def_id::LocalDefId; @@ -69,16 +69,12 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { } let span = self.tcx.def_span(body_id); - let result = param_env + let result: Result<_, ErrorGuaranteed> = param_env .and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty }) - .fully_perform(self); + .fully_perform(self, span); let result = match result { Ok(r) => r, - Err(NoSolution) => { - self.tcx.sess.delay_span_bug( - span, - "implied_outlives_bounds failed to solve all obligations", - ); + Err(_) => { return vec![]; } }; diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index 3d6c1d9e2b02e..94464895f3b2e 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -3,9 +3,10 @@ use crate::infer::InferCtxt; use crate::traits::query::type_op::TypeOpOutput; use crate::traits::query::Fallible; use crate::traits::ObligationCtxt; +use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::region_constraints::RegionConstraintData; -use rustc_middle::traits::query::NoSolution; use rustc_span::source_map::DUMMY_SP; +use rustc_span::Span; use std::fmt; @@ -35,12 +36,16 @@ where /// Processes the operation and all resulting obligations, /// returning the final result along with any region constraints /// (they will be given over to the NLL region solver). - fn fully_perform(self, infcx: &InferCtxt<'tcx>) -> Fallible> { + fn fully_perform( + self, + infcx: &InferCtxt<'tcx>, + span: Span, + ) -> Result, ErrorGuaranteed> { if cfg!(debug_assertions) { info!("fully_perform({:?})", self); } - Ok(scrape_region_constraints(infcx, self.closure)?.0) + Ok(scrape_region_constraints(infcx, self.closure, self.description, span)?.0) } } @@ -55,7 +60,9 @@ impl fmt::Debug for CustomTypeOp { pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>( infcx: &InferCtxt<'tcx>, op: impl FnOnce(&ObligationCtxt<'_, 'tcx>) -> Fallible, -) -> Fallible<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>)> { + name: &'static str, + span: Span, +) -> Result<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>), ErrorGuaranteed> { // During NLL, we expect that nobody will register region // obligations **except** as part of a custom type op (and, at the // end of each custom type op, we scrape out the region @@ -70,16 +77,17 @@ pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>( let value = infcx.commit_if_ok(|_| { let ocx = ObligationCtxt::new_in_snapshot(infcx); - let value = op(&ocx)?; + let value = op(&ocx).map_err(|_| { + infcx.tcx.sess.delay_span_bug(span, format!("error performing operation: {name}")) + })?; let errors = ocx.select_all_or_error(); if errors.is_empty() { Ok(value) } else { - infcx.tcx.sess.delay_span_bug( + Err(infcx.tcx.sess.delay_span_bug( DUMMY_SP, format!("errors selecting obligation during MIR typeck: {:?}", errors), - ); - Err(NoSolution) + )) } })?; diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index 9e8bc8bce9a8f..a34ea3fb3dd30 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -4,11 +4,12 @@ use crate::infer::canonical::{ use crate::infer::{InferCtxt, InferOk}; use crate::traits::query::Fallible; use crate::traits::ObligationCause; +use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::canonical::Certainty; -use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::PredicateObligations; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; +use rustc_span::Span; use std::fmt; pub mod ascribe_user_type; @@ -32,7 +33,11 @@ pub trait TypeOp<'tcx>: Sized + fmt::Debug { /// Processes the operation and all resulting obligations, /// returning the final result along with any region constraints /// (they will be given over to the NLL region solver). - fn fully_perform(self, infcx: &InferCtxt<'tcx>) -> Fallible>; + fn fully_perform( + self, + infcx: &InferCtxt<'tcx>, + span: Span, + ) -> Result, ErrorGuaranteed>; } /// The output from performing a type op @@ -120,10 +125,16 @@ where type Output = Q::QueryResponse; type ErrorInfo = Canonical<'tcx, ParamEnvAnd<'tcx, Q>>; - fn fully_perform(self, infcx: &InferCtxt<'tcx>) -> Fallible> { + fn fully_perform( + self, + infcx: &InferCtxt<'tcx>, + span: Span, + ) -> Result, ErrorGuaranteed> { let mut region_constraints = QueryRegionConstraints::default(); let (output, error_info, mut obligations, _) = - Q::fully_perform_into(self, infcx, &mut region_constraints)?; + Q::fully_perform_into(self, infcx, &mut region_constraints).map_err(|_| { + infcx.tcx.sess.delay_span_bug(span, format!("error performing {self:?}")) + })?; // Typically, instantiating NLL query results does not // create obligations. However, in some cases there @@ -151,7 +162,10 @@ where } } if !progress { - return Err(NoSolution); + return Err(infcx.tcx.sess.delay_span_bug( + span, + format!("ambiguity processing {obligations:?} from {self:?}"), + )); } } From 0a35db5e0d0f855ec9706280cef21fdc8a1f6ce5 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 25 May 2023 17:29:22 +0000 Subject: [PATCH 2/2] Fallible<_> -> Result<_, NoSolution> --- compiler/rustc_borrowck/src/type_check/mod.rs | 9 +++++---- .../src/type_check/relate_tys.rs | 6 +++--- .../src/infer/canonical/query_response.rs | 4 ++-- compiler/rustc_middle/src/traits/query.rs | 2 -- compiler/rustc_trait_selection/src/infer.rs | 10 +++++----- .../src/traits/engine.rs | 4 ++-- .../traits/query/type_op/ascribe_user_type.rs | 4 ++-- .../src/traits/query/type_op/custom.rs | 8 ++++---- .../src/traits/query/type_op/eq.rs | 4 ++-- .../query/type_op/implied_outlives_bounds.rs | 4 ++-- .../src/traits/query/type_op/mod.rs | 19 +++++++++++-------- .../src/traits/query/type_op/normalize.rs | 14 +++++++------- .../src/traits/query/type_op/outlives.rs | 4 ++-- .../traits/query/type_op/prove_predicate.rs | 4 ++-- .../src/traits/query/type_op/subtype.rs | 4 ++-- .../src/implied_outlives_bounds.rs | 4 ++-- compiler/rustc_traits/src/type_op.rs | 4 ++-- 17 files changed, 55 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index b2693e6054674..51a84ce6cadea 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -27,6 +27,7 @@ use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::AssertKind; use rustc_middle::mir::*; +use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::subst::{SubstsRef, UserSubsts}; @@ -42,7 +43,7 @@ use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints; use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; -use rustc_trait_selection::traits::query::Fallible; + use rustc_trait_selection::traits::PredicateObligation; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; @@ -1133,7 +1134,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { sup: Ty<'tcx>, locations: Locations, category: ConstraintCategory<'tcx>, - ) -> Fallible<()> { + ) -> Result<(), NoSolution> { // Use this order of parameters because the sup type is usually the // "expected" type in diagnostics. self.relate_types(sup, ty::Variance::Contravariant, sub, locations, category) @@ -1146,7 +1147,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { found: Ty<'tcx>, locations: Locations, category: ConstraintCategory<'tcx>, - ) -> Fallible<()> { + ) -> Result<(), NoSolution> { self.relate_types(expected, ty::Variance::Invariant, found, locations, category) } @@ -1158,7 +1159,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { user_ty: &UserTypeProjection, locations: Locations, category: ConstraintCategory<'tcx>, - ) -> Fallible<()> { + ) -> Result<(), NoSolution> { let annotated_type = self.user_type_annotations[user_ty.base].inferred_ty; trace!(?annotated_type); let mut curr_projected_ty = PlaceTy::from_ty(annotated_type); diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 6f3451d56574e..8c4bfb2c6e0d3 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -3,11 +3,11 @@ use rustc_infer::infer::nll_relate::{TypeRelating, TypeRelatingDelegate}; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::traits::PredicateObligations; use rustc_middle::mir::ConstraintCategory; +use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::{self, Ty}; use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; -use rustc_trait_selection::traits::query::Fallible; use crate::constraints::OutlivesConstraint; use crate::diagnostics::UniverseInfo; @@ -31,7 +31,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { b: Ty<'tcx>, locations: Locations, category: ConstraintCategory<'tcx>, - ) -> Fallible<()> { + ) -> Result<(), NoSolution> { TypeRelating::new( self.infcx, NllTypeRelatingDelegate::new(self, locations, category, UniverseInfo::relate(a, b)), @@ -48,7 +48,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { b: ty::SubstsRef<'tcx>, locations: Locations, category: ConstraintCategory<'tcx>, - ) -> Fallible<()> { + ) -> Result<(), NoSolution> { TypeRelating::new( self.infcx, NllTypeRelatingDelegate::new(self, locations, category, UniverseInfo::other()), diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index de9afbbcaabbd..88256c819f4d4 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -15,7 +15,7 @@ use crate::infer::canonical::{ use crate::infer::nll_relate::{TypeRelating, TypeRelatingDelegate}; use crate::infer::region_constraints::{Constraint, RegionConstraintData}; use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult, NllRegionVariableOrigin}; -use crate::traits::query::{Fallible, NoSolution}; +use crate::traits::query::NoSolution; use crate::traits::{Obligation, ObligationCause, PredicateObligation}; use crate::traits::{PredicateObligations, TraitEngine, TraitEngineExt}; use rustc_data_structures::captures::Captures; @@ -57,7 +57,7 @@ impl<'tcx> InferCtxt<'tcx> { inference_vars: CanonicalVarValues<'tcx>, answer: T, fulfill_cx: &mut dyn TraitEngine<'tcx>, - ) -> Fallible> + ) -> Result, NoSolution> where T: Debug + TypeFoldable>, Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index c4f8718754f5f..eae5a280e114d 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -95,8 +95,6 @@ pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = #[derive(Copy, Clone, Debug, HashStable, PartialEq, Eq)] pub struct NoSolution; -pub type Fallible = Result; - impl<'tcx> From> for NoSolution { fn from(_: TypeError<'tcx>) -> NoSolution { NoSolution diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 142c20014a015..312bd38178fdd 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -5,7 +5,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse}; -use rustc_middle::traits::query::Fallible; +use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_middle::ty::{GenericArg, ToPredicate}; use rustc_span::DUMMY_SP; @@ -82,8 +82,8 @@ pub trait InferCtxtBuilderExt<'tcx> { fn enter_canonical_trait_query( &mut self, canonical_key: &Canonical<'tcx, K>, - operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible, - ) -> Fallible> + operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result, + ) -> Result, NoSolution> where K: TypeFoldable>, R: Debug + TypeFoldable>, @@ -110,8 +110,8 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> { fn enter_canonical_trait_query( &mut self, canonical_key: &Canonical<'tcx, K>, - operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible, - ) -> Fallible> + operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Result, + ) -> Result, NoSolution> where K: TypeFoldable>, R: Debug + TypeFoldable>, diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 000427bbe83ec..2c5ffd664fe1d 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -14,11 +14,11 @@ use rustc_infer::infer::canonical::{ }; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk}; -use rustc_infer::traits::query::Fallible; use rustc_infer::traits::{ FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _, }; use rustc_middle::arena::ArenaAllocatable; +use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::ToPredicate; use rustc_middle::ty::TypeFoldable; @@ -235,7 +235,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { &self, inference_vars: CanonicalVarValues<'tcx>, answer: T, - ) -> Fallible> + ) -> Result, NoSolution> where T: Debug + TypeFoldable>, Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs index e6db96c9e5580..c61f5454ec52e 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs @@ -1,5 +1,5 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; -use crate::traits::query::Fallible; +use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; pub use rustc_middle::traits::query::type_op::AscribeUserType; @@ -17,7 +17,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> { fn perform_query( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, - ) -> Fallible> { + ) -> Result, NoSolution> { tcx.type_op_ascribe_user_type(canonicalized) } } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index 94464895f3b2e..6d8d2103f3904 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -1,10 +1,10 @@ use crate::infer::canonical::query_response; use crate::infer::InferCtxt; use crate::traits::query::type_op::TypeOpOutput; -use crate::traits::query::Fallible; use crate::traits::ObligationCtxt; use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::region_constraints::RegionConstraintData; +use rustc_middle::traits::query::NoSolution; use rustc_span::source_map::DUMMY_SP; use rustc_span::Span; @@ -18,7 +18,7 @@ pub struct CustomTypeOp { impl CustomTypeOp { pub fn new<'tcx, R>(closure: F, description: &'static str) -> Self where - F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Fallible, + F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result, { CustomTypeOp { closure, description } } @@ -26,7 +26,7 @@ impl CustomTypeOp { impl<'tcx, F, R: fmt::Debug> super::TypeOp<'tcx> for CustomTypeOp where - F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Fallible, + F: FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result, { type Output = R; /// We can't do any custom error reporting for `CustomTypeOp`, so @@ -59,7 +59,7 @@ impl fmt::Debug for CustomTypeOp { /// constraints that result, creating query-region-constraints. pub fn scrape_region_constraints<'tcx, Op: super::TypeOp<'tcx, Output = R>, R>( infcx: &InferCtxt<'tcx>, - op: impl FnOnce(&ObligationCtxt<'_, 'tcx>) -> Fallible, + op: impl FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result, name: &'static str, span: Span, ) -> Result<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>), ErrorGuaranteed> { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs index 8c9b9610cb6ef..40f8ecfd4ce10 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/eq.rs @@ -1,5 +1,5 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; -use crate::traits::query::Fallible; +use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; pub use rustc_middle::traits::query::type_op::Eq; @@ -17,7 +17,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Eq<'tcx> { fn perform_query( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, - ) -> Fallible> { + ) -> Result, NoSolution> { tcx.type_op_eq(canonicalized) } } 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 18d7c9b193601..26f0d554d3508 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 @@ -1,6 +1,6 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; -use crate::traits::query::Fallible; use rustc_infer::traits::query::OutlivesBound; +use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, HashStable, TypeFoldable, TypeVisitable, Lift)] @@ -28,7 +28,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { fn perform_query( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, - ) -> Fallible> { + ) -> Result, NoSolution> { // FIXME this `unchecked_map` is only necessary because the // query is defined as taking a `ParamEnvAnd`; it should // take an `ImpliedOutlivesBounds` instead diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index a34ea3fb3dd30..6423265984804 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -2,11 +2,11 @@ use crate::infer::canonical::{ Canonical, CanonicalQueryResponse, OriginalQueryValues, QueryRegionConstraints, }; use crate::infer::{InferCtxt, InferOk}; -use crate::traits::query::Fallible; use crate::traits::ObligationCause; use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::canonical::Certainty; use rustc_infer::traits::PredicateObligations; +use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; use rustc_span::Span; @@ -79,18 +79,21 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable> + 't fn perform_query( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, - ) -> Fallible>; + ) -> Result, NoSolution>; fn fully_perform_into( query_key: ParamEnvAnd<'tcx, Self>, infcx: &InferCtxt<'tcx>, output_query_region_constraints: &mut QueryRegionConstraints<'tcx>, - ) -> Fallible<( - Self::QueryResponse, - Option>>, - PredicateObligations<'tcx>, - Certainty, - )> { + ) -> Result< + ( + Self::QueryResponse, + Option>>, + PredicateObligations<'tcx>, + Certainty, + ), + NoSolution, + > { if let Some(result) = QueryTypeOp::try_fast_path(infcx.tcx, &query_key) { return Ok((result, None, vec![], Certainty::Proven)); } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs index 5b216c0769236..776c74fdfae4b 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs @@ -1,5 +1,5 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; -use crate::traits::query::Fallible; +use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt}; use std::fmt; @@ -19,7 +19,7 @@ where fn perform_query( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, - ) -> Fallible> { + ) -> Result, NoSolution> { T::type_op_method(tcx, canonicalized) } } @@ -28,14 +28,14 @@ pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable> + Lift<'tc fn type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>, - ) -> Fallible>; + ) -> Result, NoSolution>; } impl<'tcx> Normalizable<'tcx> for Ty<'tcx> { fn type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>, - ) -> Fallible> { + ) -> Result, NoSolution> { tcx.type_op_normalize_ty(canonicalized) } } @@ -44,7 +44,7 @@ impl<'tcx> Normalizable<'tcx> for ty::Predicate<'tcx> { fn type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>, - ) -> Fallible> { + ) -> Result, NoSolution> { tcx.type_op_normalize_predicate(canonicalized) } } @@ -53,7 +53,7 @@ impl<'tcx> Normalizable<'tcx> for ty::PolyFnSig<'tcx> { fn type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>, - ) -> Fallible> { + ) -> Result, NoSolution> { tcx.type_op_normalize_poly_fn_sig(canonicalized) } } @@ -62,7 +62,7 @@ impl<'tcx> Normalizable<'tcx> for ty::FnSig<'tcx> { fn type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize>>, - ) -> Fallible> { + ) -> Result, NoSolution> { tcx.type_op_normalize_fn_sig(canonicalized) } } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs index 21ef4e24fdb05..7ce09bbdb7af3 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/outlives.rs @@ -1,6 +1,6 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; use crate::traits::query::dropck_outlives::{trivial_dropck_outlives, DropckOutlivesResult}; -use crate::traits::query::Fallible; +use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt}; #[derive(Copy, Clone, Debug, HashStable, TypeFoldable, TypeVisitable, Lift)] @@ -27,7 +27,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for DropckOutlives<'tcx> { fn perform_query( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, - ) -> Fallible> { + ) -> Result, NoSolution> { // Subtle: note that we are not invoking // `infcx.at(...).dropck_outlives(...)` here, but rather the // underlying `dropck_outlives` query. This same underlying diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs index baa2fbb6751c3..7c02f363960d7 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs @@ -1,5 +1,5 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; -use crate::traits::query::Fallible; +use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt}; pub use rustc_middle::traits::query::type_op::ProvePredicate; @@ -33,7 +33,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> { fn perform_query( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, - ) -> Fallible> { + ) -> Result, NoSolution> { tcx.type_op_prove_predicate(canonicalized) } } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs index c51292eba14be..2f2b931afcff4 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/subtype.rs @@ -1,5 +1,5 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; -use crate::traits::query::Fallible; +use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{ParamEnvAnd, TyCtxt}; pub use rustc_middle::traits::query::type_op::Subtype; @@ -14,7 +14,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for Subtype<'tcx> { fn perform_query( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Self>>, - ) -> Fallible> { + ) -> Result, NoSolution> { tcx.type_op_subtype(canonicalized) } } diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 0c2bb863e1fe0..49cbf9efa7493 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -11,7 +11,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::source_map::DUMMY_SP; use rustc_trait_selection::infer::InferCtxtBuilderExt; -use rustc_trait_selection::traits::query::{CanonicalTyGoal, Fallible, NoSolution}; +use rustc_trait_selection::traits::query::{CanonicalTyGoal, NoSolution}; use rustc_trait_selection::traits::wf; use rustc_trait_selection::traits::ObligationCtxt; use smallvec::{smallvec, SmallVec}; @@ -37,7 +37,7 @@ fn compute_implied_outlives_bounds<'tcx>( ocx: &ObligationCtxt<'_, 'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, -) -> Fallible>> { +) -> Result>, NoSolution> { let tcx = ocx.infcx.tcx; // Sometimes when we ask what it takes for T: WF, we get back that diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index b1cbd88ce27ea..faf985169deff 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -2,6 +2,7 @@ use rustc_hir as hir; use rustc_infer::infer::canonical::{Canonical, QueryResponse}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::query::Providers; +use rustc_middle::traits::query::NoSolution; use rustc_middle::traits::{DefiningAnchor, ObligationCauseCode}; use rustc_middle::ty::{self, FnSig, Lift, PolyFnSig, Ty, TyCtxt, TypeFoldable}; use rustc_middle::ty::{ParamEnvAnd, Predicate}; @@ -15,7 +16,6 @@ use rustc_trait_selection::traits::query::type_op::eq::Eq; use rustc_trait_selection::traits::query::type_op::normalize::Normalize; use rustc_trait_selection::traits::query::type_op::prove_predicate::ProvePredicate; use rustc_trait_selection::traits::query::type_op::subtype::Subtype; -use rustc_trait_selection::traits::query::{Fallible, NoSolution}; use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, ObligationCtxt}; use std::fmt; @@ -160,7 +160,7 @@ fn type_op_eq<'tcx>( fn type_op_normalize<'tcx, T>( ocx: &ObligationCtxt<'_, 'tcx>, key: ParamEnvAnd<'tcx, Normalize>, -) -> Fallible +) -> Result where T: fmt::Debug + TypeFoldable> + Lift<'tcx>, {