Apply the capture dependency rules only to captured wildcards - #8034
Apply the capture dependency rules only to captured wildcards#8034smillst wants to merge 2 commits into
Conversation
JLS 18.5.2.1 says that when the return type of a poly invocation is a parameterized type G<A1, ..., An> and one of A1, ..., An is a wildcard, fresh inference variables B1, ..., Bn are created along with the bound G<B1, ..., Bn> = capture(G<A1, ..., An>). A variable is created for every type argument, not only for the wildcards. javac creates fewer. Infer#generateReturnConstraints captures the return type and then adds an inference variable only for a type argument that capture conversion replaced, which is only a wildcard. For the return type `Collector<E, ?, List<E>>` of `toImmutableList()` in the new test case, javac adds one variable and the Checker Framework adds three. The extra variables change inference, because the two dependency rules that JLS 18.4 states for a variable on the left-hand side of a capture bound reverse the usual direction of a dependency. For a non-wildcard type argument Ai the bound alphai = Ai holds, so applying those rules makes every variable mentioned in Ai's bounds depend on alphai. In the new test case that puts the variable for `Optional.empty()` in the same resolution set as the variable it is a lower bound of. Resolution then instantiates them together, discards the lower bound `Optional<T>` because it is not proper, and derives the false bound `Optional<Object> <: Optional<Foo>`. Inference reported "type.argument.inference.crashed"; it now infers `Optional<? extends Object>`, as javac does. Apply the two rules only to a variable that captures a wildcard. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 4 included reviews per hour; 1 remains after this review. 📝 WalkthroughWalkthroughThe change records whether capture variables represent wildcard type arguments. Suggested reviewers: Merge Risk: ⚪ Minimal · up to The change is merge-ready after normal checks and review; no actionable merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
JLS 18.5.2.1 says that when the return type of a poly invocation is a parameterized type G<A1, ..., An> and one of A1, ..., An is a wildcard, fresh inference variables B1, ..., Bn are created along with the bound G<B1, ..., Bn> = capture(G<A1, ..., An>). A variable is created for every type argument, not only for the wildcards.
javac creates fewer. Infer#generateReturnConstraints captures the return type and then adds an inference variable only for a type argument that capture conversion replaced, which is only a wildcard. For the return type
Collector<E, ?, List<E>>oftoImmutableList()in the new test case, javac adds one variable and the Checker Framework adds three.The extra variables change inference, because the two dependency rules that JLS 18.4 states for a variable on the left-hand side of a capture bound reverse the usual direction of a dependency. For a non-wildcard type argument Ai the bound alphai = Ai holds, so applying those rules makes every variable mentioned in Ai's bounds depend on alphai. In the new test case that puts the variable for
Optional.empty()in the same resolution set as the variable it is a lower bound of. Resolution then instantiates them together, discards the lower boundOptional<T>because it is not proper, and derives the false boundOptional<Object> <: Optional<Foo>. Inference reported "type.argument.inference.crashed"; it now infersOptional<? extends Object>, as javac does.Apply the two rules only to a variable that captures a wildcard.
Fixes #7694.