Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ use rustc_span::{BytePos, DUMMY_SP, Span};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::regions::InferCtxtRegionExt;
use rustc_trait_selection::solve::NextSolverError;
use rustc_trait_selection::traits::{
self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt,
self, FromSolverError, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt,
OldSolverError,
};
use tracing::{debug, instrument};

Expand Down Expand Up @@ -801,10 +803,7 @@ struct ImplTraitInTraitCollector<'a, 'tcx, E> {
impl_m_id: LocalDefId,
}

impl<'a, 'tcx, E> ImplTraitInTraitCollector<'a, 'tcx, E>
where
E: 'tcx,
{
impl<'a, 'tcx, E> ImplTraitInTraitCollector<'a, 'tcx, E> {
fn new(
ocx: &'a ObligationCtxt<'a, 'tcx, E>,
span: Span,
Expand All @@ -817,7 +816,7 @@ where

impl<'tcx, E> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx, E>
where
E: 'tcx,
E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>,
{
fn cx(&self) -> TyCtxt<'tcx> {
self.ocx.infcx.tcx
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_middle::ty::{self, FloatVid, Ty, TyCtxt, TypeSuperVisitable, TypeVisit
use rustc_session::lint;
use rustc_span::def_id::LocalDefId;
use rustc_span::{DUMMY_SP, Span};
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt, TraitEngine};
use tracing::debug;

use crate::{FnCtxt, diagnostics};
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use rustc_span::def_id::LocalDefId;
use rustc_span::hygiene::DesugaringKind;
use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
use rustc_trait_selection::traits::{
self, NormalizeExt, ObligationCauseCode, StructurallyNormalizeExt,
self, NormalizeExt, ObligationCauseCode, StructurallyNormalizeExt, TraitEngine,
};
use tracing::{debug, instrument};

Expand Down Expand Up @@ -1499,7 +1499,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// in a reentrant borrow, causing an ICE.
let result = self.at(&self.misc(sp), self.param_env).structurally_normalize_const(
Unnormalized::new_wip(ct),
&mut **self.fulfillment_cx.borrow_mut(),
&mut *self.fulfillment_cx.borrow_mut(),
);
match result {
Ok(normalized_ct) => normalized_ct,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use rustc_trait_selection::solve::Certainty;
use rustc_trait_selection::solve::inspect::{
InferCtxtProofTreeExt, InspectConfig, InspectGoal, ProofTreeVisitor,
};
use rustc_trait_selection::traits::TraitEngine;
use tracing::{debug, instrument, trace};

use crate::FnCtxt;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir_typeck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ use rustc_middle::{bug, span_bug};
use rustc_session::config;
use rustc_span::Span;
use rustc_span::def_id::LocalDefId;
use rustc_trait_selection::traits::TraitEngine;
use tracing::{debug, instrument};
use typeck_root_ctxt::TypeckRootCtxt;

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_middle::span_bug;
use rustc_middle::ty::{self, Ty, TyCtxt, TyVid, TypeVisitableExt, TypingMode};
use rustc_span::Span;
use rustc_span::def_id::LocalDefIdMap;
use rustc_trait_selection::traits::{self, FulfillmentError, TraitEngine, TraitEngineExt as _};
use rustc_trait_selection::traits::{self, DualFulfillmentCtxt, FulfillmentError, TraitEngine};
use tracing::instrument;

use super::callee::DeferredCallResolution;
Expand All @@ -31,7 +31,7 @@ pub(crate) struct TypeckRootCtxt<'tcx> {

pub(super) locals: RefCell<HirIdMap<Ty<'tcx>>>,

pub(super) fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx, FulfillmentError<'tcx>>>>,
pub(super) fulfillment_cx: RefCell<DualFulfillmentCtxt<'tcx, FulfillmentError<'tcx>>>,

// Used to detect opaque types uses added after we've already checked them.
//
Expand Down Expand Up @@ -85,7 +85,7 @@ impl<'tcx> TypeckRootCtxt<'tcx> {
.in_hir_typeck()
.build(TypingMode::typeck_for_body(tcx, def_id));
let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner));
let fulfillment_cx = RefCell::new(<dyn TraitEngine<'_, _>>::new(&infcx));
let fulfillment_cx = RefCell::new(DualFulfillmentCtxt::new(&infcx));

TypeckRootCtxt {
infcx,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl<'tcx> ScrubbedTraitError<'tcx> {
}
}

pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
pub trait TraitEngine<'tcx, E>: 'tcx {
/// Requires that `ty` must implement the trait with `def_id` in
/// the given environment. This trait must not have any type
/// parameters (except for `Self`).
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_middle/src/ty/context/impl_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,14 +690,17 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.specializes((impl_def_id, victim_def_id))
}

#[inline]
fn impl_is_default(self, impl_def_id: DefId) -> bool {
self.defaultness(impl_def_id).is_default()
}

#[inline]
fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
self.impl_trait_ref(impl_def_id)
}

#[inline]
fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
self.impl_polarity(impl_def_id)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/solve/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type PendingObligations<'tcx> =
///
/// It is also likely that we want to use slightly different datastructures
/// here as this will have to deal with far more root goals than `evaluate_all`.
pub struct FulfillmentCtxt<'tcx, E: 'tcx> {
pub struct FulfillmentCtxt<'tcx, E> {
obligations: ObligationStorage<'tcx>,

/// The snapshot in which this context was created. Using the context
Expand Down
114 changes: 95 additions & 19 deletions compiler/rustc_trait_selection/src/traits/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ use rustc_infer::infer::canonical::{
};
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk, RegionResolutionError, TypeTrace};
use rustc_infer::traits::PredicateObligations;
use rustc_macros::extension;
use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::relate::Relate;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Unnormalized, Upcast, Variance};
use rustc_middle::ty::{self, Ty, TyCtxt, TyVid, TypeFoldable, Unnormalized, Upcast, Variance};

use super::{FromSolverError, FulfillmentContext, ScrubbedTraitError, TraitEngine};
use crate::error_reporting::InferCtxtErrorExt;
Expand All @@ -27,20 +26,95 @@ use crate::traits::{
StructurallyNormalizeExt,
};

#[extension(pub trait TraitEngineExt<'tcx, E>)]
impl<'tcx, E> dyn TraitEngine<'tcx, E>
/// An enum that lets us switch between the old and new solvers.
pub enum DualFulfillmentCtxt<'tcx, E> {
Old(FulfillmentContext<'tcx, E>),
Next(NextFulfillmentCtxt<'tcx, E>),
}

impl<'tcx, E> DualFulfillmentCtxt<'tcx, E>
where
E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>,
E: FromSolverError<'tcx, OldSolverError<'tcx>>,
{
fn new(infcx: &InferCtxt<'tcx>) -> Box<Self> {
#[inline]
pub fn new(infcx: &InferCtxt<'tcx>) -> Self {
if infcx.next_trait_solver() {
Box::new(NextFulfillmentCtxt::new(infcx))
DualFulfillmentCtxt::Next(NextFulfillmentCtxt::new(infcx))
} else {
assert!(
!infcx.tcx.next_trait_solver_globally(),
"using old solver even though new solver is enabled globally"
);
Box::new(FulfillmentContext::new(infcx))
DualFulfillmentCtxt::Old(FulfillmentContext::new(infcx))
}
}
}

impl<'tcx, E> TraitEngine<'tcx, E> for DualFulfillmentCtxt<'tcx, E>
where
E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>,
{
fn register_predicate_obligation(
&mut self,
infcx: &InferCtxt<'tcx>,
obligation: PredicateObligation<'tcx>,
) {
match self {
DualFulfillmentCtxt::Old(cx) => cx.register_predicate_obligation(infcx, obligation),
DualFulfillmentCtxt::Next(cx) => cx.register_predicate_obligation(infcx, obligation),
}
}

fn try_evaluate_obligations(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E> {
match self {
DualFulfillmentCtxt::Old(cx) => cx.try_evaluate_obligations(infcx),
DualFulfillmentCtxt::Next(cx) => cx.try_evaluate_obligations(infcx),
}
}

fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E> {
match self {
DualFulfillmentCtxt::Old(cx) => cx.collect_remaining_errors(infcx),
DualFulfillmentCtxt::Next(cx) => cx.collect_remaining_errors(infcx),
}
}

fn has_pending_obligations(&self) -> bool {
match self {
DualFulfillmentCtxt::Old(cx) => cx.has_pending_obligations(),
DualFulfillmentCtxt::Next(cx) => cx.has_pending_obligations(),
}
}

fn pending_obligations(&self) -> PredicateObligations<'tcx> {
match self {
DualFulfillmentCtxt::Old(cx) => cx.pending_obligations(),
DualFulfillmentCtxt::Next(cx) => cx.pending_obligations(),
}
}

fn pending_obligations_potentially_referencing_sub_root(
&self,
infcx: &InferCtxt<'tcx>,
sub_root: TyVid,
) -> PredicateObligations<'tcx> {
match self {
DualFulfillmentCtxt::Old(cx) => {
cx.pending_obligations_potentially_referencing_sub_root(infcx, sub_root)
}
DualFulfillmentCtxt::Next(cx) => {
cx.pending_obligations_potentially_referencing_sub_root(infcx, sub_root)
}
}
}

fn drain_stalled_obligations_for_coroutines(
&mut self,
infcx: &InferCtxt<'tcx>,
) -> PredicateObligations<'tcx> {
match self {
DualFulfillmentCtxt::Old(cx) => cx.drain_stalled_obligations_for_coroutines(infcx),
DualFulfillmentCtxt::Next(cx) => cx.drain_stalled_obligations_for_coroutines(infcx),
}
}
}
Expand All @@ -49,24 +123,26 @@ where
/// with obligations outside of hir or mir typeck.
pub struct ObligationCtxt<'a, 'tcx, E = ScrubbedTraitError<'tcx>> {
pub infcx: &'a InferCtxt<'tcx>,
engine: RefCell<Box<dyn TraitEngine<'tcx, E>>>,
engine: RefCell<DualFulfillmentCtxt<'tcx, E>>,
}

impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>> {
#[inline]
pub fn new_with_diagnostics(infcx: &'a InferCtxt<'tcx>) -> Self {
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'tcx, _>>::new(infcx)) }
Self { infcx, engine: RefCell::new(DualFulfillmentCtxt::new(infcx)) }
}
}

impl<'a, 'tcx> ObligationCtxt<'a, 'tcx, ScrubbedTraitError<'tcx>> {
#[inline]
pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'tcx, _>>::new(infcx)) }
Self { infcx, engine: RefCell::new(DualFulfillmentCtxt::new(infcx)) }
}
}

impl<'a, 'tcx, E> ObligationCtxt<'a, 'tcx, E>
where
E: 'tcx,
E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>,
{
pub fn register_obligation(&self, obligation: PredicateObligation<'tcx>) {
self.engine.borrow_mut().register_predicate_obligation(self.infcx, obligation);
Expand Down Expand Up @@ -297,14 +373,14 @@ impl<'tcx> ObligationCtxt<'_, 'tcx, ScrubbedTraitError<'tcx>> {
self.infcx.make_canonicalized_query_response(
inference_vars,
answer,
&mut **self.engine.borrow_mut(),
&mut *self.engine.borrow_mut(),
)
}
}

impl<'tcx, E> ObligationCtxt<'_, 'tcx, E>
where
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>,
{
pub fn assumed_wf_types(
&self,
Expand All @@ -331,7 +407,7 @@ where
match self
.infcx
.at(&cause, param_env)
.deeply_normalize(Unnormalized::new_wip(ty), &mut **self.engine.borrow_mut())
.deeply_normalize(Unnormalized::new_wip(ty), &mut *self.engine.borrow_mut())
{
// Insert well-formed types, ignoring duplicates.
Ok(normalized) => drop(implied_bounds.insert(normalized)),
Expand All @@ -348,7 +424,7 @@ where
param_env: ty::ParamEnv<'tcx>,
value: Unnormalized<'tcx, T>,
) -> Result<T, Vec<E>> {
self.infcx.at(cause, param_env).deeply_normalize(value, &mut **self.engine.borrow_mut())
self.infcx.at(cause, param_env).deeply_normalize(value, &mut *self.engine.borrow_mut())
}

pub fn structurally_normalize_ty(
Expand All @@ -359,7 +435,7 @@ where
) -> Result<Ty<'tcx>, Vec<E>> {
self.infcx
.at(cause, param_env)
.structurally_normalize_ty(value, &mut **self.engine.borrow_mut())
.structurally_normalize_ty(value, &mut *self.engine.borrow_mut())
}

pub fn structurally_normalize_const(
Expand All @@ -370,7 +446,7 @@ where
) -> Result<ty::Const<'tcx>, Vec<E>> {
self.infcx
.at(cause, param_env)
.structurally_normalize_const(value, &mut **self.engine.borrow_mut())
.structurally_normalize_const(value, &mut *self.engine.borrow_mut())
}

pub fn structurally_normalize_term(
Expand All @@ -381,6 +457,6 @@ where
) -> Result<ty::Term<'tcx>, Vec<E>> {
self.infcx
.at(cause, param_env)
.structurally_normalize_term(value, &mut **self.engine.borrow_mut())
.structurally_normalize_term(value, &mut *self.engine.borrow_mut())
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> {
/// along. Once all type inference constraints have been generated, the
/// method `evaluate_obligations_error_on_ambiguity` can be used to report any remaining
/// ambiguous cases as errors.
pub struct FulfillmentContext<'tcx, E: 'tcx> {
pub struct FulfillmentContext<'tcx, E> {
/// A list of all obligations that have been registered with this
/// fulfillment context.
predicates: ObligationForest<PendingPredicateObligation<'tcx>>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ pub use self::dyn_compatibility::{
DynCompatibilityViolation, dyn_compatibility_violations_for_assoc_item,
hir_ty_lowering_dyn_compatibility_violations, is_vtable_safe_method,
};
pub use self::engine::{ObligationCtxt, TraitEngineExt};
pub use self::engine::{DualFulfillmentCtxt, ObligationCtxt};
pub use self::fulfill::{FulfillmentContext, OldSolverError, PendingPredicateObligation};
pub use self::normalize::NormalizeExt;
pub use self::project::{normalize_inherent_projection, normalize_projection_term};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use rustc_span::Span;
use tracing::{debug, instrument};

use crate::solve::NextSolverError;
use crate::traits::fulfill::OldSolverError;
use crate::traits::query::NoSolution;
use crate::traits::query::normalize::QueryNormalizeExt;
use crate::traits::{FromSolverError, Normalized, ObligationCause, ObligationCtxt};
Expand Down Expand Up @@ -106,7 +107,7 @@ pub fn compute_dropck_outlives_with_errors<'tcx, E>(
span: Span,
) -> Result<DropckOutlivesResult<'tcx>, Vec<E>>
where
E: FromSolverError<'tcx, NextSolverError<'tcx>>,
E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>,
{
let tcx = ocx.infcx.tcx;
let ParamEnvAnd { param_env, value: DropckOutlives { dropped_ty } } = goal;
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_type_ir/src/fast_reject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
// and small enough to prevent hangs.
const STARTING_DEPTH: usize = 8;

#[inline]
pub fn args_may_unify(
self,
obligation_args: I::GenericArgs,
Expand All @@ -224,6 +225,7 @@ impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_
self.types_may_unify_inner(lhs, rhs, depth_limit)
}

#[inline]
fn args_may_unify_inner(
self,
obligation_args: I::GenericArgs,
Expand Down
Loading