Reverse parameter to placeholder substitution in chalk results

This commit is contained in:
Matthew Jasper 2022-02-09 10:03:47 +00:00
parent d4fa173ed3
commit 1e6d38230f
2 changed files with 40 additions and 10 deletions

View file

@ -1034,10 +1034,6 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
match *t.kind() {
// FIXME(chalk): currently we convert params to placeholders starting at
// index `0`. To support placeholders, we'll actually need to do a
// first pass to collect placeholders. Then we can insert params after.
ty::Placeholder(_) => unimplemented!(),
ty::Param(param) => match self.list.iter().position(|r| r == &param) {
Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: ty::UniverseIndex::from_usize(0),
@ -1053,15 +1049,15 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
}))
}
},
_ => t.super_fold_with(self),
}
}
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
match r {
// FIXME(chalk) - jackh726 - this currently isn't hit in any tests.
// This covers any region variables in a goal, right?
// FIXME(chalk) - jackh726 - this currently isn't hit in any tests,
// since canonicalization will already change these to canonical
// variables (ty::ReLateBound).
ty::ReEarlyBound(_re) => match self.named_regions.get(&_re.def_id) {
Some(idx) => {
let br = ty::BoundRegion {
@ -1084,6 +1080,39 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
}
}
crate struct ReverseParamsSubstitutor<'tcx> {
tcx: TyCtxt<'tcx>,
params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>,
}
impl<'tcx> ReverseParamsSubstitutor<'tcx> {
crate fn new(
tcx: TyCtxt<'tcx>,
params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>,
) -> Self {
Self { tcx, params }
}
}
impl<'tcx> TypeFolder<'tcx> for ReverseParamsSubstitutor<'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.tcx
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
match *t.kind() {
ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::ROOT, name }) => {
match self.params.get(&name.as_usize()) {
Some(param) => self.tcx.mk_ty(ty::Param(*param)),
None => t,
}
}
_ => t.super_fold_with(self),
}
}
}
/// Used to collect `Placeholder`s.
crate struct PlaceholdersCollector {
universe_index: ty::UniverseIndex,

View file

@ -23,7 +23,7 @@ use rustc_infer::traits::{self, CanonicalChalkEnvironmentAndGoal};
use crate::chalk::db::RustIrDatabase as ChalkRustIrDatabase;
use crate::chalk::lowering::LowerInto;
use crate::chalk::lowering::{ParamsSubstitutor, PlaceholdersCollector};
use crate::chalk::lowering::{ParamsSubstitutor, PlaceholdersCollector, ReverseParamsSubstitutor};
use chalk_solve::Solution;
@ -44,7 +44,7 @@ crate fn evaluate_goal<'tcx>(
let mut params_substitutor =
ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder);
let obligation = obligation.fold_with(&mut params_substitutor);
let _params: FxHashMap<usize, ParamTy> = params_substitutor.params;
let params: FxHashMap<usize, ParamTy> = params_substitutor.params;
let max_universe = obligation.max_universe.index();
@ -101,8 +101,9 @@ crate fn evaluate_goal<'tcx>(
use rustc_middle::infer::canonical::CanonicalVarInfo;
let mut var_values: IndexVec<BoundVar, GenericArg<'tcx>> = IndexVec::new();
let mut reverse_param_substitutor = ReverseParamsSubstitutor::new(tcx, params);
subst.as_slice(interner).iter().for_each(|p| {
var_values.push(p.lower_into(interner));
var_values.push(p.lower_into(interner).fold_with(&mut reverse_param_substitutor));
});
let variables: Vec<_> = binders
.iter(interner)