Add CoroutineClosure to TyKind, AggregateKind, UpvarArgs
This commit is contained in:
parent
a20421734b
commit
c567eddec2
91 changed files with 579 additions and 101 deletions
|
@ -340,7 +340,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::Never
|
||||
| ty::Tuple(_) => {
|
||||
|
@ -538,6 +539,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
| ty::FnPtr(_)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
@ -694,6 +696,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
| ty::FnPtr(_)
|
||||
| ty::Alias(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
|
|
@ -57,6 +57,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
|
|||
|
||||
ty::Closure(_, args) => Ok(vec![args.as_closure().tupled_upvars_ty()]),
|
||||
|
||||
ty::CoroutineClosure(_, args) => Ok(vec![args.as_coroutine_closure().tupled_upvars_ty()]),
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
let coroutine_args = args.as_coroutine();
|
||||
Ok(vec![coroutine_args.tupled_upvars_ty(), coroutine_args.witness()])
|
||||
|
@ -128,6 +130,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
|
|||
| ty::CoroutineWitness(..)
|
||||
| ty::Array(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Never
|
||||
| ty::Dynamic(_, _, ty::DynStar)
|
||||
| ty::Error(_) => Ok(vec![]),
|
||||
|
@ -193,6 +196,8 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
|
|||
|
||||
ty::Closure(_, args) => Ok(vec![args.as_closure().tupled_upvars_ty()]),
|
||||
|
||||
ty::CoroutineClosure(..) => Err(NoSolution),
|
||||
|
||||
ty::Coroutine(def_id, args) => match ecx.tcx().coroutine_movability(def_id) {
|
||||
Movability::Static => Err(NoSolution),
|
||||
Movability::Movable => {
|
||||
|
@ -267,6 +272,10 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
|
|||
}
|
||||
Ok(Some(closure_args.sig().map_bound(|sig| (sig.inputs()[0], sig.output()))))
|
||||
}
|
||||
|
||||
// Coroutine closures don't implement `Fn` traits the normal way.
|
||||
ty::CoroutineClosure(..) => Err(NoSolution),
|
||||
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
|
|
|
@ -391,6 +391,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
|
@ -627,6 +628,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
|
|||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
|
|
|
@ -950,7 +950,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
| ty::Ref(_, _, _)
|
||||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
|
|
@ -863,7 +863,7 @@ where
|
|||
}
|
||||
}
|
||||
ty::Error(_) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)),
|
||||
ty::Closure(did, ..) | ty::Coroutine(did, ..) => {
|
||||
ty::Closure(did, ..) | ty::CoroutineClosure(did, ..) | ty::Coroutine(did, ..) => {
|
||||
if self.def_id_is_local(did) {
|
||||
ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
|
||||
} else {
|
||||
|
|
|
@ -959,9 +959,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
) -> Option<ErrorGuaranteed> {
|
||||
if let ty::Closure(closure_def_id, closure_args) = *trait_ref.self_ty().skip_binder().kind()
|
||||
let self_ty = trait_ref.self_ty().skip_binder();
|
||||
if let ty::Closure(closure_def_id, closure_args) = *self_ty.kind()
|
||||
&& let Some(expected_kind) = self.tcx.fn_trait_kind_from_def_id(trait_ref.def_id())
|
||||
&& let Some(found_kind) = self.closure_kind(closure_args)
|
||||
&& let Some(found_kind) = self.closure_kind(self_ty)
|
||||
&& !found_kind.extends(expected_kind)
|
||||
&& let sig = closure_args.as_closure().sig()
|
||||
&& self.can_sub(
|
||||
|
@ -1875,6 +1876,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
ty::Coroutine(..) => Some(18),
|
||||
ty::Foreign(..) => Some(19),
|
||||
ty::CoroutineWitness(..) => Some(20),
|
||||
ty::CoroutineClosure(..) => Some(21),
|
||||
ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1854,6 +1854,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
@ -1903,6 +1904,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
|
|
@ -48,7 +48,11 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
|
|||
// (T1..Tn) and closures have same properties as T1..Tn --
|
||||
// check if *all* of them are trivial.
|
||||
ty::Tuple(tys) => tys.iter().all(|t| trivial_dropck_outlives(tcx, t)),
|
||||
|
||||
ty::Closure(_, args) => trivial_dropck_outlives(tcx, args.as_closure().tupled_upvars_ty()),
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
trivial_dropck_outlives(tcx, args.as_coroutine_closure().tupled_upvars_ty())
|
||||
}
|
||||
|
||||
ty::Adt(def, _) => {
|
||||
if Some(def.did()) == tcx.lang_items().manually_drop() {
|
||||
|
@ -239,6 +243,22 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
|
|||
Ok::<_, NoSolution>(())
|
||||
})?,
|
||||
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
rustc_data_structures::stack::ensure_sufficient_stack(|| {
|
||||
for ty in args.as_coroutine_closure().upvar_tys() {
|
||||
dtorck_constraint_for_ty_inner(
|
||||
tcx,
|
||||
param_env,
|
||||
span,
|
||||
depth + 1,
|
||||
ty,
|
||||
constraints,
|
||||
)?;
|
||||
}
|
||||
Ok::<_, NoSolution>(())
|
||||
})?
|
||||
}
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
// rust-lang/rust#49918: types can be constructed, stored
|
||||
// in the interior, and sit idle when coroutine yields
|
||||
|
|
|
@ -306,11 +306,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// Okay to skip binder because the args on closure types never
|
||||
// touch bound regions, they just capture the in-scope
|
||||
// type/region parameters
|
||||
match *obligation.self_ty().skip_binder().kind() {
|
||||
ty::Closure(def_id, closure_args) => {
|
||||
let self_ty = obligation.self_ty().skip_binder();
|
||||
match *self_ty.kind() {
|
||||
ty::Closure(def_id, _) => {
|
||||
let is_const = self.tcx().is_const_fn_raw(def_id);
|
||||
debug!(?kind, ?obligation, "assemble_unboxed_candidates");
|
||||
match self.infcx.closure_kind(closure_args) {
|
||||
match self.infcx.closure_kind(self_ty) {
|
||||
Some(closure_kind) => {
|
||||
debug!(?closure_kind, "assemble_unboxed_candidates");
|
||||
if closure_kind.extends(kind) {
|
||||
|
@ -488,7 +489,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
| ty::Slice(_)
|
||||
| ty::RawPtr(_)
|
||||
| ty::Ref(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
@ -623,7 +625,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(_)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(_)
|
||||
|
@ -1000,6 +1003,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
| ty::Array(..)
|
||||
| ty::Slice(_)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::Tuple(_)
|
||||
| ty::CoroutineWitness(..) => {
|
||||
|
@ -1076,7 +1080,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
| ty::FnDef(_, _)
|
||||
| ty::FnPtr(_)
|
||||
| ty::Dynamic(_, _, _)
|
||||
| ty::Closure(_, _)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(_, _)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
@ -1139,6 +1144,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
| ty::Placeholder(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Coroutine(..)
|
||||
| ty::CoroutineWitness(..)
|
||||
| ty::Never
|
||||
|
|
|
@ -2106,6 +2106,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
| ty::CoroutineWitness(..)
|
||||
| ty::Array(..)
|
||||
| ty::Closure(..)
|
||||
| ty::CoroutineClosure(..)
|
||||
| ty::Never
|
||||
| ty::Dynamic(_, _, ty::DynStar)
|
||||
| ty::Error(_) => {
|
||||
|
@ -2227,6 +2228,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME(async_closures): These are never clone, for now.
|
||||
ty::CoroutineClosure(_, _) => None,
|
||||
|
||||
ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {
|
||||
// Fallback to whatever user-defined impls exist in this case.
|
||||
None
|
||||
|
@ -2305,6 +2309,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
t.rebind(vec![ty])
|
||||
}
|
||||
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
let ty = self.infcx.shallow_resolve(args.as_coroutine_closure().tupled_upvars_ty());
|
||||
t.rebind(vec![ty])
|
||||
}
|
||||
|
||||
ty::Coroutine(_, args) => {
|
||||
let ty = self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
|
||||
let witness = args.as_coroutine().witness();
|
||||
|
|
|
@ -79,6 +79,9 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
|
|||
ty::Closure(..) => {
|
||||
return ControlFlow::Break(ty);
|
||||
}
|
||||
ty::CoroutineClosure(..) => {
|
||||
return ControlFlow::Break(ty);
|
||||
}
|
||||
ty::Coroutine(..) | ty::CoroutineWitness(..) => {
|
||||
return ControlFlow::Break(ty);
|
||||
}
|
||||
|
|
|
@ -727,6 +727,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
|||
self.out.extend(obligations);
|
||||
}
|
||||
|
||||
ty::CoroutineClosure(did, args) => {
|
||||
// See the above comments.
|
||||
walker.skip_current_subtree();
|
||||
self.compute(args.as_coroutine_closure().tupled_upvars_ty().into());
|
||||
let obligations = self.nominal_obligations(did, args);
|
||||
self.out.extend(obligations);
|
||||
}
|
||||
|
||||
ty::FnPtr(_) => {
|
||||
// let the loop iterate into the argument/return
|
||||
// types appearing in the fn signature
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue