1
Fork 0

Separate bounds and predicates for associated/opaque types

This commit is contained in:
Matthew Jasper 2020-06-27 21:36:35 +01:00
parent d297147e62
commit f958e6c246
107 changed files with 923 additions and 1117 deletions

View file

@ -73,18 +73,28 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
}
let bound_vars = bound_vars_for_item(self.interner.tcx, def_id);
let binders = binders_for(&self.interner, bound_vars);
// FIXME(chalk): this really isn't right I don't think. The functions
// for GATs are a bit hard to figure out. Are these supposed to be where
// clauses or bounds?
let where_clauses = self.where_clauses_for(def_id, bound_vars);
let bounds = self
.tcx
.explicit_item_bounds(def_id)
.iter()
.map(|(bound, _)| bound.subst(self.tcx, &bound_vars))
.filter_map(|bound| {
LowerInto::<
Option<chalk_solve::rust_ir::QuantifiedInlineBound<RustInterner<'tcx>>>,
>::lower_into(bound, &self.interner)
})
.collect();
Arc::new(chalk_solve::rust_ir::AssociatedTyDatum {
trait_id: chalk_ir::TraitId(trait_def_id),
id: assoc_type_id,
name: (),
binders: chalk_ir::Binders::new(
binders,
chalk_solve::rust_ir::AssociatedTyDatumBound { bounds: vec![], where_clauses },
chalk_solve::rust_ir::AssociatedTyDatumBound { bounds, where_clauses },
),
})
}
@ -443,10 +453,17 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
let binders = binders_for(&self.interner, bound_vars);
let where_clauses = self.where_clauses_for(opaque_ty_id.0, bound_vars);
let bounds: Vec<_> = predicates
.iter()
.map(|(bound, _)| bound.subst(self.tcx, &bound_vars))
.filter_map(|bound| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(bound, &self.interner))
.collect();
let value = chalk_solve::rust_ir::OpaqueTyDatumBound {
bounds: chalk_ir::Binders::new(binders.clone(), vec![]),
bounds: chalk_ir::Binders::new(binders, bounds),
where_clauses: chalk_ir::Binders::new(binders, where_clauses),
};
Arc::new(chalk_solve::rust_ir::OpaqueTyDatum {
opaque_ty_id,
bound: chalk_ir::Binders::empty(&self.interner, value),

View file

@ -728,6 +728,84 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::FnSig<RustInterner<'tcx>>> for ty::Binder<t
}
}
// We lower into an Option here since there are some predicates which Chalk
// doesn't have a representation for yet (as an `InlineBound`). The `Option` will
// eventually be removed.
impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<RustInterner<'tcx>>>>
for ty::Predicate<'tcx>
{
fn lower_into(
self,
interner: &RustInterner<'tcx>,
) -> Option<chalk_solve::rust_ir::QuantifiedInlineBound<RustInterner<'tcx>>> {
match &self.kind() {
ty::PredicateKind::Trait(predicate, _) => {
let (predicate, binders, _named_regions) =
collect_bound_vars(interner, interner.tcx, predicate);
Some(chalk_ir::Binders::new(
binders,
chalk_solve::rust_ir::InlineBound::TraitBound(
predicate.trait_ref.lower_into(interner),
),
))
}
ty::PredicateKind::Projection(predicate) => {
let (predicate, binders, _named_regions) =
collect_bound_vars(interner, interner.tcx, predicate);
Some(chalk_ir::Binders::new(
binders,
chalk_solve::rust_ir::InlineBound::AliasEqBound(predicate.lower_into(interner)),
))
}
ty::PredicateKind::TypeOutlives(_predicate) => None,
ty::PredicateKind::WellFormed(_ty) => None,
ty::PredicateKind::RegionOutlives(..)
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", &self),
}
}
}
impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::TraitBound<RustInterner<'tcx>>>
for ty::TraitRef<'tcx>
{
fn lower_into(
self,
interner: &RustInterner<'tcx>,
) -> chalk_solve::rust_ir::TraitBound<RustInterner<'tcx>> {
chalk_solve::rust_ir::TraitBound {
trait_id: chalk_ir::TraitId(self.def_id),
args_no_self: self.substs[1..].iter().map(|arg| arg.lower_into(interner)).collect(),
}
}
}
impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>>>
for ty::ProjectionPredicate<'tcx>
{
fn lower_into(
self,
interner: &RustInterner<'tcx>,
) -> chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>> {
let trait_ref = self.projection_ty.trait_ref(interner.tcx);
chalk_solve::rust_ir::AliasEqBound {
trait_bound: trait_ref.lower_into(interner),
associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.item_def_id),
parameters: self.projection_ty.substs[trait_ref.substs.len()..]
.iter()
.map(|arg| arg.lower_into(interner))
.collect(),
value: self.ty.lower_into(interner),
}
}
}
/// To collect bound vars, we have to do two passes. In the first pass, we
/// collect all `BoundRegion`s and `ty::Bound`s. In the second pass, we then
/// replace `BrNamed` into `BrAnon`. The two separate passes are important,