Skip to content

Commit 66b4a08

Browse files
committed
Reorganize chalk_context::program_clauses
1 parent 60ea7cb commit 66b4a08

File tree

3 files changed

+343
-319
lines changed

3 files changed

+343
-319
lines changed
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
use rustc::traits::{
2+
GoalKind,
3+
Clause,
4+
ProgramClause,
5+
ProgramClauseCategory,
6+
};
7+
use rustc::ty;
8+
use rustc::ty::subst::{InternalSubsts, Subst};
9+
use rustc::hir::def_id::DefId;
10+
use crate::lowering::Lower;
11+
use crate::generic_types;
12+
13+
crate fn assemble_builtin_sized_impls<'tcx>(
14+
tcx: ty::TyCtxt<'_, '_, 'tcx>,
15+
sized_def_id: DefId,
16+
ty: ty::Ty<'tcx>,
17+
clauses: &mut Vec<Clause<'tcx>>
18+
) {
19+
let mut push_builtin_impl = |ty: ty::Ty<'tcx>, nested: &[ty::Ty<'tcx>]| {
20+
let clause = ProgramClause {
21+
goal: ty::TraitPredicate {
22+
trait_ref: ty::TraitRef {
23+
def_id: sized_def_id,
24+
substs: tcx.mk_substs_trait(ty, &[]),
25+
},
26+
}.lower(),
27+
hypotheses: tcx.mk_goals(
28+
nested.iter()
29+
.cloned()
30+
.map(|nested_ty| ty::TraitRef {
31+
def_id: sized_def_id,
32+
substs: tcx.mk_substs_trait(nested_ty, &[]),
33+
})
34+
.map(|trait_ref| ty::TraitPredicate { trait_ref })
35+
.map(|pred| GoalKind::DomainGoal(pred.lower()))
36+
.map(|goal_kind| tcx.mk_goal(goal_kind))
37+
),
38+
category: ProgramClauseCategory::Other,
39+
};
40+
// Bind innermost bound vars that may exist in `ty` and `nested`.
41+
clauses.push(Clause::ForAll(ty::Binder::bind(clause)));
42+
};
43+
44+
match &ty.sty {
45+
// Non parametric primitive types.
46+
ty::Bool |
47+
ty::Char |
48+
ty::Int(..) |
49+
ty::Uint(..) |
50+
ty::Float(..) |
51+
ty::Error |
52+
ty::Never => push_builtin_impl(ty, &[]),
53+
54+
// These ones are always `Sized`.
55+
&ty::Array(_, length) => {
56+
push_builtin_impl(tcx.mk_ty(ty::Array(generic_types::bound(tcx, 0), length)), &[]);
57+
}
58+
ty::RawPtr(ptr) => {
59+
push_builtin_impl(generic_types::raw_ptr(tcx, ptr.mutbl), &[]);
60+
}
61+
&ty::Ref(_, _, mutbl) => {
62+
push_builtin_impl(generic_types::ref_ty(tcx, mutbl), &[]);
63+
}
64+
ty::FnPtr(fn_ptr) => {
65+
let fn_ptr = fn_ptr.skip_binder();
66+
let fn_ptr = generic_types::fn_ptr(
67+
tcx,
68+
fn_ptr.inputs_and_output.len(),
69+
fn_ptr.c_variadic,
70+
fn_ptr.unsafety,
71+
fn_ptr.abi
72+
);
73+
push_builtin_impl(fn_ptr, &[]);
74+
}
75+
&ty::FnDef(def_id, ..) => {
76+
push_builtin_impl(generic_types::fn_def(tcx, def_id), &[]);
77+
}
78+
&ty::Closure(def_id, ..) => {
79+
push_builtin_impl(generic_types::closure(tcx, def_id), &[]);
80+
}
81+
&ty::Generator(def_id, ..) => {
82+
push_builtin_impl(generic_types::generator(tcx, def_id), &[]);
83+
}
84+
85+
// `Sized` if the last type is `Sized` (because else we will get a WF error anyway).
86+
&ty::Tuple(type_list) => {
87+
let type_list = generic_types::type_list(tcx, type_list.len());
88+
push_builtin_impl(tcx.mk_ty(ty::Tuple(type_list)), &**type_list);
89+
}
90+
91+
// Struct def
92+
ty::Adt(adt_def, _) => {
93+
let substs = InternalSubsts::bound_vars_for_item(tcx, adt_def.did);
94+
let adt = tcx.mk_ty(ty::Adt(adt_def, substs));
95+
let sized_constraint = adt_def.sized_constraint(tcx)
96+
.iter()
97+
.map(|ty| ty.subst(tcx, substs))
98+
.collect::<Vec<_>>();
99+
push_builtin_impl(adt, &sized_constraint);
100+
}
101+
102+
// Artificially trigger an ambiguity.
103+
ty::Infer(..) => {
104+
// Everybody can find at least two types to unify against:
105+
// general ty vars, int vars and float vars.
106+
push_builtin_impl(tcx.types.i32, &[]);
107+
push_builtin_impl(tcx.types.u32, &[]);
108+
push_builtin_impl(tcx.types.f32, &[]);
109+
push_builtin_impl(tcx.types.f64, &[]);
110+
}
111+
112+
ty::Projection(_projection_ty) => {
113+
// FIXME: add builtin impls from the associated type values found in
114+
// trait impls of `projection_ty.trait_ref(tcx)`.
115+
}
116+
117+
// The `Sized` bound can only come from the environment.
118+
ty::Param(..) |
119+
ty::Placeholder(..) |
120+
ty::UnnormalizedProjection(..) => (),
121+
122+
// Definitely not `Sized`.
123+
ty::Foreign(..) |
124+
ty::Str |
125+
ty::Slice(..) |
126+
ty::Dynamic(..) |
127+
ty::Opaque(..) => (),
128+
129+
ty::Bound(..) |
130+
ty::GeneratorWitness(..) => bug!("unexpected type {:?}", ty),
131+
}
132+
}

0 commit comments

Comments
 (0)