Reduce boilerplate around infallible folders

This commit is contained in:
Alan Egerton 2021-12-01 00:55:57 +00:00
parent db7295fa96
commit bfc434b6d0
No known key found for this signature in database
GPG key ID: 07CAC3CCA7E0643F
41 changed files with 898 additions and 727 deletions

View file

@ -45,7 +45,7 @@ impl<'tcx> RustIrDatabase<'tcx> {
predicates
.iter()
.map(|(wc, _)| wc.subst(self.interner.tcx, bound_vars))
.map(|wc| wc.fold_with(&mut regions_substitutor).into_ok())
.map(|wc| wc.fold_with(&mut regions_substitutor))
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect()
}
@ -287,7 +287,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars);
let mut regions_substitutor =
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
let trait_ref = trait_ref.fold_with(&mut regions_substitutor).into_ok();
let trait_ref = trait_ref.fold_with(&mut regions_substitutor);
let where_clauses = self.where_clauses_for(def_id, bound_vars);
@ -335,7 +335,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
let self_ty = self_ty.subst(self.interner.tcx, bound_vars);
let mut regions_substitutor =
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
let self_ty = self_ty.fold_with(&mut regions_substitutor).into_ok();
let self_ty = self_ty.fold_with(&mut regions_substitutor);
let lowered_ty = self_ty.lower_into(&self.interner);
parameters[0].assert_ty_ref(&self.interner).could_match(
@ -501,24 +501,22 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
.iter()
.map(|(bound, _)| bound.subst(self.interner.tcx, &bound_vars))
.map(|bound| {
bound
.fold_with(&mut ty::fold::BottomUpFolder {
tcx: self.interner.tcx,
ty_op: |ty| {
if let ty::Opaque(def_id, substs) = *ty.kind() {
if def_id == opaque_ty_id.0 && substs == identity_substs {
return self.interner.tcx.mk_ty(ty::Bound(
ty::INNERMOST,
ty::BoundTy::from(ty::BoundVar::from_u32(0)),
));
}
bound.fold_with(&mut ty::fold::BottomUpFolder {
tcx: self.interner.tcx,
ty_op: |ty| {
if let ty::Opaque(def_id, substs) = *ty.kind() {
if def_id == opaque_ty_id.0 && substs == identity_substs {
return self.interner.tcx.mk_ty(ty::Bound(
ty::INNERMOST,
ty::BoundTy::from(ty::BoundVar::from_u32(0)),
));
}
ty
},
lt_op: |lt| lt,
ct_op: |ct| ct,
})
.into_ok()
}
ty
},
lt_op: |lt| lt,
ct_op: |ct| ct,
})
})
.filter_map(|bound| {
LowerInto::<

View file

@ -817,7 +817,7 @@ crate fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>(
.collect();
let mut bound_var_substitutor = NamedBoundVarSubstitutor::new(tcx, &named_parameters);
let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor).into_ok();
let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor);
for var in named_parameters.values() {
parameters.insert(*var, chalk_ir::VariableKind::Lifetime);
@ -943,23 +943,20 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> {
self.tcx
}
fn fold_binder<T: TypeFoldable<'tcx>>(
&mut self,
t: Binder<'tcx, T>,
) -> Result<Binder<'tcx, T>, Self::Error> {
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> {
self.binder_index.shift_in(1);
let result = t.super_fold_with(self);
self.binder_index.shift_out(1);
result
}
fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> {
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
match r {
ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind {
ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) {
Some(idx) => {
let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(*idx) };
return Ok(self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br)));
return self.tcx.mk_region(RegionKind::ReLateBound(*index, new_br));
}
None => panic!("Missing `BrNamed`."),
},
@ -1002,35 +999,32 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
self.tcx
}
fn fold_binder<T: TypeFoldable<'tcx>>(
&mut self,
t: Binder<'tcx, T>,
) -> Result<Binder<'tcx, T>, Self::Error> {
fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> {
self.binder_index.shift_in(1);
let result = t.super_fold_with(self);
self.binder_index.shift_out(1);
result
}
fn fold_ty(&mut self, t: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
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) => Ok(self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: ty::UniverseIndex::from_usize(0),
name: ty::BoundVar::from_usize(idx),
}))),
})),
None => {
self.list.push(param);
let idx = self.list.len() - 1 + self.next_ty_placeholder;
self.params.insert(idx, param);
Ok(self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: ty::UniverseIndex::from_usize(0),
name: ty::BoundVar::from_usize(idx),
})))
}))
}
},
@ -1038,7 +1032,7 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
}
}
fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> {
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?
@ -1048,14 +1042,14 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> {
var: ty::BoundVar::from_u32(*idx),
kind: ty::BrAnon(*idx),
};
Ok(self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)))
self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br))
}
None => {
let idx = self.named_regions.len() as u32;
let br =
ty::BoundRegion { var: ty::BoundVar::from_u32(idx), kind: ty::BrAnon(idx) };
self.named_regions.insert(_re.def_id, idx);
Ok(self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br)))
self.tcx.mk_region(RegionKind::ReLateBound(self.binder_index, br))
}
},
@ -1131,11 +1125,11 @@ impl<'tcx> TypeFolder<'tcx> for RegionsSubstitutor<'tcx> {
self.tcx
}
fn fold_region(&mut self, r: Region<'tcx>) -> Result<Region<'tcx>, Self::Error> {
fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> {
match r {
ty::ReEmpty(ui) => {
assert_eq!(ui.as_usize(), 0);
Ok(self.reempty_placeholder)
self.reempty_placeholder
}
_ => r.super_fold_with(self),

View file

@ -49,12 +49,12 @@ 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).into_ok();
let obligation = obligation.fold_with(&mut params_substitutor);
// FIXME(chalk): we really should be substituting these back in the solution
let _params: FxHashMap<usize, ParamTy> = params_substitutor.params;
let mut regions_substitutor = RegionsSubstitutor::new(tcx, reempty_placeholder);
let obligation = obligation.fold_with(&mut regions_substitutor).into_ok();
let obligation = obligation.fold_with(&mut regions_substitutor);
let max_universe = obligation.max_universe.index();

View file

@ -4,7 +4,6 @@
#![feature(crate_visibility_modifier)]
#![feature(in_band_lifetimes)]
#![feature(nll)]
#![feature(unwrap_infallible)]
#![recursion_limit = "256"]
#[macro_use]