Skip to content

Commit 7b8da79

Browse files
committed
Add utilities for creating generic types
1 parent ec73624 commit 7b8da79

File tree

4 files changed

+87
-59
lines changed

4 files changed

+87
-59
lines changed

src/librustc_traits/chalk_context/program_clauses.rs

Lines changed: 19 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc::hir::def_id::DefId;
1515
use rustc_target::spec::abi;
1616
use super::ChalkInferenceContext;
1717
use crate::lowering::Lower;
18+
use crate::generic_types;
1819
use std::iter;
1920

2021
fn assemble_clauses_from_impls<'tcx>(
@@ -47,24 +48,19 @@ fn assemble_clauses_from_assoc_ty_values<'tcx>(
4748
});
4849
}
4950

50-
fn program_clauses_for_raw_ptr<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx> {
51-
let ty = ty::Bound(
52-
ty::INNERMOST,
53-
ty::BoundVar::from_u32(0).into()
54-
);
55-
let ty = tcx.mk_ty(ty);
5651

57-
let ptr_ty = tcx.mk_ptr(ty::TypeAndMut {
58-
ty,
59-
mutbl: hir::Mutability::MutImmutable,
60-
});
52+
fn program_clauses_for_raw_ptr<'tcx>(
53+
tcx: ty::TyCtxt<'_, '_, 'tcx>,
54+
mutbl: hir::Mutability
55+
) -> Clauses<'tcx> {
56+
let ptr_ty = generic_types::raw_ptr(tcx, mutbl);
6157

6258
let wf_clause = ProgramClause {
6359
goal: DomainGoal::WellFormed(WellFormed::Ty(ptr_ty)),
6460
hypotheses: ty::List::empty(),
6561
category: ProgramClauseCategory::WellFormed,
6662
};
67-
let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
63+
let wf_clause = Clause::Implies(wf_clause);
6864

6965
// `forall<T> { WellFormed(*const T). }`
7066
tcx.mk_clauses(iter::once(wf_clause))
@@ -77,20 +73,7 @@ fn program_clauses_for_fn_ptr<'tcx>(
7773
unsafety: hir::Unsafety,
7874
abi: abi::Abi
7975
) -> Clauses<'tcx> {
80-
let inputs_and_output = tcx.mk_type_list(
81-
(0..arity_and_output).into_iter()
82-
.map(|i| ty::BoundVar::from(i))
83-
// DebruijnIndex(1) because we are going to inject these in a `PolyFnSig`
84-
.map(|var| tcx.mk_ty(ty::Bound(ty::DebruijnIndex::from(1usize), var.into())))
85-
);
86-
87-
let fn_sig = ty::Binder::bind(ty::FnSig {
88-
inputs_and_output,
89-
variadic,
90-
unsafety,
91-
abi,
92-
});
93-
let fn_ptr = tcx.mk_fn_ptr(fn_sig);
76+
let fn_ptr = generic_types::fn_ptr(tcx, arity_and_output, variadic, unsafety, abi);
9477

9578
let wf_clause = ProgramClause {
9679
goal: DomainGoal::WellFormed(WellFormed::Ty(fn_ptr)),
@@ -105,12 +88,7 @@ fn program_clauses_for_fn_ptr<'tcx>(
10588
}
10689

10790
fn program_clauses_for_slice<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx> {
108-
let ty = ty::Bound(
109-
ty::INNERMOST,
110-
ty::BoundVar::from_u32(0).into()
111-
);
112-
let ty = tcx.mk_ty(ty);
113-
91+
let ty = generic_types::bound(tcx, 0);
11492
let slice_ty = tcx.mk_slice(ty);
11593

11694
let sized_trait = match tcx.lang_items().sized_trait() {
@@ -142,12 +120,7 @@ fn program_clauses_for_array<'tcx>(
142120
tcx: ty::TyCtxt<'_, '_, 'tcx>,
143121
length: &'tcx ty::Const<'tcx>
144122
) -> Clauses<'tcx> {
145-
let ty = ty::Bound(
146-
ty::INNERMOST,
147-
ty::BoundVar::from_u32(0).into()
148-
);
149-
let ty = tcx.mk_ty(ty);
150-
123+
let ty = generic_types::bound(tcx, 0);
151124
let array_ty = tcx.mk_ty(ty::Array(ty, length));
152125

153126
let sized_trait = match tcx.lang_items().sized_trait() {
@@ -179,12 +152,7 @@ fn program_clauses_for_tuple<'tcx>(
179152
tcx: ty::TyCtxt<'_, '_, 'tcx>,
180153
arity: usize
181154
) -> Clauses<'tcx> {
182-
let type_list = tcx.mk_type_list(
183-
(0..arity).into_iter()
184-
.map(|i| ty::BoundVar::from(i))
185-
.map(|var| tcx.mk_ty(ty::Bound(ty::INNERMOST, var.into())))
186-
);
187-
155+
let type_list = generic_types::type_list(tcx, arity);
188156
let tuple_ty = tcx.mk_ty(ty::Tuple(type_list));
189157

190158
let sized_trait = match tcx.lang_items().sized_trait() {
@@ -221,17 +189,17 @@ fn program_clauses_for_tuple<'tcx>(
221189
tcx.mk_clauses(iter::once(wf_clause))
222190
}
223191

224-
fn program_clauses_for_ref<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx> {
192+
fn program_clauses_for_ref<'tcx>(
193+
tcx: ty::TyCtxt<'_, '_, 'tcx>,
194+
mutbl: hir::Mutability
195+
) -> Clauses<'tcx> {
225196
let region = tcx.mk_region(
226197
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0))
227198
);
228-
let ty = tcx.mk_ty(
229-
ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(1).into())
230-
);
231-
199+
let ty = generic_types::bound(tcx, 1);
232200
let ref_ty = tcx.mk_ref(region, ty::TypeAndMut {
233201
ty,
234-
mutbl: hir::Mutability::MutImmutable,
202+
mutbl,
235203
});
236204

237205
let outlives: DomainGoal = ty::OutlivesPredicate(ty, region).lower();
@@ -367,7 +335,7 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
367335
}
368336

369337
// Always WF (recall that we do not check for parameters to be WF).
370-
ty::RawPtr(..) => program_clauses_for_raw_ptr(self.infcx.tcx),
338+
ty::RawPtr(ptr) => program_clauses_for_raw_ptr(self.infcx.tcx, ptr.mutbl),
371339

372340
// Always WF (recall that we do not check for parameters to be WF).
373341
ty::FnPtr(fn_ptr) => {
@@ -394,7 +362,7 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
394362
),
395363

396364
// WF if `sub_ty` outlives `region`.
397-
ty::Ref(..) => program_clauses_for_ref(self.infcx.tcx),
365+
ty::Ref(_, _, mutbl) => program_clauses_for_ref(self.infcx.tcx, mutbl),
398366

399367
ty::Dynamic(..) => {
400368
// FIXME: no rules yet for trait objects

src/librustc_traits/generic_types.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//! Utilities for creating generic types with bound vars in place of parameter values.
2+
3+
use rustc::ty::{self, Ty, TyCtxt};
4+
use rustc::hir;
5+
use rustc_target::spec::abi;
6+
7+
crate fn bound(tcx: ty::TyCtxt<'_, '_, 'tcx>, index: u32) -> Ty<'tcx> {
8+
let ty = ty::Bound(
9+
ty::INNERMOST,
10+
ty::BoundVar::from_u32(index).into()
11+
);
12+
tcx.mk_ty(ty)
13+
}
14+
15+
crate fn raw_ptr(tcx: TyCtxt<'_, '_, 'tcx>, mutbl: hir::Mutability) -> Ty<'tcx> {
16+
tcx.mk_ptr(ty::TypeAndMut {
17+
ty: bound(tcx, 0),
18+
mutbl,
19+
})
20+
}
21+
22+
crate fn fn_ptr(
23+
tcx: ty::TyCtxt<'_, '_, 'tcx>,
24+
arity_and_output: usize,
25+
variadic: bool,
26+
unsafety: hir::Unsafety,
27+
abi: abi::Abi
28+
) -> Ty<'tcx> {
29+
let inputs_and_output = tcx.mk_type_list(
30+
(0..arity_and_output).into_iter()
31+
.map(|i| ty::BoundVar::from(i))
32+
// DebruijnIndex(1) because we are going to inject these in a `PolyFnSig`
33+
.map(|var| tcx.mk_ty(ty::Bound(ty::DebruijnIndex::from(1usize), var.into())))
34+
);
35+
36+
let fn_sig = ty::Binder::bind(ty::FnSig {
37+
inputs_and_output,
38+
variadic,
39+
unsafety,
40+
abi,
41+
});
42+
tcx.mk_fn_ptr(fn_sig)
43+
}
44+
45+
crate fn type_list(tcx: ty::TyCtxt<'_, '_, 'tcx>, arity: usize) -> &'tcx ty::List<Ty<'tcx>> {
46+
tcx.mk_type_list(
47+
(0..arity).into_iter()
48+
.map(|i| ty::BoundVar::from(i))
49+
.map(|var| tcx.mk_ty(ty::Bound(ty::INNERMOST, var.into())))
50+
)
51+
}
52+
53+
crate fn _ref_ty(tcx: ty::TyCtxt<'_, '_, 'tcx>, mutbl: hir::Mutability) -> Ty<'tcx> {
54+
let region = tcx.mk_region(
55+
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0))
56+
);
57+
58+
tcx.mk_ref(region, ty::TypeAndMut {
59+
ty: bound(tcx, 1),
60+
mutbl,
61+
})
62+
}

src/librustc_traits/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ mod implied_outlives_bounds;
2525
mod normalize_projection_ty;
2626
mod normalize_erasing_regions;
2727
pub mod lowering;
28+
mod generic_types;
2829
mod type_op;
2930

3031
use rustc::ty::query::Providers;

src/librustc_traits/lowering/environment.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc::ty::{self, TyCtxt, Ty};
1111
use rustc::hir::def_id::DefId;
1212
use rustc_data_structures::fx::FxHashSet;
1313
use super::Lower;
14+
use crate::generic_types;
1415
use std::iter;
1516

1617
struct ClauseVisitor<'set, 'a, 'tcx: 'a + 'set> {
@@ -38,20 +39,16 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
3839
}
3940

4041
// forall<'a, T> { `Outlives(T: 'a) :- FromEnv(&'a T)` }
41-
ty::Ref(..) => {
42-
use rustc::hir;
43-
42+
ty::Ref(_, _, mutbl) => {
4443
let region = self.tcx.mk_region(
4544
ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0))
4645
);
47-
let ty = self.tcx.mk_ty(
48-
ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(1).into())
49-
);
50-
46+
let ty = generic_types::bound(self.tcx, 1);
5147
let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut {
5248
ty,
53-
mutbl: hir::Mutability::MutImmutable,
49+
mutbl,
5450
});
51+
5552
let from_env = DomainGoal::FromEnv(FromEnv::Ty(ref_ty));
5653

5754
let clause = ProgramClause {

0 commit comments

Comments
 (0)