From 085ae9e8b4f903073c1600061934d9e697e3a65e Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 4 Jul 2023 18:28:10 +0000 Subject: [PATCH] Add support for inherent projections --- compiler/rustc_middle/src/ty/sty.rs | 2 +- .../src/solve/inherent_projection.rs | 42 +++++++++++++++++++ .../rustc_trait_selection/src/solve/mod.rs | 1 + .../src/solve/project_goals.rs | 2 +- .../src/traits/project.rs | 2 +- .../ui/associated-inherent-types/inference.rs | 2 + 6 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 compiler/rustc_trait_selection/src/solve/inherent_projection.rs diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 66d8a79de42..cdb0b2240a4 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1313,7 +1313,7 @@ impl<'tcx> AliasTy<'tcx> { /// I_i impl subst /// P_j GAT subst /// ``` - pub fn rebase_args_onto_impl( + pub fn rebase_inherent_args_onto_impl( self, impl_args: ty::GenericArgsRef<'tcx>, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_trait_selection/src/solve/inherent_projection.rs b/compiler/rustc_trait_selection/src/solve/inherent_projection.rs new file mode 100644 index 00000000000..23f38466de1 --- /dev/null +++ b/compiler/rustc_trait_selection/src/solve/inherent_projection.rs @@ -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) + } +} diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 1d9c975a97a..7c15c3c0e8b 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -25,6 +25,7 @@ mod canonicalize; mod eval_ctxt; mod fulfill; +mod inherent_projection; pub mod inspect; mod normalize; mod opaques; diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 564451a31ed..8708b000961 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -48,7 +48,7 @@ pub(super) fn compute_projection_goal( self.merge_candidates(candidates) } ty::AssocItemContainer::ImplContainer => { - bug!("IATs not supported here yet") + self.normalize_inherent_associated_type(goal) } } } else { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index e137ed9cda8..783f3569feb 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -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> { diff --git a/tests/ui/associated-inherent-types/inference.rs b/tests/ui/associated-inherent-types/inference.rs index ebd8e1d5594..66f879c5a71 100644 --- a/tests/ui/associated-inherent-types/inference.rs +++ b/tests/ui/associated-inherent-types/inference.rs @@ -1,5 +1,7 @@ // Testing inference capabilities. // check-pass +// revisions: current next +//[next] compile-flags: -Ztrait-solver=next #![feature(inherent_associated_types)] #![allow(incomplete_features)]