Do not apply var where the declaration cannot legally carry it - #1221
Merged
Conversation
A C-style array declarator keeps its brackets after the variable name, so replacing the type with `var` produces `var address[] = new int[8]`, which is not legal. The check belongs in the shared applicability gate rather than one recipe, since object declarations reach it the same way. Normalizing the declarator instead would need a further guard, because a bare array initializer has no target type to infer from. A type witness is only legal on a qualified invocation, so an unqualified generic call whose return type still mentions a type variable cannot be given one. Suppressing only the witness would not be enough either: without the declared target type the variable would silently re-infer to Object.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
var address[] = new int[8]for C-style array declarators #1218var x = <T>foo(...)#1219Two declaration shapes cannot legally carry
var, and thelang.varrecipes rewrite both into source that does not compile.C-style array declarators
A declarator that keeps its brackets after the variable name:
becomes
which is a compile-time error — a
vardeclarator may not have extra array dimension brackets (JLS 14.4.1).The guard goes in
DeclarationCheck.isVarApplicablerather than inUseVarForPrimitive, for two reasons.UseVarForObjectreaches the same shape (String s[] = getStrings();producedvar s[] = ...just as badly), andisVarApplicableis already where every sibling recipe bails out for fields, parameters, multiple declarators and ternaries — this is the same class of "varis not legal here" constraint.Bailing out rather than normalizing to
var address = new int[8]is deliberate: normalizing is not uniformly safe, becauseint a[] = {1, 2, 3};cannot becomevar a = {1, 2, 3};— a bare array initializer has no target type to infer from. A normalizing fix would need its own additional guard; bailing needs none.Type witnesses on unqualified invocations
A type witness is only legal on a qualified invocation —
this.<T>foo(),Type.<T>foo(),super.<T>foo().UseVarForGenericMethodInvocationsemitted one on an unqualified call:became
which does not parse (JLS 15.12 — type arguments follow the
.of a qualified invocation).The guard is narrower than "skip when there is no
select". That would regress the existingwithOwnFactoryMethodscase, whereList<String> strs = myList("one", "two")legally becomesvarbecauseTis inferable from the arguments and no witness is needed. The witness is only ever synthesized when the resolved return type still mentions a type variable, so that is what the guard keys on.Suppressing only the witness would not have been enough either: without the declared target type,
Tre-infers toObjectand the variable silently changes type. Skipping the transformation is the correct outcome.Tests
Added to the existing
NotApplicablenested classes in both test files. Fulllang.varpackage: 113 tests, 0 failures. Both new tests fail without the corresponding fix.Found by compiling the output of
UpgradeToJava25across a set of open source repositories.