//! variables from the current `Binder`.
use rustc_middle::traits::{
- ChalkEnvironmentAndGoal, ChalkEnvironmentClause, ChalkRustDefId as RustDefId,
- ChalkRustInterner as RustInterner,
+ ChalkEnvironmentAndGoal, ChalkEnvironmentClause, ChalkRustInterner as RustInterner,
};
use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
impl<'tcx> LowerInto<'tcx, chalk_ir::AliasTy<RustInterner<'tcx>>> for ty::ProjectionTy<'tcx> {
fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::AliasTy<RustInterner<'tcx>> {
chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
- associated_ty_id: chalk_ir::AssocTypeId(RustDefId::AssocTy(self.item_def_id)),
+ associated_ty_id: chalk_ir::AssocTypeId(self.item_def_id),
substitution: self.substs.lower_into(interner),
})
}
.intern(interner),
)
}
- // FIXME(chalk): need to add RegionOutlives/TypeOutlives
- ty::PredicateKind::RegionOutlives(_) => None,
+ ty::PredicateKind::RegionOutlives(predicate) => {
+ let (predicate, binders, _named_regions) =
+ collect_bound_vars(interner, interner.tcx, predicate);
+
+ Some(
+ chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
+ binders,
+ chalk_ir::ProgramClauseImplication {
+ consequence: chalk_ir::DomainGoal::Holds(
+ chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives {
+ a: predicate.0.lower_into(interner),
+ b: predicate.1.lower_into(interner),
+ })
+ ),
+ conditions: chalk_ir::Goals::new(interner),
+ priority: chalk_ir::ClausePriority::High,
+ },
+ ))
+ .intern(interner),
+ )
+ },
+ // FIXME(chalk): need to add TypeOutlives
ty::PredicateKind::TypeOutlives(_) => None,
ty::PredicateKind::Projection(predicate) => {
let (predicate, binders, _named_regions) =
fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GoalData<RustInterner<'tcx>> {
match self.kind() {
ty::PredicateKind::Trait(predicate, _) => predicate.lower_into(interner),
- // FIXME(chalk): we need to register constraints.
- ty::PredicateKind::RegionOutlives(_predicate) => {
- chalk_ir::GoalData::All(chalk_ir::Goals::new(interner))
+ ty::PredicateKind::RegionOutlives(predicate) => {
+ let (predicate, binders, _named_regions) =
+ collect_bound_vars(interner, interner.tcx, predicate);
+
+ chalk_ir::GoalData::Quantified(
+ chalk_ir::QuantifierKind::ForAll,
+ chalk_ir::Binders::new(
+ binders,
+ chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds(
+ chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives {
+ a: predicate.0.lower_into(interner),
+ b: predicate.1.lower_into(interner),
+ })
+ )).intern(interner)
+ )
+ )
}
+ // FIXME(chalk): TypeOutlives
ty::PredicateKind::TypeOutlives(_predicate) => {
chalk_ir::GoalData::All(chalk_ir::Goals::new(interner))
}
ty::PredicateKind::Projection(predicate) => predicate.lower_into(interner),
ty::PredicateKind::WellFormed(arg) => match arg.unpack() {
GenericArgKind::Type(ty) => match ty.kind {
- // These types are always WF.
- ty::Str | ty::Placeholder(..) | ty::Error(_) | ty::Never => {
- chalk_ir::GoalData::All(chalk_ir::Goals::new(interner))
- }
+ // FIXME(chalk): In Chalk, a placeholder is WellFormed if it
+ // `FromEnv`. However, when we "lower" Params, we don't update
+ // the environment.
+ ty::Placeholder(..) => chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)),
- // FIXME(chalk): Well-formed only if ref lifetime outlives type
- ty::Ref(..) => chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)),
-
- ty::Param(..) => panic!("No Params expected."),
-
- // FIXME(chalk) -- ultimately I think this is what we
- // want to do, and we just have rules for how to prove
- // `WellFormed` for everything above, instead of
- // inlining a bit the rules of the proof here.
_ => chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::WellFormed(
chalk_ir::WellFormed::Ty(ty.lower_into(interner)),
)),
GenericArgKind::Lifetime(lt) => bug!("unexpect well formed predicate: {:?}", lt),
},
+ ty::PredicateKind::ObjectSafe(t) => {
+ chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::ObjectSafe(chalk_ir::TraitId(*t)))
+ }
+
// FIXME(chalk): other predicates
//
// We can defer this, but ultimately we'll want to express
// some of these in terms of chalk operations.
- ty::PredicateKind::ObjectSafe(..)
- | ty::PredicateKind::ClosureKind(..)
+ ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..) => {
{
fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::TraitRef<RustInterner<'tcx>> {
chalk_ir::TraitRef {
- trait_id: chalk_ir::TraitId(RustDefId::Trait(self.def_id)),
+ trait_id: chalk_ir::TraitId(self.def_id),
substitution: self.substs.lower_into(interner),
}
}
use TyKind::*;
let empty = || chalk_ir::Substitution::empty(interner);
- let struct_ty = |def_id| chalk_ir::TypeName::Struct(chalk_ir::StructId(def_id));
+ let struct_ty = |def_id| chalk_ir::TypeName::Adt(chalk_ir::AdtId(def_id));
let apply = |name, substitution| {
TyData::Apply(chalk_ir::ApplicationTy { name, substitution }).intern(interner)
};
ast::FloatTy::F32 => float(chalk_ir::FloatTy::F32),
ast::FloatTy::F64 => float(chalk_ir::FloatTy::F64),
},
- Adt(def, substs) => {
- apply(struct_ty(RustDefId::Adt(def.did)), substs.lower_into(interner))
- }
+ Adt(def, substs) => apply(struct_ty(def.did), substs.lower_into(interner)),
Foreign(_def_id) => unimplemented!(),
- Str => apply(struct_ty(RustDefId::Str), empty()),
+ Str => apply(chalk_ir::TypeName::Str, empty()),
Array(ty, _) => apply(
- struct_ty(RustDefId::Array),
- chalk_ir::Substitution::from1(
+ chalk_ir::TypeName::Array,
+ chalk_ir::Substitution::from(
interner,
- chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner),
+ &[
+ chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner),
+ chalk_ir::GenericArgData::Const(
+ chalk_ir::ConstData {
+ ty: apply(chalk_ir::TypeName::Tuple(0), empty()),
+ value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst {
+ interned: 0,
+ }),
+ }
+ .intern(interner),
+ )
+ .intern(interner),
+ ],
),
),
Slice(ty) => apply(
- struct_ty(RustDefId::Slice),
+ chalk_ir::TypeName::Slice,
chalk_ir::Substitution::from1(
interner,
- chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner),
+ chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner),
),
),
- RawPtr(_) => apply(struct_ty(RustDefId::RawPtr), empty()),
- Ref(region, ty, mutability) => apply(
- struct_ty(RustDefId::Ref(mutability)),
- chalk_ir::Substitution::from(
- interner,
- [
- chalk_ir::ParameterKind::Lifetime(region.lower_into(interner))
- .intern(interner),
- chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner),
- ]
- .iter(),
- ),
+ RawPtr(ptr) => {
+ let name = match ptr.mutbl {
+ ast::Mutability::Mut => chalk_ir::TypeName::Raw(chalk_ir::Mutability::Mut),
+ ast::Mutability::Not => chalk_ir::TypeName::Raw(chalk_ir::Mutability::Not),
+ };
+ apply(name, chalk_ir::Substitution::from1(interner, ptr.ty.lower_into(interner)))
+ }
+ Ref(region, ty, mutability) => {
+ let name = match mutability {
+ ast::Mutability::Mut => chalk_ir::TypeName::Ref(chalk_ir::Mutability::Mut),
+ ast::Mutability::Not => chalk_ir::TypeName::Ref(chalk_ir::Mutability::Not),
+ };
+ apply(
+ name,
+ chalk_ir::Substitution::from(
+ interner,
+ &[
+ chalk_ir::GenericArgData::Lifetime(region.lower_into(interner))
+ .intern(interner),
+ chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner),
+ ],
+ ),
+ )
+ }
+ FnDef(def_id, substs) => apply(
+ chalk_ir::TypeName::FnDef(chalk_ir::FnDefId(def_id)),
+ substs.lower_into(interner),
),
- FnDef(def_id, _) => apply(struct_ty(RustDefId::FnDef(def_id)), empty()),
FnPtr(sig) => {
let (inputs_and_outputs, binders, _named_regions) =
collect_bound_vars(interner, interner.tcx, &sig.inputs_and_output());
substitution: chalk_ir::Substitution::from(
interner,
inputs_and_outputs.iter().map(|ty| {
- chalk_ir::ParameterKind::Ty(ty.lower_into(interner)).intern(interner)
+ chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner)
}),
),
})
Closure(_def_id, _) => unimplemented!(),
Generator(_def_id, _substs, _) => unimplemented!(),
GeneratorWitness(_) => unimplemented!(),
- Never => apply(struct_ty(RustDefId::Never), empty()),
+ Never => apply(chalk_ir::TypeName::Never, empty()),
Tuple(substs) => {
apply(chalk_ir::TypeName::Tuple(substs.len()), substs.lower_into(interner))
}
Projection(proj) => TyData::Alias(proj.lower_into(interner)).intern(interner),
Opaque(def_id, substs) => {
TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
- opaque_ty_id: chalk_ir::OpaqueTyId(RustDefId::Opaque(def_id)),
+ opaque_ty_id: chalk_ir::OpaqueTyId(def_id),
substitution: substs.lower_into(interner),
}))
.intern(interner)
}
}
-impl<'tcx> LowerInto<'tcx, chalk_ir::Parameter<RustInterner<'tcx>>> for GenericArg<'tcx> {
- fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Parameter<RustInterner<'tcx>> {
+impl<'tcx> LowerInto<'tcx, chalk_ir::GenericArg<RustInterner<'tcx>>> for GenericArg<'tcx> {
+ fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GenericArg<RustInterner<'tcx>> {
match self.unpack() {
ty::subst::GenericArgKind::Type(ty) => {
- chalk_ir::ParameterKind::Ty(ty.lower_into(interner))
+ chalk_ir::GenericArgData::Ty(ty.lower_into(interner))
}
ty::subst::GenericArgKind::Lifetime(lifetime) => {
- chalk_ir::ParameterKind::Lifetime(lifetime.lower_into(interner))
+ chalk_ir::GenericArgData::Lifetime(lifetime.lower_into(interner))
}
- ty::subst::GenericArgKind::Const(_) => chalk_ir::ParameterKind::Ty(
+ ty::subst::GenericArgKind::Const(_) => chalk_ir::GenericArgData::Ty(
chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
name: chalk_ir::TypeName::Tuple(0),
substitution: chalk_ir::Substitution::empty(interner),
chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner)),
))
}
- ty::PredicateKind::RegionOutlives(_predicate) => None,
+ ty::PredicateKind::RegionOutlives(predicate) => {
+ let (predicate, binders, _named_regions) =
+ collect_bound_vars(interner, interner.tcx, predicate);
+
+ Some(chalk_ir::Binders::new(
+ binders,
+ chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives {
+ a: predicate.0.lower_into(interner),
+ b: predicate.1.lower_into(interner),
+ }),
+ ))
+
+ },
ty::PredicateKind::TypeOutlives(_predicate) => None,
ty::PredicateKind::Projection(_predicate) => None,
ty::PredicateKind::WellFormed(_ty) => None,
let where_clauses = predicates.into_iter().map(|predicate| match predicate {
ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef { def_id, substs }) => {
chalk_ir::Binders::new(
- chalk_ir::ParameterKinds::new(interner),
+ chalk_ir::VariableKinds::new(interner),
chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef {
- trait_id: chalk_ir::TraitId(RustDefId::Trait(*def_id)),
+ trait_id: chalk_ir::TraitId(*def_id),
substitution: substs.lower_into(interner),
}),
)
}
ty::ExistentialPredicate::Projection(_predicate) => unimplemented!(),
ty::ExistentialPredicate::AutoTrait(def_id) => chalk_ir::Binders::new(
- chalk_ir::ParameterKinds::new(interner),
+ chalk_ir::VariableKinds::new(interner),
chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef {
- trait_id: chalk_ir::TraitId(RustDefId::Trait(*def_id)),
+ trait_id: chalk_ir::TraitId(*def_id),
substitution: chalk_ir::Substitution::empty(interner),
}),
),
interner: &RustInterner<'tcx>,
tcx: TyCtxt<'tcx>,
ty: &'a Binder<T>,
-) -> (T, chalk_ir::ParameterKinds<RustInterner<'tcx>>, BTreeMap<DefId, u32>) {
+) -> (T, chalk_ir::VariableKinds<RustInterner<'tcx>>, BTreeMap<DefId, u32>) {
let mut bound_vars_collector = BoundVarsCollector::new();
ty.skip_binder().visit_with(&mut bound_vars_collector);
let mut parameters = bound_vars_collector.parameters;
let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor);
for var in named_parameters.values() {
- parameters.insert(*var, chalk_ir::ParameterKind::Lifetime(()));
+ parameters.insert(*var, chalk_ir::VariableKind::Lifetime);
}
(0..parameters.len()).for_each(|i| {
parameters.get(&(i as u32)).expect("Skipped bound var index.");
});
- let binders = chalk_ir::ParameterKinds::from(interner, parameters.into_iter().map(|(_, v)| v));
+ let binders = chalk_ir::VariableKinds::from(interner, parameters.into_iter().map(|(_, v)| v));
(new_ty, binders, named_parameters)
}
-crate struct BoundVarsCollector {
+crate struct BoundVarsCollector<'tcx> {
binder_index: ty::DebruijnIndex,
- crate parameters: BTreeMap<u32, chalk_ir::ParameterKind<()>>,
+ crate parameters: BTreeMap<u32, chalk_ir::VariableKind<RustInterner<'tcx>>>,
crate named_parameters: Vec<DefId>,
}
-impl BoundVarsCollector {
+impl<'tcx> BoundVarsCollector<'tcx> {
crate fn new() -> Self {
BoundVarsCollector {
binder_index: ty::INNERMOST,
}
}
-impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector {
+impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
fn visit_binder<T: TypeFoldable<'tcx>>(&mut self, t: &Binder<T>) -> bool {
self.binder_index.shift_in(1);
let result = t.super_visit_with(self);
ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => {
match self.parameters.entry(bound_ty.var.as_u32()) {
Entry::Vacant(entry) => {
- entry.insert(chalk_ir::ParameterKind::Ty(()));
- }
- Entry::Occupied(entry) => {
- entry.get().assert_ty_ref();
+ entry.insert(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General));
}
+ Entry::Occupied(entry) => match entry.get() {
+ chalk_ir::VariableKind::Ty(_) => {}
+ _ => panic!(),
+ },
}
}
ty::BoundRegion::BrAnon(var) => match self.parameters.entry(*var) {
Entry::Vacant(entry) => {
- entry.insert(chalk_ir::ParameterKind::Lifetime(()));
- }
- Entry::Occupied(entry) => {
- entry.get().assert_lifetime_ref();
+ entry.insert(chalk_ir::VariableKind::Lifetime);
}
+ Entry::Occupied(entry) => match entry.get() {
+ chalk_ir::VariableKind::Lifetime => {}
+ _ => panic!(),
+ },
},
ty::BrEnv => unimplemented!(),