Fix various Chalk lowering bugs
- Add more well-known traits - Use the correct binders when lowering trait objects - Use correct substs when lowering trait objects - Use the correct binders for opaque_ty_data - Lower negative impls with the correct polarity - Supply associated type values - Use `predicates_defined_on` for where clauses
This commit is contained in:
parent
299a65ff71
commit
acb6a06123
4 changed files with 161 additions and 42 deletions
|
@ -37,7 +37,7 @@ impl<'tcx> RustIrDatabase<'tcx> {
|
|||
def_id: DefId,
|
||||
bound_vars: SubstsRef<'tcx>,
|
||||
) -> Vec<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>> {
|
||||
let predicates = self.interner.tcx.predicates_of(def_id).predicates;
|
||||
let predicates = self.interner.tcx.predicates_defined_on(def_id).predicates;
|
||||
let mut regions_substitutor =
|
||||
lowering::RegionsSubstitutor::new(self.interner.tcx, self.reempty_placeholder);
|
||||
predicates
|
||||
|
@ -118,34 +118,27 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
.map(|i| chalk_ir::AssocTypeId(i.def_id))
|
||||
.collect();
|
||||
|
||||
let well_known = if self.interner.tcx.lang_items().sized_trait() == Some(def_id) {
|
||||
let lang_items = self.interner.tcx.lang_items();
|
||||
let well_known = if lang_items.sized_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Sized)
|
||||
} else if self.interner.tcx.lang_items().copy_trait() == Some(def_id) {
|
||||
} else if lang_items.copy_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Copy)
|
||||
} else if self.interner.tcx.lang_items().clone_trait() == Some(def_id) {
|
||||
} else if lang_items.clone_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Clone)
|
||||
} else if self.interner.tcx.lang_items().drop_trait() == Some(def_id) {
|
||||
} else if lang_items.drop_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Drop)
|
||||
} else if self.interner.tcx.lang_items().fn_trait() == Some(def_id) {
|
||||
} else if lang_items.fn_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Fn)
|
||||
} else if self
|
||||
.interner
|
||||
.tcx
|
||||
.lang_items()
|
||||
.fn_once_trait()
|
||||
.map(|t| def_id == t)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
} else if lang_items.fn_once_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::FnOnce)
|
||||
} else if self
|
||||
.interner
|
||||
.tcx
|
||||
.lang_items()
|
||||
.fn_mut_trait()
|
||||
.map(|t| def_id == t)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
} else if lang_items.fn_mut_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::FnMut)
|
||||
} else if lang_items.unsize_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Unsize)
|
||||
} else if lang_items.unpin_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::Unpin)
|
||||
} else if lang_items.coerce_unsized_trait() == Some(def_id) {
|
||||
Some(chalk_solve::rust_ir::WellKnownTrait::CoerceUnsized)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -281,11 +274,20 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
where_clauses,
|
||||
};
|
||||
|
||||
let associated_ty_value_ids: Vec<_> = self
|
||||
.interner
|
||||
.tcx
|
||||
.associated_items(def_id)
|
||||
.in_definition_order()
|
||||
.filter(|i| i.kind == AssocKind::Type)
|
||||
.map(|i| chalk_solve::rust_ir::AssociatedTyValueId(i.def_id))
|
||||
.collect();
|
||||
|
||||
Arc::new(chalk_solve::rust_ir::ImplDatum {
|
||||
polarity: chalk_solve::rust_ir::Polarity::Positive,
|
||||
polarity: self.interner.tcx.impl_polarity(def_id).lower_into(&self.interner),
|
||||
binders: chalk_ir::Binders::new(binders, value),
|
||||
impl_type: chalk_solve::rust_ir::ImplType::Local,
|
||||
associated_ty_value_ids: vec![],
|
||||
associated_ty_value_ids,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -406,24 +408,38 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
) -> Arc<chalk_solve::rust_ir::AssociatedTyValue<RustInterner<'tcx>>> {
|
||||
let def_id = associated_ty_id.0;
|
||||
let assoc_item = self.interner.tcx.associated_item(def_id);
|
||||
let impl_id = match assoc_item.container {
|
||||
AssocItemContainer::TraitContainer(def_id) => def_id,
|
||||
_ => unimplemented!("Not possible??"),
|
||||
let (impl_id, trait_id) = match assoc_item.container {
|
||||
AssocItemContainer::TraitContainer(def_id) => (def_id, def_id),
|
||||
AssocItemContainer::ImplContainer(def_id) => {
|
||||
(def_id, self.interner.tcx.impl_trait_ref(def_id).unwrap().def_id)
|
||||
}
|
||||
};
|
||||
match assoc_item.kind {
|
||||
AssocKind::Type => {}
|
||||
_ => unimplemented!("Not possible??"),
|
||||
}
|
||||
|
||||
let trait_item = self
|
||||
.interner
|
||||
.tcx
|
||||
.associated_items(trait_id)
|
||||
.find_by_name_and_kind(self.interner.tcx, assoc_item.ident, assoc_item.kind, trait_id)
|
||||
.unwrap();
|
||||
let bound_vars = bound_vars_for_item(self.interner.tcx, def_id);
|
||||
let binders = binders_for(&self.interner, bound_vars);
|
||||
let ty = self.interner.tcx.type_of(def_id);
|
||||
let ty = self
|
||||
.interner
|
||||
.tcx
|
||||
.type_of(def_id)
|
||||
.subst(self.interner.tcx, bound_vars)
|
||||
.lower_into(&self.interner);
|
||||
|
||||
Arc::new(chalk_solve::rust_ir::AssociatedTyValue {
|
||||
impl_id: chalk_ir::ImplId(impl_id),
|
||||
associated_ty_id: chalk_ir::AssocTypeId(def_id),
|
||||
associated_ty_id: chalk_ir::AssocTypeId(trait_item.def_id),
|
||||
value: chalk_ir::Binders::new(
|
||||
binders,
|
||||
chalk_solve::rust_ir::AssociatedTyValueBound { ty: ty.lower_into(&self.interner) },
|
||||
chalk_solve::rust_ir::AssociatedTyValueBound { ty },
|
||||
),
|
||||
})
|
||||
}
|
||||
|
@ -443,19 +459,61 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
|
|||
&self,
|
||||
opaque_ty_id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
|
||||
) -> Arc<chalk_solve::rust_ir::OpaqueTyDatum<RustInterner<'tcx>>> {
|
||||
let bound_vars = bound_vars_for_item(self.interner.tcx, opaque_ty_id.0);
|
||||
let binders = binders_for(&self.interner, bound_vars);
|
||||
let bound_vars = ty::fold::shift_vars(
|
||||
self.interner.tcx,
|
||||
&bound_vars_for_item(self.interner.tcx, opaque_ty_id.0),
|
||||
1,
|
||||
);
|
||||
let where_clauses = self.where_clauses_for(opaque_ty_id.0, bound_vars);
|
||||
let bounds = self.bounds_for(opaque_ty_id.0, bound_vars);
|
||||
|
||||
let identity_substs = InternalSubsts::identity_for_item(self.interner.tcx, opaque_ty_id.0);
|
||||
|
||||
let bounds =
|
||||
self.interner
|
||||
.tcx
|
||||
.explicit_item_bounds(opaque_ty_id.0)
|
||||
.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)),
|
||||
));
|
||||
}
|
||||
}
|
||||
ty
|
||||
},
|
||||
lt_op: |lt| lt,
|
||||
ct_op: |ct| ct,
|
||||
})
|
||||
})
|
||||
.filter_map(|bound| {
|
||||
LowerInto::<
|
||||
Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>
|
||||
>::lower_into(bound, &self.interner)
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Binder for the bound variable representing the concrete impl Trait type.
|
||||
let existential_binder = chalk_ir::VariableKinds::from1(
|
||||
&self.interner,
|
||||
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
|
||||
);
|
||||
|
||||
let value = chalk_solve::rust_ir::OpaqueTyDatumBound {
|
||||
bounds: chalk_ir::Binders::new(binders.clone(), bounds),
|
||||
where_clauses: chalk_ir::Binders::new(binders, where_clauses),
|
||||
bounds: chalk_ir::Binders::new(existential_binder.clone(), bounds),
|
||||
where_clauses: chalk_ir::Binders::new(existential_binder, where_clauses),
|
||||
};
|
||||
|
||||
let binders = binders_for(&self.interner, bound_vars);
|
||||
Arc::new(chalk_solve::rust_ir::OpaqueTyDatum {
|
||||
opaque_ty_id,
|
||||
bound: chalk_ir::Binders::empty(&self.interner, value),
|
||||
bound: chalk_ir::Binders::new(binders, value),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -638,8 +638,16 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru
|
|||
self,
|
||||
interner: &RustInterner<'tcx>,
|
||||
) -> chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<RustInterner<'tcx>>> {
|
||||
// `Self` has one binder:
|
||||
// Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>
|
||||
// The return type has two:
|
||||
// Binders<&[Binders<WhereClause<I>>]>
|
||||
// This means that any variables that are escaping `self` need to be
|
||||
// shifted in by one so that they are still escaping.
|
||||
let shifted_predicates = ty::fold::shift_vars(interner.tcx, &self, 1);
|
||||
|
||||
let (predicates, binders, _named_regions) =
|
||||
collect_bound_vars(interner, interner.tcx, &self);
|
||||
collect_bound_vars(interner, interner.tcx, &shifted_predicates);
|
||||
let self_ty = interner.tcx.mk_ty(ty::Bound(
|
||||
// This is going to be wrapped in a binder
|
||||
ty::DebruijnIndex::from_usize(1),
|
||||
|
@ -648,7 +656,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru
|
|||
let where_clauses = predicates.into_iter().map(|predicate| match predicate {
|
||||
ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef { def_id, substs }) => {
|
||||
chalk_ir::Binders::new(
|
||||
chalk_ir::VariableKinds::empty(interner),
|
||||
binders.clone(),
|
||||
chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef {
|
||||
trait_id: chalk_ir::TraitId(def_id),
|
||||
substitution: interner
|
||||
|
@ -659,25 +667,34 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru
|
|||
)
|
||||
}
|
||||
ty::ExistentialPredicate::Projection(predicate) => chalk_ir::Binders::new(
|
||||
chalk_ir::VariableKinds::empty(interner),
|
||||
binders.clone(),
|
||||
chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq {
|
||||
alias: chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
|
||||
associated_ty_id: chalk_ir::AssocTypeId(predicate.item_def_id),
|
||||
substitution: predicate.substs.lower_into(interner),
|
||||
substitution: interner
|
||||
.tcx
|
||||
.mk_substs_trait(self_ty, predicate.substs)
|
||||
.lower_into(interner),
|
||||
}),
|
||||
ty: predicate.ty.lower_into(interner),
|
||||
}),
|
||||
),
|
||||
ty::ExistentialPredicate::AutoTrait(def_id) => chalk_ir::Binders::new(
|
||||
chalk_ir::VariableKinds::empty(interner),
|
||||
binders.clone(),
|
||||
chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef {
|
||||
trait_id: chalk_ir::TraitId(def_id),
|
||||
substitution: interner.tcx.mk_substs_trait(self_ty, &[]).lower_into(interner),
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
// Binder for the bound variable representing the concrete underlying type.
|
||||
let existential_binder = chalk_ir::VariableKinds::from1(
|
||||
interner,
|
||||
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
|
||||
);
|
||||
let value = chalk_ir::QuantifiedWhereClauses::from_iter(interner, where_clauses);
|
||||
chalk_ir::Binders::new(binders, value)
|
||||
chalk_ir::Binders::new(existential_binder, value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -750,6 +767,17 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::TraitBound<RustInterner<'tcx>>>
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::Polarity> for ty::ImplPolarity {
|
||||
fn lower_into(self, _interner: &RustInterner<'tcx>) -> chalk_solve::rust_ir::Polarity {
|
||||
match self {
|
||||
ty::ImplPolarity::Positive => chalk_solve::rust_ir::Polarity::Positive,
|
||||
ty::ImplPolarity::Negative => chalk_solve::rust_ir::Polarity::Negative,
|
||||
// FIXME(chalk) reservation impls
|
||||
ty::ImplPolarity::Reservation => chalk_solve::rust_ir::Polarity::Negative,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx>>>
|
||||
for ty::ProjectionPredicate<'tcx>
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue