mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8359145: Implement JEP 530: Primitive Types in Patterns, instanceof, and switch (Fourth Preview)
Reviewed-by: jlahoda
This commit is contained in:
parent
02ff38f2d7
commit
99135d2e05
@ -777,7 +777,7 @@ public final class SwitchBootstraps {
|
||||
return name + "$$TypeSwitch";
|
||||
}
|
||||
|
||||
// this method should be in sync with com.sun.tools.javac.code.Types.checkUnconditionallyExactPrimitives
|
||||
// this method should be in sync with com.sun.tools.javac.code.Types.isUnconditionallyExactTypeBased
|
||||
private static boolean unconditionalExactnessCheck(Class<?> selectorType, Class<?> targetType) {
|
||||
Wrapper selectorWrapper = Wrapper.forBasicType(selectorType);
|
||||
Wrapper targetWrapper = Wrapper.forBasicType(targetType);
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
import com.sun.source.tree.Tree.Kind;
|
||||
|
||||
import java.lang.runtime.ExactConversionsSupport;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
|
||||
import static com.sun.tools.javac.code.TypeTag.NumericClasses.*;
|
||||
@ -186,6 +186,10 @@ public enum TypeTag {
|
||||
return (this.numericClass & tag.superClasses) != 0;
|
||||
}
|
||||
|
||||
public boolean isNumeric() {
|
||||
return this.numericClass != 0;
|
||||
}
|
||||
|
||||
/** Returns the number of type tags.
|
||||
*/
|
||||
public static int getTypeTagCount() {
|
||||
@ -247,11 +251,11 @@ public enum TypeTag {
|
||||
case BOOLEAN:
|
||||
return 0 <= value && value <= 1;
|
||||
case BYTE:
|
||||
return Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE;
|
||||
return ExactConversionsSupport.isIntToByteExact(value);
|
||||
case CHAR:
|
||||
return Character.MIN_VALUE <= value && value <= Character.MAX_VALUE;
|
||||
return ExactConversionsSupport.isIntToCharExact(value);
|
||||
case SHORT:
|
||||
return Short.MIN_VALUE <= value && value <= Short.MAX_VALUE;
|
||||
return ExactConversionsSupport.isIntToShortExact(value);
|
||||
case INT:
|
||||
return true;
|
||||
default:
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
package com.sun.tools.javac.code;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.runtime.ExactConversionsSupport;
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
@ -5086,46 +5087,128 @@ public class Types {
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
// <editor-fold defaultstate="collapsed" desc="Unconditionality">
|
||||
/** Check unconditionality between any combination of reference or primitive types.
|
||||
// <editor-fold defaultstate="collapsed" desc="Unconditional Exactness">
|
||||
/** Check type-based unconditional exactness between any combination of
|
||||
* reference or primitive types according to JLS 5.7.2.
|
||||
*
|
||||
* Rules:
|
||||
* an identity conversion
|
||||
* a widening reference conversion
|
||||
* a widening primitive conversion (delegates to `checkUnconditionallyExactPrimitives`)
|
||||
* a boxing conversion
|
||||
* a boxing conversion followed by a widening reference conversion
|
||||
* The following are unconditionally exact regardless of the input
|
||||
* expression:
|
||||
*
|
||||
* - an identity conversion
|
||||
* - a widening reference conversion
|
||||
* - an exact widening primitive conversion
|
||||
* - a boxing conversion
|
||||
* - a boxing conversion followed by a widening reference conversion
|
||||
*
|
||||
* @param source Source primitive or reference type
|
||||
* @param target Target primitive or reference type
|
||||
*/
|
||||
public boolean isUnconditionallyExact(Type source, Type target) {
|
||||
public boolean isUnconditionallyExactTypeBased(Type source, Type target) {
|
||||
if (isSameType(source, target)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return target.isPrimitive()
|
||||
? isUnconditionallyExactPrimitives(source, target)
|
||||
: isSubtype(boxedTypeOrType(erasure(source)), target);
|
||||
if (target.isPrimitive()) {
|
||||
if (source.isPrimitive() &&
|
||||
((source.getTag().isStrictSubRangeOf(target.getTag())) &&
|
||||
!((source.hasTag(BYTE) && target.hasTag(CHAR)) ||
|
||||
(source.hasTag(INT) && target.hasTag(FLOAT)) ||
|
||||
(source.hasTag(LONG) && (target.hasTag(DOUBLE) || target.hasTag(FLOAT)))))) return true;
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return isSubtype(boxedTypeOrType(erasure(source)), target);
|
||||
}
|
||||
}
|
||||
|
||||
/** Check unconditionality between primitive types.
|
||||
/** Check value-based unconditional exactness between any combination of
|
||||
* reference or primitive types for the value of a constant expression
|
||||
* according to JLS 5.7.2.
|
||||
*
|
||||
* - widening from one integral type to another,
|
||||
* - widening from one floating point type to another,
|
||||
* - widening from byte, short, or char to a floating point type,
|
||||
* - widening from int to double.
|
||||
* The following can be unconditionally exact if the source primitive is a
|
||||
* constant expression and the conversions is exact for that constant
|
||||
* expression:
|
||||
*
|
||||
* @param selectorType Type of selector
|
||||
* @param targetType Target type
|
||||
* - a narrowing primitive conversion
|
||||
* - a widening and narrowing primitive conversion
|
||||
* - a widening primitive conversion that is not exact
|
||||
*
|
||||
* @param source Source primitive or reference type, should be a numeric value
|
||||
* @param target Target primitive or reference type
|
||||
*/
|
||||
public boolean isUnconditionallyExactPrimitives(Type selectorType, Type targetType) {
|
||||
return isSameType(selectorType, targetType) ||
|
||||
(selectorType.isPrimitive() && targetType.isPrimitive()) &&
|
||||
((selectorType.getTag().isStrictSubRangeOf(targetType.getTag())) &&
|
||||
!((selectorType.hasTag(BYTE) && targetType.hasTag(CHAR)) ||
|
||||
(selectorType.hasTag(INT) && targetType.hasTag(FLOAT)) ||
|
||||
(selectorType.hasTag(LONG) && (targetType.hasTag(DOUBLE) || targetType.hasTag(FLOAT)))));
|
||||
public boolean isUnconditionallyExactValueBased(Type source, Type target) {
|
||||
if (!(source.constValue() instanceof Number value) || !target.getTag().isNumeric()) return false;
|
||||
|
||||
switch (source.getTag()) {
|
||||
case BYTE:
|
||||
switch (target.getTag()) {
|
||||
case CHAR: return ExactConversionsSupport.isIntToCharExact(value.intValue());
|
||||
}
|
||||
break;
|
||||
case CHAR:
|
||||
switch (target.getTag()) {
|
||||
case BYTE: return ExactConversionsSupport.isIntToByteExact(value.intValue());
|
||||
case SHORT: return ExactConversionsSupport.isIntToShortExact(value.intValue());
|
||||
}
|
||||
break;
|
||||
case SHORT:
|
||||
switch (target.getTag()) {
|
||||
case BYTE: return ExactConversionsSupport.isIntToByteExact(value.intValue());
|
||||
case CHAR: return ExactConversionsSupport.isIntToCharExact(value.intValue());
|
||||
}
|
||||
break;
|
||||
case INT:
|
||||
switch (target.getTag()) {
|
||||
case BYTE: return ExactConversionsSupport.isIntToByteExact(value.intValue());
|
||||
case CHAR: return ExactConversionsSupport.isIntToCharExact(value.intValue());
|
||||
case SHORT: return ExactConversionsSupport.isIntToShortExact(value.intValue());
|
||||
case FLOAT: return ExactConversionsSupport.isIntToFloatExact(value.intValue());
|
||||
}
|
||||
break;
|
||||
case FLOAT:
|
||||
switch (target.getTag()) {
|
||||
case BYTE: return ExactConversionsSupport.isFloatToByteExact(value.floatValue());
|
||||
case CHAR: return ExactConversionsSupport.isFloatToCharExact(value.floatValue());
|
||||
case SHORT: return ExactConversionsSupport.isFloatToShortExact(value.floatValue());
|
||||
case INT: return ExactConversionsSupport.isFloatToIntExact(value.floatValue());
|
||||
case LONG: return ExactConversionsSupport.isFloatToLongExact(value.floatValue());
|
||||
}
|
||||
break;
|
||||
case LONG:
|
||||
switch (target.getTag()) {
|
||||
case BYTE: return ExactConversionsSupport.isLongToByteExact(value.longValue());
|
||||
case CHAR: return ExactConversionsSupport.isLongToCharExact(value.longValue());
|
||||
case SHORT: return ExactConversionsSupport.isLongToShortExact(value.longValue());
|
||||
case INT: return ExactConversionsSupport.isLongToIntExact(value.longValue());
|
||||
case FLOAT: return ExactConversionsSupport.isLongToFloatExact(value.longValue());
|
||||
case DOUBLE: return ExactConversionsSupport.isLongToDoubleExact(value.longValue());
|
||||
}
|
||||
break;
|
||||
case DOUBLE:
|
||||
switch (target.getTag()) {
|
||||
case BYTE: return ExactConversionsSupport.isDoubleToByteExact(value.doubleValue());
|
||||
case CHAR: return ExactConversionsSupport.isDoubleToCharExact(value.doubleValue());
|
||||
case SHORT: return ExactConversionsSupport.isDoubleToShortExact(value.doubleValue());
|
||||
case INT: return ExactConversionsSupport.isDoubleToIntExact(value.doubleValue());
|
||||
case FLOAT: return ExactConversionsSupport.isDoubleToFloatExact(value.doubleValue());
|
||||
case LONG: return ExactConversionsSupport.isDoubleToLongExact(value.doubleValue());
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check both type or value-based unconditional exactness between any
|
||||
* combination of reference or primitive types for the value of a constant
|
||||
* expression according to JLS 5.7.2.
|
||||
*
|
||||
* @param source Source primitive or reference type, should be a numeric value
|
||||
* @param target Target primitive or reference type
|
||||
*/
|
||||
public boolean isUnconditionallyExactCombined(Type currentType, Type testType) {
|
||||
return isUnconditionallyExactTypeBased(currentType, testType) ||
|
||||
(currentType.constValue() instanceof Number && isUnconditionallyExactValueBased(currentType, testType));
|
||||
}
|
||||
// </editor-fold>
|
||||
|
||||
|
||||
@ -1861,7 +1861,7 @@ public class Attr extends JCTree.Visitor {
|
||||
boolean unconditional =
|
||||
unguarded &&
|
||||
!patternType.isErroneous() &&
|
||||
types.isUnconditionallyExact(seltype, patternType);
|
||||
types.isUnconditionallyExactTypeBased(seltype, patternType);
|
||||
if (unconditional) {
|
||||
if (hasUnconditionalPattern) {
|
||||
log.error(pat.pos(), Errors.DuplicateUnconditionalPattern);
|
||||
|
||||
@ -28,7 +28,6 @@ package com.sun.tools.javac.comp;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.ToIntBiFunction;
|
||||
@ -167,6 +166,7 @@ public class Check {
|
||||
allowModules = Feature.MODULES.allowedInSource(source);
|
||||
allowRecords = Feature.RECORDS.allowedInSource(source);
|
||||
allowSealed = Feature.SEALED_CLASSES.allowedInSource(source);
|
||||
allowPrimitivePatterns = preview.isEnabled() && Feature.PRIMITIVE_PATTERNS.allowedInSource(source);
|
||||
}
|
||||
|
||||
/** Character for synthetic names
|
||||
@ -190,6 +190,10 @@ public class Check {
|
||||
*/
|
||||
private final boolean allowSealed;
|
||||
|
||||
/** Are primitive patterns allowed
|
||||
*/
|
||||
private final boolean allowPrimitivePatterns;
|
||||
|
||||
/** Whether to force suppression of deprecation and preview warnings.
|
||||
* This happens when attributing import statements for JDK 9+.
|
||||
* @see Feature#DEPRECATION_ON_IMPORT
|
||||
@ -4764,21 +4768,26 @@ public class Check {
|
||||
JCCase testCase = caseAndLabel.fst;
|
||||
JCCaseLabel testCaseLabel = caseAndLabel.snd;
|
||||
Type testType = labelType(testCaseLabel);
|
||||
|
||||
// an unconditional pattern cannot be followed by any other label
|
||||
if (allowPrimitivePatterns && unconditionalCaseLabel == testCaseLabel && unconditionalCaseLabel != label) {
|
||||
log.error(label.pos(), Errors.PatternDominated);
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean dominated = false;
|
||||
if (types.isUnconditionallyExact(currentType, testType) &&
|
||||
!currentType.hasTag(ERROR) && !testType.hasTag(ERROR)) {
|
||||
//the current label is potentially dominated by the existing (test) label, check:
|
||||
if (label instanceof JCConstantCaseLabel) {
|
||||
dominated |= !(testCaseLabel instanceof JCConstantCaseLabel) &&
|
||||
if (!currentType.hasTag(ERROR) && !testType.hasTag(ERROR)) {
|
||||
// the current label is potentially dominated by the existing (test) label, check:
|
||||
if (types.isUnconditionallyExactCombined(currentType, testType) &&
|
||||
label instanceof JCConstantCaseLabel) {
|
||||
dominated = !(testCaseLabel instanceof JCConstantCaseLabel) &&
|
||||
TreeInfo.unguardedCase(testCase);
|
||||
} else if (label instanceof JCPatternCaseLabel patternCL &&
|
||||
testCaseLabel instanceof JCPatternCaseLabel testPatternCaseLabel &&
|
||||
(testCase.equals(c) || TreeInfo.unguardedCase(testCase))) {
|
||||
dominated = patternDominated(testPatternCaseLabel.pat,
|
||||
patternCL.pat);
|
||||
dominated = patternDominated(testPatternCaseLabel.pat, patternCL.pat);
|
||||
}
|
||||
}
|
||||
|
||||
if (dominated) {
|
||||
log.error(label.pos(), Errors.PatternDominated);
|
||||
}
|
||||
@ -4798,7 +4807,7 @@ public class Check {
|
||||
private boolean patternDominated(JCPattern existingPattern, JCPattern currentPattern) {
|
||||
Type existingPatternType = types.erasure(existingPattern.type);
|
||||
Type currentPatternType = types.erasure(currentPattern.type);
|
||||
if (!types.isUnconditionallyExact(currentPatternType, existingPatternType)) {
|
||||
if (!types.isUnconditionallyExactTypeBased(currentPatternType, existingPatternType)) {
|
||||
return false;
|
||||
}
|
||||
if (currentPattern instanceof JCBindingPattern ||
|
||||
|
||||
@ -568,8 +568,8 @@ public class ExhaustivenessComputer {
|
||||
Type pattype = types.erasure(bp.type);
|
||||
|
||||
return seltype.isPrimitive() ?
|
||||
types.isUnconditionallyExact(seltype, pattype) :
|
||||
(bp.type.isPrimitive() && types.isUnconditionallyExact(types.unboxedType(seltype), bp.type)) || types.isSubtype(seltype, pattype);
|
||||
types.isUnconditionallyExactTypeBased(seltype, pattype) :
|
||||
(bp.type.isPrimitive() && types.isUnconditionallyExactTypeBased(types.unboxedType(seltype), bp.type)) || types.isSubtype(seltype, pattype);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -36,7 +36,6 @@ import com.sun.tools.javac.jvm.*;
|
||||
import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant;
|
||||
import com.sun.tools.javac.main.Option.PkgInfo;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
|
||||
import com.sun.tools.javac.resources.CompilerProperties.Notes;
|
||||
import com.sun.tools.javac.tree.*;
|
||||
import com.sun.tools.javac.util.*;
|
||||
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
|
||||
@ -2835,7 +2834,7 @@ public class Lower extends TreeTranslator {
|
||||
JCExpression exactnessCheck;
|
||||
JCExpression instanceOfExpr = translate(tree.expr);
|
||||
|
||||
if (types.isUnconditionallyExact(tree.expr.type, tree.pattern.type)) {
|
||||
if (types.isUnconditionallyExactTypeBased(tree.expr.type, tree.pattern.type)) {
|
||||
// instanceOfExpr; true
|
||||
prefixStatement = make.Exec(instanceOfExpr);
|
||||
exactnessCheck = make.Literal(BOOLEAN, 1).setType(syms.booleanType.constType(1));
|
||||
@ -2844,7 +2843,7 @@ public class Lower extends TreeTranslator {
|
||||
prefixStatement = null;
|
||||
exactnessCheck = getExactnessCheck(tree, instanceOfExpr);
|
||||
} else if (tree.expr.type.isReference()) {
|
||||
if (types.isUnconditionallyExact(types.unboxedType(tree.expr.type), tree.pattern.type)) {
|
||||
if (types.isUnconditionallyExactTypeBased(types.unboxedType(tree.expr.type), tree.pattern.type)) {
|
||||
// instanceOfExpr != null
|
||||
prefixStatement = null;
|
||||
exactnessCheck = makeBinary(NE, instanceOfExpr, makeNull());
|
||||
|
||||
@ -921,7 +921,7 @@ public class TransPatterns extends TreeTranslator {
|
||||
JCBindingPattern binding = (JCBindingPattern) instanceofCheck.pattern;
|
||||
hasUnconditional =
|
||||
(!types.erasure(binding.type).isPrimitive() ? instanceofCheck.allowNull :
|
||||
types.isUnconditionallyExact(commonNestedExpression.type, types.erasure(binding.type))) &&
|
||||
types.isUnconditionallyExactTypeBased(commonNestedExpression.type, types.erasure(binding.type))) &&
|
||||
accList.tail.isEmpty();
|
||||
List<JCCaseLabel> newLabel;
|
||||
|
||||
|
||||
@ -26,8 +26,8 @@
|
||||
* @bug 8262891 8290709
|
||||
* @summary Check the pattern domination error are reported correctly.
|
||||
* @compile/fail/ref=Domination.out -XDrawDiagnostics Domination.java
|
||||
* @compile/fail/ref=DominationWithPP.out --enable-preview --source ${jdk.version} -XDrawDiagnostics Domination.java
|
||||
*/
|
||||
|
||||
public class Domination {
|
||||
int testDominatesError1(Object o) {
|
||||
switch (o) {
|
||||
@ -218,4 +218,14 @@ public class Domination {
|
||||
case null : return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int testCasePatternDominatedbyPreceedingUnconditionalCasePattern () {
|
||||
interface A {}
|
||||
interface B {}
|
||||
A aa = new A() {};
|
||||
switch (aa) {
|
||||
case A a : return 1;
|
||||
case B b : return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14
test/langtools/tools/javac/patterns/DominationWithPP.out
Normal file
14
test/langtools/tools/javac/patterns/DominationWithPP.out
Normal file
@ -0,0 +1,14 @@
|
||||
Domination.java:35:18: compiler.err.pattern.dominated
|
||||
Domination.java:43:18: compiler.err.pattern.dominated
|
||||
Domination.java:51:18: compiler.err.pattern.dominated
|
||||
Domination.java:67:18: compiler.err.pattern.dominated
|
||||
Domination.java:88:18: compiler.err.pattern.dominated
|
||||
Domination.java:113:18: compiler.err.pattern.dominated
|
||||
Domination.java:144:18: compiler.err.pattern.dominated
|
||||
Domination.java:153:18: compiler.err.pattern.dominated
|
||||
Domination.java:184:18: compiler.err.pattern.dominated
|
||||
Domination.java:193:18: compiler.err.pattern.dominated
|
||||
Domination.java:202:18: compiler.err.pattern.dominated
|
||||
Domination.java:211:18: compiler.err.pattern.dominated
|
||||
Domination.java:228:18: compiler.err.pattern.dominated
|
||||
13 errors
|
||||
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @summary Retain exhaustiveness properties of switches with a constant selector
|
||||
* @enablePreview
|
||||
* @compile/fail/ref=PrimitivePatternsSwitchConstants.out -XDrawDiagnostics -XDshould-stop.at=FLOW PrimitivePatternsSwitchConstants.java
|
||||
*/
|
||||
public class PrimitivePatternsSwitchConstants {
|
||||
void testConstExpressions() {
|
||||
switch (42) { // error: not exhaustive
|
||||
case byte _ :
|
||||
}
|
||||
|
||||
switch (42l) { // error: not exhaustive
|
||||
case byte _ :
|
||||
}
|
||||
|
||||
switch (123456) { // error: not exhaustive
|
||||
case byte _ :
|
||||
}
|
||||
|
||||
switch (16_777_216) { // error: not exhaustive
|
||||
case float _ :
|
||||
}
|
||||
|
||||
switch (16_777_217) { // error: not exhaustive
|
||||
case float _ :
|
||||
}
|
||||
|
||||
switch (42d) { // error: not exhaustive
|
||||
case float _ :
|
||||
}
|
||||
|
||||
switch (1) { // OK
|
||||
case long _ :
|
||||
}
|
||||
|
||||
final int i = 42;
|
||||
switch (i) { // OK
|
||||
case long _ :
|
||||
}
|
||||
|
||||
switch (1) { // error: non-exhaustive
|
||||
case Long _ : // error: widening primitive conversion and boxing is not supported
|
||||
}
|
||||
|
||||
switch (42) {
|
||||
case byte bb -> {}
|
||||
case int ii -> {} // OK
|
||||
};
|
||||
|
||||
switch (42) {
|
||||
case 42 -> {}
|
||||
case int ii -> {} // OK
|
||||
};
|
||||
|
||||
switch (42) {
|
||||
case (byte) 42 -> {}
|
||||
case int ii -> {} // OK
|
||||
};
|
||||
|
||||
switch (42) {
|
||||
case 42 -> {}
|
||||
default -> {} // OK
|
||||
};
|
||||
|
||||
switch (42) {
|
||||
default -> {} // OK
|
||||
case 42 -> {}
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
PrimitivePatternsSwitchConstants.java:43:18: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.Long)
|
||||
PrimitivePatternsSwitchConstants.java:9:9: compiler.err.not.exhaustive.statement
|
||||
PrimitivePatternsSwitchConstants.java:13:9: compiler.err.not.exhaustive.statement
|
||||
PrimitivePatternsSwitchConstants.java:17:9: compiler.err.not.exhaustive.statement
|
||||
PrimitivePatternsSwitchConstants.java:21:9: compiler.err.not.exhaustive.statement
|
||||
PrimitivePatternsSwitchConstants.java:25:9: compiler.err.not.exhaustive.statement
|
||||
PrimitivePatternsSwitchConstants.java:29:9: compiler.err.not.exhaustive.statement
|
||||
PrimitivePatternsSwitchConstants.java:42:9: compiler.err.not.exhaustive.statement
|
||||
- compiler.note.preview.filename: PrimitivePatternsSwitchConstants.java, DEFAULT
|
||||
- compiler.note.preview.recompile
|
||||
8 errors
|
||||
@ -59,7 +59,7 @@ public class PrimitivePatternsSwitchErrors {
|
||||
int i = 42;
|
||||
return switch (i) {
|
||||
case Integer ib -> ib;
|
||||
case byte ip -> ip; // OK - not dominated!
|
||||
case byte ip -> ip; // Error - dominated!
|
||||
};
|
||||
}
|
||||
|
||||
@ -265,4 +265,69 @@ public class PrimitivePatternsSwitchErrors {
|
||||
public static <T extends Integer> boolean wideningReferenceConversionUnboxingAndNarrowingPrimitive(T i) {
|
||||
return i instanceof byte b; // not allowed as a conversion
|
||||
}
|
||||
|
||||
public static void dominanceIntFloat() {
|
||||
int ii = 42;
|
||||
switch (ii) {
|
||||
case int i -> {}
|
||||
case float f -> {} // Error - dominated!
|
||||
}
|
||||
}
|
||||
|
||||
public static void noDominanceIntFloat() {
|
||||
int ii = 42;
|
||||
switch (ii) {
|
||||
case float f -> {}
|
||||
case int i -> {} // ok
|
||||
}
|
||||
}
|
||||
|
||||
public static void strengtheningDominance() {
|
||||
byte x = 42;
|
||||
switch (x) {
|
||||
case short s -> {}
|
||||
case 42 -> {} // error: dominated
|
||||
}
|
||||
|
||||
long l = 42l;
|
||||
switch (l) {
|
||||
case short s -> {}
|
||||
case 42l -> {} // error: dominated
|
||||
case long _ -> {}
|
||||
}
|
||||
|
||||
char c = 'a';
|
||||
switch (c) {
|
||||
case short s -> {}
|
||||
case 42 -> {} // error: dominated
|
||||
case char _ -> {}
|
||||
}
|
||||
|
||||
int x2 = 42;
|
||||
switch(x2) {
|
||||
case float f -> {}
|
||||
case 16_777_216 -> {} // error: dominated
|
||||
default -> {}
|
||||
}
|
||||
|
||||
switch(x2) {
|
||||
case float f -> {}
|
||||
case 16_777_217 -> {} // OK
|
||||
default -> {}
|
||||
}
|
||||
|
||||
switch(x2) {
|
||||
case int ii -> {}
|
||||
case float f -> {} // error: dominated
|
||||
}
|
||||
}
|
||||
|
||||
public static void unconditionalFollowedByDefault() {
|
||||
int ii = 42;
|
||||
switch (ii) {
|
||||
case int i -> {}
|
||||
case float f -> {} // Error - dominated!
|
||||
default -> {} // Error - unconditional and default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
PrimitivePatternsSwitchErrors.java:15:18: compiler.err.pattern.dominated
|
||||
PrimitivePatternsSwitchErrors.java:24:18: compiler.err.pattern.dominated
|
||||
PrimitivePatternsSwitchErrors.java:31:24: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.Long)
|
||||
PrimitivePatternsSwitchErrors.java:62:18: compiler.err.pattern.dominated
|
||||
PrimitivePatternsSwitchErrors.java:70:18: compiler.err.pattern.dominated
|
||||
PrimitivePatternsSwitchErrors.java:78:18: compiler.err.pattern.dominated
|
||||
PrimitivePatternsSwitchErrors.java:84:18: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: long, byte)
|
||||
@ -29,6 +30,14 @@ PrimitivePatternsSwitchErrors.java:248:18: compiler.err.prob.found.req: (compile
|
||||
PrimitivePatternsSwitchErrors.java:255:18: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Long, int)
|
||||
PrimitivePatternsSwitchErrors.java:261:18: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Short, char)
|
||||
PrimitivePatternsSwitchErrors.java:266:16: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: T, byte)
|
||||
PrimitivePatternsSwitchErrors.java:273:18: compiler.err.pattern.dominated
|
||||
PrimitivePatternsSwitchErrors.java:289:18: compiler.err.pattern.dominated
|
||||
PrimitivePatternsSwitchErrors.java:295:18: compiler.err.pattern.dominated
|
||||
PrimitivePatternsSwitchErrors.java:302:18: compiler.err.pattern.dominated
|
||||
PrimitivePatternsSwitchErrors.java:309:18: compiler.err.pattern.dominated
|
||||
PrimitivePatternsSwitchErrors.java:321:18: compiler.err.pattern.dominated
|
||||
PrimitivePatternsSwitchErrors.java:330:13: compiler.err.unconditional.pattern.and.default
|
||||
PrimitivePatternsSwitchErrors.java:329:18: compiler.err.pattern.dominated
|
||||
PrimitivePatternsSwitchErrors.java:30:16: compiler.err.not.exhaustive
|
||||
PrimitivePatternsSwitchErrors.java:37:16: compiler.err.not.exhaustive
|
||||
PrimitivePatternsSwitchErrors.java:44:16: compiler.err.not.exhaustive
|
||||
@ -43,4 +52,4 @@ PrimitivePatternsSwitchErrors.java:254:16: compiler.err.not.exhaustive
|
||||
PrimitivePatternsSwitchErrors.java:260:16: compiler.err.not.exhaustive
|
||||
- compiler.note.preview.filename: PrimitivePatternsSwitchErrors.java, DEFAULT
|
||||
- compiler.note.preview.recompile
|
||||
43 errors
|
||||
52 errors
|
||||
|
||||
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Check assignability of narrowing p.c. with constant expressions vs exact conversion methods
|
||||
* @library /tools/lib/types
|
||||
* @modules jdk.compiler/com.sun.tools.javac.code
|
||||
* jdk.compiler/com.sun.tools.javac.comp
|
||||
* jdk.compiler/com.sun.tools.javac.file
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.tree
|
||||
* @build TypeHarness
|
||||
* @compile PrimitiveUnconditionallyExactInAssignability.java
|
||||
* @run main PrimitiveUnconditionallyExactInAssignability
|
||||
*/
|
||||
|
||||
import com.sun.tools.javac.code.Type;
|
||||
import com.sun.tools.javac.code.TypeTag;
|
||||
|
||||
import java.lang.runtime.ExactConversionsSupport;
|
||||
|
||||
import static com.sun.tools.javac.code.TypeTag.ERROR;
|
||||
import static com.sun.tools.javac.code.TypeTag.INT;
|
||||
|
||||
public class PrimitiveUnconditionallyExactInAssignability extends TypeHarness {
|
||||
PrimitiveUnconditionallyExactInAssignability() {
|
||||
}
|
||||
|
||||
void assertOriginalAssignmentNarrowingAndUnconditionality() {
|
||||
// byte b = <constant short> vs ExactConversionsSupport::isIntToByteExact
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Short.MIN_VALUE), predef.byteType, ExactConversionsSupport.isIntToByteExact(Short.MIN_VALUE));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant((short) (Byte.MIN_VALUE - 1)), predef.byteType, ExactConversionsSupport.isIntToByteExact((short) (Byte.MIN_VALUE - 1)));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant((short) (Byte.MAX_VALUE + 1)), predef.byteType, ExactConversionsSupport.isIntToByteExact((short) (Byte.MAX_VALUE + 1)));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Short.MAX_VALUE), predef.byteType, ExactConversionsSupport.isIntToByteExact(Short.MAX_VALUE));
|
||||
|
||||
// byte b = <constant char> vs ExactConversionsSupport::isIntToByteExact
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Character.MIN_VALUE), predef.byteType, ExactConversionsSupport.isIntToByteExact(Character.MIN_VALUE));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant((char) (Byte.MAX_VALUE + 1)), predef.byteType, ExactConversionsSupport.isIntToByteExact((char) (Byte.MAX_VALUE + 1)));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Character.MAX_VALUE), predef.byteType, ExactConversionsSupport.isIntToByteExact(Character.MAX_VALUE));
|
||||
|
||||
// byte b = <constant int> vs ExactConversionsSupport::isIntToByteExact
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Integer.MIN_VALUE), predef.byteType, ExactConversionsSupport.isIntToByteExact(Integer.MIN_VALUE));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant((int) (Byte.MIN_VALUE - 1)), predef.byteType, ExactConversionsSupport.isIntToByteExact((int) (Byte.MIN_VALUE - 1)));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant((int) (Byte.MAX_VALUE + 1)), predef.byteType, ExactConversionsSupport.isIntToByteExact((int) (Byte.MAX_VALUE + 1)));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Integer.MAX_VALUE), predef.byteType, ExactConversionsSupport.isIntToByteExact(Integer.MAX_VALUE));
|
||||
|
||||
// char c = <constant short> vs ExactConversionsSupport::isIntToCharExact
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Short.MIN_VALUE), predef.charType, ExactConversionsSupport.isIntToCharExact(Short.MIN_VALUE));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant((short) (Character.MIN_VALUE - 1)), predef.charType, ExactConversionsSupport.isIntToCharExact((short) (Character.MIN_VALUE - 1)));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant((short) (Character.MAX_VALUE + 1)), predef.charType, ExactConversionsSupport.isIntToCharExact((short) (Character.MIN_VALUE + 1)));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Short.MAX_VALUE), predef.charType, ExactConversionsSupport.isIntToCharExact(Short.MAX_VALUE));
|
||||
|
||||
// char c = <constant int> vs ExactConversionsSupport::isIntToCharExact
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Integer.MIN_VALUE), predef.charType, ExactConversionsSupport.isIntToCharExact(Integer.MIN_VALUE));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant((int) (Character.MIN_VALUE - 1)), predef.charType, ExactConversionsSupport.isIntToCharExact((int) (Character.MIN_VALUE - 1)));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant((int) (Character.MAX_VALUE + 1)), predef.charType, ExactConversionsSupport.isIntToCharExact((int) (Character.MAX_VALUE + 1)));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Integer.MAX_VALUE), predef.charType, ExactConversionsSupport.isIntToCharExact(Integer.MAX_VALUE));
|
||||
|
||||
// short b = <constant char> vs ExactConversionsSupport::isIntToShortExact
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Character.MIN_VALUE), predef.shortType, ExactConversionsSupport.isIntToShortExact(Character.MIN_VALUE));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant((char) (Character.MAX_VALUE + 1)), predef.shortType, ExactConversionsSupport.isIntToShortExact((char) (Character.MAX_VALUE + 1)));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Character.MAX_VALUE), predef.shortType, ExactConversionsSupport.isIntToShortExact(Character.MAX_VALUE));
|
||||
|
||||
// short b = <constant int> vs ExactConversionsSupport::isIntToShortExact
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Integer.MIN_VALUE), predef.shortType, ExactConversionsSupport.isIntToShortExact(Integer.MIN_VALUE));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant((int) (Short.MIN_VALUE - 1)), predef.shortType, ExactConversionsSupport.isIntToShortExact((int) (Short.MIN_VALUE - 1)));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant((int) (Short.MAX_VALUE + 1)), predef.shortType, ExactConversionsSupport.isIntToShortExact((int) (Short.MAX_VALUE + 1)));
|
||||
assertOriginaAndUpdatedAssignable(fac.Constant(Integer.MAX_VALUE), predef.shortType, ExactConversionsSupport.isIntToShortExact(Integer.MAX_VALUE));
|
||||
}
|
||||
// where
|
||||
public void assertOriginaAndUpdatedAssignable(Type s, Type t, boolean expected) {
|
||||
assertAssignable(s, t, originalIsAssignable(s, t));
|
||||
}
|
||||
public boolean originalIsAssignable(Type t, Type s) {
|
||||
if (t.hasTag(ERROR))
|
||||
return true;
|
||||
if (t.getTag().isSubRangeOf(INT) && t.constValue() != null) {
|
||||
int value = ((Number)t.constValue()).intValue();
|
||||
switch (s.getTag()) {
|
||||
case BYTE:
|
||||
case CHAR:
|
||||
case SHORT:
|
||||
case INT:
|
||||
if (originalCheckRange(s.getTag(), value))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return types.isConvertible(t, s);
|
||||
}
|
||||
public boolean originalCheckRange(TypeTag that, int value) {
|
||||
switch (that) {
|
||||
case BOOLEAN:
|
||||
return 0 <= value && value <= 1;
|
||||
case BYTE:
|
||||
return Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE;
|
||||
case CHAR:
|
||||
return Character.MIN_VALUE <= value && value <= Character.MAX_VALUE;
|
||||
case SHORT:
|
||||
return Short.MIN_VALUE <= value && value <= Short.MAX_VALUE;
|
||||
case INT:
|
||||
return true;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
private void error(String msg) {
|
||||
throw new AssertionError("Unexpected result in original isAssignable: " + msg);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
PrimitiveUnconditionallyExactInAssignability harness = new PrimitiveUnconditionallyExactInAssignability();
|
||||
harness.assertOriginalAssignmentNarrowingAndUnconditionality();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Check the unconditionally exact for constant primitives used in the exhaustiveness check
|
||||
* @library /tools/lib/types
|
||||
* @modules jdk.compiler/com.sun.tools.javac.code
|
||||
* jdk.compiler/com.sun.tools.javac.comp
|
||||
* jdk.compiler/com.sun.tools.javac.file
|
||||
* jdk.compiler/com.sun.tools.javac.util
|
||||
* jdk.compiler/com.sun.tools.javac.main
|
||||
* jdk.compiler/com.sun.tools.javac.tree
|
||||
* @build TypeHarness
|
||||
* @compile PrimitiveUnconditionallyExactInExhaustiveSwitches.java
|
||||
* @run main PrimitiveUnconditionallyExactInExhaustiveSwitches
|
||||
*/
|
||||
|
||||
public class PrimitiveUnconditionallyExactInExhaustiveSwitches extends TypeHarness {
|
||||
|
||||
PrimitiveUnconditionallyExactInExhaustiveSwitches() {
|
||||
}
|
||||
public void testByte() {
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MAX_VALUE))), predef.byteType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (0))),predef.byteType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MIN_VALUE))),predef.byteType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MAX_VALUE))),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (0))),predef.byteType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MIN_VALUE))),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MAX_VALUE))),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MIN_VALUE))),predef.byteType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MAX_VALUE)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0)),predef.byteType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MIN_VALUE)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MAX_VALUE)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0L)),predef.byteType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MIN_VALUE)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MAX_VALUE)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((float) 0)),predef.byteType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MIN_VALUE)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NaN)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.POSITIVE_INFINITY)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NEGATIVE_INFINITY)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0f)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0f)),predef.byteType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MAX_VALUE)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((double) 0)),predef.byteType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MIN_VALUE)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NaN)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.POSITIVE_INFINITY)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NEGATIVE_INFINITY)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0d)),predef.byteType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0d)),predef.byteType, true);
|
||||
}
|
||||
public void testShort() {
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MAX_VALUE))),predef.shortType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (0))),predef.shortType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MIN_VALUE))),predef.shortType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MAX_VALUE))),predef.shortType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (0))),predef.shortType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MIN_VALUE))),predef.shortType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MAX_VALUE))),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MIN_VALUE))),predef.shortType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MAX_VALUE)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0)),predef.shortType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MIN_VALUE)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MAX_VALUE)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0L)),predef.shortType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MIN_VALUE)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MAX_VALUE)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((float) 0)),predef.shortType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MIN_VALUE)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MIN_VALUE)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NaN)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.POSITIVE_INFINITY)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NEGATIVE_INFINITY)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0f)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0f)),predef.shortType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MAX_VALUE)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((double) 0)),predef.shortType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MIN_VALUE)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NaN)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.POSITIVE_INFINITY)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NEGATIVE_INFINITY)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0d)),predef.shortType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0d)),predef.shortType, true);
|
||||
}
|
||||
public void testChar() {
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MAX_VALUE))),predef.charType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (0))),predef.charType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MIN_VALUE))),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MAX_VALUE))),predef.charType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (0))),predef.charType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MIN_VALUE))),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MAX_VALUE))),predef.charType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MIN_VALUE))),predef.charType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MAX_VALUE)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0)),predef.charType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MIN_VALUE)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MAX_VALUE)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0L)),predef.charType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MIN_VALUE)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MAX_VALUE)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((float) 0)),predef.charType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MIN_VALUE)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NaN)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.POSITIVE_INFINITY)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NEGATIVE_INFINITY)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0f)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0f)),predef.charType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MAX_VALUE)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((double) 0)),predef.charType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MIN_VALUE)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NaN)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.POSITIVE_INFINITY)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NEGATIVE_INFINITY)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0d)),predef.charType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0d)),predef.charType, true);
|
||||
}
|
||||
public void testInt() {
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MAX_VALUE))),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (0))),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MIN_VALUE))),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MAX_VALUE))),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (0))),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MIN_VALUE))),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MAX_VALUE))),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MIN_VALUE))),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MAX_VALUE)),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0)),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MIN_VALUE)),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MAX_VALUE)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0L)),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MIN_VALUE)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MAX_VALUE)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((float) 0)),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MIN_VALUE)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NaN)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.POSITIVE_INFINITY)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NEGATIVE_INFINITY)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0f)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0f)),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MAX_VALUE)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((double) 0)),predef.intType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MIN_VALUE)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NaN)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.POSITIVE_INFINITY)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NEGATIVE_INFINITY)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0d)),predef.intType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0d)),predef.intType, true);
|
||||
}
|
||||
public void testLong() {
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MAX_VALUE))),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (0))),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MIN_VALUE))),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MAX_VALUE))),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (0))),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MIN_VALUE))),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MAX_VALUE))),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MIN_VALUE))),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MAX_VALUE)),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0L)),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MIN_VALUE)),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MAX_VALUE)),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0)),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MIN_VALUE)),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MAX_VALUE)),predef.longType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((float) 0)),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MIN_VALUE)),predef.longType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NaN)),predef.longType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.POSITIVE_INFINITY)),predef.longType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NEGATIVE_INFINITY)),predef.longType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0f)),predef.longType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0f)),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MAX_VALUE)),predef.longType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((double) 0)),predef.longType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MIN_VALUE)),predef.longType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NaN)),predef.longType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.POSITIVE_INFINITY)),predef.longType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NEGATIVE_INFINITY)),predef.longType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0d)),predef.longType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0d)),predef.longType, true);
|
||||
}
|
||||
public void testFloat() {
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MAX_VALUE))),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((byte) (0)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MIN_VALUE))),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MAX_VALUE))),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (0))),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MIN_VALUE))),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MAX_VALUE))),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MIN_VALUE))),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MAX_VALUE)),predef.floatType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MIN_VALUE)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MAX_VALUE)),predef.floatType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0L)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MIN_VALUE)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MAX_VALUE)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((float) 0)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MIN_VALUE)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NaN)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.POSITIVE_INFINITY)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NEGATIVE_INFINITY)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0f)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0f)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MAX_VALUE)),predef.floatType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((double) 0)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MIN_VALUE)),predef.floatType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NaN)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.POSITIVE_INFINITY)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NEGATIVE_INFINITY)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0d)),predef.floatType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0d)),predef.floatType, true);
|
||||
}
|
||||
public void testDouble() {
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MAX_VALUE))),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (0))),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((byte) (Byte.MIN_VALUE))),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MAX_VALUE))),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (0))),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((short) (Short.MIN_VALUE))),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MAX_VALUE))),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((char) (Character.MIN_VALUE))),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MAX_VALUE)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Integer.MIN_VALUE)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MAX_VALUE)),predef.doubleType, false);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((0L)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Long.MIN_VALUE)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MAX_VALUE)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((float) 0)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.MIN_VALUE)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NaN)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.POSITIVE_INFINITY)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Float.NEGATIVE_INFINITY)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0f)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0f)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MAX_VALUE)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant(((double) 0)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.MIN_VALUE)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NaN)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.POSITIVE_INFINITY)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((Double.NEGATIVE_INFINITY)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((-0.0d)),predef.doubleType, true);
|
||||
assertIsUnconditionallyExactConstantPrimitives(fac.Constant((+0.0d)),predef.doubleType, true);
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
PrimitiveUnconditionallyExactInExhaustiveSwitches harness = new PrimitiveUnconditionallyExactInExhaustiveSwitches();
|
||||
harness.testByte();
|
||||
harness.testShort();
|
||||
harness.testChar();
|
||||
harness.testInt();
|
||||
harness.testDouble();
|
||||
harness.testLong();
|
||||
harness.testFloat();
|
||||
}
|
||||
}
|
||||
@ -25,14 +25,14 @@
|
||||
* @test
|
||||
* @bug 8332463
|
||||
* @summary Byte conditional pattern case element dominates short constant case element
|
||||
* @compile --enable-preview --source ${jdk.version} T8332463a.java
|
||||
* @compile/fail/ref=T8332463a.out -XDrawDiagnostics --enable-preview --source ${jdk.version} T8332463a.java
|
||||
*/
|
||||
public class T8332463a {
|
||||
public int test2() {
|
||||
Byte i = (byte) 42;
|
||||
return switch (i) {
|
||||
case Byte ib -> 1;
|
||||
case short s -> 2;
|
||||
case short s -> 2; // dominated
|
||||
};
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ public class T8332463a {
|
||||
int i = 42;
|
||||
return switch (i) {
|
||||
case Integer ib -> 1;
|
||||
case byte ip -> 2;
|
||||
case byte ip -> 2; // dominated
|
||||
};
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ public class T8332463a {
|
||||
int i = 42;
|
||||
return switch (i) {
|
||||
case Integer ib -> 1;
|
||||
case (byte) 0 -> 2;
|
||||
case (byte) 0 -> 2; // dominated
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
6
test/langtools/tools/javac/patterns/T8332463a.out
Normal file
6
test/langtools/tools/javac/patterns/T8332463a.out
Normal file
@ -0,0 +1,6 @@
|
||||
T8332463a.java:35:18: compiler.err.pattern.dominated
|
||||
T8332463a.java:43:18: compiler.err.pattern.dominated
|
||||
T8332463a.java:51:18: compiler.err.pattern.dominated
|
||||
- compiler.note.preview.filename: T8332463a.java, DEFAULT
|
||||
- compiler.note.preview.recompile
|
||||
3 errors
|
||||
@ -26,15 +26,14 @@
|
||||
* @bug 8332463
|
||||
* @summary Byte conditional pattern case element dominates short constant case element
|
||||
* @enablePreview
|
||||
* @compile T8332463b.java
|
||||
* @compile --enable-preview --source ${jdk.version} T8332463b.java
|
||||
* @compile/fail/ref=T8332463b.out -XDrawDiagnostics --enable-preview --source ${jdk.version} T8332463b.java
|
||||
*/
|
||||
public class T8332463b {
|
||||
public int test1() {
|
||||
Byte i = (byte) 42;
|
||||
return switch (i) {
|
||||
case Byte ib -> 1;
|
||||
case (short) 0 -> 2;
|
||||
case (short) 0 -> 2; // dominated
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
2
test/langtools/tools/javac/patterns/T8332463b.out
Normal file
2
test/langtools/tools/javac/patterns/T8332463b.out
Normal file
@ -0,0 +1,2 @@
|
||||
T8332463b.java:36:18: compiler.err.pattern.dominated
|
||||
1 error
|
||||
@ -73,7 +73,9 @@ public class UnknownTypeTest extends TypeHarness {
|
||||
types::isSameType,
|
||||
types::isSubtype,
|
||||
types::isSuperType,
|
||||
types::isUnconditionallyExact,
|
||||
types::isUnconditionallyExactValueBased,
|
||||
types::isUnconditionallyExactTypeBased,
|
||||
types::isUnconditionallyExactCombined,
|
||||
(t1, _) -> types.isArray(t1),
|
||||
(t1, _) -> types.isDerivedRaw(t1),
|
||||
(t1, _) -> types.isReifiable(t1),
|
||||
|
||||
@ -188,6 +188,21 @@ public class TypeHarness {
|
||||
}
|
||||
}
|
||||
|
||||
/** assert that 's' is unconditionally exact to 't' */
|
||||
public void assertIsUnconditionallyExactConstantPrimitives(Type s, Type t) {
|
||||
assertIsUnconditionallyExactConstantPrimitives(s, t, true);
|
||||
}
|
||||
|
||||
/** assert that 's' is/is not unconditionally exact to 't' */
|
||||
public void assertIsUnconditionallyExactConstantPrimitives(Type s, Type t, boolean expected) {
|
||||
if (types.isUnconditionallyExactValueBased(s, t) != expected) {
|
||||
String msg = expected ?
|
||||
" is not unconditionally exact to " :
|
||||
" is unconditionally exact to ";
|
||||
error(s + msg + t);
|
||||
}
|
||||
}
|
||||
|
||||
/** assert that generic type 't' is well-formed */
|
||||
public void assertValidGenericType(Type t) {
|
||||
assertValidGenericType(t, true);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user