]> git.lizzy.rs Git - rust.git/blob - src/librustc_traits/chalk_context/program_clauses/primitive.rs
Update const_forget.rs
[rust.git] / src / librustc_traits / chalk_context / program_clauses / primitive.rs
1 use crate::generic_types;
2 use crate::lowering::Lower;
3 use rustc::traits::{
4     Clause, Clauses, DomainGoal, GoalKind, ProgramClause, ProgramClauseCategory, WellFormed,
5 };
6 use rustc::ty::{self, TyCtxt};
7 use rustc_hir as hir;
8 use rustc_hir::def_id::DefId;
9 use rustc_target::spec::abi;
10 use std::iter;
11
12 crate fn wf_clause_for_raw_ptr(tcx: TyCtxt<'_>, mutbl: hir::Mutability) -> Clauses<'_> {
13     let ptr_ty = generic_types::raw_ptr(tcx, mutbl);
14
15     let wf_clause = ProgramClause {
16         goal: DomainGoal::WellFormed(WellFormed::Ty(ptr_ty)),
17         hypotheses: ty::List::empty(),
18         category: ProgramClauseCategory::WellFormed,
19     };
20     let wf_clause = Clause::Implies(wf_clause);
21
22     // `forall<T> { WellFormed(*const T). }`
23     tcx.mk_clauses(iter::once(wf_clause))
24 }
25
26 crate fn wf_clause_for_fn_ptr(
27     tcx: TyCtxt<'_>,
28     arity_and_output: usize,
29     variadic: bool,
30     unsafety: hir::Unsafety,
31     abi: abi::Abi,
32 ) -> Clauses<'_> {
33     let fn_ptr = generic_types::fn_ptr(tcx, arity_and_output, variadic, unsafety, abi);
34
35     let wf_clause = ProgramClause {
36         goal: DomainGoal::WellFormed(WellFormed::Ty(fn_ptr)),
37         hypotheses: ty::List::empty(),
38         category: ProgramClauseCategory::WellFormed,
39     };
40     let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
41
42     // `forall <T1, ..., Tn+1> { WellFormed(for<> fn(T1, ..., Tn) -> Tn+1). }`
43     // where `n + 1` == `arity_and_output`
44     tcx.mk_clauses(iter::once(wf_clause))
45 }
46
47 crate fn wf_clause_for_slice(tcx: TyCtxt<'_>) -> Clauses<'_> {
48     let ty = generic_types::bound(tcx, 0);
49     let slice_ty = tcx.mk_slice(ty);
50
51     let sized_trait = match tcx.lang_items().sized_trait() {
52         Some(def_id) => def_id,
53         None => return ty::List::empty(),
54     };
55     let sized_implemented =
56         ty::TraitRef { def_id: sized_trait, substs: tcx.mk_substs_trait(ty, ty::List::empty()) };
57     let sized_implemented: DomainGoal<'_> =
58         ty::TraitPredicate { trait_ref: sized_implemented }.lower();
59
60     let wf_clause = ProgramClause {
61         goal: DomainGoal::WellFormed(WellFormed::Ty(slice_ty)),
62         hypotheses: tcx.mk_goals(iter::once(tcx.mk_goal(GoalKind::DomainGoal(sized_implemented)))),
63         category: ProgramClauseCategory::WellFormed,
64     };
65     let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
66
67     // `forall<T> { WellFormed([T]) :- Implemented(T: Sized). }`
68     tcx.mk_clauses(iter::once(wf_clause))
69 }
70
71 crate fn wf_clause_for_array<'tcx>(
72     tcx: TyCtxt<'tcx>,
73     length: &'tcx ty::Const<'tcx>,
74 ) -> Clauses<'tcx> {
75     let ty = generic_types::bound(tcx, 0);
76     let array_ty = tcx.mk_ty(ty::Array(ty, length));
77
78     let sized_trait = match tcx.lang_items().sized_trait() {
79         Some(def_id) => def_id,
80         None => return ty::List::empty(),
81     };
82     let sized_implemented =
83         ty::TraitRef { def_id: sized_trait, substs: tcx.mk_substs_trait(ty, ty::List::empty()) };
84     let sized_implemented: DomainGoal<'_> =
85         ty::TraitPredicate { trait_ref: sized_implemented }.lower();
86
87     let wf_clause = ProgramClause {
88         goal: DomainGoal::WellFormed(WellFormed::Ty(array_ty)),
89         hypotheses: tcx.mk_goals(iter::once(tcx.mk_goal(GoalKind::DomainGoal(sized_implemented)))),
90         category: ProgramClauseCategory::WellFormed,
91     };
92     let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
93
94     // `forall<T> { WellFormed([T; length]) :- Implemented(T: Sized). }`
95     tcx.mk_clauses(iter::once(wf_clause))
96 }
97
98 crate fn wf_clause_for_tuple(tcx: TyCtxt<'_>, arity: usize) -> Clauses<'_> {
99     let type_list = generic_types::type_list(tcx, arity);
100     let tuple_ty = tcx.mk_ty(ty::Tuple(type_list));
101
102     let sized_trait = match tcx.lang_items().sized_trait() {
103         Some(def_id) => def_id,
104         None => return ty::List::empty(),
105     };
106
107     // If `arity == 0` (i.e. the unit type) or `arity == 1`, this list of
108     // hypotheses is actually empty.
109     let sized_implemented = type_list[0..std::cmp::max(arity, 1) - 1]
110         .iter()
111         .map(|ty| ty::TraitRef {
112             def_id: sized_trait,
113             substs: tcx.mk_substs_trait(ty.expect_ty(), ty::List::empty()),
114         })
115         .map(|trait_ref| ty::TraitPredicate { trait_ref })
116         .map(|predicate| predicate.lower());
117
118     let wf_clause = ProgramClause {
119         goal: DomainGoal::WellFormed(WellFormed::Ty(tuple_ty)),
120         hypotheses: tcx.mk_goals(
121             sized_implemented.map(|domain_goal| tcx.mk_goal(GoalKind::DomainGoal(domain_goal))),
122         ),
123         category: ProgramClauseCategory::WellFormed,
124     };
125     let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
126
127     // ```
128     // forall<T1, ..., Tn-1, Tn> {
129     //     WellFormed((T1, ..., Tn)) :-
130     //         Implemented(T1: Sized),
131     //         ...
132     //         Implemented(Tn-1: Sized).
133     // }
134     // ```
135     tcx.mk_clauses(iter::once(wf_clause))
136 }
137
138 crate fn wf_clause_for_ref(tcx: TyCtxt<'_>, mutbl: hir::Mutability) -> Clauses<'_> {
139     let region = tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0)));
140     let ty = generic_types::bound(tcx, 1);
141     let ref_ty = tcx.mk_ref(region, ty::TypeAndMut { ty, mutbl });
142
143     let outlives: DomainGoal<'_> = ty::OutlivesPredicate(ty, region).lower();
144     let wf_clause = ProgramClause {
145         goal: DomainGoal::WellFormed(WellFormed::Ty(ref_ty)),
146         hypotheses: tcx.mk_goals(iter::once(tcx.mk_goal(outlives.into_goal()))),
147         category: ProgramClauseCategory::WellFormed,
148     };
149     let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
150
151     // `forall<'a, T> { WellFormed(&'a T) :- Outlives(T: 'a). }`
152     tcx.mk_clauses(iter::once(wf_clause))
153 }
154
155 crate fn wf_clause_for_fn_def(tcx: TyCtxt<'_>, def_id: DefId) -> Clauses<'_> {
156     let fn_def = generic_types::fn_def(tcx, def_id);
157
158     let wf_clause = ProgramClause {
159         goal: DomainGoal::WellFormed(WellFormed::Ty(fn_def)),
160         hypotheses: ty::List::empty(),
161         category: ProgramClauseCategory::WellFormed,
162     };
163     let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
164
165     // `forall <T1, ..., Tn+1> { WellFormed(fn some_fn(T1, ..., Tn) -> Tn+1). }`
166     // where `def_id` maps to the `some_fn` function definition
167     tcx.mk_clauses(iter::once(wf_clause))
168 }