Skip to content

Commit 1e6d382

Browse files
committed
Reverse parameter to placeholder substitution in chalk results
1 parent d4fa173 commit 1e6d382

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

compiler/rustc_traits/src/chalk/lowering.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,10 +1034,6 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
10341034

10351035
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
10361036
match *t.kind() {
1037-
// FIXME(chalk): currently we convert params to placeholders starting at
1038-
// index `0`. To support placeholders, we'll actually need to do a
1039-
// first pass to collect placeholders. Then we can insert params after.
1040-
ty::Placeholder(_) => unimplemented!(),
10411037
ty::Param(param) => match self.list.iter().position(|r| r == &param) {
10421038
Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
10431039
universe: ty::UniverseIndex::from_usize(0),
@@ -1053,15 +1049,15 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
10531049
}))
10541050
}
10551051
},
1056-
10571052
_ => t.super_fold_with(self),
10581053
}
10591054
}
10601055

10611056
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
10621057
match r {
1063-
// FIXME(chalk) - jackh726 - this currently isn't hit in any tests.
1064-
// This covers any region variables in a goal, right?
1058+
// FIXME(chalk) - jackh726 - this currently isn't hit in any tests,
1059+
// since canonicalization will already change these to canonical
1060+
// variables (ty::ReLateBound).
10651061
ty::ReEarlyBound(_re) => match self.named_regions.get(&_re.def_id) {
10661062
Some(idx) => {
10671063
let br = ty::BoundRegion {
@@ -1084,6 +1080,39 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
10841080
}
10851081
}
10861082

1083+
crate struct ReverseParamsSubstitutor<'tcx> {
1084+
tcx: TyCtxt<'tcx>,
1085+
params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>,
1086+
}
1087+
1088+
impl<'tcx> ReverseParamsSubstitutor<'tcx> {
1089+
crate fn new(
1090+
tcx: TyCtxt<'tcx>,
1091+
params: rustc_data_structures::fx::FxHashMap<usize, rustc_middle::ty::ParamTy>,
1092+
) -> Self {
1093+
Self { tcx, params }
1094+
}
1095+
}
1096+
1097+
impl<'tcx> TypeFolder<'tcx> for ReverseParamsSubstitutor<'tcx> {
1098+
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
1099+
self.tcx
1100+
}
1101+
1102+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
1103+
match *t.kind() {
1104+
ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::ROOT, name }) => {
1105+
match self.params.get(&name.as_usize()) {
1106+
Some(param) => self.tcx.mk_ty(ty::Param(*param)),
1107+
None => t,
1108+
}
1109+
}
1110+
1111+
_ => t.super_fold_with(self),
1112+
}
1113+
}
1114+
}
1115+
10871116
/// Used to collect `Placeholder`s.
10881117
crate struct PlaceholdersCollector {
10891118
universe_index: ty::UniverseIndex,

compiler/rustc_traits/src/chalk/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_infer::traits::{self, CanonicalChalkEnvironmentAndGoal};
2323

2424
use crate::chalk::db::RustIrDatabase as ChalkRustIrDatabase;
2525
use crate::chalk::lowering::LowerInto;
26-
use crate::chalk::lowering::{ParamsSubstitutor, PlaceholdersCollector};
26+
use crate::chalk::lowering::{ParamsSubstitutor, PlaceholdersCollector, ReverseParamsSubstitutor};
2727

2828
use chalk_solve::Solution;
2929

@@ -44,7 +44,7 @@ crate fn evaluate_goal<'tcx>(
4444
let mut params_substitutor =
4545
ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder);
4646
let obligation = obligation.fold_with(&mut params_substitutor);
47-
let _params: FxHashMap<usize, ParamTy> = params_substitutor.params;
47+
let params: FxHashMap<usize, ParamTy> = params_substitutor.params;
4848

4949
let max_universe = obligation.max_universe.index();
5050

@@ -101,8 +101,9 @@ crate fn evaluate_goal<'tcx>(
101101
use rustc_middle::infer::canonical::CanonicalVarInfo;
102102

103103
let mut var_values: IndexVec<BoundVar, GenericArg<'tcx>> = IndexVec::new();
104+
let mut reverse_param_substitutor = ReverseParamsSubstitutor::new(tcx, params);
104105
subst.as_slice(interner).iter().for_each(|p| {
105-
var_values.push(p.lower_into(interner));
106+
var_values.push(p.lower_into(interner).fold_with(&mut reverse_param_substitutor));
106107
});
107108
let variables: Vec<_> = binders
108109
.iter(interner)

0 commit comments

Comments
 (0)