1 use rustc_hir
::{Movability, Mutability}
;
2 use rustc_infer
::{infer::InferCtxt, traits::query::NoSolution}
;
3 use rustc_middle
::ty
::{self, Ty, TyCtxt}
;
5 // Calculates the constituent types of a type for `auto trait` purposes.
7 // For types with an "existential" binder, i.e. generator witnesses, we also
8 // instantiate the binder with placeholders eagerly.
9 pub(super) fn instantiate_constituent_tys_for_auto_trait
<'tcx
>(
10 infcx
: &InferCtxt
<'tcx
>,
12 ) -> Result
<Vec
<Ty
<'tcx
>>, NoSolution
> {
23 | ty
::Infer(ty
::IntVar(_
) | ty
::FloatVar(_
))
25 | ty
::Char
=> Ok(vec
![]),
31 | ty
::Alias(ty
::Projection
, ..)
33 | ty
::Infer(ty
::TyVar(_
)) => Err(NoSolution
),
35 ty
::Infer(ty
::FreshTy(_
) | ty
::FreshIntTy(_
) | ty
::FreshFloatTy(_
)) => bug
!(),
37 ty
::RawPtr(ty
::TypeAndMut { ty: element_ty, .. }
) | ty
::Ref(_
, element_ty
, _
) => {
41 ty
::Array(element_ty
, _
) | ty
::Slice(element_ty
) => Ok(vec
![element_ty
]),
43 ty
::Tuple(ref tys
) => {
44 // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
45 Ok(tys
.iter().collect())
48 ty
::Closure(_
, ref substs
) => Ok(vec
![substs
.as_closure().tupled_upvars_ty()]),
50 ty
::Generator(_
, ref substs
, _
) => {
51 let generator_substs
= substs
.as_generator();
52 Ok(vec
![generator_substs
.tupled_upvars_ty(), generator_substs
.witness()])
55 ty
::GeneratorWitness(types
) => {
56 Ok(infcx
.replace_bound_vars_with_placeholders(types
).to_vec())
59 // For `PhantomData<T>`, we pass `T`.
60 ty
::Adt(def
, substs
) if def
.is_phantom_data() => Ok(vec
![substs
.type_at(0)]),
62 ty
::Adt(def
, substs
) => Ok(def
.all_fields().map(|f
| f
.ty(tcx
, substs
)).collect()),
64 ty
::Alias(ty
::Opaque
, ty
::AliasTy { def_id, substs, .. }
) => {
65 // We can resolve the `impl Trait` to its concrete type,
66 // which enforces a DAG between the functions requiring
67 // the auto trait bounds in question.
68 Ok(vec
![tcx
.bound_type_of(def_id
).subst(tcx
, substs
)])
73 pub(super) fn instantiate_constituent_tys_for_sized_trait
<'tcx
>(
74 infcx
: &InferCtxt
<'tcx
>,
76 ) -> Result
<Vec
<Ty
<'tcx
>>, NoSolution
> {
78 ty
::Infer(ty
::IntVar(_
) | ty
::FloatVar(_
))
89 | ty
::GeneratorWitness(..)
93 | ty
::Dynamic(_
, _
, ty
::DynStar
)
94 | ty
::Error(_
) => Ok(vec
![]),
102 | ty
::Infer(ty
::TyVar(_
)) => Err(NoSolution
),
106 | ty
::Infer(ty
::FreshTy(_
) | ty
::FreshIntTy(_
) | ty
::FreshFloatTy(_
)) => bug
!(),
108 ty
::Tuple(tys
) => Ok(tys
.to_vec()),
110 ty
::Adt(def
, substs
) => {
111 let sized_crit
= def
.sized_constraint(infcx
.tcx
);
115 .map(|ty
| sized_crit
.rebind(*ty
).subst(infcx
.tcx
, substs
))
121 pub(super) fn instantiate_constituent_tys_for_copy_clone_trait
<'tcx
>(
122 infcx
: &InferCtxt
<'tcx
>,
124 ) -> Result
<Vec
<Ty
<'tcx
>>, NoSolution
> {
126 ty
::Infer(ty
::IntVar(_
) | ty
::FloatVar(_
))
129 | ty
::Error(_
) => Ok(vec
![]),
131 // Implementations are provided in core
139 | ty
::Ref(_
, _
, Mutability
::Not
)
140 | ty
::Array(..) => Err(NoSolution
),
145 | ty
::Generator(_
, _
, Movability
::Static
)
147 | ty
::Ref(_
, _
, Mutability
::Mut
)
151 | ty
::Infer(ty
::TyVar(_
)) => Err(NoSolution
),
155 | ty
::Infer(ty
::FreshTy(_
) | ty
::FreshIntTy(_
) | ty
::FreshFloatTy(_
)) => bug
!(),
157 ty
::Tuple(tys
) => Ok(tys
.to_vec()),
159 ty
::Closure(_
, substs
) => Ok(vec
![substs
.as_closure().tupled_upvars_ty()]),
161 ty
::Generator(_
, substs
, Movability
::Movable
) => {
162 if infcx
.tcx
.features().generator_clone
{
163 let generator
= substs
.as_generator();
164 Ok(vec
![generator
.tupled_upvars_ty(), generator
.witness()])
170 ty
::GeneratorWitness(types
) => {
171 Ok(infcx
.replace_bound_vars_with_placeholders(types
).to_vec())
176 pub(crate) fn extract_tupled_inputs_and_output_from_callable
<'tcx
>(
179 goal_kind
: ty
::ClosureKind
,
180 ) -> Result
<Option
<ty
::Binder
<'tcx
, (Ty
<'tcx
>, Ty
<'tcx
>)>>, NoSolution
> {
181 match *self_ty
.kind() {
182 ty
::FnDef(def_id
, substs
) => Ok(Some(
183 tcx
.bound_fn_sig(def_id
)
185 .map_bound(|sig
| (tcx
.mk_tup(sig
.inputs().iter()), sig
.output())),
188 Ok(Some(sig
.map_bound(|sig
| (tcx
.mk_tup(sig
.inputs().iter()), sig
.output()))))
190 ty
::Closure(_
, substs
) => {
191 let closure_substs
= substs
.as_closure();
192 match closure_substs
.kind_ty().to_opt_closure_kind() {
193 Some(closure_kind
) if closure_kind
.extends(goal_kind
) => {}
194 None
=> return Ok(None
),
195 _
=> return Err(NoSolution
),
197 Ok(Some(closure_substs
.sig().map_bound(|sig
| (sig
.inputs()[0], sig
.output()))))
211 | ty
::Dynamic(_
, _
, _
)
212 | ty
::Generator(_
, _
, _
)
213 | ty
::GeneratorWitness(_
)
221 | ty
::Error(_
) => Err(NoSolution
),