7 use rustc
::ty
::{self, Ty, TyCtxt}
;
8 use rustc
::ty
::subst
::{GenericArg, InternalSubsts, Subst}
;
10 use rustc
::hir
::def_id
::DefId
;
11 use crate::lowering
::Lower
;
12 use crate::generic_types
;
14 /// Returns a predicate of the form
15 /// `Implemented(ty: Trait) :- Implemented(nested: Trait)...`
16 /// where `Trait` is specified by `trait_def_id`.
17 fn builtin_impl_clause(
20 nested
: &[GenericArg
<'tcx
>],
22 ) -> ProgramClause
<'tcx
> {
24 goal
: ty
::TraitPredicate
{
25 trait_ref
: ty
::TraitRef
{
27 substs
: tcx
.mk_substs_trait(ty
, &[]),
30 hypotheses
: tcx
.mk_goals(
33 .map(|nested_ty
| ty
::TraitRef
{
35 substs
: tcx
.mk_substs_trait(nested_ty
.expect_ty(), &[]),
37 .map(|trait_ref
| ty
::TraitPredicate { trait_ref }
)
38 .map(|pred
| GoalKind
::DomainGoal(pred
.lower()))
39 .map(|goal_kind
| tcx
.mk_goal(goal_kind
))
41 category
: ProgramClauseCategory
::Other
,
45 crate fn assemble_builtin_unsize_impls
<'tcx
>(
50 clauses
: &mut Vec
<Clause
<'tcx
>>,
52 match (&source
.kind
, &target
.kind
) {
53 (ty
::Dynamic(data_a
, ..), ty
::Dynamic(data_b
, ..)) => {
54 if data_a
.principal_def_id() != data_b
.principal_def_id()
55 || data_b
.auto_traits().any(|b
| data_a
.auto_traits().all(|a
| a
!= b
))
60 // FIXME: rules for trait upcast
63 (_
, &ty
::Dynamic(..)) => {
64 // FIXME: basically, we should have something like:
67 // Implemented(T: Unsize< for<...> dyn Trait<...> >) :-
68 // for<...> Implemented(T: Trait<...>).
71 // The question is: how to correctly handle the higher-ranked
72 // `for<...>` binder in order to have a generic rule?
73 // (Having generic rules is useful for caching, as we may be able
74 // to turn this function and others into tcx queries later on).
77 (ty
::Array(_
, length
), ty
::Slice(_
)) => {
78 let ty_param
= generic_types
::bound(tcx
, 0);
79 let array_ty
= tcx
.mk_ty(ty
::Array(ty_param
, length
));
80 let slice_ty
= tcx
.mk_ty(ty
::Slice(ty_param
));
82 // `forall<T> { Implemented([T; N]: Unsize<[T]>). }`
83 let clause
= ProgramClause
{
84 goal
: ty
::TraitPredicate
{
85 trait_ref
: ty
::TraitRef
{
86 def_id
: unsize_def_id
,
87 substs
: tcx
.mk_substs_trait(array_ty
, &[slice_ty
.into()])
90 hypotheses
: ty
::List
::empty(),
91 category
: ProgramClauseCategory
::Other
,
94 clauses
.push(Clause
::ForAll(ty
::Binder
::bind(clause
)));
97 (ty
::Infer(ty
::TyVar(_
)), _
) | (_
, ty
::Infer(ty
::TyVar(_
))) => {
101 (ty
::Adt(def_id_a
, ..), ty
::Adt(def_id_b
, ..)) => {
102 if def_id_a
!= def_id_b
{
106 // FIXME: rules for struct unsizing
109 (&ty
::Tuple(tys_a
), &ty
::Tuple(tys_b
)) => {
110 if tys_a
.len() != tys_b
.len() {
114 // FIXME: rules for tuple unsizing
121 crate fn assemble_builtin_sized_impls
<'tcx
>(
125 clauses
: &mut Vec
<Clause
<'tcx
>>,
127 let mut push_builtin_impl
= |ty
: Ty
<'tcx
>, nested
: &[GenericArg
<'tcx
>]| {
128 let clause
= builtin_impl_clause(tcx
, ty
, nested
, sized_def_id
);
129 // Bind innermost bound vars that may exist in `ty` and `nested`.
130 clauses
.push(Clause
::ForAll(ty
::Binder
::bind(clause
)));
134 // Non parametric primitive types.
140 ty
::Infer(ty
::IntVar(_
)) |
141 ty
::Infer(ty
::FloatVar(_
)) |
143 ty
::Never
=> push_builtin_impl(ty
, &[]),
145 // These ones are always `Sized`.
146 &ty
::Array(_
, length
) => {
147 push_builtin_impl(tcx
.mk_ty(ty
::Array(generic_types
::bound(tcx
, 0), length
)), &[]);
150 push_builtin_impl(generic_types
::raw_ptr(tcx
, ptr
.mutbl
), &[]);
152 &ty
::Ref(_
, _
, mutbl
) => {
153 push_builtin_impl(generic_types
::ref_ty(tcx
, mutbl
), &[]);
155 ty
::FnPtr(fn_ptr
) => {
156 let fn_ptr
= fn_ptr
.skip_binder();
157 let fn_ptr
= generic_types
::fn_ptr(
159 fn_ptr
.inputs_and_output
.len(),
164 push_builtin_impl(fn_ptr
, &[]);
166 &ty
::FnDef(def_id
, ..) => {
167 push_builtin_impl(generic_types
::fn_def(tcx
, def_id
), &[]);
169 &ty
::Closure(def_id
, ..) => {
170 push_builtin_impl(generic_types
::closure(tcx
, def_id
), &[]);
172 &ty
::Generator(def_id
, ..) => {
173 push_builtin_impl(generic_types
::generator(tcx
, def_id
), &[]);
176 // `Sized` if the last type is `Sized` (because else we will get a WF error anyway).
177 &ty
::Tuple(type_list
) => {
178 let type_list
= generic_types
::type_list(tcx
, type_list
.len());
179 push_builtin_impl(tcx
.mk_ty(ty
::Tuple(type_list
)), &type_list
);
183 ty
::Adt(adt_def
, _
) => {
184 let substs
= InternalSubsts
::bound_vars_for_item(tcx
, adt_def
.did
);
185 let adt
= tcx
.mk_ty(ty
::Adt(adt_def
, substs
));
186 let sized_constraint
= adt_def
.sized_constraint(tcx
)
188 .map(|ty
| GenericArg
::from(ty
.subst(tcx
, substs
)))
189 .collect
::<Vec
<_
>>();
190 push_builtin_impl(adt
, &sized_constraint
);
193 // Artificially trigger an ambiguity by adding two possible types to
195 ty
::Infer(ty
::TyVar(_
)) => {
196 push_builtin_impl(tcx
.types
.i32, &[]);
197 push_builtin_impl(tcx
.types
.f32, &[]);
200 ty
::Projection(_projection_ty
) => {
201 // FIXME: add builtin impls from the associated type values found in
202 // trait impls of `projection_ty.trait_ref(tcx)`.
205 // The `Sized` bound can only come from the environment.
207 ty
::Placeholder(..) |
208 ty
::UnnormalizedProjection(..) => (),
210 // Definitely not `Sized`.
215 ty
::Opaque(..) => (),
218 ty
::GeneratorWitness(..) |
219 ty
::Infer(ty
::FreshTy(_
)) |
220 ty
::Infer(ty
::FreshIntTy(_
)) |
221 ty
::Infer(ty
::FreshFloatTy(_
)) => bug
!("unexpected type {:?}", ty
),
225 crate fn assemble_builtin_copy_clone_impls
<'tcx
>(
229 clauses
: &mut Vec
<Clause
<'tcx
>>,
231 let mut push_builtin_impl
= |ty
: Ty
<'tcx
>, nested
: &[GenericArg
<'tcx
>]| {
232 let clause
= builtin_impl_clause(tcx
, ty
, nested
, trait_def_id
);
233 // Bind innermost bound vars that may exist in `ty` and `nested`.
234 clauses
.push(Clause
::ForAll(ty
::Binder
::bind(clause
)));
238 // Implementations provided in libcore.
246 ty
::Ref(_
, _
, hir
::Mutability
::Immutable
) => (),
248 // Non parametric primitive types.
249 ty
::Infer(ty
::IntVar(_
)) |
250 ty
::Infer(ty
::FloatVar(_
)) |
251 ty
::Error
=> push_builtin_impl(ty
, &[]),
253 // These implement `Copy`/`Clone` if their element types do.
254 &ty
::Array(_
, length
) => {
255 let element_ty
= generic_types
::bound(tcx
, 0);
257 tcx
.mk_ty(ty
::Array(element_ty
, length
)),
258 &[GenericArg
::from(element_ty
)],
261 &ty
::Tuple(type_list
) => {
262 let type_list
= generic_types
::type_list(tcx
, type_list
.len());
263 push_builtin_impl(tcx
.mk_ty(ty
::Tuple(type_list
)), &**type_list
);
265 &ty
::Closure(def_id
, ..) => {
266 let closure_ty
= generic_types
::closure(tcx
, def_id
);
267 let upvar_tys
: Vec
<_
> = match &closure_ty
.kind
{
268 ty
::Closure(_
, substs
) => {
270 .upvar_tys(def_id
, tcx
)
271 .map(|ty
| GenericArg
::from(ty
))
276 push_builtin_impl(closure_ty
, &upvar_tys
);
279 // These ones are always `Clone`.
280 ty
::FnPtr(fn_ptr
) => {
281 let fn_ptr
= fn_ptr
.skip_binder();
282 let fn_ptr
= generic_types
::fn_ptr(
284 fn_ptr
.inputs_and_output
.len(),
289 push_builtin_impl(fn_ptr
, &[]);
291 &ty
::FnDef(def_id
, ..) => {
292 push_builtin_impl(generic_types
::fn_def(tcx
, def_id
), &[]);
295 // These depend on whatever user-defined impls might exist.
298 // Artificially trigger an ambiguity by adding two possible types to
300 ty
::Infer(ty
::TyVar(_
)) => {
301 push_builtin_impl(tcx
.types
.i32, &[]);
302 push_builtin_impl(tcx
.types
.f32, &[]);
305 ty
::Projection(_projection_ty
) => {
306 // FIXME: add builtin impls from the associated type values found in
307 // trait impls of `projection_ty.trait_ref(tcx)`.
310 // The `Copy`/`Clone` bound can only come from the environment.
312 ty
::Placeholder(..) |
313 ty
::UnnormalizedProjection(..) |
314 ty
::Opaque(..) => (),
316 // Definitely not `Copy`/`Clone`.
322 ty
::Ref(_
, _
, hir
::Mutability
::Mutable
) => (),
325 ty
::GeneratorWitness(..) |
326 ty
::Infer(ty
::FreshTy(_
)) |
327 ty
::Infer(ty
::FreshIntTy(_
)) |
328 ty
::Infer(ty
::FreshFloatTy(_
)) => bug
!("unexpected type {:?}", ty
),