Repository: astral-sh/ruff
File: crates/ty_python_semantic/src/types/infer/builder.rs (Rust)

Code before:
                let inferred_elt_ty = infer_elt_expression(self, elt, elt_tcx);

                // Simplify the inference based on the declared type of the element.
                if let Some(elt_tcx) = elt_tcx.annotation {
                    if inferred_elt_ty.is_assignable_to(self.db(), elt_tcx) {
                        continue;
                    }
                }

                // Convert any element literals to their promoted type form to avoid excessively large
                // unions for large nested list literals, which the constraint solver struggles with.
                let inferred_elt_ty = inferred_elt_ty.promote_literals(self.db(), elt_tcx);

                builder.infer(Type::TypeVar(elt_ty), inferred_elt_ty).ok()?;
            }
        }

        let class_type = class_literal.apply_specialization(self.db(), |_| {
            builder.build(generic_context, TypeContext::default())
        });

        Type::from(class_type).to_instance(self.db())
    }

    /// Infer the type of the `iter` expression of the first comprehension.
    fn infer_first_comprehension_iter(&mut self, comprehensions: &[ast::Comprehension]) -> bool {
        let mut comprehensions_iter = comprehensions.iter();
        let Some(first_comprehension) = comprehensions_iter.next() else {
            unreachable!("Comprehension must contain at least one generator");
        };
        self.infer_standalone_expression(&first_comprehension.iter, TypeContext::default());

        first_comprehension.is_async
    }

    fn infer_generator_expression(&mut self, generator: &ast::ExprGenerator) -> Type<'db> {
        let ast::ExprGenerator {
            range: _,
            node_index: _,
            elt,
            generators,
            parenthesized: _,
        } = generator;

        let is_async = self.infer_first_comprehension_iter(generators);

        let scope_id = self
            .index
            .node_scope(NodeWithScopeRef::GeneratorExpression(generator));
        let scope = scope_id.to_scope_id(self.db(), self.file());
        let inference = infer_scope_types(self.db(), scope);

Review comment (suggestion):
What about

```diff
diff --git a/crates/ty_python_semantic/src/types/infer/builder.rs b/crates/ty_python_semantic/src/types/infer/builder.rs
index d9894f9c54..8cef32101a 100644
--- a/crates/ty_python_semantic/src/types/infer/builder.rs
+++ b/crates/ty_python_semantic/src/types/infer/builder.rs
@@ -7392,14 +7392,19 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
     }
 
     /// Infer the type of the `iter` expression of the first comprehension.
-    fn infer_first_comprehension_iter(&mut self, comprehensions: &[ast::Comprehension]) -> bool {
+    /// Returns the evaluation mode (async or sync) of the comprehension.
+    fn infer_first_comprehension_iter(&mut self, comprehensions: &[ast::Comprehension]) -> EvaluationMode {
         let mut comprehensions_iter = comprehensions.iter();
         let Some(first_comprehension) = comprehensions_iter.next() else {
             unreachable!("Comprehension must contain at least one generator");
         };
         self.infer_standalone_expression(&first_comprehension.iter, TypeContext::default());
 
-        first_comprehension.is_async
+        if first_comprehension.is_async {
+            EvaluationMode::Async
+        } else {
+            EvaluationMode::Sync
+        }
     }
 
     fn infer_generator_expression(&mut self, generator: &ast::ExprGenerator) -> Type<'db> {
@@ -7411,7 +7416,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
             parenthesized: _,
         } = generator;
 
-        let is_async = self.infer_first_comprehension_iter(generators);
+        let evaluation_mode = self.infer_first_comprehension_iter(generators);
 
         let scope_id = self
             .index
@@ -7420,7 +7425,7 @@ impl<'db, 'ast> TypeInferenceBuilder<'db, 'ast> {
         let inference = infer_scope_types(self.db(), scope);
         let yield_type = inference.expression_type(elt.as_ref());
 
-        if is_async {
+        if evaluation_mode.is_async() {
             KnownClass::AsyncGeneratorType
                 .to_specialized_instance(self.db(), [yield_type, Type::none(self.db())])
         } else {
```

Code after:
                let inferred_elt_ty = infer_elt_expression(self, elt, elt_tcx);

                // Simplify the inference based on the declared type of the element.
                if let Some(elt_tcx) = elt_tcx.annotation {
                    if inferred_elt_ty.is_assignable_to(self.db(), elt_tcx) {
                        continue;
                    }
                }

                // Convert any element literals to their promoted type form to avoid excessively large
                // unions for large nested list literals, which the constraint solver struggles with.
                let inferred_elt_ty = inferred_elt_ty.promote_literals(self.db(), elt_tcx);

                builder.infer(Type::TypeVar(elt_ty), inferred_elt_ty).ok()?;
            }
        }

        let class_type = class_literal.apply_specialization(self.db(), |_| {
            builder.build(generic_context, TypeContext::default())
        });

        Type::from(class_type).to_instance(self.db())
    }

    /// Infer the type of the `iter` expression of the first comprehension.
    /// Returns the evaluation mode (async or sync) of the comprehension.
    fn infer_first_comprehension_iter(
        &mut self,
        comprehensions: &[ast::Comprehension],
    ) -> EvaluationMode {
        let mut comprehensions_iter = comprehensions.iter();
        let Some(first_comprehension) = comprehensions_iter.next() else {
            unreachable!("Comprehension must contain at least one generator");
        };
        self.infer_standalone_expression(&first_comprehension.iter, TypeContext::default());

        if first_comprehension.is_async {
            EvaluationMode::Async
        } else {
            EvaluationMode::Sync
        }
    }

    fn infer_generator_expression(&mut self, generator: &ast::ExprGenerator) -> Type<'db> {
        let ast::ExprGenerator {
            range: _,
            node_index: _,
            elt,
            generators,
            parenthesized: _,
        } = generator;