changeset 50627:2934689eff44 switch

Removing support for case null and additional switch types as suggested. SwitchBootstraps removed for now as well, as these are not strictly necessary.
author jlahoda
date Tue, 15 May 2018 10:50:25 +0200
parents 7f135cad741e
children 849e15e87fd9
files make/CompileJavaModules.gmk src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java src/java.base/share/classes/module-info.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties test/jdk/java/lang/runtime/TestSwitchBootstrap.java test/langtools/tools/javac/modules/JavaBaseTest.java test/langtools/tools/javac/switchexpr/ExpressionSwitch-old.out test/langtools/tools/javac/switchexpr/ExpressionSwitch.java test/langtools/tools/javac/switchexpr/ExpressionSwitchBugs.java test/langtools/tools/javac/switchexpr/ExpressionSwitchFallThrough1.java test/langtools/tools/javac/switchexpr/ExpressionSwitchInfer.java test/langtools/tools/javac/switchexpr/ExpressionSwitchInfer.out test/langtools/tools/javac/switchextra/MultipleLabelsExpression-old.out test/langtools/tools/javac/switchextra/MultipleLabelsExpression.java test/langtools/tools/javac/switchextra/MultipleLabelsStatement-old.out test/langtools/tools/javac/switchextra/MultipleLabelsStatement.java test/langtools/tools/javac/switchextra/SwitchBooleanExhaustivness.java test/langtools/tools/javac/switchextra/SwitchBooleanExhaustivness.out test/langtools/tools/javac/switchextra/SwitchExtra-old.out test/langtools/tools/javac/switchextra/SwitchExtra.java test/langtools/tools/javac/switchextra/SwitchNoExtraTypes.java test/langtools/tools/javac/switchextra/SwitchNoExtraTypes.out test/langtools/tools/javac/switchextra/SwitchObject.out test/langtools/tools/javac/switchextra/SwitchStatementArrow.java test/langtools/tools/javac/switchnull/SwitchNull-old.out test/langtools/tools/javac/switchnull/SwitchNull.java test/langtools/tools/javac/switchnull/SwitchNull.out test/langtools/tools/javac/switchnull/SwitchNullDisabled.java test/langtools/tools/javac/switchnull/SwitchNullDisabled.out test/langtools/tools/javac/switchnull/SwitchNullNegative.java test/langtools/tools/javac/switchnull/SwitchNullNegative.out
diffstat 34 files changed, 97 insertions(+), 1886 deletions(-) [+]
line wrap: on
line diff
--- a/make/CompileJavaModules.gmk	Thu May 10 22:08:15 2018 +0200
+++ b/make/CompileJavaModules.gmk	Tue May 15 10:50:25 2018 +0200
@@ -40,7 +40,7 @@
 
 ################################################################################
 
-java.base_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-reference '-Xdoclint/package:java.*,javax.*' -XDstringConcat=inline -XDdisableIndySwitch=true
+java.base_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-reference '-Xdoclint/package:java.*,javax.*' -XDstringConcat=inline
 java.base_COPY += .icu .dat .spp content-types.properties hijrah-config-islamic-umalqura.properties
 java.base_CLEAN += intrinsic.properties
 
--- a/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java	Thu May 10 22:08:15 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,786 +0,0 @@
-/*
- * Copyright (c) 2017, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-package java.lang.runtime;
-
-import java.lang.invoke.CallSite;
-import java.lang.invoke.ConstantCallSite;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-import java.util.stream.IntStream;
-import java.util.stream.LongStream;
-import java.util.stream.Stream;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * Bootstrap methods for linking {@code invokedynamic} call sites that implement
- * the selection functionality of the {@code switch} statement.  The bootstraps
- * take additional static arguments corresponding to the {@code case} labels
- * of the {@code switch}, implicitly numbered sequentially from {@code [0..N)}.
- *
- * <p>The bootstrap call site accepts a single parameter of the type of the
- * operand of the {@code switch}, and return an {@code int} that is the index of
- * the matched {@code case} label, {@code -1} if the target is {@code null},
- * or {@code N} if the target is not null but matches no {@code case} label.
- */
-public class SwitchBootstraps {
-
-    // Shared INIT_HOOK for all switch call sites; looks the target method up in a map
-    private static final MethodHandle CONSTANT_INIT_HOOK;
-    private static final MethodHandle PATTERN_INIT_HOOK;
-    private static final MethodHandle PATTERN_SWITCH_METHOD;
-    private static final Map<Class<?>, MethodHandle> switchMethods = new ConcurrentHashMap<>();
-
-    private static final Set<Class<?>> BOOLEAN_TYPES
-            = Set.of(boolean.class, Boolean.class);
-    // Types that can be handled as int switches
-    private static final Set<Class<?>> INT_TYPES
-            = Set.of(int.class, short.class, byte.class, char.class,
-                     Integer.class, Short.class, Byte.class, Character.class);
-    private static final Set<Class<?>> FLOAT_TYPES
-            = Set.of(float.class, Float.class);
-    private static final Set<Class<?>> LONG_TYPES
-            = Set.of(long.class, Long.class);
-    private static final Set<Class<?>> DOUBLE_TYPES
-            = Set.of(double.class, Double.class);
-
-    private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
-    private static final Function<Class<?>, MethodHandle> lookupSwitchMethod =
-            new Function<>() {
-                @Override
-                public MethodHandle apply(Class<?> c) {
-                    try {
-                        Class<?> switchClass;
-                        if (c == Enum.class)
-                            switchClass = EnumSwitchCallSite.class;
-                        else if (c == String.class)
-                            switchClass = StringSwitchCallSite.class;
-                        else if (BOOLEAN_TYPES.contains(c) || INT_TYPES.contains(c) ||
-                                 FLOAT_TYPES.contains(c))
-                            switchClass = IntSwitchCallSite.class;
-                        else if (LONG_TYPES.contains(c) || DOUBLE_TYPES.contains(c))
-                            switchClass = LongSwitchCallSite.class;
-                        else if (c == Object.class)
-                            switchClass = TypeSwitchCallSite.class;
-                        else
-                            throw new BootstrapMethodError("Invalid switch type: " + c);
-
-                        return LOOKUP.findVirtual(switchClass, "doSwitch",
-                                                  MethodType.methodType(int.class, c));
-                    }
-                    catch (ReflectiveOperationException e) {
-                        throw new BootstrapMethodError("Invalid switch type: " + c);
-                    }
-                }
-            };
-
-    static {
-        try {
-            CONSTANT_INIT_HOOK = LOOKUP.findStatic(SwitchBootstraps.class, "constantInitHook",
-                                                   MethodType.methodType(MethodHandle.class, CallSite.class));
-            PATTERN_INIT_HOOK = LOOKUP.findStatic(SwitchBootstraps.class, "patternInitHook",
-                                                  MethodType.methodType(MethodHandle.class, CallSite.class));
-            PATTERN_SWITCH_METHOD = LOOKUP.findVirtual(TypeSwitchCallSite.class, "doSwitch",
-                                                       MethodType.methodType(int.class, Object.class));
-        }
-        catch (ReflectiveOperationException e) {
-            throw new ExceptionInInitializerError(e);
-        }
-    }
-
-    private static<T extends CallSite> MethodHandle constantInitHook(T receiver) {
-        return switchMethods.computeIfAbsent(receiver.type().parameterType(0), lookupSwitchMethod)
-                            .bindTo(receiver);
-    }
-
-    private static<T extends CallSite> MethodHandle patternInitHook(T receiver) {
-        return PATTERN_SWITCH_METHOD.bindTo(receiver);
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on a {@code boolean} or {@code Boolean}.
-     * The static arguments are a varargs array of {@code boolean} labels,
-     *
-     * <p>The results are undefined if the labels array contains duplicates.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter which is
-     *                       {@code boolean} or {@code Boolean},and return {@code int}.
-     *                       When used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param booleanLabels boolean values corresponding to the case labels of the
-     *                  {@code switch} statement.
-     * @return the index into {@code booleanLabels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code booleanLabels.length} if the target value does
-     *         not match any of the labels.
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if the invocation type is not
-     * {@code (boolean)int} or {@code (Boolean)int}
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite booleanSwitch(MethodHandles.Lookup lookup,
-                                         String invocationName,
-                                         MethodType invocationType,
-                                         boolean... booleanLabels) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!BOOLEAN_TYPES.contains(invocationType.parameterType(0))))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(booleanLabels);
-
-        int[] intLabels = IntStream.range(0, booleanLabels.length)
-                                   .map(i -> booleanLabels[i] ? 1 : 0)
-                                   .toArray();
-
-        assert IntStream.of(intLabels).distinct().count() == intLabels.length
-                : "switch labels are not distinct: " + Arrays.toString(booleanLabels);
-
-        return new IntSwitchCallSite(invocationType, intLabels);
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on an {@code int}, {@code short}, {@code byte},
-     * {@code char}, or one of their box types.  The static arguments are a
-     * varargs array of {@code int} labels.
-     *
-     * <p>The results are undefined if the labels array contains duplicates.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter which is
-     *                       one of the 32-bit or shorter primitive types, or
-     *                       one of their box types, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param intLabels integral values corresponding to the case labels of the
-     *                  {@code switch} statement.
-     * @return the index into {@code intLabels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code intLabels.length} if the target value does
-     *         not match any of the labels.
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if the invocation type is not
-     * {@code (T)int}, where {@code T} is one of the 32-bit or smaller integral
-     * primitive types, or one of their box types
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite intSwitch(MethodHandles.Lookup lookup,
-                                     String invocationName,
-                                     MethodType invocationType,
-                                     int... intLabels) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!INT_TYPES.contains(invocationType.parameterType(0))))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(intLabels);
-
-        assert IntStream.of(intLabels).distinct().count() == intLabels.length
-                : "switch labels are not distinct: " + Arrays.toString(intLabels);
-
-        return new IntSwitchCallSite(invocationType, intLabels);
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on an {@code float} or {@code Float}.
-     * The static arguments are a varargs array of {@code float} labels.
-     *
-     * <p>The results are undefined if the labels array contains duplicates
-     * according to {@link Float#floatToIntBits(float)}.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter which is
-     *                       one of the 32-bit or shorter primitive types, or
-     *                       one of their box types, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param floatLabels float values corresponding to the case labels of the
-     *                    {@code switch} statement.
-     * @return the index into {@code floatLabels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code floatLabels.length} if the target value does
-     *         not match any of the labels.
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if the invocation type is not
-     * {@code (float)int} or {@code (Float)int}
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite floatSwitch(MethodHandles.Lookup lookup,
-                                       String invocationName,
-                                       MethodType invocationType,
-                                       float... floatLabels) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!FLOAT_TYPES.contains(invocationType.parameterType(0))))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(floatLabels);
-
-        int[] intLabels = new int[floatLabels.length];
-        for (int i=0; i<floatLabels.length; i++)
-            intLabels[i] = Float.floatToIntBits(floatLabels[i]);
-
-        assert IntStream.of(intLabels).distinct().count() == intLabels.length
-                : "switch labels are not distinct: " + Arrays.toString(floatLabels);
-
-        return new IntSwitchCallSite(invocationType, intLabels);
-    }
-
-    static class IntSwitchCallSite extends ConstantCallSite {
-        private final int[] labels;
-        private final int[] indexes;
-
-        IntSwitchCallSite(MethodType targetType,
-                          int[] intLabels) throws Throwable {
-            super(targetType, CONSTANT_INIT_HOOK);
-
-            // expensive way to index an array
-            indexes = IntStream.range(0, intLabels.length)
-                               .boxed()
-                               .sorted(Comparator.comparingInt(a -> intLabels[a]))
-                               .mapToInt(Integer::intValue)
-                               .toArray();
-            labels = new int[indexes.length];
-            for (int i=0; i<indexes.length; i++)
-                labels[i] = intLabels[indexes[i]];
-        }
-
-        int doSwitch(boolean target) {
-            int index = Arrays.binarySearch(labels, target ? 1 : 0);
-            return (index >= 0) ? indexes[index] : indexes.length;
-        }
-
-        int doSwitch(int target) {
-            int index = Arrays.binarySearch(labels, target);
-            return (index >= 0) ? indexes[index] : indexes.length;
-        }
-
-        int doSwitch(float target) {
-            return doSwitch(Float.floatToIntBits(target));
-        }
-
-        int doSwitch(short target) {
-            return doSwitch((int) target);
-        }
-
-        int doSwitch(byte target) {
-            return doSwitch((int) target);
-        }
-
-        int doSwitch(char target) {
-            return doSwitch((int) target);
-        }
-
-        int doSwitch(Boolean target) {
-            return (target == null) ? -1 : doSwitch((boolean) target);
-        }
-
-        int doSwitch(Integer target) {
-            return (target == null) ? -1 : doSwitch((int) target);
-        }
-
-        int doSwitch(Float target) {
-            return (target == null) ? -1 : doSwitch((float) target);
-        }
-
-        int doSwitch(Short target) {
-            return (target == null) ? -1 : doSwitch((int) target);
-        }
-
-        int doSwitch(Character target) {
-            return (target == null) ? -1 : doSwitch((int) target);
-        }
-
-        int doSwitch(Byte target) {
-            return (target == null) ? -1 : doSwitch((int) target);
-        }
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on a {@code long} or {@code Long}.
-     * The static arguments are a varargs array of {@code long} labels.
-     *
-     * <p>The results are undefined if the labels array contains duplicates.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter which is
-     *                       one of the 32-bit or shorter primitive types, or
-     *                       one of their box types, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param longLabels long values corresponding to the case labels of the
-     *                  {@code switch} statement.
-     * @return the index into {@code longLabels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code longLabels.length} if the target value does
-     *         not match any of the labels.
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if the invocation type is not
-     * {@code (long)int} or {@code (Long)int}
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite longSwitch(MethodHandles.Lookup lookup,
-                                      String invocationName,
-                                      MethodType invocationType,
-                                      long... longLabels) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!LONG_TYPES.contains(invocationType.parameterType(0))))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(longLabels);
-
-        assert LongStream.of(longLabels).distinct().count() == longLabels.length
-                : "switch labels are not distinct: " + Arrays.toString(longLabels);
-
-        return new LongSwitchCallSite(invocationType, longLabels);
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on a {@code double} or {@code Double}.
-     * The static arguments are a varargs array of {@code double} labels.
-     *
-     * <p>The results are undefined if the labels array contains duplicates
-     * according to {@link Double#doubleToLongBits(double)}.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter which is
-     *                       one of the 32-bit or shorter primitive types, or
-     *                       one of their box types, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param doubleLabels long values corresponding to the case labels of the
-     *                  {@code switch} statement.
-     * @return the index into {@code doubleLabels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code doubleLabels.length} if the target value does
-     *         not match any of the labels.
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if the invocation type is not
-     * {@code (double)int} or {@code (Double)int}
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite doubleSwitch(MethodHandles.Lookup lookup,
-                                        String invocationName,
-                                        MethodType invocationType,
-                                        double... doubleLabels) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!DOUBLE_TYPES.contains(invocationType.parameterType(0))))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(doubleLabels);
-
-        long[] longLabels = new long[doubleLabels.length];
-        for (int i=0; i<doubleLabels.length; i++)
-            longLabels[i] = Double.doubleToLongBits(doubleLabels[i]);
-
-        assert LongStream.of(longLabels).distinct().count() == longLabels.length
-                : "switch labels are not distinct: " + Arrays.toString(doubleLabels);
-
-        return new LongSwitchCallSite(invocationType, longLabels);
-    }
-
-    static class LongSwitchCallSite extends ConstantCallSite {
-        private final long[] labels;
-        private final int[] indexes;
-
-        LongSwitchCallSite(MethodType targetType,
-                           long[] longLabels) throws Throwable {
-            super(targetType, CONSTANT_INIT_HOOK);
-
-            // expensive way to index an array
-            indexes = IntStream.range(0, longLabels.length)
-                               .boxed()
-                               .sorted(Comparator.comparingLong(a -> longLabels[a]))
-                               .mapToInt(Integer::intValue)
-                               .toArray();
-            labels = new long[indexes.length];
-            for (int i=0; i<indexes.length; i++)
-                labels[i] = longLabels[indexes[i]];
-        }
-
-        int doSwitch(long target) {
-            int index = Arrays.binarySearch(labels, target);
-            return (index >= 0) ? indexes[index] : indexes.length;
-        }
-
-        int doSwitch(double target) {
-            return doSwitch(Double.doubleToLongBits(target));
-        }
-
-        int doSwitch(Long target) {
-            return (target == null) ? -1 : doSwitch((long) target);
-        }
-
-        int doSwitch(Double target) {
-            return (target == null) ? -1 : doSwitch((double) target);
-        }
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on a {@code String} target.  The static
-     * arguments are a varargs array of {@code String} labels.
-     *
-     * <p>The results are undefined if the labels array contains duplicates
-     * according to {@link String#equals(Object)}.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter of
-     *                       {@code String}, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param stringLabels non-null string values corresponding to the case
-     *                     labels of the {@code switch} statement.
-     * @return the index into {@code labels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code stringLabels.length} if the target value
-     *         does not match any of the labels.
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if any labels are null, or if the
-     * invocation type is not {@code (String)int}
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite stringSwitch(MethodHandles.Lookup lookup,
-                                        String invocationName,
-                                        MethodType invocationType,
-                                        String... stringLabels) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!invocationType.parameterType(0).equals(String.class)))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(stringLabels);
-        if (Stream.of(stringLabels).anyMatch(Objects::isNull))
-            throw new IllegalArgumentException("null label found");
-
-        assert Stream.of(stringLabels).distinct().count() == stringLabels.length
-                : "switch labels are not distinct: " + Arrays.toString(stringLabels);
-
-        return new StringSwitchCallSite(invocationType, stringLabels);
-    }
-
-    static class StringSwitchCallSite extends ConstantCallSite {
-        private static final Comparator<String> STRING_BY_HASH
-                = Comparator.comparingInt(Objects::hashCode);
-
-        private final String[] sortedByHash;
-        private final int[] indexes;
-        private final boolean collisions;
-
-        StringSwitchCallSite(MethodType targetType,
-                             String[] stringLabels) throws Throwable {
-            super(targetType, CONSTANT_INIT_HOOK);
-
-            // expensive way to index an array
-            indexes = IntStream.range(0, stringLabels.length)
-                               .boxed()
-                               .sorted(Comparator.comparingInt(i -> stringLabels[i].hashCode()))
-                               .mapToInt(Integer::intValue)
-                               .toArray();
-            sortedByHash = new String[indexes.length];
-            for (int i=0; i<indexes.length; i++)
-                sortedByHash[i] = stringLabels[indexes[i]];
-
-            collisions = IntStream.range(0, sortedByHash.length-1)
-                                  .anyMatch(i -> sortedByHash[i].hashCode() == sortedByHash[i + 1].hashCode());
-        }
-
-        int doSwitch(String target) {
-            if (target == null)
-                return -1;
-
-            int index = Arrays.binarySearch(sortedByHash, target, STRING_BY_HASH);
-            if (index < 0)
-                return indexes.length;
-            else if (target.equals(sortedByHash[index])) {
-                return indexes[index];
-            }
-            else if (collisions) {
-                int hash = target.hashCode();
-                while (index > 0 && sortedByHash[index-1].hashCode() == hash)
-                    --index;
-                for (; index < sortedByHash.length && sortedByHash[index].hashCode() == hash; index++)
-                    if (target.equals(sortedByHash[index]))
-                        return indexes[index];
-            }
-
-            return indexes.length;
-        }
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on an {@code Enum} target.  The static
-     * arguments are the enum class, and a varargs arrays of {@code String}
-     * that are the names of the enum constants corresponding to the
-     * {@code case} labels.
-     *
-     * <p>The results are undefined if the names array contains duplicates.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param <E> the enum type
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter of
-     *                       {@code Enum}, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param enumClass the enum class
-     * @param enumNames names of the enum constants against which the target
-     *                  should be matched
-     * @return the index into {@code labels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code stringLabels.length} if the target value
-     *         does not match any of the labels.
-     * @throws IllegalArgumentException if the specified class is not an
-     *                                  enum class, or any label name is null,
-     *                                  or if the invocation type is not
-     *                                  {@code (Enum)int}
-     * @throws NullPointerException if any required argument is null
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static<E extends Enum<E>> CallSite enumSwitch(MethodHandles.Lookup lookup,
-                                                         String invocationName,
-                                                         MethodType invocationType,
-                                                         Class<E> enumClass,
-                                                         String... enumNames) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!invocationType.parameterType(0).equals(Enum.class)))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(enumClass);
-        requireNonNull(enumNames);
-        if (!enumClass.isEnum())
-            throw new IllegalArgumentException("not an enum class");
-        if (Stream.of(enumNames).anyMatch(Objects::isNull))
-            throw new IllegalArgumentException("null label found");
-
-        assert Stream.of(enumNames).distinct().count() == enumNames.length
-                : "switch labels are not distinct: " + Arrays.toString(enumNames);
-
-        return new EnumSwitchCallSite<>(invocationType, enumClass, enumNames);
-    }
-
-    static class EnumSwitchCallSite<E extends Enum<E>> extends ConstantCallSite {
-        private final int[] ordinalMap;
-
-        EnumSwitchCallSite(MethodType targetType,
-                           Class<E> enumClass,
-                           String... enumNames) throws Throwable {
-            super(targetType, CONSTANT_INIT_HOOK);
-
-            ordinalMap = new int[enumClass.getEnumConstants().length];
-            Arrays.fill(ordinalMap, enumNames.length);
-
-            for (int i=0; i<enumNames.length; i++) {
-                try {
-                    ordinalMap[E.valueOf(enumClass, enumNames[i]).ordinal()] = i;
-                }
-                catch (Exception e) {
-                    // allow non-existent labels, but never match them
-                    continue;
-                }
-            }
-        }
-
-        @SuppressWarnings("rawtypes")
-        int doSwitch(Enum target) {
-            return (target == null) ? -1 : ordinalMap[target.ordinal()];
-        }
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on a reference-typed target.  The static
-     * arguments are a varargs array of {@code Class} labels.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter of
-     *                       a reference type, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param types non-null {@link Class} values
-     * @return the index into {@code labels} of the target value, if the target
-     *         is an instance of any of the types, {@literal -1} if the target
-     *         value is {@code null}, or {@code types.length} if the target value
-     *         is not an instance of any of the types
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if any labels are null, or if the
-     * invocation type is not {@code (T)int for some reference type {@code T}}
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite typeSwitch(MethodHandles.Lookup lookup,
-                                      String invocationName,
-                                      MethodType invocationType,
-                                      Class<?>... types) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || invocationType.parameterType(0).isPrimitive())
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(types);
-
-        types = types.clone();
-        if (Stream.of(types).anyMatch(Objects::isNull))
-            throw new IllegalArgumentException("null label found");
-
-        assert Stream.of(types).distinct().count() == types.length
-                : "switch labels are not distinct: " + Arrays.toString(types);
-
-        return new TypeSwitchCallSite(invocationType, types);
-    }
-
-    static class TypeSwitchCallSite extends ConstantCallSite {
-        private final Class<?>[] types;
-
-        TypeSwitchCallSite(MethodType targetType,
-                           Class<?>[] types) throws Throwable {
-            super(targetType, PATTERN_INIT_HOOK);
-            this.types = types;
-        }
-
-        int doSwitch(Object target) {
-            if (target == null)
-                return -1;
-
-            // Dumbest possible strategy
-            Class<?> targetClass = target.getClass();
-            for (int i = 0; i < types.length; i++) {
-                Class<?> c = types[i];
-                if (c.isAssignableFrom(targetClass))
-                    return i;
-            }
-
-            return types.length;
-        }
-    }
-}
--- a/src/java.base/share/classes/module-info.java	Thu May 10 22:08:15 2018 +0200
+++ b/src/java.base/share/classes/module-info.java	Tue May 15 10:50:25 2018 +0200
@@ -83,7 +83,6 @@
     exports java.lang.module;
     exports java.lang.ref;
     exports java.lang.reflect;
-    exports java.lang.runtime;
     exports java.math;
     exports java.net;
     exports java.net.spi;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java	Thu May 10 22:08:15 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java	Tue May 15 10:50:25 2018 +0200
@@ -183,9 +183,7 @@
         PRIVATE_INTERFACE_METHODS(JDK9, Fragments.FeaturePrivateIntfMethods, DiagKind.PLURAL),
         LOCAL_VARIABLE_TYPE_INFERENCE(JDK10),
         SWITCH_MULTIPLE_CASE_LABELS(JDK10, Fragments.FeatureMultipleCaseLabels, DiagKind.PLURAL),
-        SWITCH_EXPRESSION(JDK10, Fragments.FeatureSwitchExpressions, DiagKind.PLURAL),
-        SWITCH_CASE_NULL(JDK10, Fragments.FeatureCaseNull, DiagKind.NORMAL),
-        SWITCH_EXTRA_TYPES(JDK10, Fragments.FeatureSwitchExtraTypes, DiagKind.NORMAL);
+        SWITCH_EXPRESSION(JDK10, Fragments.FeatureSwitchExpressions, DiagKind.PLURAL);
 
         enum DiagKind {
             NORMAL,
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu May 10 22:08:15 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Tue May 15 10:50:25 2018 +0200
@@ -157,8 +157,6 @@
 
         Source source = Source.instance(context);
         allowStringsInSwitch = Feature.STRINGS_IN_SWITCH.allowedInSource(source);
-        allowExtraTypesInSwitch = Feature.SWITCH_EXTRA_TYPES.allowedInSource(source);
-        allowNullCase = Feature.SWITCH_EXTRA_TYPES.allowedInSource(source);
         allowPoly = Feature.POLY.allowedInSource(source);
         allowTypeAnnos = Feature.TYPE_ANNOTATIONS.allowedInSource(source);
         allowLambda = Feature.LAMBDA.allowedInSource(source);
@@ -208,16 +206,6 @@
     boolean allowStringsInSwitch;
 
     /**
-     * Switch: allow extra types in switch?
-     */
-    boolean allowExtraTypesInSwitch;
-
-    /**
-     * Switch: allow case null in switch?
-     */
-    boolean allowNullCase;
-
-    /**
      * Switch: name of source level; used for error reporting.
      */
     String sourceName;
@@ -1469,14 +1457,8 @@
             if (stringSwitch && !allowStringsInSwitch) {
                 log.error(DiagnosticFlag.SOURCE_LEVEL, selector.pos(), Feature.STRINGS_IN_SWITCH.error(sourceName));
             }
-            Type unboxedSelType = types.unboxedTypeOrType(seltype);
-            if (!enumSwitch && !stringSwitch) {
-                if (!unboxedSelType.isPrimitive()) {
-                    log.error(selector.pos(), Errors.SwitchInvalidType(seltype));
-                } else if (!types.isSubtype(unboxedSelType, syms.intType) && !allowExtraTypesInSwitch) {
-                    log.error(DiagnosticFlag.SOURCE_LEVEL, selector.pos(), Feature.SWITCH_EXTRA_TYPES.error(sourceName));
-                }
-            }
+            if (!enumSwitch && !stringSwitch)
+                seltype = chk.checkType(selector.pos(), seltype, syms.intType);
 
             // Attribute all cases and
             // check that there are no duplicate case labels or default clauses.
@@ -1496,19 +1478,8 @@
                 if (c.getExpressions().nonEmpty()) {
                     for (JCExpression pat : c.getExpressions()) {
                         if (TreeInfo.isNull(pat)) {
-                            if (!allowNullCase) {
-                                log.error(DiagnosticFlag.SOURCE_LEVEL,
-                                          selector.pos(),
-                                          Feature.SWITCH_CASE_NULL.error(sourceName));
-                            }
-                            //case null:
-                            //TODO: check -source
-                            if (seltype.isPrimitive()) {
-                                log.error(c.pos(), Errors.SwitchNullMustBeReference);
-                            }
-                            if (!labels.add(null)) {
-                                log.error(c.pos(), Errors.DuplicateCaseLabel);
-                            }
+                            log.error(pat.pos(),
+                                      Errors.SwitchNullNotAllowed);
                         } else if (enumSwitch) {
                             Symbol sym = enumConstant(pat, seltype);
                             if (sym == null) {
@@ -1517,7 +1488,7 @@
                                 log.error(c.pos(), Errors.DuplicateCaseLabel);
                             }
                         } else {
-                            Type pattype = attribExpr(pat, switchEnv, unboxedSelType);
+                            Type pattype = attribExpr(pat, switchEnv, seltype);
                             if (!pattype.hasTag(ERROR)) {
                                 if (pattype.constValue() == null) {
                                     log.error(pat.pos(),
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Thu May 10 22:08:15 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java	Tue May 15 10:50:25 2018 +0200
@@ -100,7 +100,6 @@
     private final Types types;
     private final boolean debugLower;
     private final PkgInfo pkginfoOpt;
-    private final boolean generateNewSwitch;
 
     protected Lower(Context context) {
         context.put(lowerKey, this);
@@ -128,8 +127,6 @@
         Options options = Options.instance(context);
         debugLower = options.isSet("debuglower");
         pkginfoOpt = PkgInfo.get(options);
-        
-        generateNewSwitch = !options.isSet("disableIndySwitch") && target.hasSwichBootstraps();
     }
 
     /** The currently enclosing class.
@@ -3357,170 +3354,19 @@
             (tree.selector.type.tsym.flags() & ENUM) != 0;
         boolean stringSwitch = selsuper != null &&
             types.isSameType(tree.selector.type, syms.stringType);
-        Type unboxed = types.unboxedTypeOrType(tree.selector.type);
-        boolean intSwitch = types.isSubtype(unboxed, syms.intType);
-        boolean boxSwitch = selsuper != null &&
-            unboxed.isPrimitive();
         Type target = enumSwitch ? tree.selector.type :
             (stringSwitch? syms.stringType : syms.intType);
 
-        boolean useNewSwitch = generateNewSwitch &&
-                               ((boxSwitch && hasNullCase(tree)) || stringSwitch ||
-                                enumSwitch || !intSwitch);
-        if (!useNewSwitch && (hasNullCase(tree) ||
-            (!enumSwitch && !stringSwitch && !intSwitch))) {
-            log.error(tree.pos(), Errors.NoLegacyDesugaring);
-            useNewSwitch = true;
-        }
-        if (useNewSwitch) {
-            tree.selector = translate(tree.selector);
-            tree.cases = translateCases(tree.cases);
-
-            JCExpression qualifier;
-            
-            if (enumSwitch) {
-                qualifier = prepareSwitchIndySelector(tree,
-                                                      names.enumSwitch,
-                                                      syms.stringType,
-                                                      tree.selector.type,
-                                                      syms.enumSym.type,
-                                                      true,
-                                                      pat -> TreeInfo.name(pat).toString());
-            } else if (stringSwitch) {
-                qualifier = prepareSwitchIndySelector(tree,
-                                                      names.stringSwitch,
-                                                      syms.stringType,
-                                                      syms.stringType,
-                                                      syms.stringType,
-                                                      false,
-                                                      pat -> pat.type.constValue());
-            } else {
-                Name switchName;
-                Type methodType;
-                Function<JCExpression, Object> caseToValue = pat -> pat.type.constValue();
-                if (types.isSameType(unboxed, syms.longType)) {
-                    switchName = names.longSwitch;
-                    methodType = syms.longType;
-                } else if (types.isSameType(unboxed, syms.floatType)) {
-                    switchName = names.floatSwitch;
-                    methodType = syms.floatType;
-                } else if (types.isSameType(unboxed, syms.doubleType)) {
-                    switchName = names.doubleSwitch;
-                    methodType = syms.doubleType;
-                } else if (types.isSameType(unboxed, syms.booleanType)) {
-                    switchName = names.booleanSwitch;
-                    methodType = syms.booleanType;
-                    caseToValue = pat -> {
-                        Symbol getStaticFinal = rs.resolveInternalMethod(tree.pos(), attrEnv,
-                                syms.constantBootstraps, names.getStaticFinal,
-                                List.of(syms.methodHandleLookupType,
-                                        syms.stringType,
-                                        syms.classType,
-                                        syms.classType), List.nil());
-
-                        int value = (Integer) pat.type.constValue();
-                        Name valueName = value != 0 ? names.TRUE : names.FALSE;
-                        Symbol.DynamicMethodSymbol dynSym = new Symbol.DynamicMethodSymbol(valueName,
-                                syms.noSymbol,
-                                ClassFile.REF_invokeStatic,
-                                (Symbol.MethodSymbol)getStaticFinal,
-                                types.boxedClass(syms.booleanType).type,
-                                new Object[] {types.boxedClass(syms.booleanType)
-                                });
-                        return dynSym;
-                    };
-                } else {
-                    switchName = names.intSwitch;
-                    methodType = syms.intType;
-                }
-
-                qualifier = prepareSwitchIndySelector(tree,
-                                                      switchName,
-                                                      methodType,
-                                                      tree.selector.type,
-                                                      tree.selector.type,
-                                                      false,
-                                                      caseToValue);
-            }
-
-            tree.selector = make.Apply(List.nil(), qualifier, List.of(tree.selector));
-            tree.selector.type = qualifier.type;
-            
-            if (!hasNullCase(tree)) {
-                JCThrow npe = make.Throw(makeNewClass(syms.nullPointerExceptionType, List.nil()));
-                tree.cases = tree.cases.prepend(make.Case(CaseKind.STATEMENT, List.of(makeNull()), List.of(npe), null));
-            }
-
-            int caseIdx = 0;
-            
-            for (JCCase c : tree.cases) {
-                if (c.pats.nonEmpty()) {
-                    c.pats = List.of(make.Literal(TreeInfo.isNull(c.pats.head) ? -1 : caseIdx++));
-                }
-            }
-
+        tree.selector = translate(tree.selector, target);
+        tree.cases = translateCases(tree.cases);
+        if (enumSwitch) {
+            result = visitEnumSwitch(tree);
+        } else if (stringSwitch) {
+            result = visitStringSwitch(tree);
+        } else {
             result = tree;
-        } else {
-            tree.selector = translate(tree.selector, target);
-            tree.cases = translateCases(tree.cases);
-            if (enumSwitch) {
-                result = visitEnumSwitch(tree);
-            } else if (stringSwitch) {
-                result = visitStringSwitch(tree);
-            } else {
-                result = tree;
-            }
         }
     }
-        //where:
-        private JCExpression prepareSwitchIndySelector(JCSwitch tree,
-                                                       Name bootstrapMethodName,
-                                                       Type labelsType,
-                                                       Type switchType,
-                                                       Type invocationType,
-                                                       boolean prependSwitchType,
-                                                       Function<JCExpression, Object> pattern2Label) {
-            Type.MethodType indyType = new Type.MethodType(List.of(invocationType),
-                    syms.intType,
-                    List.nil(),
-                    syms.methodClass);
-
-            List<Type> bsm_staticArgs = List.of(types.makeArrayType(labelsType));
-            
-            if (prependSwitchType)
-                bsm_staticArgs = bsm_staticArgs.prepend(new ClassType(syms.classType.getEnclosingType(),
-                                                                      List.of(switchType),
-                                                                      syms.classType.tsym));
-            
-            bsm_staticArgs = bsm_staticArgs.prepend(syms.methodTypeType)
-                                           .prepend(syms.stringType)
-                                           .prepend(syms.methodHandleLookupType);
-
-            Symbol intSwitch = rs.resolveInternalMethod(tree.pos(), attrEnv, syms.switchBootstraps,
-                    bootstrapMethodName, bsm_staticArgs, List.nil());
-            
-            Stream<Object> firstParam = prependSwitchType
-                    ? Stream.of(switchType.tsym)
-                    : Stream.empty();
-            Symbol.DynamicMethodSymbol dynSym = new Symbol.DynamicMethodSymbol(bootstrapMethodName,
-                    syms.noSymbol,
-                    ClassFile.REF_invokeStatic,
-                    (Symbol.MethodSymbol)intSwitch,
-                    indyType,
-                    Stream.concat(firstParam,
-                                  tree.cases.stream()
-                                            .filter(c -> c.pats.nonEmpty() && !TreeInfo.isNull(c.pats.head))
-                                            .map(c -> pattern2Label.apply(c.pats.head))
-                                 )
-                          .toArray());
-
-            JCFieldAccess qualifier = make.Select(make.QualIdent(intSwitch.owner),
-                                                  bootstrapMethodName);
-            qualifier.sym = dynSym;
-            qualifier.type = indyType.getReturnType();
-            
-            return qualifier;
-        }
 
     public JCTree visitEnumSwitch(JCSwitch tree) {
         TypeSymbol enumSym = tree.selector.type.tsym;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Thu May 10 22:08:15 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue May 15 10:50:25 2018 +0200
@@ -2806,12 +2806,6 @@
 compiler.misc.feature.switch.expressions=\
     switch expressions
 
-compiler.misc.feature.switch.extra.types=\
-    switch over boolean, long, float and double
-
-compiler.misc.feature.case.null=\
-    case null
-
 compiler.warn.underscore.as.identifier=\
     as of release 9, ''_'' is a keyword, and may not be used as an identifier
 
@@ -3301,8 +3295,8 @@
 compiler.err.illegal.argument.for.option=\
     illegal argument for {0}: {1}
 
-compiler.err.switch.null.must.be.reference=\
-    case null must only be used in a reference switch
+compiler.err.switch.null.not.allowed=\
+    null label in case is not allowed
 
 compiler.err.no.legacy.desugaring=\
     cannot desugar this statement with -XDdisableIndySwitch set
--- a/test/jdk/java/lang/runtime/TestSwitchBootstrap.java	Thu May 10 22:08:15 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,466 +0,0 @@
-/*
- * Copyright (c) 2012, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * 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.
- */
-
-import java.io.Serializable;
-import java.lang.invoke.CallSite;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.lang.runtime.SwitchBootstraps;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-import java.util.stream.Stream;
-import jdk.test.lib.RandomFactory;
-
-import org.testng.annotations.Test;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-
-/**
- * @test
- * @key randomness
- * @library /test/lib
- * @build jdk.test.lib.RandomFactory
- * @run testng TestSwitchBootstrap
- */
-@Test
-public class TestSwitchBootstrap {
-    private final static Set<Class<?>> BOOLEAN_TYPES = Set.of(boolean.class, Boolean.class);
-    private final static Set<Class<?>> ALL_INT_TYPES = Set.of(int.class, short.class, byte.class, char.class,
-                                                              Integer.class, Short.class, Byte.class, Character.class);
-    private final static Set<Class<?>> SIGNED_NON_BYTE_TYPES = Set.of(int.class, Integer.class, short.class, Short.class);
-    private final static Set<Class<?>> CHAR_TYPES = Set.of(char.class, Character.class);
-    private final static Set<Class<?>> BYTE_TYPES = Set.of(byte.class, Byte.class);
-    private final static Set<Class<?>> SIGNED_TYPES
-            = Set.of(int.class, short.class, byte.class,
-                     Integer.class, Short.class, Byte.class);
-
-    public static final MethodHandle BSM_BOOLEAN_SWITCH;
-    public static final MethodHandle BSM_INT_SWITCH;
-    public static final MethodHandle BSM_LONG_SWITCH;
-    public static final MethodHandle BSM_FLOAT_SWITCH;
-    public static final MethodHandle BSM_DOUBLE_SWITCH;
-    public static final MethodHandle BSM_STRING_SWITCH;
-    public static final MethodHandle BSM_ENUM_SWITCH;
-    public static final MethodHandle BSM_TYPE_SWITCH;
-
-    private final static Random random = RandomFactory.getRandom();
-
-    static {
-        try {
-            BSM_BOOLEAN_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "booleanSwitch",
-                                                                   MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, boolean[].class));
-            BSM_INT_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "intSwitch",
-                                                               MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int[].class));
-            BSM_LONG_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "longSwitch",
-                                                                MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, long[].class));
-            BSM_FLOAT_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "floatSwitch",
-                                                                 MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, float[].class));
-            BSM_DOUBLE_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "doubleSwitch",
-                                                                  MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, double[].class));
-            BSM_STRING_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "stringSwitch",
-                                                                  MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String[].class));
-            BSM_ENUM_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "enumSwitch",
-                                                                MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, Class.class, String[].class));
-            BSM_TYPE_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "typeSwitch",
-                                                                MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, Class[].class));
-        }
-        catch (NoSuchMethodException | IllegalAccessException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private MethodType switchType(Class<?> target) {
-        return MethodType.methodType(int.class, target);
-    }
-
-    private Object box(Class<?> clazz, int i) {
-        if (clazz == Integer.class)
-            return i;
-        else if (clazz == Short.class)
-            return (short) i;
-        else if (clazz == Character.class)
-            return (char) i;
-        else if (clazz == Byte.class)
-            return (byte) i;
-        else
-            throw new IllegalArgumentException(clazz.toString());
-    }
-
-    private void testBoolean(boolean... labels) throws Throwable {
-        Map<Class<?>, MethodHandle> mhs
-                = Map.of(boolean.class, ((CallSite) BSM_BOOLEAN_SWITCH.invoke(MethodHandles.lookup(), "", switchType(boolean.class), labels)).dynamicInvoker(),
-                         Boolean.class, ((CallSite) BSM_BOOLEAN_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Boolean.class), labels)).dynamicInvoker());
-
-        List<Boolean> labelList = new ArrayList<>();
-        for (boolean label : labels)
-            labelList.add(label);
-
-        for (int i=0; i<labels.length; i++) {
-            assertEquals(i, (int) mhs.get(boolean.class).invokeExact((boolean) labels[i]));
-            assertEquals(i, (int) mhs.get(Boolean.class).invokeExact((Boolean) labels[i]));
-        }
-
-        boolean[] booleans = { false, true };
-        for (boolean b : booleans) {
-            if (!labelList.contains(b)) {
-                assertEquals(labels.length, mhs.get(boolean.class).invoke((boolean) b));
-                assertEquals(labels.length, mhs.get(Boolean.class).invoke((boolean) b));
-            }
-        }
-
-        assertEquals(-1, (int) mhs.get(Boolean.class).invoke(null));
-    }
-
-    private void testInt(Set<Class<?>> targetTypes, int... labels) throws Throwable {
-        Map<Class<?>, MethodHandle> mhs
-                = Map.of(char.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(char.class), labels)).dynamicInvoker(),
-                         byte.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(byte.class), labels)).dynamicInvoker(),
-                         short.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(short.class), labels)).dynamicInvoker(),
-                         int.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(int.class), labels)).dynamicInvoker(),
-                         Character.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Character.class), labels)).dynamicInvoker(),
-                         Byte.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Byte.class), labels)).dynamicInvoker(),
-                         Short.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Short.class), labels)).dynamicInvoker(),
-                         Integer.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Integer.class), labels)).dynamicInvoker());
-
-        List<Integer> labelList = IntStream.of(labels)
-                                           .boxed()
-                                           .collect(Collectors.toList());
-
-        for (int i=0; i<labels.length; i++) {
-            // test with invokeExact
-            if (targetTypes.contains(char.class))
-                assertEquals(i, (int) mhs.get(char.class).invokeExact((char) labels[i]));
-            if (targetTypes.contains(byte.class))
-                assertEquals(i, (int) mhs.get(byte.class).invokeExact((byte) labels[i]));
-            if (targetTypes.contains(short.class))
-                assertEquals(i, (int) mhs.get(short.class).invokeExact((short) labels[i]));
-            if (targetTypes.contains(int.class))
-                assertEquals(i, (int) mhs.get(int.class).invokeExact(labels[i]));
-            if (targetTypes.contains(Integer.class))
-                assertEquals(i, (int) mhs.get(Integer.class).invokeExact((Integer) labels[i]));
-            if (targetTypes.contains(Short.class))
-                assertEquals(i, (int) mhs.get(Short.class).invokeExact((Short) (short) labels[i]));
-            if (targetTypes.contains(Byte.class))
-                assertEquals(i, (int) mhs.get(Byte.class).invokeExact((Byte) (byte) labels[i]));
-            if (targetTypes.contains(Character.class))
-                assertEquals(i, (int) mhs.get(Character.class).invokeExact((Character) (char) labels[i]));
-
-            // and with invoke
-            assertEquals(i, (int) mhs.get(int.class).invoke(labels[i]));
-            assertEquals(i, (int) mhs.get(Integer.class).invoke(labels[i]));
-        }
-
-        for (int i=-1000; i<1000; i++) {
-            if (!labelList.contains(i)) {
-                assertEquals(labels.length, mhs.get(short.class).invoke((short) i));
-                assertEquals(labels.length, mhs.get(Short.class).invoke((short) i));
-                assertEquals(labels.length, mhs.get(int.class).invoke(i));
-                assertEquals(labels.length, mhs.get(Integer.class).invoke(i));
-                if (i >= 0) {
-                    assertEquals(labels.length, mhs.get(char.class).invoke((char)i));
-                    assertEquals(labels.length, mhs.get(Character.class).invoke((char)i));
-                }
-                if (i >= -128 && i <= 127) {
-                    assertEquals(labels.length, mhs.get(byte.class).invoke((byte)i));
-                    assertEquals(labels.length, mhs.get(Byte.class).invoke((byte)i));
-                }
-            }
-        }
-
-        assertEquals(-1, (int) mhs.get(Integer.class).invoke(null));
-        assertEquals(-1, (int) mhs.get(Short.class).invoke(null));
-        assertEquals(-1, (int) mhs.get(Byte.class).invoke(null));
-        assertEquals(-1, (int) mhs.get(Character.class).invoke(null));
-    }
-
-    private void testFloat(float... labels) throws Throwable {
-        Map<Class<?>, MethodHandle> mhs
-                = Map.of(float.class, ((CallSite) BSM_FLOAT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(float.class), labels)).dynamicInvoker(),
-                         Float.class, ((CallSite) BSM_FLOAT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Float.class), labels)).dynamicInvoker());
-
-        List<Float> labelList = new ArrayList<>();
-        for (float label : labels)
-            labelList.add(label);
-
-        for (int i=0; i<labels.length; i++) {
-            assertEquals(i, (int) mhs.get(float.class).invokeExact((float) labels[i]));
-            assertEquals(i, (int) mhs.get(Float.class).invokeExact((Float) labels[i]));
-        }
-
-        float[] someFloats = { 1.0f, Float.MIN_VALUE, 3.14f };
-        for (float f : someFloats) {
-            if (!labelList.contains(f)) {
-                assertEquals(labels.length, mhs.get(float.class).invoke((float) f));
-                assertEquals(labels.length, mhs.get(Float.class).invoke((float) f));
-            }
-        }
-
-        assertEquals(-1, (int) mhs.get(Float.class).invoke(null));
-    }
-
-    private void testDouble(double... labels) throws Throwable {
-        Map<Class<?>, MethodHandle> mhs
-                = Map.of(double.class, ((CallSite) BSM_DOUBLE_SWITCH.invoke(MethodHandles.lookup(), "", switchType(double.class), labels)).dynamicInvoker(),
-                         Double.class, ((CallSite) BSM_DOUBLE_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Double.class), labels)).dynamicInvoker());
-
-        var labelList = new ArrayList<Double>();
-        for (double label : labels)
-            labelList.add(label);
-
-        for (int i=0; i<labels.length; i++) {
-            assertEquals(i, (int) mhs.get(double.class).invokeExact((double) labels[i]));
-            assertEquals(i, (int) mhs.get(Double.class).invokeExact((Double) labels[i]));
-        }
-
-        double[] someDoubles = { 1.0, Double.MIN_VALUE, 3.14 };
-        for (double f : someDoubles) {
-            if (!labelList.contains(f)) {
-                assertEquals(labels.length, mhs.get(double.class).invoke((double) f));
-                assertEquals(labels.length, mhs.get(Double.class).invoke((double) f));
-            }
-        }
-
-        assertEquals(-1, (int) mhs.get(Double.class).invoke(null));
-    }
-
-    private void testLong(long... labels) throws Throwable {
-        Map<Class<?>, MethodHandle> mhs
-                = Map.of(long.class, ((CallSite) BSM_LONG_SWITCH.invoke(MethodHandles.lookup(), "", switchType(long.class), labels)).dynamicInvoker(),
-                         Long.class, ((CallSite) BSM_LONG_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Long.class), labels)).dynamicInvoker());
-
-        List<Long> labelList = new ArrayList<>();
-        for (long label : labels)
-            labelList.add(label);
-
-        for (int i=0; i<labels.length; i++) {
-            assertEquals(i, (int) mhs.get(long.class).invokeExact((long) labels[i]));
-            assertEquals(i, (int) mhs.get(Long.class).invokeExact((Long) labels[i]));
-        }
-
-        long[] someLongs = { 1L, Long.MIN_VALUE, Long.MAX_VALUE };
-        for (long l : someLongs) {
-            if (!labelList.contains(l)) {
-                assertEquals(labels.length, mhs.get(long.class).invoke((long) l));
-                assertEquals(labels.length, mhs.get(Long.class).invoke((long) l));
-            }
-        }
-
-        assertEquals(-1, (int) mhs.get(Long.class).invoke(null));
-    }
-
-    private void testString(String... targets) throws Throwable {
-        MethodHandle indy = ((CallSite) BSM_STRING_SWITCH.invoke(MethodHandles.lookup(), "", switchType(String.class), targets)).dynamicInvoker();
-        List<String> targetList = Stream.of(targets)
-                                        .collect(Collectors.toList());
-
-        for (int i=0; i<targets.length; i++) {
-            String s = targets[i];
-            int result = (int) indy.invoke(s);
-            assertEquals((s == null) ? -1 : i, result);
-        }
-
-        for (String s : List.of("", "A", "AA", "AAA", "AAAA")) {
-            if (!targetList.contains(s)) {
-                assertEquals(targets.length, indy.invoke(s));
-            }
-        }
-        assertEquals(-1, (int) indy.invoke(null));
-    }
-
-    private<E extends Enum<E>> void testEnum(Class<E> enumClass, String... targets) throws Throwable {
-        MethodHandle indy = ((CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Enum.class), enumClass, targets)).dynamicInvoker();
-        List<E> targetList = Stream.of(targets)
-                                   .map(s -> Enum.valueOf(enumClass, s))
-                                   .collect(Collectors.toList());
-
-        for (int i=0; i<targets.length; i++) {
-            String s = targets[i];
-            E e = Enum.valueOf(enumClass, s);
-            int result = (int) indy.invoke(e);
-            assertEquals((s == null) ? -1 : i, result);
-        }
-
-        for (E e : enumClass.getEnumConstants()) {
-            int index = (int) indy.invoke(e);
-            if (targetList.contains(e))
-                assertEquals(e.name(), targets[index]);
-            else
-                assertEquals(targets.length, index);
-        }
-
-        assertEquals(-1, (int) indy.invoke(null));
-    }
-
-    public void testBoolean() throws Throwable {
-        testBoolean(new boolean[0]);
-        testBoolean(false);
-        testBoolean(true);
-        testBoolean(false, true);
-    }
-
-    public void testInt() throws Throwable {
-        testInt(ALL_INT_TYPES, 8, 6, 7, 5, 3, 0, 9);
-        testInt(ALL_INT_TYPES, 1, 2, 4, 8, 16);
-        testInt(ALL_INT_TYPES, 5, 4, 3, 2, 1, 0);
-        testInt(SIGNED_TYPES, 5, 4, 3, 2, 1, 0, -1);
-        testInt(SIGNED_TYPES, -1);
-        testInt(ALL_INT_TYPES, new int[] { });
-
-        for (int i=0; i<5; i++) {
-            int len = 50 + random.nextInt(800);
-            int[] arr = IntStream.generate(() -> random.nextInt(10000) - 5000)
-                                 .distinct()
-                                 .limit(len)
-                                 .toArray();
-            testInt(SIGNED_NON_BYTE_TYPES, arr);
-
-            arr = IntStream.generate(() -> random.nextInt(10000))
-                    .distinct()
-                    .limit(len)
-                    .toArray();
-            testInt(CHAR_TYPES, arr);
-
-            arr = IntStream.generate(() -> random.nextInt(127) - 64)
-                           .distinct()
-                           .limit(120)
-                           .toArray();
-            testInt(BYTE_TYPES, arr);
-        }
-    }
-
-    public void testLong() throws Throwable {
-        testLong(1L, Long.MIN_VALUE, Long.MAX_VALUE);
-        testLong(8L, 2L, 5L, 4L, 3L, 9L, 1L);
-        testLong(new long[] { });
-
-        // @@@ Random tests
-        // @@@ More tests for weird values
-    }
-
-    public void testFloat() throws Throwable {
-        testFloat(0.0f, -0.0f, -1.0f, 1.0f, 3.14f, Float.MIN_VALUE, Float.MAX_VALUE, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY);
-        testFloat(new float[] { });
-        testFloat(0.0f, 1.0f, 3.14f, Float.NaN);
-
-        // @@@ Random tests
-        // @@@ More tests for weird values
-    }
-
-    public void testDouble() throws Throwable {
-        testDouble(0.0, -0.0, -1.0, 1.0, 3.14, Double.MIN_VALUE, Double.MAX_VALUE,
-                   Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY);
-        testDouble(new double[] { });
-        testDouble(0.0f, 1.0f, 3.14f, Double.NaN);
-
-        // @@@ Random tests
-        // @@@ More tests for weird values
-    }
-
-    public void testString() throws Throwable {
-        testString("a", "b", "c");
-        testString("c", "b", "a");
-        testString("cow", "pig", "horse", "orangutan", "elephant", "dog", "frog", "ant");
-        testString("a", "b", "c", "A", "B", "C");
-        testString("C", "B", "A", "c", "b", "a");
-
-        // Tests with hash collisions; Ba/CB, Ca/DB
-        testString("Ba", "CB");
-        testString("Ba", "CB", "Ca", "DB");
-
-        // Test with null
-        try {
-            testString("a", null, "c");
-            fail("expected failure");
-        }
-        catch (IllegalArgumentException t) {
-            // success
-        }
-    }
-
-    enum E1 { A, B }
-    enum E2 { C, D, E, F, G, H }
-
-    public void testEnum() throws Throwable {
-        testEnum(E1.class);
-        testEnum(E1.class, "A");
-        testEnum(E1.class, "A", "B");
-        testEnum(E1.class, "B", "A");
-        testEnum(E2.class, "C");
-        testEnum(E2.class, "C", "D", "E", "F", "H");
-        testEnum(E2.class, "H", "C", "G", "D", "F", "E");
-
-        // Bad enum class
-        try {
-            testEnum((Class) String.class, "A");
-            fail("expected failure");
-        }
-        catch (IllegalArgumentException t) {
-            // success
-        }
-
-        // Bad enum constants
-        try {
-            testEnum(E1.class, "B", "A", "FILE_NOT_FOUND");
-            fail("expected failure");
-        }
-        catch (IllegalArgumentException t) {
-            // success
-        }
-
-        // Null enum constant
-        try {
-            testEnum(E1.class, "A", null, "B");
-            fail("expected failure");
-        }
-        catch (IllegalArgumentException t) {
-            // success
-        }
-    }
-
-    private void testType(Object target, int result, Class... labels) throws Throwable {
-        MethodHandle indy = ((CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Object.class), labels)).dynamicInvoker();
-        assertEquals((int) indy.invoke(target), result);
-        assertEquals(-1, (int) indy.invoke(null));
-    }
-
-    public void testTypes() throws Throwable {
-        testType("", 0, String.class, Object.class);
-        testType("", 0, Object.class);
-        testType("", 1, Integer.class);
-        testType("", 1, Integer.class, Serializable.class);
-        testType(E1.A, 0, E1.class, Object.class);
-        testType(E2.C, 1, E1.class, Object.class);
-        testType(new Serializable() { }, 1, Comparable.class, Serializable.class);
-
-        // test failures: duplicates, nulls, dominance inversion
-    }
-}
--- a/test/langtools/tools/javac/modules/JavaBaseTest.java	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/modules/JavaBaseTest.java	Tue May 15 10:50:25 2018 +0200
@@ -29,6 +29,7 @@
  * @modules
  *      jdk.compiler/com.sun.tools.javac.api
  *      jdk.compiler/com.sun.tools.javac.main
+ *      jdk.compiler/com.sun.tools.javac.platform
  *      jdk.jdeps/com.sun.tools.classfile
  * @build toolbox.ToolBox toolbox.JavacTask
  * @run main JavaBaseTest
@@ -67,6 +68,10 @@
     );
 
     final List<String> targets = List.of("9", "10", "current");
+    
+    {
+        JDKPlatformProvider.
+    }
 
     enum Mode { SOURCE, CLASS };
 
--- a/test/langtools/tools/javac/switchexpr/ExpressionSwitch-old.out	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitch-old.out	Tue May 15 10:50:25 2018 +0200
@@ -1,2 +1,2 @@
-ExpressionSwitch.java:48:16: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.switch.expressions), 9, 10
+ExpressionSwitch.java:46:16: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.switch.expressions), 9, 10
 1 error
--- a/test/langtools/tools/javac/switchexpr/ExpressionSwitch.java	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitch.java	Tue May 15 10:50:25 2018 +0200
@@ -36,17 +36,14 @@
     }
 
     private void run() {
-        check(null, "NULL");
         check(T.A, "A");
         check(T.B, "B");
         check(T.C, "other");
         exhaustive1(T.C);
-        exhaustive2(null);
     }
 
     private String print(T t) {
         return switch (t) {
-            case null -> "NULL";
             case A -> "A";
             case B -> { break "B"; }
             default -> { break "other"; }
@@ -64,7 +61,6 @@
 
     private String exhaustive2(T t) {
         return switch (t) {
-            case null -> "NULL";
             case A -> "A";
             case B -> "B";
             case C -> "C";
--- a/test/langtools/tools/javac/switchexpr/ExpressionSwitchBugs.java	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitchBugs.java	Tue May 15 10:50:25 2018 +0200
@@ -55,8 +55,8 @@
         i = 0;
         check(42, id(switch (42) {
             case 42: if (i == 0) {
-                break 41 + switch (true) {
-                    case true -> 1;
+                break 41 + switch (0) {
+                    case 0 -> 1;
                     default -> -1;
                 };
             }
--- a/test/langtools/tools/javac/switchexpr/ExpressionSwitchFallThrough1.java	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitchFallThrough1.java	Tue May 15 10:50:25 2018 +0200
@@ -1,6 +1,3 @@
-
-import java.util.Objects;
-
 /*
  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -29,7 +26,8 @@
  * @compile ExpressionSwitchFallThrough1.java
  * @run main ExpressionSwitchFallThrough1
  */
-// * @compile/fail/ref=ExpressionSwitchFallThrough.out -XDrawDiagnistics ExpressionSwitchFallThrough.java
+
+import java.util.Objects;
 
 public class ExpressionSwitchFallThrough1 {
     public static void main(String... args) {
@@ -37,11 +35,9 @@
     }
 
     private void test() {
-        assertEquals("NULL01", printExprFallThrough(null));
         assertEquals("01", printExprFallThrough(0));
         assertEquals("1", printExprFallThrough(1));
         assertEquals("other", printExprFallThrough(3));
-        assertEquals("NULL01", printStatementFallThrough(null));
         assertEquals("01", printStatementFallThrough(0));
         assertEquals("1", printStatementFallThrough(1));
         assertEquals("other", printStatementFallThrough(3));
@@ -50,7 +46,6 @@
     private String printExprFallThrough(Integer p) {
         String result = "";
         return switch (p) {
-            case null: result += "NULL";
             case 0: result += "0";
             case 1: result += "1";
                 break result;
@@ -61,7 +56,6 @@
     private String printStatementFallThrough(Integer p) {
         String result = "";
         switch (p) {
-            case null: result += "NULL";
             case 0: result += "0";
             case 1: result += "1";
                 break ;
--- a/test/langtools/tools/javac/switchexpr/ExpressionSwitchInfer.java	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitchInfer.java	Tue May 15 10:50:25 2018 +0200
@@ -9,16 +9,18 @@
 
 public class ExpressionSwitchInfer {
 
+    private static final String NULL = "null";
+
     private <T> T test(List<T> l, Class<T> c, String param) {
-        test(param == null ? new ArrayList<>() : new ArrayList<>(), CharSequence.class, param).charAt(0);
-        test(param == null ? new ArrayList<>() : new ArrayList<>(), CharSequence.class, param).substring(0);
+        test(param == NULL ? new ArrayList<>() : new ArrayList<>(), CharSequence.class, param).charAt(0);
+        test(param == NULL ? new ArrayList<>() : new ArrayList<>(), CharSequence.class, param).substring(0);
 
         test(switch (param) {
-            case null -> new ArrayList<>();
+            case NULL -> new ArrayList<>();
             default -> new ArrayList<>();
         }, CharSequence.class, param).charAt(0);
         test(switch (param) {
-            case null -> new ArrayList<>();
+            case NULL -> new ArrayList<>();
             default -> new ArrayList<>();
         }, CharSequence.class, param).substring(0);
 
--- a/test/langtools/tools/javac/switchexpr/ExpressionSwitchInfer.out	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/switchexpr/ExpressionSwitchInfer.out	Tue May 15 10:50:25 2018 +0200
@@ -1,3 +1,3 @@
-ExpressionSwitchInfer.java:14:95: compiler.err.cant.resolve.location.args: kindname.method, substring, , int, (compiler.misc.location: kindname.interface, java.lang.CharSequence, null)
-ExpressionSwitchInfer.java:23:38: compiler.err.cant.resolve.location.args: kindname.method, substring, , int, (compiler.misc.location: kindname.interface, java.lang.CharSequence, null)
+ExpressionSwitchInfer.java:16:95: compiler.err.cant.resolve.location.args: kindname.method, substring, , int, (compiler.misc.location: kindname.interface, java.lang.CharSequence, null)
+ExpressionSwitchInfer.java:25:38: compiler.err.cant.resolve.location.args: kindname.method, substring, , int, (compiler.misc.location: kindname.interface, java.lang.CharSequence, null)
 2 errors
--- a/test/langtools/tools/javac/switchextra/MultipleLabelsExpression-old.out	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/switchextra/MultipleLabelsExpression-old.out	Tue May 15 10:50:25 2018 +0200
@@ -1,3 +1,3 @@
-MultipleLabelsExpression.java:53:16: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.switch.expressions), 9, 10
-MultipleLabelsExpression.java:54:22: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.multiple.case.labels), 9, 10
+MultipleLabelsExpression.java:52:16: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.switch.expressions), 9, 10
+MultipleLabelsExpression.java:54:19: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.multiple.case.labels), 9, 10
 2 errors
--- a/test/langtools/tools/javac/switchextra/MultipleLabelsExpression.java	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/switchextra/MultipleLabelsExpression.java	Tue May 15 10:50:25 2018 +0200
@@ -41,8 +41,7 @@
     }
 
     private void runTest(Function<T, String> print) {
-        check(null, print, "NULL-A");
-        check(T.A,  print, "NULL-A");
+        check(T.A,  print, "A");
         check(T.B,  print, "B-C");
         check(T.C,  print, "B-C");
         check(T.D,  print, "D");
@@ -51,7 +50,7 @@
 
     private String expression1(T t) {
         return switch (t) {
-            case null, A -> "NULL-A";
+            case A -> "A";
             case B, C -> { break "B-C"; }
             case D -> "D";
             default -> "other";
--- a/test/langtools/tools/javac/switchextra/MultipleLabelsStatement-old.out	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/switchextra/MultipleLabelsStatement-old.out	Tue May 15 10:50:25 2018 +0200
@@ -1,2 +1,2 @@
-MultipleLabelsStatement.java:56:24: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.multiple.case.labels), 9, 10
+MultipleLabelsStatement.java:56:21: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.multiple.case.labels), 9, 10
 1 error
--- a/test/langtools/tools/javac/switchextra/MultipleLabelsStatement.java	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/switchextra/MultipleLabelsStatement.java	Tue May 15 10:50:25 2018 +0200
@@ -41,8 +41,7 @@
     }
 
     private void runTest(Function<T, String> print) {
-        check(null, print, "NULL-A");
-        check(T.A,  print, "NULL-A");
+        check(T.A,  print, "A");
         check(T.B,  print, "B-C");
         check(T.C,  print, "B-C");
         check(T.D,  print, "D");
@@ -53,7 +52,7 @@
         String res;
 
         switch (t) {
-            case null, A: res = "NULL-A"; break;
+            case A: res = "A"; break;
             case B, C: res = "B-C"; break;
             case D: res = "D"; break;
             default: res = "other"; break;
--- a/test/langtools/tools/javac/switchextra/SwitchBooleanExhaustivness.java	Thu May 10 22:08:15 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * @test /nodynamiccopyright/
- * @compile/fail/ref=SwitchBooleanExhaustivness.out -XDrawDiagnostics SwitchBooleanExhaustivness.java
- */
-public class SwitchBooleanExhaustivness {
-
-    private int exhaustive1(boolean b) {
-        switch (b) {
-            case false: return 0;
-            case true: return 1;
-        }
-    }
-
-    private int exhaustive2(boolean b) {
-        switch (b) {
-            case false: return 0;
-            default: return 1;
-        }
-    }
-
-    private int exhaustive3(boolean b) {
-        return switch (b) {
-            case false: break 0;
-            case true: break 1;
-        };
-    }
-
-    private int exhaustive4(boolean b) {
-        return switch (b) {
-            case false: break 0;
-            default: break 1;
-        };
-    }
-
-    private int notExhaustive1(boolean b) {
-        switch (b) {
-            case false: return 0;
-        }
-    }
-
-    private int notExhaustive2(boolean b) {
-        return switch (b) {
-            case false: break 0;
-        };
-    }
-
-}
\ No newline at end of file
--- a/test/langtools/tools/javac/switchextra/SwitchBooleanExhaustivness.out	Thu May 10 22:08:15 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-SwitchBooleanExhaustivness.java:39:5: compiler.err.missing.ret.stmt
-SwitchBooleanExhaustivness.java:42:16: compiler.err.not.exhaustive
-2 errors
--- a/test/langtools/tools/javac/switchextra/SwitchExtra-old.out	Thu May 10 22:08:15 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-SwitchExtra.java:186:16: compiler.err.feature.not.supported.in.source.plural: (compiler.misc.feature.switch.expressions), 9, 10
-SwitchExtra.java:91:16: compiler.err.feature.not.supported.in.source: (compiler.misc.feature.switch.extra.types), 9, 10
-2 errors
--- a/test/langtools/tools/javac/switchextra/SwitchExtra.java	Thu May 10 22:08:15 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2018, 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
- * @compile/fail/ref=SwitchExtra-old.out -source 9 -Xlint:-options -XDrawDiagnostics -XDshould-stop.at=FLOW SwitchExtra.java
- * @compile SwitchExtra.java
- * @run main SwitchExtra
- */
-public class SwitchExtra {
-    public static void main(String... args) {
-        new SwitchExtra().run();
-    }
-
-    private static final long LONG_KEY = 2L << 32;
-
-    private void run() {
-        assertEquals(0, longSwitch(-1));
-        assertEquals(1, longSwitch(Long.MIN_VALUE));
-        assertEquals(2, longSwitch(Long.MAX_VALUE));
-        assertEquals(3, longSwitch(LONG_KEY));
-        assertEquals(4, longSwitch(0));
-        assertEquals(5, longSwitch(LONG_KEY + 1));
-        assertEquals(0, longSwitchBoxed(-1l));
-        assertEquals(1, longSwitchBoxed(Long.MIN_VALUE));
-        assertEquals(2, longSwitchBoxed(Long.MAX_VALUE));
-        assertEquals(3, longSwitchBoxed(LONG_KEY));
-        assertEquals(4, longSwitchBoxed(0l));
-        assertEquals(5, longSwitchBoxed(LONG_KEY + 1));
-        assertEquals(0, floatSwitch(-1f));
-        assertEquals(1, floatSwitch(Float.MIN_VALUE));
-        assertEquals(2, floatSwitch(Float.MAX_VALUE));
-        assertEquals(3, floatSwitch(Float.NaN));
-        assertEquals(4, floatSwitch(Float.NEGATIVE_INFINITY));
-        assertEquals(5, floatSwitch(Float.POSITIVE_INFINITY));
-        assertEquals(6, floatSwitch(0));
-        assertEquals(7, floatSwitch(3.14f));
-        assertEquals(0, floatSwitchBoxed(-1f));
-        assertEquals(1, floatSwitchBoxed(Float.MIN_VALUE));
-        assertEquals(2, floatSwitchBoxed(Float.MAX_VALUE));
-        assertEquals(3, floatSwitchBoxed(Float.NaN));
-        assertEquals(4, floatSwitchBoxed(Float.NEGATIVE_INFINITY));
-        assertEquals(5, floatSwitchBoxed(Float.POSITIVE_INFINITY));
-        assertEquals(6, floatSwitchBoxed(0f));
-        assertEquals(7, floatSwitchBoxed(3.14f));
-        assertEquals(0, doubleSwitch(-1d));
-        assertEquals(1, doubleSwitch(Double.MIN_VALUE));
-        assertEquals(2, doubleSwitch(Double.MAX_VALUE));
-        assertEquals(3, doubleSwitch(Double.NaN));
-        assertEquals(4, doubleSwitch(Double.NEGATIVE_INFINITY));
-        assertEquals(5, doubleSwitch(Double.POSITIVE_INFINITY));
-        assertEquals(6, doubleSwitch(0));
-        assertEquals(7, doubleSwitch(3.14));
-        assertEquals(0, doubleSwitchBoxed(-1d));
-        assertEquals(1, doubleSwitchBoxed(Double.MIN_VALUE));
-        assertEquals(2, doubleSwitchBoxed(Double.MAX_VALUE));
-        assertEquals(3, doubleSwitchBoxed(Double.NaN));
-        assertEquals(4, doubleSwitchBoxed(Double.NEGATIVE_INFINITY));
-        assertEquals(5, doubleSwitchBoxed(Double.POSITIVE_INFINITY));
-        assertEquals(6, doubleSwitchBoxed(0d));
-        assertEquals(7, doubleSwitchBoxed(3.14));
-        assertEquals(0, booleanSwitch1(false));
-        assertEquals(1, booleanSwitch1(true));
-        assertEquals(0, booleanSwitch2(false));
-        assertEquals(1, booleanSwitch2(true));
-        assertEquals(0, booleanSwitchBoxed(false));
-        assertEquals(1, booleanSwitchBoxed(true));
-    }
-
-    private int longSwitch(long l) {
-        switch (l) {
-            case -1: return 0;
-            case Long.MIN_VALUE: return 1;
-            case Long.MAX_VALUE: return 2;
-            case LONG_KEY: return 3;
-            case 0: return 4;
-            default: return 5;
-        }
-    }
-
-    private int longSwitchBoxed(Long l) {
-        switch (l) {
-            case -1: return 0;
-            case Long.MIN_VALUE: return 1;
-            case Long.MAX_VALUE: return 2;
-            case LONG_KEY: return 3;
-            case 0: return 4;
-            default: return 5;
-        }
-    }
-
-    private int floatSwitch(float f) {
-        switch (f) {
-            case -1: return 0;
-            case Float.MIN_VALUE: return 1;
-            case Float.MAX_VALUE: return 2;
-            case Float.NaN: return 3;
-            case Float.NEGATIVE_INFINITY: return 4;
-            case Float.POSITIVE_INFINITY: return 5;
-            case 0.0f: return 6;
-            default: return 7;
-        }
-    }
-
-    private int floatSwitchBoxed(Float f) {
-        switch (f) {
-            case -1: return 0;
-            case Float.MIN_VALUE: return 1;
-            case Float.MAX_VALUE: return 2;
-            case Float.NaN: return 3;
-            case Float.NEGATIVE_INFINITY: return 4;
-            case Float.POSITIVE_INFINITY: return 5;
-            case 0.0f: return 6;
-            default: return 7;
-        }
-    }
-
-    private int doubleSwitch(double d) {
-        switch (d) {
-            case -1: return 0;
-            case Double.MIN_VALUE: return 1;
-            case Double.MAX_VALUE: return 2;
-            case Double.NaN: return 3;
-            case Double.NEGATIVE_INFINITY: return 4;
-            case Double.POSITIVE_INFINITY: return 5;
-            case 0.0: return 6;
-            default: return 7;
-        }
-    }
-
-    private int doubleSwitchBoxed(Double d) {
-        switch (d) {
-            case -1: return 0;
-            case Double.MIN_VALUE: return 1;
-            case Double.MAX_VALUE: return 2;
-            case Double.NaN: return 3;
-            case Double.NEGATIVE_INFINITY: return 4;
-            case Double.POSITIVE_INFINITY: return 5;
-            case 0.0: return 6;
-            default: return 7;
-        }
-    }
-
-    private int booleanSwitch1(boolean b) {
-        switch (b) {
-            case false: return 0;
-            case true: return 1;
-        }
-    }
-
-    private int booleanSwitch2(boolean b) {
-        switch (b) {
-            case false: return 0;
-            default: return 1;
-        }
-    }
-
-    private int booleanSwitchBoxed(Boolean b) {
-        switch (b) {
-            case false: return 0;
-            case true: return 1;
-        }
-    }
-
-    private int booleanSwitchExpr(boolean b) {
-        return switch (b) {
-            case false -> 0;
-            case true -> 1;
-        };
-    }
-
-    private void assertEquals(int expected, int actual) {
-        if (expected != actual) {
-            throw new AssertionError();
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/switchextra/SwitchNoExtraTypes.java	Tue May 15 10:50:25 2018 +0200
@@ -0,0 +1,32 @@
+/**
+ * @test
+ * @compile/fail/ref=SwitchNoExtraTypes.out -XDrawDiagnostics SwitchNoExtraTypes.java
+ */
+
+public class SwitchNoExtraTypes {
+
+    private void switchBoolean(boolean b) {
+        switch (b) {
+            case true: return ;
+        }
+    }
+
+    private void switchLong(long l) {
+        switch (l) {
+            case 0: return ;
+        }
+    }
+
+    private void switchFloat(float f) {
+        switch (f) {
+            case 0: return ;
+        }
+    }
+
+    private void switchDouble(double d) {
+        switch (d) {
+            case 0: return ;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/switchextra/SwitchNoExtraTypes.out	Tue May 15 10:50:25 2018 +0200
@@ -0,0 +1,5 @@
+SwitchNoExtraTypes.java:9:16: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: boolean, int)
+SwitchNoExtraTypes.java:15:16: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: long, int)
+SwitchNoExtraTypes.java:21:16: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: float, int)
+SwitchNoExtraTypes.java:27:16: compiler.err.prob.found.req: (compiler.misc.possible.loss.of.precision: double, int)
+4 errors
--- a/test/langtools/tools/javac/switchextra/SwitchObject.out	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/switchextra/SwitchObject.out	Tue May 15 10:50:25 2018 +0200
@@ -1,2 +1,2 @@
-SwitchObject.java:8:16: compiler.err.switch.invalid.type: java.lang.Object
+SwitchObject.java:8:16: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Object, int)
 1 error
--- a/test/langtools/tools/javac/switchextra/SwitchStatementArrow.java	Thu May 10 22:08:15 2018 +0200
+++ b/test/langtools/tools/javac/switchextra/SwitchStatementArrow.java	Tue May 15 10:50:25 2018 +0200
@@ -41,8 +41,7 @@
     }
 
     private void runTest(Function<T, String> print) {
-        check(null, print, "NULL-A");
-        check(T.A,  print, "NULL-A");
+        check(T.A,  print, "A");
         check(T.B,  print, "B-C");
         check(T.C,  print, "B-C");
         try {
@@ -59,7 +58,7 @@
         String res;
 
         switch (t) {
-            case null, A -> { res = "NULL-A"; }
+            case A -> { res = "A"; }
             case B, C -> res = "B-C";
             case D -> throw new IllegalStateException("D");
             default -> { res = "other"; break; }
--- a/test/langtools/tools/javac/switchnull/SwitchNull-old.out	Thu May 10 22:08:15 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-SwitchNull.java:32:16: compiler.err.feature.not.supported.in.source: (compiler.misc.feature.case.null), 9, 10
-1 error
--- a/test/langtools/tools/javac/switchnull/SwitchNull.java	Thu May 10 22:08:15 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/**
- * @test
- * @compile/fail/ref=SwitchNull-old.out -source 9 -Xlint:-options -XDrawDiagnostics SwitchNull.java
- * @compile/fail/ref=SwitchNull.out -XDdisableIndySwitch=true -XDrawDiagnostics SwitchNull.java
- * @compile SwitchNull.java
- * @run main SwitchNull
- */
-
-public class SwitchNull {
-    public static void main(String... args) {
-        new SwitchNull().run();
-    }
-
-    private void run() {
-        assertEquals(0, stringNoNPE(null));
-        assertEquals(1, stringNoNPE(""));
-        assertEquals(2, stringNoNPE("other"));
-        assertEquals(0, stringNoNPENotFirst1(null));
-        assertEquals(0, stringNoNPENotFirst2(null));
-        assertEquals(0, boxNoNPE(null));
-        assertEquals(1, boxNoNPE(1));
-        assertEquals(2, boxNoNPE(2));
-        assertEquals(0, boxByteNoNPE(null));
-        assertEquals(1, boxByteNoNPE((byte) 1));
-        assertEquals(2, boxByteNoNPE((byte) 2));
-        assertEquals(0, enumNoNPE(null));
-        assertEquals(1, enumNoNPE(E.A));
-        assertEquals(2, enumNoNPE(E.B));
-    }
-
-    private int stringNoNPE(String str) {
-        switch (str) {
-            case null: return 0;
-            case "": return 1;
-            default: return 2;
-        }
-    }
-
-    private int stringNoNPENotFirst1(String str) {
-        switch (str) {
-            case "": return 1;
-            case null: return 0;
-            default: return 2;
-        }
-    }
-
-    private int stringNoNPENotFirst2(String str) {
-        switch (str) {
-            case "": return 1;
-            default: return 2;
-            case null: return 0;
-        }
-    }
-
-    private int boxNoNPE(Integer i) {
-        switch (i) {
-            case null: return 0;
-            case 1: return 1;
-            default: return 2;
-        }
-    }
-
-    private int boxByteNoNPE(Byte i) {
-        switch (i) {
-            case null: return 0;
-            case 1: return 1;
-            default: return 2;
-        }
-    }
-
-    private int enumNoNPE(E e) {
-        switch (e) {
-            case null: return 0;
-            case A: return 1;
-            default: return 2;
-        }
-    }
-
-    private static enum E {
-        A, B;
-    }
-
-    private void assertEquals(int expected, int actual) {
-        if (expected != actual) {
-            throw new AssertionError();
-        }
-    }
-}
--- a/test/langtools/tools/javac/switchnull/SwitchNull.out	Thu May 10 22:08:15 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-SwitchNull.java:32:9: compiler.err.no.legacy.desugaring
-SwitchNull.java:40:9: compiler.err.no.legacy.desugaring
-SwitchNull.java:48:9: compiler.err.no.legacy.desugaring
-SwitchNull.java:56:9: compiler.err.no.legacy.desugaring
-SwitchNull.java:64:9: compiler.err.no.legacy.desugaring
-SwitchNull.java:72:9: compiler.err.no.legacy.desugaring
-6 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/switchnull/SwitchNullDisabled.java	Tue May 15 10:50:25 2018 +0200
@@ -0,0 +1,14 @@
+/**
+ * @test
+ * @compile/fail/ref=SwitchNullDisabled.out -XDrawDiagnostics SwitchNullDisabled.java
+ */
+
+public class SwitchNullDisabled {
+    private int switchNull(String str) {
+        switch (str) {
+            case null: return 0;
+            case "": return 1;
+            default: return 2;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/switchnull/SwitchNullDisabled.out	Tue May 15 10:50:25 2018 +0200
@@ -0,0 +1,2 @@
+SwitchNullDisabled.java:9:18: compiler.err.switch.null.not.allowed
+1 error
--- a/test/langtools/tools/javac/switchnull/SwitchNullNegative.java	Thu May 10 22:08:15 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/**
- * @test /nodynamiccopyright/
- * @compile/fail/ref=SwitchNullNegative.out -XDrawDiagnostics SwitchNullNegative.java
- */
-
-public class SwitchNullNegative {
-    private int notReference(int i) {
-        switch (i) {
-            case null: return 0;
-            case 1: return 1;
-            default: return 2;
-        }
-    }
-
-    private int notReferenceExpression(int i) {
-        return switch (i) {
-            case null -> 0;
-            case 1 -> 1;
-            default -> 2;
-        };
-    }
-
-    private int repeatedStatement(Integer i) {
-        return switch (i) {
-            case 0: break 0;
-            case null: break -1;
-            case null: break -1;
-            case 1: break 1;
-        };
-    }
-
-    private int repeatedExpression(Integer i) {
-        return switch (i) {
-            case 0 -> 0;
-            case null -> -1;
-            case null -> -1;
-            case 1 -> 1;
-        };
-    }
-}
--- a/test/langtools/tools/javac/switchnull/SwitchNullNegative.out	Thu May 10 22:08:15 2018 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-SwitchNullNegative.java:9:13: compiler.err.switch.null.must.be.reference
-SwitchNullNegative.java:17:13: compiler.err.switch.null.must.be.reference
-SwitchNullNegative.java:27:13: compiler.err.duplicate.case.label
-SwitchNullNegative.java:36:13: compiler.err.duplicate.case.label
-4 errors