Add support for inherent projections

This commit is contained in:
Michael Goulet 2023-07-04 18:28:10 +00:00
parent c4083faade
commit 085ae9e8b4
6 changed files with 48 additions and 3 deletions

View File

@ -1313,7 +1313,7 @@ impl<'tcx> AliasTy<'tcx> {
/// I_i impl subst /// I_i impl subst
/// P_j GAT subst /// P_j GAT subst
/// ``` /// ```
pub fn rebase_args_onto_impl( pub fn rebase_inherent_args_onto_impl(
self, self,
impl_args: ty::GenericArgsRef<'tcx>, impl_args: ty::GenericArgsRef<'tcx>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,

View File

@ -0,0 +1,42 @@
use rustc_middle::traits::solve::{Certainty, Goal, QueryResult};
use rustc_middle::ty;
use super::EvalCtxt;
impl<'tcx> EvalCtxt<'_, 'tcx> {
pub(super) fn normalize_inherent_associated_type(
&mut self,
goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>,
) -> QueryResult<'tcx> {
let tcx = self.tcx();
let inherent = goal.predicate.projection_ty;
let expected = goal.predicate.term.ty().expect("inherent consts are treated separately");
let impl_def_id = tcx.parent(inherent.def_id);
let impl_substs = self.fresh_args_for_item(impl_def_id);
// Equate impl header and add impl where clauses
self.eq(
goal.param_env,
inherent.self_ty(),
tcx.type_of(impl_def_id).instantiate(tcx, impl_substs),
)?;
self.add_goals(
tcx.predicates_of(impl_def_id)
.instantiate(tcx, impl_substs)
.into_iter()
.map(|(pred, _)| goal.with(tcx, pred)),
);
// Equate IAT with the RHS of the project goal
let inherent_substs = inherent.rebase_inherent_args_onto_impl(impl_substs, tcx);
self.eq(
goal.param_env,
expected,
tcx.type_of(inherent.def_id).instantiate(tcx, inherent_substs),
)
.expect("expected goal term to be fully unconstrained");
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
}

View File

@ -25,6 +25,7 @@
mod canonicalize; mod canonicalize;
mod eval_ctxt; mod eval_ctxt;
mod fulfill; mod fulfill;
mod inherent_projection;
pub mod inspect; pub mod inspect;
mod normalize; mod normalize;
mod opaques; mod opaques;

View File

@ -48,7 +48,7 @@ pub(super) fn compute_projection_goal(
self.merge_candidates(candidates) self.merge_candidates(candidates)
} }
ty::AssocItemContainer::ImplContainer => { ty::AssocItemContainer::ImplContainer => {
bug!("IATs not supported here yet") self.normalize_inherent_associated_type(goal)
} }
} }
} else { } else {

View File

@ -1421,7 +1421,7 @@ pub fn compute_inherent_assoc_ty_args<'a, 'b, 'tcx>(
} }
} }
alias_ty.rebase_args_onto_impl(impl_args, tcx) alias_ty.rebase_inherent_args_onto_impl(impl_args, tcx)
} }
enum Projected<'tcx> { enum Projected<'tcx> {

View File

@ -1,5 +1,7 @@
// Testing inference capabilities. // Testing inference capabilities.
// check-pass // check-pass
// revisions: current next
//[next] compile-flags: -Ztrait-solver=next
#![feature(inherent_associated_types)] #![feature(inherent_associated_types)]
#![allow(incomplete_features)] #![allow(incomplete_features)]