mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-13 00:18:59 +00:00
8371683: TYPE_USE annotation on var lambda parameter should be rejected
Reviewed-by: vromero
This commit is contained in:
parent
e92726c352
commit
6c39d1bb73
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -156,12 +156,22 @@ public class Flags {
|
||||
@Use({FlagTarget.CLASS})
|
||||
public static final int IMPLICIT_CLASS = 1<<19;
|
||||
|
||||
/** Variable with implicit/inferred type.
|
||||
*/
|
||||
@Use(FlagTarget.VARIABLE)
|
||||
public static final int VAR_VARIABLE = 1<<19;
|
||||
|
||||
/** Flag is set for compiler-generated anonymous method symbols
|
||||
* that `own' an initializer block.
|
||||
*/
|
||||
@Use({FlagTarget.METHOD})
|
||||
public static final int BLOCK = 1<<20;
|
||||
|
||||
/** A parameter of a lambda function.
|
||||
*/
|
||||
@Use(FlagTarget.VARIABLE)
|
||||
public static final int LAMBDA_PARAMETER = 1<<20;
|
||||
|
||||
/** Flag is set for ClassSymbols that are being compiled from source.
|
||||
*/
|
||||
@Use({FlagTarget.CLASS})
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2002, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -272,6 +272,7 @@ public enum Source {
|
||||
CASE_NULL(JDK21, Fragments.FeatureCaseNull, DiagKind.NORMAL),
|
||||
PATTERN_SWITCH(JDK21, Fragments.FeaturePatternSwitch, DiagKind.PLURAL),
|
||||
REDUNDANT_STRICTFP(JDK17),
|
||||
TYPE_ANNOTATIONS_ON_VAR_LAMBDA_PARAMETER(MIN, JDK19),
|
||||
UNCONDITIONAL_PATTERN_IN_INSTANCEOF(JDK21, Fragments.FeatureUnconditionalPatternsInInstanceof, DiagKind.PLURAL),
|
||||
RECORD_PATTERNS(JDK21, Fragments.FeatureDeconstructionPatterns, DiagKind.PLURAL),
|
||||
IMPLICIT_CLASSES(JDK25, Fragments.FeatureImplicitClasses, DiagKind.PLURAL),
|
||||
|
||||
@ -4224,7 +4224,8 @@ public class Attr extends JCTree.Visitor {
|
||||
type = resultInfo.pt;
|
||||
}
|
||||
tree.type = tree.var.type = type;
|
||||
BindingSymbol v = new BindingSymbol(tree.var.mods.flags, tree.var.name, type, env.info.scope.owner);
|
||||
BindingSymbol v = new BindingSymbol(tree.var.mods.flags | tree.var.declKind.additionalSymbolFlags,
|
||||
tree.var.name, type, env.info.scope.owner);
|
||||
v.pos = tree.pos;
|
||||
tree.var.sym = v;
|
||||
if (chk.checkUnique(tree.var.pos(), v, env.info.scope)) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -3544,7 +3544,10 @@ public class Check {
|
||||
if (s.kind == PCK)
|
||||
applicableTargets.add(names.PACKAGE);
|
||||
} else if (target == names.TYPE_USE) {
|
||||
if (s.kind == VAR && s.owner.kind == MTH && s.type.hasTag(NONE)) {
|
||||
if (s.kind == VAR &&
|
||||
(s.flags() & Flags.VAR_VARIABLE) != 0 &&
|
||||
(!Feature.TYPE_ANNOTATIONS_ON_VAR_LAMBDA_PARAMETER.allowedInSource(source) ||
|
||||
((s.flags() & Flags.LAMBDA_PARAMETER) == 0))) {
|
||||
//cannot type annotate implicitly typed locals
|
||||
continue;
|
||||
} else if (s.kind == TYP || s.kind == VAR ||
|
||||
@ -5632,8 +5635,8 @@ public class Check {
|
||||
}
|
||||
case JCVariableDecl variableDecl -> {
|
||||
if (variableDecl.vartype != null &&
|
||||
(variableDecl.sym.flags_field & RECORD) == 0 ||
|
||||
(variableDecl.sym.flags_field & ~(Flags.PARAMETER | RECORD | GENERATED_MEMBER)) != 0) {
|
||||
((variableDecl.sym.flags_field & RECORD) == 0 ||
|
||||
(variableDecl.sym.flags_field & ~(Flags.PARAMETER | RECORD | GENERATED_MEMBER)) != 0)) {
|
||||
/* we don't want to warn twice so if this variable is a compiler generated parameter of
|
||||
* a canonical record constructor, we don't want to issue a warning as we will warn the
|
||||
* corresponding compiler generated private record field anyways
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -281,7 +281,7 @@ public class MemberEnter extends JCTree.Visitor {
|
||||
: tree.vartype.type;
|
||||
Name name = tree.name;
|
||||
VarSymbol v = new VarSymbol(0, name, vartype, enclScope.owner);
|
||||
v.flags_field = chk.checkFlags(tree.mods.flags, v, tree);
|
||||
v.flags_field = chk.checkFlags(tree.mods.flags | tree.declKind.additionalSymbolFlags, v, tree);
|
||||
tree.sym = v;
|
||||
if (tree.init != null) {
|
||||
v.flags_field |= HASINIT;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -3902,7 +3902,7 @@ public class JavacParser implements Parser {
|
||||
if (allowThisIdent ||
|
||||
!lambdaParameter ||
|
||||
LAX_IDENTIFIER.test(token.kind) ||
|
||||
mods.flags != Flags.PARAMETER ||
|
||||
(mods.flags & ~(Flags.PARAMETER | Flags.LAMBDA_PARAMETER)) != 0 ||
|
||||
mods.annotations.nonEmpty()) {
|
||||
JCExpression pn;
|
||||
if (token.kind == UNDERSCORE && (catchParameter || lambdaParameter)) {
|
||||
@ -5405,7 +5405,13 @@ public class JavacParser implements Parser {
|
||||
* LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
|
||||
*/
|
||||
protected JCVariableDecl formalParameter(boolean lambdaParameter, boolean recordComponent) {
|
||||
JCModifiers mods = !recordComponent ? optFinal(Flags.PARAMETER) : modifiersOpt();
|
||||
JCModifiers mods;
|
||||
|
||||
if (recordComponent) {
|
||||
mods = modifiersOpt();
|
||||
} else {
|
||||
mods = optFinal(Flags.PARAMETER | (lambdaParameter ? Flags.LAMBDA_PARAMETER : 0));
|
||||
}
|
||||
if (recordComponent && mods.flags != 0) {
|
||||
log.error(mods.pos, Errors.RecordCantDeclareFieldModifiers);
|
||||
}
|
||||
@ -5436,7 +5442,7 @@ public class JavacParser implements Parser {
|
||||
}
|
||||
|
||||
protected JCVariableDecl implicitParameter() {
|
||||
JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
|
||||
JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER | Flags.LAMBDA_PARAMETER);
|
||||
return variableDeclaratorId(mods, null, false, true, false);
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -1012,9 +1012,16 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
public static class JCVariableDecl extends JCStatement implements VariableTree {
|
||||
|
||||
public enum DeclKind {
|
||||
EXPLICIT, // "SomeType name"
|
||||
IMPLICIT, // "name"
|
||||
VAR, // "var name"
|
||||
EXPLICIT(0), // "SomeType name"
|
||||
IMPLICIT(Flags.VAR_VARIABLE), // "name"
|
||||
VAR(Flags.VAR_VARIABLE), // "var name"
|
||||
;
|
||||
|
||||
public final long additionalSymbolFlags;
|
||||
|
||||
private DeclKind(long additionalSymbolFlags) {
|
||||
this.additionalSymbolFlags = additionalSymbolFlags;
|
||||
}
|
||||
}
|
||||
|
||||
/** variable modifiers */
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
VarVariables.java:34:36: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.deconstruction.patterns), 19, 21
|
||||
VarVariables.java:18:9: compiler.err.annotation.type.not.applicable
|
||||
VarVariables.java:24:14: compiler.err.annotation.type.not.applicable
|
||||
VarVariables.java:27:14: compiler.err.annotation.type.not.applicable
|
||||
VarVariables.java:32:14: compiler.err.annotation.type.not.applicable
|
||||
VarVariables.java:36:37: compiler.err.annotation.type.not.applicable
|
||||
VarVariables.java:32:18: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @VarVariables.TA), java.lang, @VarVariables.TA java.lang.AutoCloseable
|
||||
VarVariables.java:36:41: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @VarVariables.TA), java.lang, @VarVariables.TA java.lang.String
|
||||
8 errors
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8371683
|
||||
* @summary Test that type annotations cannot appears on 'var' variables
|
||||
* @compile/fail/ref=VarVariables.out -XDrawDiagnostics VarVariables.java
|
||||
* @compile/fail/ref=VarVariables-old.out --release 19 -XDrawDiagnostics -XDshould-stop.at=FLOW VarVariables.java
|
||||
*/
|
||||
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
class VarVariables {
|
||||
private void test(Object o) {
|
||||
@DA var v1 = "";
|
||||
@DTA var v2 = "";
|
||||
@TA var v3 = "";
|
||||
Consumer<String> c1 = (@DA var v) -> {};
|
||||
Consumer<String> c2 = (@DTA var v) -> {};
|
||||
Consumer<String> c3 = (@TA var v) -> {};
|
||||
for (@DA var v = ""; !v.isEmpty(); ) {}
|
||||
for (@DTA var v = ""; !v.isEmpty(); ) {}
|
||||
for (@TA var v = ""; !v.isEmpty(); ) {}
|
||||
for (@DA var v : List.of("")) {}
|
||||
for (@DTA var v : List.of("")) {}
|
||||
for (@TA var v : List.of("")) {}
|
||||
try (@DA var v = open()) {
|
||||
} catch (Exception ex) {}
|
||||
try (@DTA var v = open()) {
|
||||
} catch (Exception ex) {}
|
||||
try (@TA var v = open()) {
|
||||
} catch (Exception ex) {}
|
||||
boolean b1 = o instanceof R(@DA var v);
|
||||
boolean b2 = o instanceof R(@DTA var v);
|
||||
boolean b3 = o instanceof R(@TA var v);
|
||||
}
|
||||
|
||||
private AutoCloseable open() {
|
||||
return null;
|
||||
}
|
||||
record R(String str) {}
|
||||
|
||||
@Target(ElementType.TYPE_USE)
|
||||
@interface TA { }
|
||||
|
||||
@Target({ElementType.TYPE_USE, ElementType.LOCAL_VARIABLE, ElementType.PARAMETER})
|
||||
@interface DTA { }
|
||||
|
||||
@Target({ElementType.LOCAL_VARIABLE, ElementType.PARAMETER})
|
||||
@interface DA { }
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
VarVariables.java:18:9: compiler.err.annotation.type.not.applicable
|
||||
VarVariables.java:21:32: compiler.err.annotation.type.not.applicable
|
||||
VarVariables.java:24:14: compiler.err.annotation.type.not.applicable
|
||||
VarVariables.java:27:14: compiler.err.annotation.type.not.applicable
|
||||
VarVariables.java:32:14: compiler.err.annotation.type.not.applicable
|
||||
VarVariables.java:36:37: compiler.err.annotation.type.not.applicable
|
||||
VarVariables.java:32:18: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @VarVariables.TA), java.lang, @VarVariables.TA java.lang.AutoCloseable
|
||||
VarVariables.java:36:41: compiler.err.type.annotation.inadmissible: (compiler.misc.type.annotation.1: @VarVariables.TA), java.lang, @VarVariables.TA java.lang.String
|
||||
8 errors
|
||||
Loading…
x
Reference in New Issue
Block a user