Repository: python/mypy

Issue:
'got "C[T]", expected "C[T]"' with staticmethod
**Bug Report**

In the below playground link, mypy gives this error:

```
main.py:10: error: Incompatible return value type (got "C[T]", expected "C[T]")  [return-value]
```

I think the program should pass type checking (it does with Pyright), but if there is some problem with it I'm not understanding, at least the error message should be better.

**To Reproduce**

https://mypy-play.net/?mypy=latest&python=3.12&gist=bcfed78680f130f0b4d87886bb196af7

```python
from typing import Generic, TypeVar 
T = TypeVar('T')

class C(Generic[T]):
    @staticmethod
    def c() -> 'C[T]':
        return C()

def f(t: T) -> C[T]:
    return C[T].c()
```

**Your Environment**

- Mypy version used: 1.7.1 on playground
- Mypy command-line flags: -
- Mypy configuration options from `mypy.ini` (and other config files): -
- Python version used: 3.12



Discussion:

Resolving patch:
diff --git a/mypy/checkmember.py b/mypy/checkmember.py
--- a/mypy/checkmember.py
+++ b/mypy/checkmember.py
@@ -1063,11 +1063,14 @@ def analyze_class_attribute_access(
         is_classmethod = (is_decorated and cast(Decorator, node.node).func.is_class) or (
             isinstance(node.node, FuncBase) and node.node.is_class
         )
+        is_staticmethod = (is_decorated and cast(Decorator, node.node).func.is_static) or (
+            isinstance(node.node, FuncBase) and node.node.is_static
+        )
         t = get_proper_type(t)
         if isinstance(t, FunctionLike) and is_classmethod:
             t = check_self_arg(t, mx.self_type, False, mx.context, name, mx.msg)
         result = add_class_tvars(
-            t, isuper, is_classmethod, mx.self_type, original_vars=original_vars
+            t, isuper, is_classmethod, is_staticmethod, mx.self_type, original_vars=original_vars
         )
         if not mx.is_lvalue:
             result = analyze_descriptor_access(result, mx)
@@ -1177,6 +1180,7 @@ def add_class_tvars(
     t: ProperType,
     isuper: Instance | None,
     is_classmethod: bool,
+    is_staticmethod: bool,
     original_type: Type,
     original_vars: Sequence[TypeVarLikeType] | None = None,
 ) -> Type:
@@ -1195,6 +1199,7 @@ class B(A[str]): pass
         isuper: Current instance mapped to the superclass where method was defined, this
             is usually done by map_instance_to_supertype()
         is_classmethod: True if this method is decorated with @classmethod
+        is_staticmethod: True if this method is decorated with @staticmethod
         original_type: The value of the type B in the expression B.foo() or the corresponding
             component in case of a union (this is used to bind the self-types)
         original_vars: Type variables of the class callable on which the method was accessed
@@ -1220,6 +1225,7 @@ class B(A[str]): pass
         t = freshen_all_functions_type_vars(t)
         if is_classmethod:
             t = bind_self(t, original_type, is_classmethod=True)
+        if is_classmethod or is_staticmethod:
             assert isuper is not None
             t = expand_type_by_instance(t, isuper)
         freeze_all_type_vars(t)
@@ -1230,7 +1236,12 @@ class B(A[str]): pass
                 cast(
                     CallableType,
                     add_class_tvars(
-                        item, isuper, is_classmethod, original_type, original_vars=original_vars
+                        item,
+                        isuper,
+                        is_classmethod,
+                        is_staticmethod,
+                        original_type,
+                        original_vars=original_vars,
                     ),
                 )
                 for item in t.items


Test patch:
diff --git a/test-data/unit/check-generics.test b/test-data/unit/check-generics.test
--- a/test-data/unit/check-generics.test
+++ b/test-data/unit/check-generics.test
@@ -2297,6 +2297,19 @@ def func(x: S) -> S:
     return C[S].get()
 [builtins fixtures/classmethod.pyi]
 
+[case testGenericStaticMethodInGenericFunction]
+from typing import Generic, TypeVar
+T = TypeVar('T')
+S = TypeVar('S')
+
+class C(Generic[T]):
+    @staticmethod
+    def get() -> T: ...
+
+def func(x: S) -> S:
+    return C[S].get()
+[builtins fixtures/staticmethod.pyi]
+
 [case testMultipleAssignmentFromAnyIterable]
 from typing import Any
 class A: