From 41e4218d2a218896d9acde3ab68d7862b56b7f54 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Nov 2022 04:09:01 +0000 Subject: [PATCH] Use TraitEngine less --- .../src/diagnostics/conflict_errors.rs | 9 +--- .../src/region_infer/opaque_types.rs | 53 +++++++++---------- .../src/transform/check_consts/check.rs | 42 ++++++--------- compiler/rustc_hir_typeck/src/op.rs | 6 +-- .../src/for_loops_over_fallibles.rs | 11 +--- .../src/traits/outlives_bounds.rs | 22 ++++---- 6 files changed, 57 insertions(+), 86 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 583bc2e281d..8987a51757c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -23,7 +23,6 @@ use rustc_span::hygiene::DesugaringKind; use rustc_span::symbol::sym; use rustc_span::{BytePos, Span, Symbol}; use rustc_trait_selection::infer::InferCtxtExt; -use rustc_trait_selection::traits::TraitEngineExt as _; use crate::borrow_set::TwoPhaseActivation; use crate::borrowck_errors; @@ -613,24 +612,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { else { return; }; // Try to find predicates on *generic params* that would allow copying `ty` let infcx = tcx.infer_ctxt().build(); - let mut fulfill_cx = >::new(infcx.tcx); - let copy_did = infcx.tcx.lang_items().copy_trait().unwrap(); let cause = ObligationCause::new( span, self.mir_hir_id(), rustc_infer::traits::ObligationCauseCode::MiscObligation, ); - fulfill_cx.register_bound( + let errors = rustc_trait_selection::traits::fully_solve_bound( &infcx, + cause, self.param_env, // Erase any region vids from the type, which may not be resolved infcx.tcx.erase_regions(ty), copy_did, - cause, ); - // Select all, including ambiguous predicates - let errors = fulfill_cx.select_all_or_error(&infcx); // Only emit suggestion if all required predicates are on generic let predicates: Result, _> = errors diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index 465f353aaa3..95ea42b584a 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -4,7 +4,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::OpaqueTyOrigin; use rustc_infer::infer::TyCtxtInferExt as _; use rustc_infer::infer::{DefiningAnchor, InferCtxt}; -use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine}; +use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{ @@ -12,7 +12,7 @@ use rustc_middle::ty::{ }; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::TraitEngineExt as _; +use rustc_trait_selection::traits::ObligationCtxt; use super::RegionInferenceContext; @@ -252,48 +252,45 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { // type-alias-impl-trait/issue-67844-nested-opaque.rs let infcx = self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); + let ocx = ObligationCtxt::new(&infcx); // Require the hidden type to be well-formed with only the generics of the opaque type. // Defining use functions may have more bounds than the opaque type, which is ok, as long as the // hidden type is well formed even without those bounds. let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())) .to_predicate(infcx.tcx); - let mut fulfillment_cx = >::new(infcx.tcx); let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id.to_def_id()); // Require that the hidden type actually fulfills all the bounds of the opaque type, even without // the bounds that the function supplies. let opaque_ty = self.tcx.mk_opaque(def_id.to_def_id(), id_substs); - match infcx - .at(&ObligationCause::misc(instantiated_ty.span, body_id), param_env) - .eq(opaque_ty, definition_ty) - { - Ok(infer_ok) => { - for obligation in infer_ok.obligations { - fulfillment_cx.register_predicate_obligation(&infcx, obligation); - } - } - Err(err) => { - infcx - .err_ctxt() - .report_mismatched_types( - &ObligationCause::misc(instantiated_ty.span, body_id), - opaque_ty, - definition_ty, - err, - ) - .emit(); - } + if let Err(err) = ocx.eq( + &ObligationCause::misc(instantiated_ty.span, body_id), + param_env, + opaque_ty, + definition_ty, + ) { + infcx + .err_ctxt() + .report_mismatched_types( + &ObligationCause::misc(instantiated_ty.span, body_id), + opaque_ty, + definition_ty, + err, + ) + .emit(); } - fulfillment_cx.register_predicate_obligation( - &infcx, - Obligation::misc(instantiated_ty.span, body_id, param_env, predicate), - ); + ocx.register_obligation(Obligation::misc( + instantiated_ty.span, + body_id, + param_env, + predicate, + )); // Check that all obligations are satisfied by the implementation's // version. - let errors = fulfillment_cx.select_all_or_error(&infcx); + let errors = ocx.select_all_or_error(); // This is still required for many(half of the tests in ui/type-alias-impl-trait) // tests to pass diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 22a61774e8c..b1ad22b899e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -13,11 +13,8 @@ use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, use rustc_middle::ty::{Binder, TraitPredicate, TraitRef, TypeVisitable}; use rustc_mir_dataflow::{self, Analysis}; use rustc_span::{sym, Span, Symbol}; -use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::{ - self, ObligationCauseCode, SelectionContext, TraitEngine, TraitEngineExt, -}; +use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt, SelectionContext}; use std::mem; use std::ops::Deref; @@ -747,35 +744,26 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // "non-const" check. This is required for correctness here. { let infcx = tcx.infer_ctxt().build(); - let mut fulfill_cx = >::new(infcx.tcx); + let ocx = ObligationCtxt::new(&infcx); + let predicates = tcx.predicates_of(callee).instantiate(tcx, substs); let hir_id = tcx .hir() .local_def_id_to_hir_id(self.body.source.def_id().expect_local()); - let cause = || { - ObligationCause::new( - terminator.source_info.span, - hir_id, - ObligationCauseCode::ItemObligation(callee), - ) - }; - let normalized = infcx.partially_normalize_associated_types_in( - cause(), - param_env, - predicates, + let cause = ObligationCause::new( + terminator.source_info.span, + hir_id, + ObligationCauseCode::ItemObligation(callee), ); - - for p in normalized.obligations { - fulfill_cx.register_predicate_obligation(&infcx, p); - } - for obligation in traits::predicates_for_generics( - |_, _| cause(), + let normalized_predicates = + ocx.normalize(cause.clone(), param_env, predicates); + ocx.register_obligations(traits::predicates_for_generics( + |_, _| cause.clone(), self.param_env, - normalized.value, - ) { - fulfill_cx.register_predicate_obligation(&infcx, obligation); - } - let errors = fulfill_cx.select_all_or_error(&infcx); + normalized_predicates, + )); + + let errors = ocx.select_all_or_error(); if !errors.is_empty() { infcx.err_ctxt().report_fulfillment_errors(&errors, None, false); } diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 89573997693..8598369e884 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -19,7 +19,7 @@ use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt as _; -use rustc_trait_selection::traits::{FulfillmentError, TraitEngine, TraitEngineExt}; +use rustc_trait_selection::traits::FulfillmentError; use rustc_type_ir::sty::TyKind::*; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -785,9 +785,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { other_ty_expr, expected, ); - let mut fulfill = >::new(self.tcx); - fulfill.register_predicate_obligation(self, obligation); - Err(fulfill.select_where_possible(&self.infcx)) + Err(rustc_trait_selection::traits::fully_solve_obligation(self, obligation)) } } } diff --git a/compiler/rustc_lint/src/for_loops_over_fallibles.rs b/compiler/rustc_lint/src/for_loops_over_fallibles.rs index ed8d424e0c6..4187850153c 100644 --- a/compiler/rustc_lint/src/for_loops_over_fallibles.rs +++ b/compiler/rustc_lint/src/for_loops_over_fallibles.rs @@ -3,11 +3,9 @@ use crate::{LateContext, LateLintPass, LintContext}; use hir::{Expr, Pat}; use rustc_errors::{Applicability, DelayDm}; use rustc_hir as hir; -use rustc_infer::traits::TraitEngine; use rustc_infer::{infer::TyCtxtInferExt, traits::ObligationCause}; use rustc_middle::ty::{self, List}; use rustc_span::{sym, Span}; -use rustc_trait_selection::traits::TraitEngineExt; declare_lint! { /// The `for_loops_over_fallibles` lint checks for `for` loops over `Option` or `Result` values. @@ -160,24 +158,19 @@ fn suggest_question_mark<'tcx>( let ty = substs.type_at(0); let infcx = cx.tcx.infer_ctxt().build(); - let mut fulfill_cx = >::new(infcx.tcx); - let cause = ObligationCause::new( span, body_id.hir_id, rustc_infer::traits::ObligationCauseCode::MiscObligation, ); - fulfill_cx.register_bound( + let errors = rustc_trait_selection::traits::fully_solve_bound( &infcx, + cause, ty::ParamEnv::empty(), // Erase any region vids from the type, which may not be resolved infcx.tcx.erase_regions(ty), into_iterator_did, - cause, ); - // Select all, including ambiguous predicates - let errors = fulfill_cx.select_all_or_error(&infcx); - errors.is_empty() } diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 108dae092cf..b1a161c3536 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -1,7 +1,7 @@ use crate::infer::InferCtxt; use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput}; use crate::traits::query::NoSolution; -use crate::traits::{ObligationCause, TraitEngine, TraitEngineExt}; +use crate::traits::ObligationCause; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::HirId; @@ -74,20 +74,20 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { debug!(?constraints); // Instantiation may have produced new inference variables and constraints on those // variables. Process these constraints. - let mut fulfill_cx = >::new(self.tcx); let cause = ObligationCause::misc(span, body_id); - for &constraint in &constraints.outlives { - let obligation = self.query_outlives_constraint_to_obligation( - constraint, - cause.clone(), - param_env, - ); - fulfill_cx.register_predicate_obligation(self, obligation); - } + let errors = super::fully_solve_obligations( + self, + constraints.outlives.iter().map(|constraint| { + self.query_outlives_constraint_to_obligation( + *constraint, + cause.clone(), + param_env, + ) + }), + ); if !constraints.member_constraints.is_empty() { span_bug!(span, "{:#?}", constraints.member_constraints); } - let errors = fulfill_cx.select_all_or_error(self); if !errors.is_empty() { self.tcx.sess.delay_span_bug( span,