use rustc_target::spec::abi;
use super::ChalkInferenceContext;
use crate::lowering::Lower;
+use crate::generic_types;
use std::iter;
fn assemble_clauses_from_impls<'tcx>(
});
}
-fn program_clauses_for_raw_ptr<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx> {
- let ty = ty::Bound(
- ty::INNERMOST,
- ty::BoundVar::from_u32(0).into()
- );
- let ty = tcx.mk_ty(ty);
- let ptr_ty = tcx.mk_ptr(ty::TypeAndMut {
- ty,
- mutbl: hir::Mutability::MutImmutable,
- });
+fn program_clauses_for_raw_ptr<'tcx>(
+ tcx: ty::TyCtxt<'_, '_, 'tcx>,
+ mutbl: hir::Mutability
+) -> Clauses<'tcx> {
+ let ptr_ty = generic_types::raw_ptr(tcx, mutbl);
let wf_clause = ProgramClause {
goal: DomainGoal::WellFormed(WellFormed::Ty(ptr_ty)),
hypotheses: ty::List::empty(),
category: ProgramClauseCategory::WellFormed,
};
- let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
+ let wf_clause = Clause::Implies(wf_clause);
// `forall<T> { WellFormed(*const T). }`
tcx.mk_clauses(iter::once(wf_clause))
unsafety: hir::Unsafety,
abi: abi::Abi
) -> Clauses<'tcx> {
- let inputs_and_output = tcx.mk_type_list(
- (0..arity_and_output).into_iter()
- .map(|i| ty::BoundVar::from(i))
- // DebruijnIndex(1) because we are going to inject these in a `PolyFnSig`
- .map(|var| tcx.mk_ty(ty::Bound(ty::DebruijnIndex::from(1usize), var.into())))
- );
-
- let fn_sig = ty::Binder::bind(ty::FnSig {
- inputs_and_output,
- variadic,
- unsafety,
- abi,
- });
- let fn_ptr = tcx.mk_fn_ptr(fn_sig);
+ let fn_ptr = generic_types::fn_ptr(tcx, arity_and_output, variadic, unsafety, abi);
let wf_clause = ProgramClause {
goal: DomainGoal::WellFormed(WellFormed::Ty(fn_ptr)),
}
fn program_clauses_for_slice<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx> {
- let ty = ty::Bound(
- ty::INNERMOST,
- ty::BoundVar::from_u32(0).into()
- );
- let ty = tcx.mk_ty(ty);
-
+ let ty = generic_types::bound(tcx, 0);
let slice_ty = tcx.mk_slice(ty);
let sized_trait = match tcx.lang_items().sized_trait() {
tcx: ty::TyCtxt<'_, '_, 'tcx>,
length: &'tcx ty::Const<'tcx>
) -> Clauses<'tcx> {
- let ty = ty::Bound(
- ty::INNERMOST,
- ty::BoundVar::from_u32(0).into()
- );
- let ty = tcx.mk_ty(ty);
-
+ let ty = generic_types::bound(tcx, 0);
let array_ty = tcx.mk_ty(ty::Array(ty, length));
let sized_trait = match tcx.lang_items().sized_trait() {
tcx: ty::TyCtxt<'_, '_, 'tcx>,
arity: usize
) -> Clauses<'tcx> {
- let type_list = tcx.mk_type_list(
- (0..arity).into_iter()
- .map(|i| ty::BoundVar::from(i))
- .map(|var| tcx.mk_ty(ty::Bound(ty::INNERMOST, var.into())))
- );
-
+ let type_list = generic_types::type_list(tcx, arity);
let tuple_ty = tcx.mk_ty(ty::Tuple(type_list));
let sized_trait = match tcx.lang_items().sized_trait() {
tcx.mk_clauses(iter::once(wf_clause))
}
-fn program_clauses_for_ref<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx> {
+fn program_clauses_for_ref<'tcx>(
+ tcx: ty::TyCtxt<'_, '_, 'tcx>,
+ mutbl: hir::Mutability
+) -> Clauses<'tcx> {
let region = tcx.mk_region(
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0))
);
- let ty = tcx.mk_ty(
- ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(1).into())
- );
-
+ let ty = generic_types::bound(tcx, 1);
let ref_ty = tcx.mk_ref(region, ty::TypeAndMut {
ty,
- mutbl: hir::Mutability::MutImmutable,
+ mutbl,
});
let outlives: DomainGoal = ty::OutlivesPredicate(ty, region).lower();
}
// Always WF (recall that we do not check for parameters to be WF).
- ty::RawPtr(..) => program_clauses_for_raw_ptr(self.infcx.tcx),
+ ty::RawPtr(ptr) => program_clauses_for_raw_ptr(self.infcx.tcx, ptr.mutbl),
// Always WF (recall that we do not check for parameters to be WF).
ty::FnPtr(fn_ptr) => {
),
// WF if `sub_ty` outlives `region`.
- ty::Ref(..) => program_clauses_for_ref(self.infcx.tcx),
+ ty::Ref(_, _, mutbl) => program_clauses_for_ref(self.infcx.tcx, mutbl),
ty::Dynamic(..) => {
// FIXME: no rules yet for trait objects
--- /dev/null
+//! Utilities for creating generic types with bound vars in place of parameter values.
+
+use rustc::ty::{self, Ty, TyCtxt};
+use rustc::hir;
+use rustc_target::spec::abi;
+
+crate fn bound(tcx: ty::TyCtxt<'_, '_, 'tcx>, index: u32) -> Ty<'tcx> {
+ let ty = ty::Bound(
+ ty::INNERMOST,
+ ty::BoundVar::from_u32(index).into()
+ );
+ tcx.mk_ty(ty)
+}
+
+crate fn raw_ptr(tcx: TyCtxt<'_, '_, 'tcx>, mutbl: hir::Mutability) -> Ty<'tcx> {
+ tcx.mk_ptr(ty::TypeAndMut {
+ ty: bound(tcx, 0),
+ mutbl,
+ })
+}
+
+crate fn fn_ptr(
+ tcx: ty::TyCtxt<'_, '_, 'tcx>,
+ arity_and_output: usize,
+ variadic: bool,
+ unsafety: hir::Unsafety,
+ abi: abi::Abi
+) -> Ty<'tcx> {
+ let inputs_and_output = tcx.mk_type_list(
+ (0..arity_and_output).into_iter()
+ .map(|i| ty::BoundVar::from(i))
+ // DebruijnIndex(1) because we are going to inject these in a `PolyFnSig`
+ .map(|var| tcx.mk_ty(ty::Bound(ty::DebruijnIndex::from(1usize), var.into())))
+ );
+
+ let fn_sig = ty::Binder::bind(ty::FnSig {
+ inputs_and_output,
+ variadic,
+ unsafety,
+ abi,
+ });
+ tcx.mk_fn_ptr(fn_sig)
+}
+
+crate fn type_list(tcx: ty::TyCtxt<'_, '_, 'tcx>, arity: usize) -> &'tcx ty::List<Ty<'tcx>> {
+ tcx.mk_type_list(
+ (0..arity).into_iter()
+ .map(|i| ty::BoundVar::from(i))
+ .map(|var| tcx.mk_ty(ty::Bound(ty::INNERMOST, var.into())))
+ )
+}
+
+crate fn _ref_ty(tcx: ty::TyCtxt<'_, '_, 'tcx>, mutbl: hir::Mutability) -> Ty<'tcx> {
+ let region = tcx.mk_region(
+ ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0))
+ );
+
+ tcx.mk_ref(region, ty::TypeAndMut {
+ ty: bound(tcx, 1),
+ mutbl,
+ })
+}
use rustc::hir::def_id::DefId;
use rustc_data_structures::fx::FxHashSet;
use super::Lower;
+use crate::generic_types;
use std::iter;
struct ClauseVisitor<'set, 'a, 'tcx: 'a + 'set> {
}
// forall<'a, T> { `Outlives(T: 'a) :- FromEnv(&'a T)` }
- ty::Ref(..) => {
- use rustc::hir;
-
+ ty::Ref(_, _, mutbl) => {
let region = self.tcx.mk_region(
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0))
);
- let ty = self.tcx.mk_ty(
- ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(1).into())
- );
-
+ let ty = generic_types::bound(self.tcx, 1);
let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut {
ty,
- mutbl: hir::Mutability::MutImmutable,
+ mutbl,
});
+
let from_env = DomainGoal::FromEnv(FromEnv::Ty(ref_ty));
let clause = ProgramClause {