diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 39a106ac0ec..6e9cf422d5c 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -2497,13 +2497,20 @@ && getType(nameExpr).equals(STRING_TYPE)) { } if (!candidates.isEmpty()) { - Map gts = GenericsUtils.extractPlaceholders(receiverType); - stubMissingTypeVariables(receiverType.redirect().getGenericsTypes(), gts); // GROOVY-11241 - candidates.stream().map(candidate -> applyGenericsContext(gts, candidate.getReturnType())) - .reduce(WideningCategories::lowestUpperBound).ifPresent(returnType -> { - ClassNode closureType = wrapClosureType(returnType); - storeType(expression, closureType); - }); + stubMissingTypeVariables(receiverType.redirect().getGenericsTypes(), GenericsUtils.extractPlaceholders(receiverType)); // GROOVY-11241 + + ClassNode commonReturnType = null; + for (MethodNode candidate : candidates) { + ClassNode returnType = candidate.getReturnType(); + if (!candidate.isStatic() && GenericsUtils.hasUnresolvedGenerics(returnType)) { + Map spec = new HashMap<>(); // GROOVY-11364 + extractGenericsConnections(spec, receiverType, candidate.getDeclaringClass()); + returnType = applyGenericsContext(spec, returnType); + } + commonReturnType = (commonReturnType == null ? returnType + : lowestUpperBound(commonReturnType, returnType)); + } + storeType(expression, wrapClosureType(commonReturnType)); expression.putNodeMetaData(MethodNode.class, candidates); } else if (!(expression instanceof MethodReferenceExpression)) { ClassNode type = wrapTypeIfNecessary(getType(expression.getExpression()));