Separate bounds and predicates for associated/opaque types
This commit is contained in:
parent
d297147e62
commit
f958e6c246
107 changed files with 923 additions and 1117 deletions
|
@ -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),
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue