1
Fork 0

Rollup merge of #125598 - compiler-errors:proof-tree-builder, r=lcnr

Make `ProofTreeBuilder` actually generic over `Interner`

Self-explanatory. Also renamed `ecx.tcx()` to `ecx.interner()`.

r? lcnr
This commit is contained in:
Matthias Krüger 2024-05-28 18:04:33 +02:00 committed by GitHub
commit de2bf3687b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 210 additions and 175 deletions

View file

@ -218,6 +218,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
self.check_and_mk_args(def_id, args) self.check_and_mk_args(def_id, args)
} }
fn intern_canonical_goal_evaluation_step(
self,
step: solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>,
) -> &'tcx solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>> {
self.arena.alloc(step)
}
fn parent(self, def_id: Self::DefId) -> Self::DefId { fn parent(self, def_id: Self::DefId) -> Self::DefId {
self.parent(def_id) self.parent(def_id)
} }

View file

@ -26,7 +26,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
&mut self, &mut self,
goal: Goal<'tcx, (ty::Term<'tcx>, ty::Term<'tcx>, ty::AliasRelationDirection)>, goal: Goal<'tcx, (ty::Term<'tcx>, ty::Term<'tcx>, ty::AliasRelationDirection)>,
) -> QueryResult<'tcx> { ) -> QueryResult<'tcx> {
let tcx = self.tcx(); let tcx = self.interner();
let Goal { param_env, predicate: (lhs, rhs, direction) } = goal; let Goal { param_env, predicate: (lhs, rhs, direction) } = goal;
debug_assert!(lhs.to_alias_term().is_some() || rhs.to_alias_term().is_some()); debug_assert!(lhs.to_alias_term().is_some() || rhs.to_alias_term().is_some());

View file

@ -83,7 +83,7 @@ pub(super) trait GoalKind<'tcx>:
assumption: ty::Clause<'tcx>, assumption: ty::Clause<'tcx>,
) -> Result<Candidate<'tcx>, NoSolution> { ) -> Result<Candidate<'tcx>, NoSolution> {
Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| { Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| {
let tcx = ecx.tcx(); let tcx = ecx.interner();
let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else { let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
bug!("expected object type in `probe_and_consider_object_bound_candidate`"); bug!("expected object type in `probe_and_consider_object_bound_candidate`");
}; };
@ -288,8 +288,10 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect(); return self.forced_ambiguity(MaybeCause::Ambiguity).into_iter().collect();
} }
let goal: Goal<'tcx, G> = let goal: Goal<'tcx, G> = goal.with(
goal.with(self.tcx(), goal.predicate.with_self_ty(self.tcx(), normalized_self_ty)); self.interner(),
goal.predicate.with_self_ty(self.interner(), normalized_self_ty),
);
// Vars that show up in the rest of the goal substs may have been constrained by // Vars that show up in the rest of the goal substs may have been constrained by
// normalizing the self type as well, since type variables are not uniquified. // normalizing the self type as well, since type variables are not uniquified.
let goal = self.resolve_vars_if_possible(goal); let goal = self.resolve_vars_if_possible(goal);
@ -339,7 +341,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
goal: Goal<'tcx, G>, goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>, candidates: &mut Vec<Candidate<'tcx>>,
) { ) {
let tcx = self.tcx(); let tcx = self.interner();
let self_ty = goal.predicate.self_ty(); let self_ty = goal.predicate.self_ty();
let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx)); let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx));
let mut consider_impls_for_simplified_type = |simp| { let mut consider_impls_for_simplified_type = |simp| {
@ -455,7 +457,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
goal: Goal<'tcx, G>, goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>, candidates: &mut Vec<Candidate<'tcx>>,
) { ) {
let tcx = self.tcx(); let tcx = self.interner();
let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx)); let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx));
for &impl_def_id in trait_impls.blanket_impls() { for &impl_def_id in trait_impls.blanket_impls() {
// For every `default impl`, there's always a non-default `impl` // For every `default impl`, there's always a non-default `impl`
@ -478,7 +480,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
goal: Goal<'tcx, G>, goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>, candidates: &mut Vec<Candidate<'tcx>>,
) { ) {
let tcx = self.tcx(); let tcx = self.interner();
let lang_items = tcx.lang_items(); let lang_items = tcx.lang_items();
let trait_def_id = goal.predicate.trait_def_id(tcx); let trait_def_id = goal.predicate.trait_def_id(tcx);
@ -505,9 +507,9 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
G::consider_builtin_pointer_like_candidate(self, goal) G::consider_builtin_pointer_like_candidate(self, goal)
} else if lang_items.fn_ptr_trait() == Some(trait_def_id) { } else if lang_items.fn_ptr_trait() == Some(trait_def_id) {
G::consider_builtin_fn_ptr_trait_candidate(self, goal) G::consider_builtin_fn_ptr_trait_candidate(self, goal)
} else if let Some(kind) = self.tcx().fn_trait_kind_from_def_id(trait_def_id) { } else if let Some(kind) = self.interner().fn_trait_kind_from_def_id(trait_def_id) {
G::consider_builtin_fn_trait_candidates(self, goal, kind) G::consider_builtin_fn_trait_candidates(self, goal, kind)
} else if let Some(kind) = self.tcx().async_fn_trait_kind_from_def_id(trait_def_id) { } else if let Some(kind) = self.interner().async_fn_trait_kind_from_def_id(trait_def_id) {
G::consider_builtin_async_fn_trait_candidates(self, goal, kind) G::consider_builtin_async_fn_trait_candidates(self, goal, kind)
} else if lang_items.async_fn_kind_helper() == Some(trait_def_id) { } else if lang_items.async_fn_kind_helper() == Some(trait_def_id) {
G::consider_builtin_async_fn_kind_helper_candidate(self, goal) G::consider_builtin_async_fn_kind_helper_candidate(self, goal)
@ -634,7 +636,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty), ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
ty::Alias(ty::Inherent | ty::Weak, _) => { ty::Alias(ty::Inherent | ty::Weak, _) => {
self.tcx().sess.dcx().span_delayed_bug( self.interner().sess.dcx().span_delayed_bug(
DUMMY_SP, DUMMY_SP,
format!("could not normalize {self_ty}, it is not WF"), format!("could not normalize {self_ty}, it is not WF"),
); );
@ -643,7 +645,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
}; };
for assumption in for assumption in
self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args) self.interner().item_bounds(alias_ty.def_id).instantiate(self.interner(), alias_ty.args)
{ {
candidates.extend(G::probe_and_consider_implied_clause( candidates.extend(G::probe_and_consider_implied_clause(
self, self,
@ -673,7 +675,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
goal: Goal<'tcx, G>, goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>, candidates: &mut Vec<Candidate<'tcx>>,
) { ) {
let tcx = self.tcx(); let tcx = self.interner();
if !tcx.trait_def(goal.predicate.trait_def_id(tcx)).implement_via_object { if !tcx.trait_def(goal.predicate.trait_def_id(tcx)).implement_via_object {
return; return;
} }
@ -764,7 +766,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
goal: Goal<'tcx, G>, goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>, candidates: &mut Vec<Candidate<'tcx>>,
) { ) {
let tcx = self.tcx(); let tcx = self.interner();
candidates.extend(self.probe_trait_candidate(CandidateSource::CoherenceUnknowable).enter( candidates.extend(self.probe_trait_candidate(CandidateSource::CoherenceUnknowable).enter(
|ecx| { |ecx| {
@ -793,7 +795,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
goal: Goal<'tcx, G>, goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>, candidates: &mut Vec<Candidate<'tcx>>,
) { ) {
let tcx = self.tcx(); let tcx = self.interner();
let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> = let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> =
goal.with(tcx, goal.predicate.trait_ref(tcx)); goal.with(tcx, goal.predicate.trait_ref(tcx));

View file

@ -22,7 +22,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
ecx: &EvalCtxt<'_, InferCtxt<'tcx>>, ecx: &EvalCtxt<'_, InferCtxt<'tcx>>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Result<Vec<ty::Binder<'tcx, Ty<'tcx>>>, NoSolution> { ) -> Result<Vec<ty::Binder<'tcx, Ty<'tcx>>>, NoSolution> {
let tcx = ecx.tcx(); let tcx = ecx.interner();
match *ty.kind() { match *ty.kind() {
ty::Uint(_) ty::Uint(_)
| ty::Int(_) | ty::Int(_)
@ -75,7 +75,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
} }
ty::CoroutineWitness(def_id, args) => Ok(ecx ty::CoroutineWitness(def_id, args) => Ok(ecx
.tcx() .interner()
.bound_coroutine_hidden_types(def_id) .bound_coroutine_hidden_types(def_id)
.map(|bty| bty.instantiate(tcx, args)) .map(|bty| bty.instantiate(tcx, args))
.collect()), .collect()),
@ -151,8 +151,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
// "best effort" optimization and `sized_constraint` may return `Some`, even // "best effort" optimization and `sized_constraint` may return `Some`, even
// if the ADT is sized for all possible args. // if the ADT is sized for all possible args.
ty::Adt(def, args) => { ty::Adt(def, args) => {
if let Some(sized_crit) = def.sized_constraint(ecx.tcx()) { if let Some(sized_crit) = def.sized_constraint(ecx.interner()) {
Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.tcx(), args))]) Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.interner(), args))])
} else { } else {
Ok(vec![]) Ok(vec![])
} }
@ -210,10 +210,10 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
// only when `coroutine_clone` is enabled and the coroutine is movable // only when `coroutine_clone` is enabled and the coroutine is movable
// impl Copy/Clone for Coroutine where T: Copy/Clone forall T in (upvars, witnesses) // impl Copy/Clone for Coroutine where T: Copy/Clone forall T in (upvars, witnesses)
ty::Coroutine(def_id, args) => match ecx.tcx().coroutine_movability(def_id) { ty::Coroutine(def_id, args) => match ecx.interner().coroutine_movability(def_id) {
Movability::Static => Err(NoSolution), Movability::Static => Err(NoSolution),
Movability::Movable => { Movability::Movable => {
if ecx.tcx().features().coroutine_clone { if ecx.interner().features().coroutine_clone {
let coroutine = args.as_coroutine(); let coroutine = args.as_coroutine();
Ok(vec![ Ok(vec![
ty::Binder::dummy(coroutine.tupled_upvars_ty()), ty::Binder::dummy(coroutine.tupled_upvars_ty()),
@ -227,9 +227,9 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
// impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types // impl Copy/Clone for CoroutineWitness where T: Copy/Clone forall T in coroutine_hidden_types
ty::CoroutineWitness(def_id, args) => Ok(ecx ty::CoroutineWitness(def_id, args) => Ok(ecx
.tcx() .interner()
.bound_coroutine_hidden_types(def_id) .bound_coroutine_hidden_types(def_id)
.map(|bty| bty.instantiate(ecx.tcx(), args)) .map(|bty| bty.instantiate(ecx.interner(), args))
.collect()), .collect()),
} }
} }
@ -666,7 +666,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
trait_ref: ty::TraitRef<'tcx>, trait_ref: ty::TraitRef<'tcx>,
object_bound: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, object_bound: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Vec<Goal<'tcx, ty::Predicate<'tcx>>> { ) -> Vec<Goal<'tcx, ty::Predicate<'tcx>>> {
let tcx = ecx.tcx(); let tcx = ecx.interner();
let mut requirements = vec![]; let mut requirements = vec![];
requirements.extend( requirements.extend(
tcx.super_predicates_of(trait_ref.def_id).instantiate(tcx, trait_ref.args).predicates, tcx.super_predicates_of(trait_ref.def_id).instantiate(tcx, trait_ref.args).predicates,
@ -722,7 +722,7 @@ struct ReplaceProjectionWith<'a, 'tcx> {
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceProjectionWith<'_, 'tcx> { impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceProjectionWith<'_, 'tcx> {
fn interner(&self) -> TyCtxt<'tcx> { fn interner(&self) -> TyCtxt<'tcx> {
self.ecx.tcx() self.ecx.interner()
} }
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
@ -739,7 +739,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceProjectionWith<'_, 'tcx> {
.eq_and_get_goals( .eq_and_get_goals(
self.param_env, self.param_env,
alias_ty, alias_ty,
proj.projection_term.expect_ty(self.ecx.tcx()), proj.projection_term.expect_ty(self.ecx.interner()),
) )
.expect("expected to be able to unify goal projection with dyn's projection"), .expect("expected to be able to unify goal projection with dyn's projection"),
); );

View file

@ -16,7 +16,6 @@ use crate::solve::{
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_infer::infer::canonical::query_response::make_query_region_constraints; use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
use rustc_infer::infer::canonical::CanonicalVarValues;
use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints}; use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
use rustc_infer::infer::RegionVariableOrigin; use rustc_infer::infer::RegionVariableOrigin;
use rustc_infer::infer::{InferCtxt, InferOk}; use rustc_infer::infer::{InferCtxt, InferOk};
@ -32,22 +31,24 @@ use rustc_middle::ty::{self, BoundVar, GenericArgKind, Ty, TyCtxt, TypeFoldable}
use rustc_next_trait_solver::canonicalizer::{CanonicalizeMode, Canonicalizer}; use rustc_next_trait_solver::canonicalizer::{CanonicalizeMode, Canonicalizer};
use rustc_next_trait_solver::resolve::EagerResolver; use rustc_next_trait_solver::resolve::EagerResolver;
use rustc_span::{Span, DUMMY_SP}; use rustc_span::{Span, DUMMY_SP};
use rustc_type_ir::CanonicalVarValues;
use rustc_type_ir::{InferCtxtLike, Interner};
use std::assert_matches::assert_matches; use std::assert_matches::assert_matches;
use std::iter; use std::iter;
use std::ops::Deref; use std::ops::Deref;
trait ResponseT<'tcx> { trait ResponseT<'tcx> {
fn var_values(&self) -> CanonicalVarValues<'tcx>; fn var_values(&self) -> CanonicalVarValues<TyCtxt<'tcx>>;
} }
impl<'tcx> ResponseT<'tcx> for Response<TyCtxt<'tcx>> { impl<'tcx> ResponseT<'tcx> for Response<TyCtxt<'tcx>> {
fn var_values(&self) -> CanonicalVarValues<'tcx> { fn var_values(&self) -> CanonicalVarValues<TyCtxt<'tcx>> {
self.var_values self.var_values
} }
} }
impl<'tcx, T> ResponseT<'tcx> for inspect::State<TyCtxt<'tcx>, T> { impl<'tcx, T> ResponseT<'tcx> for inspect::State<TyCtxt<'tcx>, T> {
fn var_values(&self) -> CanonicalVarValues<'tcx> { fn var_values(&self) -> CanonicalVarValues<TyCtxt<'tcx>> {
self.var_values self.var_values
} }
} }
@ -71,7 +72,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
QueryInput { QueryInput {
goal, goal,
predefined_opaques_in_body: self predefined_opaques_in_body: self
.tcx() .interner()
.mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }), .mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }),
}, },
); );
@ -144,7 +145,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
Response { Response {
var_values, var_values,
certainty, certainty,
external_constraints: self.tcx().mk_external_constraints(external_constraints), external_constraints: self.interner().mk_external_constraints(external_constraints),
}, },
); );
@ -160,7 +161,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
maybe_cause: MaybeCause, maybe_cause: MaybeCause,
) -> CanonicalResponse<'tcx> { ) -> CanonicalResponse<'tcx> {
response_no_constraints_raw( response_no_constraints_raw(
self.tcx(), self.interner(),
self.max_input_universe, self.max_input_universe,
self.variables, self.variables,
Certainty::Maybe(maybe_cause), Certainty::Maybe(maybe_cause),
@ -194,7 +195,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned(); let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned();
let mut region_constraints = self.infcx.with_region_constraints(|region_constraints| { let mut region_constraints = self.infcx.with_region_constraints(|region_constraints| {
make_query_region_constraints( make_query_region_constraints(
self.tcx(), self.interner(),
region_obligations.iter().map(|r_o| { region_obligations.iter().map(|r_o| {
(r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category()) (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())
}), }),
@ -239,7 +240,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
); );
let Response { var_values, external_constraints, certainty } = let Response { var_values, external_constraints, certainty } =
response.instantiate(self.tcx(), &instantiation); response.instantiate(self.interner(), &instantiation);
Self::unify_query_var_values(self.infcx, param_env, &original_values, var_values); Self::unify_query_var_values(self.infcx, param_env, &original_values, var_values);
@ -260,7 +261,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
infcx: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
original_values: &[ty::GenericArg<'tcx>], original_values: &[ty::GenericArg<'tcx>],
response: &Canonical<'tcx, T>, response: &Canonical<'tcx, T>,
) -> CanonicalVarValues<'tcx> { ) -> CanonicalVarValues<TyCtxt<'tcx>> {
// FIXME: Longterm canonical queries should deal with all placeholders // FIXME: Longterm canonical queries should deal with all placeholders
// created inside of the query directly instead of returning them to the // created inside of the query directly instead of returning them to the
// caller. // caller.
@ -354,7 +355,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
infcx: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
original_values: &[ty::GenericArg<'tcx>], original_values: &[ty::GenericArg<'tcx>],
var_values: CanonicalVarValues<'tcx>, var_values: CanonicalVarValues<TyCtxt<'tcx>>,
) { ) {
assert_eq!(original_values.len(), var_values.len()); assert_eq!(original_values.len(), var_values.len());
@ -393,13 +394,18 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
/// evaluating a goal. The `var_values` not only include the bound variables /// evaluating a goal. The `var_values` not only include the bound variables
/// of the query input, but also contain all unconstrained inference vars /// of the query input, but also contain all unconstrained inference vars
/// created while evaluating this goal. /// created while evaluating this goal.
pub(in crate::solve) fn make_canonical_state<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>( pub(in crate::solve) fn make_canonical_state<Infcx, T, I>(
infcx: &InferCtxt<'tcx>, infcx: &Infcx,
var_values: &[ty::GenericArg<'tcx>], var_values: &[I::GenericArg],
max_input_universe: ty::UniverseIndex, max_input_universe: ty::UniverseIndex,
data: T, data: T,
) -> inspect::CanonicalState<TyCtxt<'tcx>, T> { ) -> inspect::CanonicalState<I, T>
let var_values = CanonicalVarValues { var_values: infcx.tcx.mk_args(var_values) }; where
Infcx: InferCtxtLike<Interner = I>,
I: Interner,
T: TypeFoldable<I>,
{
let var_values = CanonicalVarValues { var_values: infcx.interner().mk_args(var_values) };
let state = inspect::State { var_values, data }; let state = inspect::State { var_values, data };
let state = state.fold_with(&mut EagerResolver::new(infcx)); let state = state.fold_with(&mut EagerResolver::new(infcx));
Canonicalizer::canonicalize( Canonicalizer::canonicalize(

View file

@ -98,7 +98,7 @@ pub struct EvalCtxt<
// evaluation code. // evaluation code.
tainted: Result<(), NoSolution>, tainted: Result<(), NoSolution>,
pub(super) inspect: ProofTreeBuilder<I>, pub(super) inspect: ProofTreeBuilder<Infcx>,
} }
#[derive(derivative::Derivative)] #[derive(derivative::Derivative)]
@ -218,7 +218,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
search_graph: &'a mut search_graph::SearchGraph<TyCtxt<'tcx>>, search_graph: &'a mut search_graph::SearchGraph<TyCtxt<'tcx>>,
canonical_input: CanonicalInput<'tcx>, canonical_input: CanonicalInput<'tcx>,
canonical_goal_evaluation: &mut ProofTreeBuilder<TyCtxt<'tcx>>, canonical_goal_evaluation: &mut ProofTreeBuilder<InferCtxt<'tcx>>,
f: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>, Goal<'tcx, ty::Predicate<'tcx>>) -> R, f: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>, Goal<'tcx, ty::Predicate<'tcx>>) -> R,
) -> R { ) -> R {
let intercrate = match search_graph.solver_mode() { let intercrate = match search_graph.solver_mode() {
@ -280,7 +280,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
search_graph: &'a mut search_graph::SearchGraph<TyCtxt<'tcx>>, search_graph: &'a mut search_graph::SearchGraph<TyCtxt<'tcx>>,
canonical_input: CanonicalInput<'tcx>, canonical_input: CanonicalInput<'tcx>,
goal_evaluation: &mut ProofTreeBuilder<TyCtxt<'tcx>>, goal_evaluation: &mut ProofTreeBuilder<InferCtxt<'tcx>>,
) -> QueryResult<'tcx> { ) -> QueryResult<'tcx> {
let mut canonical_goal_evaluation = let mut canonical_goal_evaluation =
goal_evaluation.new_canonical_goal_evaluation(canonical_input); goal_evaluation.new_canonical_goal_evaluation(canonical_input);
@ -347,7 +347,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
let mut goal_evaluation = let mut goal_evaluation =
self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind); self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind);
let canonical_response = EvalCtxt::evaluate_canonical_goal( let canonical_response = EvalCtxt::evaluate_canonical_goal(
self.tcx(), self.interner(),
self.search_graph, self.search_graph,
canonical_goal, canonical_goal,
&mut goal_evaluation, &mut goal_evaluation,
@ -450,7 +450,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
} }
} else { } else {
self.infcx.enter_forall(kind, |kind| { self.infcx.enter_forall(kind, |kind| {
let goal = goal.with(self.tcx(), ty::Binder::dummy(kind)); let goal = goal.with(self.interner(), ty::Binder::dummy(kind));
self.add_goal(GoalSource::InstantiateHigherRanked, goal); self.add_goal(GoalSource::InstantiateHigherRanked, goal);
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}) })
@ -511,7 +511,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
/// ///
/// Goals for the next step get directly added to the nested goals of the `EvalCtxt`. /// Goals for the next step get directly added to the nested goals of the `EvalCtxt`.
fn evaluate_added_goals_step(&mut self) -> Result<Option<Certainty>, NoSolution> { fn evaluate_added_goals_step(&mut self) -> Result<Option<Certainty>, NoSolution> {
let tcx = self.tcx(); let tcx = self.interner();
let mut goals = core::mem::take(&mut self.nested_goals); let mut goals = core::mem::take(&mut self.nested_goals);
// If this loop did not result in any progress, what's our final certainty. // If this loop did not result in any progress, what's our final certainty.
@ -597,11 +597,13 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
} }
} }
impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> { impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> EvalCtxt<'_, Infcx> {
pub(super) fn tcx(&self) -> TyCtxt<'tcx> { pub(super) fn interner(&self) -> I {
self.infcx.tcx self.infcx.interner()
} }
}
impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
pub(super) fn next_ty_infer(&mut self) -> Ty<'tcx> { pub(super) fn next_ty_infer(&mut self) -> Ty<'tcx> {
let ty = self.infcx.next_ty_var(DUMMY_SP); let ty = self.infcx.next_ty_var(DUMMY_SP);
self.inspect.add_var_value(ty); self.inspect.add_var_value(ty);
@ -759,7 +761,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
// NOTE: this check is purely an optimization, the structural eq would // NOTE: this check is purely an optimization, the structural eq would
// always fail if the term is not an inference variable. // always fail if the term is not an inference variable.
if term.is_infer() { if term.is_infer() {
let tcx = self.tcx(); let tcx = self.interner();
// We need to relate `alias` to `term` treating only the outermost // We need to relate `alias` to `term` treating only the outermost
// constructor as rigid, relating any contained generic arguments as // constructor as rigid, relating any contained generic arguments as
// normal. We do this by first structurally equating the `term` // normal. We do this by first structurally equating the `term`
@ -1054,10 +1056,10 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
) -> Option<ty::Const<'tcx>> { ) -> Option<ty::Const<'tcx>> {
use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::mir::interpret::ErrorHandled;
match self.infcx.const_eval_resolve(param_env, unevaluated, DUMMY_SP) { match self.infcx.const_eval_resolve(param_env, unevaluated, DUMMY_SP) {
Ok(Some(val)) => Some(ty::Const::new_value(self.tcx(), val, ty)), Ok(Some(val)) => Some(ty::Const::new_value(self.interner(), val, ty)),
Ok(None) | Err(ErrorHandled::TooGeneric(_)) => None, Ok(None) | Err(ErrorHandled::TooGeneric(_)) => None,
Err(ErrorHandled::Reported(e, _)) => { Err(ErrorHandled::Reported(e, _)) => {
Some(ty::Const::new_error(self.tcx(), e.into(), ty)) Some(ty::Const::new_error(self.interner(), e.into(), ty))
} }
} }
} }
@ -1070,7 +1072,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
principal: ty::PolyTraitRef<'tcx>, principal: ty::PolyTraitRef<'tcx>,
mut supertrait_visitor: impl FnMut(&mut Self, ty::PolyTraitRef<'tcx>, usize, Option<usize>), mut supertrait_visitor: impl FnMut(&mut Self, ty::PolyTraitRef<'tcx>, usize, Option<usize>),
) { ) {
let tcx = self.tcx(); let tcx = self.interner();
let mut offset = 0; let mut offset = 0;
prepare_vtable_segments::<()>(tcx, principal, |segment| { prepare_vtable_segments::<()>(tcx, principal, |segment| {
match segment { match segment {
@ -1112,7 +1114,7 @@ struct ReplaceAliasWithInfer<'me, 'a, 'tcx> {
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceAliasWithInfer<'_, '_, 'tcx> { impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceAliasWithInfer<'_, '_, 'tcx> {
fn interner(&self) -> TyCtxt<'tcx> { fn interner(&self) -> TyCtxt<'tcx> {
self.ecx.tcx() self.ecx.interner()
} }
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {

View file

@ -3,18 +3,16 @@
//! This code is *a bit* of a mess and can hopefully be //! This code is *a bit* of a mess and can hopefully be
//! mostly ignored. For a general overview of how it works, //! mostly ignored. For a general overview of how it works,
//! see the comment on [ProofTreeBuilder]. //! see the comment on [ProofTreeBuilder].
use std::marker::PhantomData;
use std::mem; use std::mem;
use crate::solve::eval_ctxt::canonical; use crate::solve::eval_ctxt::canonical;
use crate::solve::{self, inspect, GenerateProofTree}; use crate::solve::{self, inspect, GenerateProofTree};
use rustc_infer::infer::InferCtxt;
use rustc_middle::bug; use rustc_middle::bug;
use rustc_middle::infer::canonical::CanonicalVarValues;
use rustc_middle::ty::{self, TyCtxt};
use rustc_next_trait_solver::solve::{ use rustc_next_trait_solver::solve::{
CanonicalInput, Certainty, Goal, GoalSource, QueryInput, QueryResult, CanonicalInput, Certainty, Goal, GoalSource, QueryInput, QueryResult,
}; };
use rustc_type_ir::Interner; use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
/// The core data structure when building proof trees. /// The core data structure when building proof trees.
/// ///
@ -36,7 +34,11 @@ use rustc_type_ir::Interner;
/// trees. At the end of trait solving `ProofTreeBuilder::finalize` /// trees. At the end of trait solving `ProofTreeBuilder::finalize`
/// is called to recursively convert the whole structure to a /// is called to recursively convert the whole structure to a
/// finished proof tree. /// finished proof tree.
pub(in crate::solve) struct ProofTreeBuilder<I: Interner> { pub(in crate::solve) struct ProofTreeBuilder<
Infcx: InferCtxtLike<Interner = I>,
I: Interner = <Infcx as InferCtxtLike>::Interner,
> {
_infcx: PhantomData<Infcx>,
state: Option<Box<DebugSolver<I>>>, state: Option<Box<DebugSolver<I>>>,
} }
@ -229,36 +231,36 @@ impl<I: Interner> WipProbeStep<I> {
} }
} }
// FIXME: Genericize this impl. impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> ProofTreeBuilder<Infcx> {
impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> { fn new(state: impl Into<DebugSolver<I>>) -> ProofTreeBuilder<Infcx> {
fn new(state: impl Into<DebugSolver<TyCtxt<'tcx>>>) -> ProofTreeBuilder<TyCtxt<'tcx>> { ProofTreeBuilder { state: Some(Box::new(state.into())), _infcx: PhantomData }
ProofTreeBuilder { state: Some(Box::new(state.into())) }
} }
fn opt_nested<T: Into<DebugSolver<TyCtxt<'tcx>>>>( fn opt_nested<T: Into<DebugSolver<I>>>(&self, state: impl FnOnce() -> Option<T>) -> Self {
&self,
state: impl FnOnce() -> Option<T>,
) -> Self {
ProofTreeBuilder { ProofTreeBuilder {
state: self.state.as_ref().and_then(|_| Some(state()?.into())).map(Box::new), state: self.state.as_ref().and_then(|_| Some(state()?.into())).map(Box::new),
_infcx: PhantomData,
} }
} }
fn nested<T: Into<DebugSolver<TyCtxt<'tcx>>>>(&self, state: impl FnOnce() -> T) -> Self { fn nested<T: Into<DebugSolver<I>>>(&self, state: impl FnOnce() -> T) -> Self {
ProofTreeBuilder { state: self.state.as_ref().map(|_| Box::new(state().into())) } ProofTreeBuilder {
state: self.state.as_ref().map(|_| Box::new(state().into())),
_infcx: PhantomData,
}
} }
fn as_mut(&mut self) -> Option<&mut DebugSolver<TyCtxt<'tcx>>> { fn as_mut(&mut self) -> Option<&mut DebugSolver<I>> {
self.state.as_deref_mut() self.state.as_deref_mut()
} }
pub fn take_and_enter_probe(&mut self) -> ProofTreeBuilder<TyCtxt<'tcx>> { pub fn take_and_enter_probe(&mut self) -> ProofTreeBuilder<Infcx> {
let mut nested = ProofTreeBuilder { state: self.state.take() }; let mut nested = ProofTreeBuilder { state: self.state.take(), _infcx: PhantomData };
nested.enter_probe(); nested.enter_probe();
nested nested
} }
pub fn finalize(self) -> Option<inspect::GoalEvaluation<TyCtxt<'tcx>>> { pub fn finalize(self) -> Option<inspect::GoalEvaluation<I>> {
match *self.state? { match *self.state? {
DebugSolver::GoalEvaluation(wip_goal_evaluation) => { DebugSolver::GoalEvaluation(wip_goal_evaluation) => {
Some(wip_goal_evaluation.finalize()) Some(wip_goal_evaluation.finalize())
@ -267,21 +269,19 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
} }
} }
pub fn new_maybe_root( pub fn new_maybe_root(generate_proof_tree: GenerateProofTree) -> ProofTreeBuilder<Infcx> {
generate_proof_tree: GenerateProofTree,
) -> ProofTreeBuilder<TyCtxt<'tcx>> {
match generate_proof_tree { match generate_proof_tree {
GenerateProofTree::No => ProofTreeBuilder::new_noop(), GenerateProofTree::No => ProofTreeBuilder::new_noop(),
GenerateProofTree::Yes => ProofTreeBuilder::new_root(), GenerateProofTree::Yes => ProofTreeBuilder::new_root(),
} }
} }
pub fn new_root() -> ProofTreeBuilder<TyCtxt<'tcx>> { pub fn new_root() -> ProofTreeBuilder<Infcx> {
ProofTreeBuilder::new(DebugSolver::Root) ProofTreeBuilder::new(DebugSolver::Root)
} }
pub fn new_noop() -> ProofTreeBuilder<TyCtxt<'tcx>> { pub fn new_noop() -> ProofTreeBuilder<Infcx> {
ProofTreeBuilder { state: None } ProofTreeBuilder { state: None, _infcx: PhantomData }
} }
pub fn is_noop(&self) -> bool { pub fn is_noop(&self) -> bool {
@ -290,10 +290,10 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
pub(in crate::solve) fn new_goal_evaluation( pub(in crate::solve) fn new_goal_evaluation(
&mut self, &mut self,
goal: Goal<TyCtxt<'tcx>, ty::Predicate<'tcx>>, goal: Goal<I, I::Predicate>,
orig_values: &[ty::GenericArg<'tcx>], orig_values: &[I::GenericArg],
kind: solve::GoalEvaluationKind, kind: solve::GoalEvaluationKind,
) -> ProofTreeBuilder<TyCtxt<'tcx>> { ) -> ProofTreeBuilder<Infcx> {
self.opt_nested(|| match kind { self.opt_nested(|| match kind {
solve::GoalEvaluationKind::Root => Some(WipGoalEvaluation { solve::GoalEvaluationKind::Root => Some(WipGoalEvaluation {
uncanonicalized_goal: goal, uncanonicalized_goal: goal,
@ -306,8 +306,8 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
pub fn new_canonical_goal_evaluation( pub fn new_canonical_goal_evaluation(
&mut self, &mut self,
goal: CanonicalInput<TyCtxt<'tcx>>, goal: CanonicalInput<I>,
) -> ProofTreeBuilder<TyCtxt<'tcx>> { ) -> ProofTreeBuilder<Infcx> {
self.nested(|| WipCanonicalGoalEvaluation { self.nested(|| WipCanonicalGoalEvaluation {
goal, goal,
kind: None, kind: None,
@ -318,12 +318,13 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
pub fn finalize_canonical_goal_evaluation( pub fn finalize_canonical_goal_evaluation(
&mut self, &mut self,
tcx: TyCtxt<'tcx>, tcx: I,
) -> Option<&'tcx inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>> { ) -> Option<I::CanonicalGoalEvaluationStepRef> {
self.as_mut().map(|this| match this { self.as_mut().map(|this| match this {
DebugSolver::CanonicalGoalEvaluation(evaluation) => { DebugSolver::CanonicalGoalEvaluation(evaluation) => {
let final_revision = mem::take(&mut evaluation.final_revision).unwrap(); let final_revision = mem::take(&mut evaluation.final_revision).unwrap();
let final_revision = &*tcx.arena.alloc(final_revision.finalize()); let final_revision =
tcx.intern_canonical_goal_evaluation_step(final_revision.finalize());
let kind = WipCanonicalGoalEvaluationKind::Interned { final_revision }; let kind = WipCanonicalGoalEvaluationKind::Interned { final_revision };
assert_eq!(evaluation.kind.replace(kind), None); assert_eq!(evaluation.kind.replace(kind), None);
final_revision final_revision
@ -334,7 +335,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
pub fn canonical_goal_evaluation( pub fn canonical_goal_evaluation(
&mut self, &mut self,
canonical_goal_evaluation: ProofTreeBuilder<TyCtxt<'tcx>>, canonical_goal_evaluation: ProofTreeBuilder<Infcx>,
) { ) {
if let Some(this) = self.as_mut() { if let Some(this) = self.as_mut() {
match (this, *canonical_goal_evaluation.state.unwrap()) { match (this, *canonical_goal_evaluation.state.unwrap()) {
@ -350,10 +351,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
} }
} }
pub fn canonical_goal_evaluation_kind( pub fn canonical_goal_evaluation_kind(&mut self, kind: WipCanonicalGoalEvaluationKind<I>) {
&mut self,
kind: WipCanonicalGoalEvaluationKind<TyCtxt<'tcx>>,
) {
if let Some(this) = self.as_mut() { if let Some(this) = self.as_mut() {
match this { match this {
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => { DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => {
@ -364,7 +362,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
} }
} }
pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder<TyCtxt<'tcx>>) { pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder<Infcx>) {
if let Some(this) = self.as_mut() { if let Some(this) = self.as_mut() {
match this { match this {
DebugSolver::Root => *this = *goal_evaluation.state.unwrap(), DebugSolver::Root => *this = *goal_evaluation.state.unwrap(),
@ -378,9 +376,9 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
pub fn new_goal_evaluation_step( pub fn new_goal_evaluation_step(
&mut self, &mut self,
var_values: CanonicalVarValues<'tcx>, var_values: ty::CanonicalVarValues<I>,
instantiated_goal: QueryInput<TyCtxt<'tcx>, ty::Predicate<'tcx>>, instantiated_goal: QueryInput<I, I::Predicate>,
) -> ProofTreeBuilder<TyCtxt<'tcx>> { ) -> ProofTreeBuilder<Infcx> {
self.nested(|| WipCanonicalGoalEvaluationStep { self.nested(|| WipCanonicalGoalEvaluationStep {
var_values: var_values.var_values.to_vec(), var_values: var_values.var_values.to_vec(),
instantiated_goal, instantiated_goal,
@ -394,7 +392,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
}) })
} }
pub fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder<TyCtxt<'tcx>>) { pub fn goal_evaluation_step(&mut self, goal_evaluation_step: ProofTreeBuilder<Infcx>) {
if let Some(this) = self.as_mut() { if let Some(this) = self.as_mut() {
match (this, *goal_evaluation_step.state.unwrap()) { match (this, *goal_evaluation_step.state.unwrap()) {
( (
@ -408,7 +406,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
} }
} }
pub fn add_var_value<T: Into<ty::GenericArg<'tcx>>>(&mut self, arg: T) { pub fn add_var_value<T: Into<I::GenericArg>>(&mut self, arg: T) {
match self.as_mut() { match self.as_mut() {
None => {} None => {}
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
@ -435,7 +433,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
} }
} }
pub fn probe_kind(&mut self, probe_kind: inspect::ProbeKind<TyCtxt<'tcx>>) { pub fn probe_kind(&mut self, probe_kind: inspect::ProbeKind<I>) {
match self.as_mut() { match self.as_mut() {
None => {} None => {}
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
@ -446,11 +444,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
} }
} }
pub fn probe_final_state( pub fn probe_final_state(&mut self, infcx: &Infcx, max_input_universe: ty::UniverseIndex) {
&mut self,
infcx: &InferCtxt<'tcx>,
max_input_universe: ty::UniverseIndex,
) {
match self.as_mut() { match self.as_mut() {
None => {} None => {}
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
@ -469,24 +463,24 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
pub fn add_normalizes_to_goal( pub fn add_normalizes_to_goal(
&mut self, &mut self,
infcx: &InferCtxt<'tcx>, infcx: &Infcx,
max_input_universe: ty::UniverseIndex, max_input_universe: ty::UniverseIndex,
goal: Goal<TyCtxt<'tcx>, ty::NormalizesTo<'tcx>>, goal: Goal<I, ty::NormalizesTo<I>>,
) { ) {
self.add_goal( self.add_goal(
infcx, infcx,
max_input_universe, max_input_universe,
GoalSource::Misc, GoalSource::Misc,
goal.with(infcx.tcx, goal.predicate), goal.with(infcx.interner(), goal.predicate),
); );
} }
pub fn add_goal( pub fn add_goal(
&mut self, &mut self,
infcx: &InferCtxt<'tcx>, infcx: &Infcx,
max_input_universe: ty::UniverseIndex, max_input_universe: ty::UniverseIndex,
source: GoalSource, source: GoalSource,
goal: Goal<TyCtxt<'tcx>, ty::Predicate<'tcx>>, goal: Goal<I, I::Predicate>,
) { ) {
match self.as_mut() { match self.as_mut() {
None => {} None => {}
@ -505,9 +499,9 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
pub(crate) fn record_impl_args( pub(crate) fn record_impl_args(
&mut self, &mut self,
infcx: &InferCtxt<'tcx>, infcx: &Infcx,
max_input_universe: ty::UniverseIndex, max_input_universe: ty::UniverseIndex,
impl_args: ty::GenericArgsRef<'tcx>, impl_args: I::GenericArgs,
) { ) {
match self.as_mut() { match self.as_mut() {
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
@ -540,7 +534,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
} }
} }
pub fn finish_probe(mut self) -> ProofTreeBuilder<TyCtxt<'tcx>> { pub fn finish_probe(mut self) -> ProofTreeBuilder<Infcx> {
match self.as_mut() { match self.as_mut() {
None => {} None => {}
Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => { Some(DebugSolver::CanonicalGoalEvaluationStep(state)) => {
@ -555,7 +549,7 @@ impl<'tcx> ProofTreeBuilder<TyCtxt<'tcx>> {
self self
} }
pub fn query_result(&mut self, result: QueryResult<TyCtxt<'tcx>>) { pub fn query_result(&mut self, result: QueryResult<I>) {
if let Some(this) = self.as_mut() { if let Some(this) = self.as_mut() {
match this { match this {
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => { DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation) => {

View file

@ -133,7 +133,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
} }
fn compute_object_safe_goal(&mut self, trait_def_id: DefId) -> QueryResult<'tcx> { fn compute_object_safe_goal(&mut self, trait_def_id: DefId) -> QueryResult<'tcx> {
if self.tcx().check_is_object_safe(trait_def_id) { if self.interner().check_is_object_safe(trait_def_id) {
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
} else { } else {
Err(NoSolution) Err(NoSolution)
@ -274,7 +274,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
if let ty::Alias(..) = ty.kind() { if let ty::Alias(..) = ty.kind() {
let normalized_ty = self.next_ty_infer(); let normalized_ty = self.next_ty_infer();
let alias_relate_goal = Goal::new( let alias_relate_goal = Goal::new(
self.tcx(), self.interner(),
param_env, param_env,
ty::PredicateKind::AliasRelate( ty::PredicateKind::AliasRelate(
ty.into(), ty.into(),

View file

@ -12,7 +12,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
if let Some(normalized_const) = self.try_const_eval_resolve( if let Some(normalized_const) = self.try_const_eval_resolve(
goal.param_env, goal.param_env,
ty::UnevaluatedConst::new(goal.predicate.alias.def_id, goal.predicate.alias.args), ty::UnevaluatedConst::new(goal.predicate.alias.def_id, goal.predicate.alias.args),
self.tcx() self.interner()
.type_of(goal.predicate.alias.def_id) .type_of(goal.predicate.alias.def_id)
.no_bound_vars() .no_bound_vars()
.expect("const ty should not rely on other generics"), .expect("const ty should not rely on other generics"),

View file

@ -15,7 +15,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
&mut self, &mut self,
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
) -> QueryResult<'tcx> { ) -> QueryResult<'tcx> {
let tcx = self.tcx(); let tcx = self.interner();
let inherent = goal.predicate.alias.expect_ty(tcx); let inherent = goal.predicate.alias.expect_ty(tcx);
let impl_def_id = tcx.parent(inherent.def_id); let impl_def_id = tcx.parent(inherent.def_id);

View file

@ -54,7 +54,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
&mut self, &mut self,
goal: Goal<'tcx, NormalizesTo<'tcx>>, goal: Goal<'tcx, NormalizesTo<'tcx>>,
) -> QueryResult<'tcx> { ) -> QueryResult<'tcx> {
match goal.predicate.alias.kind(self.tcx()) { match goal.predicate.alias.kind(self.interner()) {
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => { ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
let candidates = self.assemble_and_evaluate_candidates(goal); let candidates = self.assemble_and_evaluate_candidates(goal);
self.merge_candidates(candidates) self.merge_candidates(candidates)
@ -107,7 +107,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
) -> Result<Candidate<'tcx>, NoSolution> { ) -> Result<Candidate<'tcx>, NoSolution> {
if let Some(projection_pred) = assumption.as_projection_clause() { if let Some(projection_pred) = assumption.as_projection_clause() {
if projection_pred.projection_def_id() == goal.predicate.def_id() { if projection_pred.projection_def_id() == goal.predicate.def_id() {
let tcx = ecx.tcx(); let tcx = ecx.interner();
ecx.probe_trait_candidate(source).enter(|ecx| { ecx.probe_trait_candidate(source).enter(|ecx| {
let assumption_projection_pred = let assumption_projection_pred =
ecx.instantiate_binder_with_infer(projection_pred); ecx.instantiate_binder_with_infer(projection_pred);
@ -142,7 +142,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
goal: Goal<'tcx, NormalizesTo<'tcx>>, goal: Goal<'tcx, NormalizesTo<'tcx>>,
impl_def_id: DefId, impl_def_id: DefId,
) -> Result<Candidate<'tcx>, NoSolution> { ) -> Result<Candidate<'tcx>, NoSolution> {
let tcx = ecx.tcx(); let tcx = ecx.interner();
let goal_trait_ref = goal.predicate.alias.trait_ref(tcx); let goal_trait_ref = goal.predicate.alias.trait_ref(tcx);
let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap(); let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
@ -290,8 +290,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>, goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution> { ) -> Result<Candidate<'tcx>, NoSolution> {
ecx.tcx().dcx().span_delayed_bug( ecx.interner().dcx().span_delayed_bug(
ecx.tcx().def_span(goal.predicate.def_id()), ecx.interner().def_span(goal.predicate.def_id()),
"associated types not allowed on auto traits", "associated types not allowed on auto traits",
); );
Err(NoSolution) Err(NoSolution)
@ -337,7 +337,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
goal: Goal<'tcx, Self>, goal: Goal<'tcx, Self>,
goal_kind: ty::ClosureKind, goal_kind: ty::ClosureKind,
) -> Result<Candidate<'tcx>, NoSolution> { ) -> Result<Candidate<'tcx>, NoSolution> {
let tcx = ecx.tcx(); let tcx = ecx.interner();
let tupled_inputs_and_output = let tupled_inputs_and_output =
match structural_traits::extract_tupled_inputs_and_output_from_callable( match structural_traits::extract_tupled_inputs_and_output_from_callable(
tcx, tcx,
@ -380,7 +380,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
goal: Goal<'tcx, Self>, goal: Goal<'tcx, Self>,
goal_kind: ty::ClosureKind, goal_kind: ty::ClosureKind,
) -> Result<Candidate<'tcx>, NoSolution> { ) -> Result<Candidate<'tcx>, NoSolution> {
let tcx = ecx.tcx(); let tcx = ecx.interner();
let env_region = match goal_kind { let env_region = match goal_kind {
ty::ClosureKind::Fn | ty::ClosureKind::FnMut => goal.predicate.alias.args.region_at(2), ty::ClosureKind::Fn | ty::ClosureKind::FnMut => goal.predicate.alias.args.region_at(2),
@ -493,7 +493,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
} }
let upvars_ty = ty::CoroutineClosureSignature::tupled_upvars_by_closure_kind( let upvars_ty = ty::CoroutineClosureSignature::tupled_upvars_by_closure_kind(
ecx.tcx(), ecx.interner(),
goal_kind, goal_kind,
tupled_inputs_ty.expect_ty(), tupled_inputs_ty.expect_ty(),
tupled_upvars_ty.expect_ty(), tupled_upvars_ty.expect_ty(),
@ -518,7 +518,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>, ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>, goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution> { ) -> Result<Candidate<'tcx>, NoSolution> {
let tcx = ecx.tcx(); let tcx = ecx.interner();
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
assert_eq!(metadata_def_id, goal.predicate.def_id()); assert_eq!(metadata_def_id, goal.predicate.def_id());
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
@ -606,7 +606,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
}; };
// Coroutines are not futures unless they come from `async` desugaring // Coroutines are not futures unless they come from `async` desugaring
let tcx = ecx.tcx(); let tcx = ecx.interner();
if !tcx.coroutine_is_async(def_id) { if !tcx.coroutine_is_async(def_id) {
return Err(NoSolution); return Err(NoSolution);
} }
@ -618,7 +618,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
goal, goal,
ty::ProjectionPredicate { ty::ProjectionPredicate {
projection_term: ty::AliasTerm::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), projection_term: ty::AliasTerm::new(
ecx.interner(),
goal.predicate.def_id(),
[self_ty],
),
term, term,
} }
.upcast(tcx), .upcast(tcx),
@ -638,7 +642,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
}; };
// Coroutines are not Iterators unless they come from `gen` desugaring // Coroutines are not Iterators unless they come from `gen` desugaring
let tcx = ecx.tcx(); let tcx = ecx.interner();
if !tcx.coroutine_is_gen(def_id) { if !tcx.coroutine_is_gen(def_id) {
return Err(NoSolution); return Err(NoSolution);
} }
@ -650,7 +654,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc), CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
goal, goal,
ty::ProjectionPredicate { ty::ProjectionPredicate {
projection_term: ty::AliasTerm::new(ecx.tcx(), goal.predicate.def_id(), [self_ty]), projection_term: ty::AliasTerm::new(
ecx.interner(),
goal.predicate.def_id(),
[self_ty],
),
term, term,
} }
.upcast(tcx), .upcast(tcx),
@ -677,7 +685,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
}; };
// Coroutines are not AsyncIterators unless they come from `gen` desugaring // Coroutines are not AsyncIterators unless they come from `gen` desugaring
let tcx = ecx.tcx(); let tcx = ecx.interner();
if !tcx.coroutine_is_async_gen(def_id) { if !tcx.coroutine_is_async_gen(def_id) {
return Err(NoSolution); return Err(NoSolution);
} }
@ -713,7 +721,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
}; };
// `async`-desugared coroutines do not implement the coroutine trait // `async`-desugared coroutines do not implement the coroutine trait
let tcx = ecx.tcx(); let tcx = ecx.interner();
if !tcx.is_general_coroutine(def_id) { if !tcx.is_general_coroutine(def_id) {
return Err(NoSolution); return Err(NoSolution);
} }
@ -735,7 +743,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
goal, goal,
ty::ProjectionPredicate { ty::ProjectionPredicate {
projection_term: ty::AliasTerm::new( projection_term: ty::AliasTerm::new(
ecx.tcx(), ecx.interner(),
goal.predicate.def_id(), goal.predicate.def_id(),
[self_ty, coroutine.resume_ty()], [self_ty, coroutine.resume_ty()],
), ),
@ -784,7 +792,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
| ty::Slice(_) | ty::Slice(_)
| ty::Dynamic(_, _, _) | ty::Dynamic(_, _, _)
| ty::Tuple(_) | ty::Tuple(_)
| ty::Error(_) => self_ty.discriminant_ty(ecx.tcx()), | ty::Error(_) => self_ty.discriminant_ty(ecx.interner()),
// We do not call `Ty::discriminant_ty` on alias, param, or placeholder // We do not call `Ty::discriminant_ty` on alias, param, or placeholder
// types, which return `<self_ty as DiscriminantKind>::Discriminant` // types, which return `<self_ty as DiscriminantKind>::Discriminant`
@ -831,7 +839,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
| ty::Str | ty::Str
| ty::Slice(_) | ty::Slice(_)
| ty::Tuple(_) | ty::Tuple(_)
| ty::Error(_) => self_ty.async_destructor_ty(ecx.tcx(), goal.param_env), | ty::Error(_) => self_ty.async_destructor_ty(ecx.interner(), goal.param_env),
// We do not call `Ty::async_destructor_ty` on alias, param, or placeholder // We do not call `Ty::async_destructor_ty` on alias, param, or placeholder
// types, which return `<self_ty as AsyncDestruct>::AsyncDestructor` // types, which return `<self_ty as AsyncDestruct>::AsyncDestructor`
@ -887,7 +895,8 @@ fn fetch_eligible_assoc_item_def<'tcx>(
trait_assoc_def_id: DefId, trait_assoc_def_id: DefId,
impl_def_id: DefId, impl_def_id: DefId,
) -> Result<Option<LeafDef>, NoSolution> { ) -> Result<Option<LeafDef>, NoSolution> {
let node_item = specialization_graph::assoc_def(ecx.tcx(), impl_def_id, trait_assoc_def_id) let node_item =
specialization_graph::assoc_def(ecx.interner(), impl_def_id, trait_assoc_def_id)
.map_err(|ErrorGuaranteed { .. }| NoSolution)?; .map_err(|ErrorGuaranteed { .. }| NoSolution)?;
let eligible = if node_item.is_final() { let eligible = if node_item.is_final() {

View file

@ -15,7 +15,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
&mut self, &mut self,
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
) -> QueryResult<'tcx> { ) -> QueryResult<'tcx> {
let tcx = self.tcx(); let tcx = self.interner();
let opaque_ty = goal.predicate.alias; let opaque_ty = goal.predicate.alias;
let expected = goal.predicate.term.ty().expect("no such thing as an opaque const"); let expected = goal.predicate.term.ty().expect("no such thing as an opaque const");
@ -31,7 +31,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
return Err(NoSolution); return Err(NoSolution);
} }
// FIXME: This may have issues when the args contain aliases... // FIXME: This may have issues when the args contain aliases...
match self.tcx().uses_unique_placeholders_ignoring_regions(opaque_ty.args) { match self.interner().uses_unique_placeholders_ignoring_regions(opaque_ty.args) {
Err(NotUniqueParam::NotParam(param)) if param.is_non_region_infer() => { Err(NotUniqueParam::NotParam(param)) if param.is_non_region_infer() => {
return self.evaluate_added_goals_and_make_canonical_response( return self.evaluate_added_goals_and_make_canonical_response(
Certainty::AMBIGUOUS, Certainty::AMBIGUOUS,

View file

@ -14,7 +14,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
&mut self, &mut self,
goal: Goal<'tcx, ty::NormalizesTo<'tcx>>, goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
) -> QueryResult<'tcx> { ) -> QueryResult<'tcx> {
let tcx = self.tcx(); let tcx = self.interner();
let weak_ty = goal.predicate.alias; let weak_ty = goal.predicate.alias;
// Check where clauses // Check where clauses

View file

@ -11,7 +11,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
&mut self, &mut self,
goal: Goal<'tcx, ProjectionPredicate<'tcx>>, goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
) -> QueryResult<'tcx> { ) -> QueryResult<'tcx> {
let tcx = self.tcx(); let tcx = self.interner();
let projection_term = goal.predicate.projection_term.to_term(tcx); let projection_term = goal.predicate.projection_term.to_term(tcx);
let goal = goal.with( let goal = goal.with(
tcx, tcx,

View file

@ -3,6 +3,7 @@ use std::mem;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_index::Idx; use rustc_index::Idx;
use rustc_index::IndexVec; use rustc_index::IndexVec;
use rustc_infer::infer::InferCtxt;
use rustc_middle::dep_graph::dep_kinds; use rustc_middle::dep_graph::dep_kinds;
use rustc_middle::traits::solve::CacheData; use rustc_middle::traits::solve::CacheData;
use rustc_middle::traits::solve::EvaluationCache; use rustc_middle::traits::solve::EvaluationCache;
@ -261,10 +262,10 @@ impl<'tcx> SearchGraph<TyCtxt<'tcx>> {
&mut self, &mut self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
input: CanonicalInput<TyCtxt<'tcx>>, input: CanonicalInput<TyCtxt<'tcx>>,
inspect: &mut ProofTreeBuilder<TyCtxt<'tcx>>, inspect: &mut ProofTreeBuilder<InferCtxt<'tcx>>,
mut prove_goal: impl FnMut( mut prove_goal: impl FnMut(
&mut Self, &mut Self,
&mut ProofTreeBuilder<TyCtxt<'tcx>>, &mut ProofTreeBuilder<InferCtxt<'tcx>>,
) -> QueryResult<TyCtxt<'tcx>>, ) -> QueryResult<TyCtxt<'tcx>>,
) -> QueryResult<TyCtxt<'tcx>> { ) -> QueryResult<TyCtxt<'tcx>> {
self.check_invariants(); self.check_invariants();
@ -426,7 +427,7 @@ impl<'tcx> SearchGraph<TyCtxt<'tcx>> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
input: CanonicalInput<TyCtxt<'tcx>>, input: CanonicalInput<TyCtxt<'tcx>>,
available_depth: Limit, available_depth: Limit,
inspect: &mut ProofTreeBuilder<TyCtxt<'tcx>>, inspect: &mut ProofTreeBuilder<InferCtxt<'tcx>>,
) -> Option<QueryResult<TyCtxt<'tcx>>> { ) -> Option<QueryResult<TyCtxt<'tcx>>> {
let CacheData { result, proof_tree, additional_depth, encountered_overflow } = self let CacheData { result, proof_tree, additional_depth, encountered_overflow } = self
.global_cache(tcx) .global_cache(tcx)
@ -473,11 +474,11 @@ impl<'tcx> SearchGraph<TyCtxt<'tcx>> {
&mut self, &mut self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
input: CanonicalInput<TyCtxt<'tcx>>, input: CanonicalInput<TyCtxt<'tcx>>,
inspect: &mut ProofTreeBuilder<TyCtxt<'tcx>>, inspect: &mut ProofTreeBuilder<InferCtxt<'tcx>>,
prove_goal: &mut F, prove_goal: &mut F,
) -> StepResult<TyCtxt<'tcx>> ) -> StepResult<TyCtxt<'tcx>>
where where
F: FnMut(&mut Self, &mut ProofTreeBuilder<TyCtxt<'tcx>>) -> QueryResult<TyCtxt<'tcx>>, F: FnMut(&mut Self, &mut ProofTreeBuilder<InferCtxt<'tcx>>) -> QueryResult<TyCtxt<'tcx>>,
{ {
let result = prove_goal(self, inspect); let result = prove_goal(self, inspect);
let stack_entry = self.pop_stack(); let stack_entry = self.pop_stack();

View file

@ -42,7 +42,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
goal: Goal<'tcx, TraitPredicate<'tcx>>, goal: Goal<'tcx, TraitPredicate<'tcx>>,
impl_def_id: DefId, impl_def_id: DefId,
) -> Result<Candidate<'tcx>, NoSolution> { ) -> Result<Candidate<'tcx>, NoSolution> {
let tcx = ecx.tcx(); let tcx = ecx.interner();
let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap(); let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup }; let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup };
@ -181,7 +181,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
return Err(NoSolution); return Err(NoSolution);
} }
let tcx = ecx.tcx(); let tcx = ecx.interner();
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
let nested_obligations = tcx let nested_obligations = tcx
@ -235,7 +235,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
} }
// The regions of a type don't affect the size of the type // The regions of a type don't affect the size of the type
let tcx = ecx.tcx(); let tcx = ecx.interner();
// We should erase regions from both the param-env and type, since both // We should erase regions from both the param-env and type, since both
// may have infer regions. Specifically, after canonicalizing and instantiating, // may have infer regions. Specifically, after canonicalizing and instantiating,
// early bound regions turn into region vars in both the new and old solver. // early bound regions turn into region vars in both the new and old solver.
@ -296,7 +296,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
return Err(NoSolution); return Err(NoSolution);
} }
let tcx = ecx.tcx(); let tcx = ecx.interner();
let tupled_inputs_and_output = let tupled_inputs_and_output =
match structural_traits::extract_tupled_inputs_and_output_from_callable( match structural_traits::extract_tupled_inputs_and_output_from_callable(
tcx, tcx,
@ -337,7 +337,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
return Err(NoSolution); return Err(NoSolution);
} }
let tcx = ecx.tcx(); let tcx = ecx.interner();
let (tupled_inputs_and_output_and_coroutine, nested_preds) = let (tupled_inputs_and_output_and_coroutine, nested_preds) =
structural_traits::extract_tupled_inputs_and_output_from_async_callable( structural_traits::extract_tupled_inputs_and_output_from_async_callable(
tcx, tcx,
@ -447,7 +447,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
}; };
// Coroutines are not futures unless they come from `async` desugaring // Coroutines are not futures unless they come from `async` desugaring
let tcx = ecx.tcx(); let tcx = ecx.interner();
if !tcx.coroutine_is_async(def_id) { if !tcx.coroutine_is_async(def_id) {
return Err(NoSolution); return Err(NoSolution);
} }
@ -473,7 +473,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
}; };
// Coroutines are not iterators unless they come from `gen` desugaring // Coroutines are not iterators unless they come from `gen` desugaring
let tcx = ecx.tcx(); let tcx = ecx.interner();
if !tcx.coroutine_is_gen(def_id) { if !tcx.coroutine_is_gen(def_id) {
return Err(NoSolution); return Err(NoSolution);
} }
@ -499,7 +499,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
}; };
// Coroutines are not iterators unless they come from `gen` desugaring // Coroutines are not iterators unless they come from `gen` desugaring
let tcx = ecx.tcx(); let tcx = ecx.interner();
if !tcx.coroutine_is_gen(def_id) { if !tcx.coroutine_is_gen(def_id) {
return Err(NoSolution); return Err(NoSolution);
} }
@ -523,7 +523,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
}; };
// Coroutines are not iterators unless they come from `gen` desugaring // Coroutines are not iterators unless they come from `gen` desugaring
let tcx = ecx.tcx(); let tcx = ecx.interner();
if !tcx.coroutine_is_async_gen(def_id) { if !tcx.coroutine_is_async_gen(def_id) {
return Err(NoSolution); return Err(NoSolution);
} }
@ -550,7 +550,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
}; };
// `async`-desugared coroutines do not implement the coroutine trait // `async`-desugared coroutines do not implement the coroutine trait
let tcx = ecx.tcx(); let tcx = ecx.interner();
if !tcx.is_general_coroutine(def_id) { if !tcx.is_general_coroutine(def_id) {
return Err(NoSolution); return Err(NoSolution);
} }
@ -625,10 +625,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
// Erase regions because we compute layouts in `rustc_transmute`, // Erase regions because we compute layouts in `rustc_transmute`,
// which will ICE for region vars. // which will ICE for region vars.
let args = ecx.tcx().erase_regions(goal.predicate.trait_ref.args); let args = ecx.interner().erase_regions(goal.predicate.trait_ref.args);
let Some(assume) = let Some(assume) =
rustc_transmute::Assume::from_const(ecx.tcx(), goal.param_env, args.const_at(2)) rustc_transmute::Assume::from_const(ecx.interner(), goal.param_env, args.const_at(2))
else { else {
return Err(NoSolution); return Err(NoSolution);
}; };
@ -675,7 +675,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
return vec![]; return vec![];
}; };
let goal = goal.with(ecx.tcx(), (a_ty, b_ty)); let goal = goal.with(ecx.interner(), (a_ty, b_ty));
match (a_ty.kind(), b_ty.kind()) { match (a_ty.kind(), b_ty.kind()) {
(ty::Infer(ty::TyVar(..)), ..) => bug!("unexpected infer {a_ty:?} {b_ty:?}"), (ty::Infer(ty::TyVar(..)), ..) => bug!("unexpected infer {a_ty:?} {b_ty:?}"),
@ -741,7 +741,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
b_region: ty::Region<'tcx>, b_region: ty::Region<'tcx>,
) -> Vec<Candidate<'tcx>> { ) -> Vec<Candidate<'tcx>> {
let tcx = self.tcx(); let tcx = self.interner();
let Goal { predicate: (a_ty, _b_ty), .. } = goal; let Goal { predicate: (a_ty, _b_ty), .. } = goal;
let mut responses = vec![]; let mut responses = vec![];
@ -787,7 +787,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, b_data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
b_region: ty::Region<'tcx>, b_region: ty::Region<'tcx>,
) -> Result<Candidate<'tcx>, NoSolution> { ) -> Result<Candidate<'tcx>, NoSolution> {
let tcx = self.tcx(); let tcx = self.interner();
let Goal { predicate: (a_ty, _), .. } = goal; let Goal { predicate: (a_ty, _), .. } = goal;
// Can only unsize to an object-safe trait. // Can only unsize to an object-safe trait.
@ -837,8 +837,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
let a_auto_traits: FxIndexSet<DefId> = a_data let a_auto_traits: FxIndexSet<DefId> = a_data
.auto_traits() .auto_traits()
.chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| { .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
supertrait_def_ids(self.tcx(), principal_def_id) supertrait_def_ids(self.interner(), principal_def_id)
.filter(|def_id| self.tcx().trait_is_auto(*def_id)) .filter(|def_id| self.interner().trait_is_auto(*def_id))
})) }))
.collect(); .collect();
@ -907,7 +907,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
ecx.add_goal( ecx.add_goal(
GoalSource::ImplWhereBound, GoalSource::ImplWhereBound,
Goal::new( Goal::new(
ecx.tcx(), ecx.interner(),
param_env, param_env,
ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region)), ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region)),
), ),
@ -956,7 +956,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
a_args: ty::GenericArgsRef<'tcx>, a_args: ty::GenericArgsRef<'tcx>,
b_args: ty::GenericArgsRef<'tcx>, b_args: ty::GenericArgsRef<'tcx>,
) -> Result<Candidate<'tcx>, NoSolution> { ) -> Result<Candidate<'tcx>, NoSolution> {
let tcx = self.tcx(); let tcx = self.interner();
let Goal { predicate: (_a_ty, b_ty), .. } = goal; let Goal { predicate: (_a_ty, b_ty), .. } = goal;
let unsizing_params = tcx.unsizing_params_for_adt(def.did()); let unsizing_params = tcx.unsizing_params_for_adt(def.did());
@ -1017,7 +1017,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
a_tys: &'tcx ty::List<Ty<'tcx>>, a_tys: &'tcx ty::List<Ty<'tcx>>,
b_tys: &'tcx ty::List<Ty<'tcx>>, b_tys: &'tcx ty::List<Ty<'tcx>>,
) -> Result<Candidate<'tcx>, NoSolution> { ) -> Result<Candidate<'tcx>, NoSolution> {
let tcx = self.tcx(); let tcx = self.interner();
let Goal { predicate: (_a_ty, b_ty), .. } = goal; let Goal { predicate: (_a_ty, b_ty), .. } = goal;
let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap(); let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap();
@ -1077,9 +1077,9 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
// takes precedence over the structural auto trait candidate being // takes precedence over the structural auto trait candidate being
// assembled. // assembled.
ty::Coroutine(def_id, _) ty::Coroutine(def_id, _)
if Some(goal.predicate.def_id()) == self.tcx().lang_items().unpin_trait() => if Some(goal.predicate.def_id()) == self.interner().lang_items().unpin_trait() =>
{ {
match self.tcx().coroutine_movability(def_id) { match self.interner().coroutine_movability(def_id) {
Movability::Static => Some(Err(NoSolution)), Movability::Static => Some(Err(NoSolution)),
Movability::Movable => Some( Movability::Movable => Some(
self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| { self.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
@ -1124,7 +1124,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
| ty::Tuple(_) | ty::Tuple(_)
| ty::Adt(_, _) => { | ty::Adt(_, _) => {
let mut disqualifying_impl = None; let mut disqualifying_impl = None;
self.tcx().for_each_relevant_impl( self.interner().for_each_relevant_impl(
goal.predicate.def_id(), goal.predicate.def_id(),
goal.predicate.self_ty(), goal.predicate.self_ty(),
|impl_def_id| { |impl_def_id| {
@ -1164,7 +1164,10 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
.into_iter() .into_iter()
.map(|ty| { .map(|ty| {
ecx.enter_forall(ty, |ty| { ecx.enter_forall(ty, |ty| {
goal.with(ecx.tcx(), goal.predicate.with_self_ty(ecx.tcx(), ty)) goal.with(
ecx.interner(),
goal.predicate.with_self_ty(ecx.interner(), ty),
)
}) })
}) })
.collect::<Vec<_>>(), .collect::<Vec<_>>(),

View file

@ -132,7 +132,14 @@ pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
} }
pub trait Predicate<I: Interner<Predicate = Self>>: pub trait Predicate<I: Interner<Predicate = Self>>:
Copy + Debug + Hash + Eq + TypeSuperVisitable<I> + TypeSuperFoldable<I> + Flags Copy
+ Debug
+ Hash
+ Eq
+ TypeSuperVisitable<I>
+ TypeSuperFoldable<I>
+ Flags
+ UpcastFrom<I, ty::NormalizesTo<I>>
{ {
fn is_coinductive(self, interner: I) -> bool; fn is_coinductive(self, interner: I) -> bool;
} }

View file

@ -3,6 +3,7 @@ use std::fmt::Debug;
use std::hash::Hash; use std::hash::Hash;
use std::ops::Deref; use std::ops::Deref;
use crate::fold::TypeFoldable;
use crate::inherent::*; use crate::inherent::*;
use crate::ir_print::IrPrint; use crate::ir_print::IrPrint;
use crate::solve::inspect::CanonicalGoalEvaluationStep; use crate::solve::inspect::CanonicalGoalEvaluationStep;
@ -90,7 +91,7 @@ pub trait Interner:
type PlaceholderRegion: PlaceholderLike; type PlaceholderRegion: PlaceholderLike;
// Predicates // Predicates
type ParamEnv: Copy + Debug + Hash + Eq; type ParamEnv: Copy + Debug + Hash + Eq + TypeFoldable<Self>;
type Predicate: Predicate<Self>; type Predicate: Predicate<Self>;
type Clause: Clause<Self>; type Clause: Clause<Self>;
type Clauses: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags; type Clauses: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
@ -114,15 +115,18 @@ pub trait Interner:
) -> (ty::TraitRef<Self>, Self::OwnItemArgs); ) -> (ty::TraitRef<Self>, Self::OwnItemArgs);
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs; fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
fn mk_args_from_iter(self, args: impl Iterator<Item = Self::GenericArg>) -> Self::GenericArgs; fn mk_args_from_iter(self, args: impl Iterator<Item = Self::GenericArg>) -> Self::GenericArgs;
fn check_and_mk_args( fn check_and_mk_args(
self, self,
def_id: Self::DefId, def_id: Self::DefId,
args: impl IntoIterator<Item: Into<Self::GenericArg>>, args: impl IntoIterator<Item: Into<Self::GenericArg>>,
) -> Self::GenericArgs; ) -> Self::GenericArgs;
fn intern_canonical_goal_evaluation_step(
self,
step: CanonicalGoalEvaluationStep<Self>,
) -> Self::CanonicalGoalEvaluationStepRef;
fn parent(self, def_id: Self::DefId) -> Self::DefId; fn parent(self, def_id: Self::DefId) -> Self::DefId;
fn recursion_limit(self) -> usize; fn recursion_limit(self) -> usize;