import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;
import org.springframework.core.GenericTypeResolver;

public class Main {
    public interface Parent<T> {
        T m1();
        List<T> m2();
        List<List<T>> m3();
    }
    public interface Child extends Parent<String> {
    }
    public static void main(String[] args) {
        for (Method m : Parent.class.getMethods()) {
            Type type = m.getGenericReturnType();
            type = GenericTypeResolver.resolveType(type, Child.class);
            System.out.println("method " + m.getName() + "() will return " + type);
        }
    }
}

will print

method m3() will return java.util.List<java.util.List<T>>
method m1() will return class java.lang.String
method m2() will return java.util.List<java.lang.String>

The expected type for m3 should be java.util.List<java.util.List<String>>

Comment From: quaff

Type type = m.getGenericReturnType(); // List<List<T>>
ResolvableType.forType(type).hasUnresolvableGenerics(); //should be true but false

Comment From: quaff

Here is my workaround

    public static Type resolve(Type type, Class<?> contextClass) {
        if (type instanceof ParameterizedType) {
            ParameterizedType pt = (ParameterizedType) type;
            ResolvableType[] generics = new ResolvableType[pt.getActualTypeArguments().length];
            int i = 0;
            for (Type arg : pt.getActualTypeArguments()) {
                generics[i++] = ResolvableType.forType(resolve(arg, contextClass));
            }
            return ResolvableType.forClassWithGenerics((Class<?>) pt.getRawType(), generics).getType();
        }
        return GenericTypeResolver.resolveType(type, contextClass);
    }

Comment From: quaff

Any update?

Comment From: quaff

Superseded by https://github.com/spring-projects/spring-framework/pull/30079