Use TraitEngine less

This commit is contained in:
Michael Goulet 2022-11-02 04:09:01 +00:00
parent 11ebe6512b
commit 41e4218d2a
6 changed files with 57 additions and 86 deletions

View File

@ -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 = <dyn rustc_infer::traits::TraitEngine<'_>>::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<Vec<_>, _> = errors

View File

@ -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 = <dyn TraitEngine<'tcx>>::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

View File

@ -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 = <dyn TraitEngine<'_>>::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);
}

View File

@ -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 = <dyn TraitEngine<'_>>::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))
}
}
}

View File

@ -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 = <dyn TraitEngine<'_>>::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()
}

View File

@ -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 = <dyn TraitEngine<'tcx>>::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,