@@ -485,6 +485,37 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
485485 )
486486 }
487487
488+ fn consider_builtin_iterator_candidate (
489+ ecx : & mut EvalCtxt < ' _ , ' tcx > ,
490+ goal : Goal < ' tcx , Self > ,
491+ ) -> QueryResult < ' tcx > {
492+ let self_ty = goal. predicate . self_ty ( ) ;
493+ let ty:: Coroutine ( def_id, args, _) = * self_ty. kind ( ) else {
494+ return Err ( NoSolution ) ;
495+ } ;
496+
497+ // Generators are not Iterators unless they come from `gen` desugaring
498+ let tcx = ecx. tcx ( ) ;
499+ if !tcx. coroutine_is_gen ( def_id) {
500+ return Err ( NoSolution ) ;
501+ }
502+
503+ let term = args. as_coroutine ( ) . yield_ty ( ) . into ( ) ;
504+
505+ Self :: consider_implied_clause (
506+ ecx,
507+ goal,
508+ ty:: ProjectionPredicate {
509+ projection_ty : ty:: AliasTy :: new ( ecx. tcx ( ) , goal. predicate . def_id ( ) , [ self_ty] ) ,
510+ term,
511+ }
512+ . to_predicate ( tcx) ,
513+ // Technically, we need to check that the iterator type is Sized,
514+ // but that's already proven by the generator being WF.
515+ [ ] ,
516+ )
517+ }
518+
488519 fn consider_builtin_coroutine_candidate (
489520 ecx : & mut EvalCtxt < ' _ , ' tcx > ,
490521 goal : Goal < ' tcx , Self > ,
@@ -496,7 +527,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
496527
497528 // `async`-desugared coroutines do not implement the coroutine trait
498529 let tcx = ecx. tcx ( ) ;
499- if tcx. coroutine_is_async ( def_id) {
530+ if tcx. coroutine_is_async ( def_id) || tcx . coroutine_is_gen ( def_id ) {
500531 return Err ( NoSolution ) ;
501532 }
502533
@@ -523,7 +554,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
523554 term,
524555 }
525556 . to_predicate ( tcx) ,
526- // Technically, we need to check that the future type is Sized,
557+ // Technically, we need to check that the coroutine type is Sized,
527558 // but that's already proven by the coroutine being WF.
528559 [ ] ,
529560 )
0 commit comments