diff options
Diffstat (limited to 'compiler/rustc_trait_selection')
12 files changed, 76 insertions, 11 deletions
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs index 915d722dd02..e1c68039e79 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs @@ -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 diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index 274a75a125c..3c571e1d96f 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -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(_) diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs index 9f1b4a09a20..e1c6f67f05e 100644 --- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs @@ -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(..) diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index b185e4e5f8e..efaad47b6dd 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -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 diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index c49185a52c7..4b20de26219 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -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 { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index d57d9f58333..1ac0f172ef4 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -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, } } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index abbc2066eac..a960befcd4b 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -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 diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 79f03242c58..6c8834f11f1 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -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 diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 12aea88e9b6..b354ebf111f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -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 diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 6a6adcbb680..e79277b89c4 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -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(); diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index d5a37e63d87..89459f377dd 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -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); } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 0f8d9c6bf4b..88584a61b13 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -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 |
