Version 2.16.0-115.0.dev

Merge commit '59979dc9733498772cfe00c8baceb61a00da7770' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 181ddae..514d859 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -612,22 +612,20 @@
     }
 
     var conditionResultBool = conditionResult.toBoolValue();
-    if (conditionResultBool == null) {
-      node.thenExpression.accept(this);
-      node.elseExpression.accept(this);
-    } else if (conditionResultBool == true) {
+    if (conditionResultBool == true) {
       _reportNotPotentialConstants(node.elseExpression);
       return node.thenExpression.accept(this);
     } else if (conditionResultBool == false) {
       _reportNotPotentialConstants(node.thenExpression);
       return node.elseExpression.accept(this);
+    } else {
+      node.thenExpression.accept(this);
+      node.elseExpression.accept(this);
+      return DartObjectImpl.validWithUnknownValue(
+        typeSystem,
+        node.typeOrThrow,
+      );
     }
-
-    // We used to return an object with a known type and an unknown value, but
-    // we can't do that without evaluating both the 'then' and 'else'
-    // expressions, and we're not suppose to do that under lazy semantics. I'm
-    // not sure which failure mode is worse.
-    return null;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 313caf6..b6c4de1 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -165,7 +165,7 @@
   /// Create an object to represent an unknown value.
   factory DartObjectImpl.validWithUnknownValue(
     TypeSystemImpl typeSystem,
-    ParameterizedType type,
+    DartType type,
   ) {
     if (type.element!.library!.isDartCore) {
       if (type.isDartCoreBool) {
diff --git a/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart b/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
index f9bcac1..cdd3c81 100644
--- a/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_constructor_param_type_mismatch_test.dart
@@ -288,6 +288,20 @@
       error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 46, 5),
     ]);
   }
+
+  test_unknown_conditionalExpression_unknownCondition() async {
+    await assertNoErrorsInCode(r'''
+const bool kIsWeb = identical(0, 0.0);
+
+void f() {
+  const A(kIsWeb ? 0 : 1);
+}
+
+class A {
+  const A(int _);
+}
+''');
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
index 8b46bb4..e961fd2 100644
--- a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
+++ b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
@@ -882,307 +882,3 @@
   final js.Statement statement;
   HolderInitCode(this.allHolders, this.activeHolders, this.statement);
 }
-
-/// All of the code below this point is legacy code.
-
-/// [DeferredHolderExpressionFinalizerImpl] finalizes
-/// [DeferredHolderExpression]s, [DeferredHolderParameter]s,
-/// [DeferredHolderResource]s, [DeferredHolderResourceExpression]s.
-class LegacyDeferredHolderExpressionFinalizerImpl
-    implements DeferredHolderExpressionFinalizer {
-  _DeferredHolderExpressionCollectorVisitor _visitor;
-  final List<DeferredHolderExpression> holderReferences = [];
-  final List<DeferredHolderParameter> holderParameters = [];
-  final List<DeferredHolderResource> holderResources = [];
-  final Set<String> _uniqueHolders = {};
-  final List<String> _holders = [];
-  final Map<Entity, String> _entityMap = {};
-  final JCommonElements _commonElements;
-
-  LegacyDeferredHolderExpressionFinalizerImpl(this._commonElements) {
-    _visitor = _DeferredHolderExpressionCollectorVisitor(this);
-  }
-
-  @override
-  void addCode(String resourceName, js.Node code) {
-    _visitor.setResourceNameAndVisit(resourceName, code);
-  }
-
-  final List<String> userGlobalObjects =
-      List.from(Namer.reservedGlobalObjectNames)
-        ..remove('C')
-        ..remove('H')
-        ..remove('J')
-        ..remove('P')
-        ..remove('W');
-
-  /// Returns the [reservedGlobalObjectNames] for [library].
-  String globalObjectForLibrary(LibraryEntity library) {
-    if (library == _commonElements.interceptorsLibrary) return 'J';
-    Uri uri = library.canonicalUri;
-    if (uri.scheme == 'dart') {
-      if (uri.path == 'html') return 'W';
-      if (uri.path.startsWith('_')) return 'H';
-      return 'P';
-    }
-    return userGlobalObjects[library.name.hashCode % userGlobalObjects.length];
-  }
-
-  /// Returns true if [element] is stored in the static state holder
-  /// ([staticStateHolder]).  We intend to store only mutable static state
-  /// there, whereas constants are stored in 'C'. Functions, accessors,
-  /// classes, etc. are stored in one of the other objects in
-  /// [reservedGlobalObjectNames].
-  bool _isPropertyOfStaticStateHolder(MemberEntity element) {
-    // TODO(ahe): Make sure this method's documentation is always true and
-    // remove the word "intend".
-    return element.isField;
-  }
-
-  String globalObjectForMember(MemberEntity entity) {
-    if (_isPropertyOfStaticStateHolder(entity)) {
-      return globalObjectForStaticState();
-    } else {
-      return globalObjectForLibrary(entity.library);
-    }
-  }
-
-  String globalObjectForClass(ClassEntity entity) {
-    return globalObjectForLibrary(entity.library);
-  }
-
-  String globalObjectForInterceptors() => 'J';
-
-  String globalObjectForStaticState() => r'$';
-
-  String globalObjectForConstants() => 'C';
-
-  String globalObjectForEntity(Entity entity) {
-    if (entity is MemberEntity) {
-      return globalObjectForMember(entity);
-    } else if (entity is ClassEntity) {
-      return globalObjectForLibrary(entity.library);
-    } else {
-      assert(entity is LibraryEntity);
-      return globalObjectForLibrary(entity);
-    }
-  }
-
-  /// Registers an [Entity] with a specific [holder].
-  void registerHolderUse(String holder, Object data) {
-    if (_uniqueHolders.add(holder)) _holders.add(holder);
-    if (data != null && data is Entity) {
-      assert(!_entityMap.containsKey(data) || _entityMap[data] == holder);
-      _entityMap[data] = holder;
-    }
-  }
-
-  /// Returns a global object for a given [Object] based on the
-  /// [DeferredHolderExpressionKind].
-  String kindToHolder(DeferredHolderExpressionKind kind, Object data) {
-    switch (kind) {
-      case DeferredHolderExpressionKind.globalObjectForInterceptors:
-        return globalObjectForInterceptors();
-      case DeferredHolderExpressionKind.globalObjectForClass:
-        return globalObjectForClass(data);
-      case DeferredHolderExpressionKind.globalObjectForMember:
-        return globalObjectForMember(data);
-      case DeferredHolderExpressionKind.globalObjectForConstant:
-        return globalObjectForConstants();
-      case DeferredHolderExpressionKind.globalObjectForStaticState:
-        return globalObjectForStaticState();
-    }
-    throw UnsupportedError("Unreachable");
-  }
-
-  /// Finalizes [DeferredHolderExpression]s [DeferredHolderParameter]s.
-  void finalizeReferences() {
-    // Finalize [DeferredHolderExpression]s and registers holder usage.
-    for (var reference in holderReferences) {
-      if (reference.isFinalized) continue;
-      Object data = reference.data;
-      String holder = kindToHolder(reference.kind, data);
-      js.Expression value = js.VariableUse(holder);
-      registerHolderUse(holder, data);
-      reference.value =
-          value.withSourceInformation(reference.sourceInformation);
-    }
-
-    // Finalize [DeferredHolderParameter]s.
-    for (var parameter in holderParameters) {
-      if (parameter.isFinalized) continue;
-      parameter.name = globalObjectForStaticState();
-    }
-  }
-
-  /// Registers all of the holders used by a given [DeferredHolderResource].
-  void registerHolders(DeferredHolderResource resource) {
-    for (var entity in resource.holderCode.keys) {
-      var holder = globalObjectForEntity(entity);
-      registerHolderUse(holder, entity);
-    }
-  }
-
-  /// Returns a [List<String>] containing all of the holders except the static
-  /// state holder.
-  List<String> get nonStaticStateHolders {
-    return _holders
-        .where((holder) => holder != globalObjectForStaticState())
-        .toList(growable: false);
-  }
-
-  /// Generates code to declare holders.
-  LegacyHolderCode declareHolders(DeferredHolderResource resource) {
-    // Collect all holders except the static state holder. Then, create a map of
-    // holder to list of properties which are associated with that holder, but
-    // only with respect to a given [DeferredHolderResource]. Each fragment will
-    // have its own [DeferredHolderResource] and associated code.
-    Map<String, List<js.Property>> codePerHolder = {};
-    final holders = nonStaticStateHolders;
-    for (var holder in holders) {
-      codePerHolder[holder] = [];
-    }
-
-    final holderCode = resource.holderCode;
-    holderCode.forEach((entity, properties) {
-      assert(_entityMap.containsKey(entity));
-      var holder = _entityMap[entity];
-      assert(codePerHolder.containsKey(holder));
-      codePerHolder[holder].addAll(properties);
-    });
-
-    // Create holder initialization code based on the [codePerHolder]. If there
-    // are no properties associated with a given holder in this specific
-    // [DeferredHolderResource] then it will be omitted. However, in some cases,
-    // i.e. the main output unit, we still want to declare the holder with an
-    // empty object literal which will be filled in later by another
-    // [DeferredHolderResource], i.e. in a specific deferred fragment.
-    // The generated code looks like this:
-    //
-    //    {
-    //      var H = {...}, ..., G = {...};
-    //      var holders = [ H, ..., G ]; // Main unit only.
-    //    }
-
-    List<String> activeHolders = [];
-    List<js.VariableInitialization> holderInitializations = [];
-    for (var holder in holders) {
-      List<js.Property> properties = codePerHolder[holder];
-      if (properties.isEmpty) {
-        holderInitializations.add(js.VariableInitialization(
-            js.VariableDeclaration(holder, allowRename: false),
-            resource.isMainFragment ? js.ObjectInitializer(properties) : null));
-      } else {
-        activeHolders.add(holder);
-        holderInitializations.add(js.VariableInitialization(
-            js.VariableDeclaration(holder, allowRename: false),
-            js.ObjectInitializer(properties)));
-      }
-    }
-
-    List<js.Statement> statements = [];
-    statements.add(js.ExpressionStatement(js.VariableDeclarationList(
-        holderInitializations,
-        indentSplits: false)));
-    if (resource.isMainFragment) {
-      statements.add(js.js.statement(
-          'var holders = #',
-          js.ArrayInitializer(holders
-              .map((holder) => js.VariableUse(holder))
-              .toList(growable: false))));
-    }
-    return LegacyHolderCode(activeHolders, statements);
-  }
-
-  /// Finalizes [resource] to code that updates holders. [resource] must be in
-  /// the AST of a deferred fragment.
-  void updateHolders(DeferredHolderResource resource) {
-    // Declare holders.
-    final holderCode = declareHolders(resource);
-
-    // Set names if necessary on deferred holders list.
-    js.Expression deferredHoldersList = js.ArrayInitializer(holderCode
-        .activeHolders
-        .map((holder) => js.js("#", holder))
-        .toList(growable: false));
-    js.Statement setNames = js.js.statement(
-        'hunkHelpers.setFunctionNamesIfNecessary(#deferredHoldersList)',
-        {'deferredHoldersList': deferredHoldersList});
-
-    // Update holder assignments.
-    final holders = nonStaticStateHolders;
-    List<js.Statement> updateHolderAssignments = [setNames];
-    for (int i = 0; i < holders.length; i++) {
-      var holder = holders[i];
-      if (holderCode.activeHolders.contains(holder)) {
-        updateHolderAssignments.add(js.js.statement(
-            '#holder = hunkHelpers.updateHolder(holdersList[#index], #holder)',
-            {'index': js.number(i), 'holder': js.VariableUse(holder)}));
-      } else {
-        // TODO(sra): Change declaration followed by assignments to declarations
-        // with initialization.
-        updateHolderAssignments.add(js.js.statement(
-            '#holder = holdersList[#index]',
-            {'index': js.number(i), 'holder': js.VariableUse(holder)}));
-      }
-    }
-
-    // Create a single block of all statements.
-    List<js.Statement> statements = holderCode.statements
-        .followedBy(updateHolderAssignments)
-        .toList(growable: false);
-    resource.statement = js.Block(statements);
-  }
-
-  /// Allocates all [DeferredHolderResource]s and
-  /// [DeferredHolderResourceExpression]s.
-  void allocateResources() {
-    // First ensure all holders used in all [DeferredHolderResource]s have been
-    // allocated.
-    for (var resource in holderResources) {
-      registerHolders(resource);
-    }
-    _holders.sort();
-
-    // Next finalize all [DeferredHolderResource]s.
-    for (var resource in holderResources) {
-      switch (resource.kind) {
-        case DeferredHolderResourceKind.mainFragment:
-          var holderCode = declareHolders(resource);
-          resource.statement = js.Block(holderCode.statements);
-          break;
-        case DeferredHolderResourceKind.deferredFragment:
-          updateHolders(resource);
-          break;
-      }
-    }
-  }
-
-  @override
-  void finalize() {
-    finalizeReferences();
-    allocateResources();
-  }
-
-  @override
-  void registerDeferredHolderExpression(
-      String resourceName, DeferredHolderExpression node) {
-    holderReferences.add(node);
-  }
-
-  @override
-  void registerDeferredHolderResource(DeferredHolderResource node) {
-    holderResources.add(node);
-  }
-
-  @override
-  void registerDeferredHolderParameter(DeferredHolderParameter node) {
-    holderParameters.add(node);
-  }
-}
-
-class LegacyHolderCode {
-  final List<String> activeHolders;
-  final List<js.Statement> statements;
-  LegacyHolderCode(this.activeHolders, this.statements);
-}
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 5e67e37..e07ef90 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -640,10 +640,8 @@
       this._nativeEmitter,
       this._closedWorld,
       this._codegenWorld)
-      : _holderFinalizer = _options.features.newHolders.isEnabled
-            ? DeferredHolderExpressionFinalizerImpl(_closedWorld.commonElements)
-            : LegacyDeferredHolderExpressionFinalizerImpl(
-                _closedWorld.commonElements) {
+      : _holderFinalizer =
+            DeferredHolderExpressionFinalizerImpl(_closedWorld.commonElements) {
     _recipeEncoder = RecipeEncoderImpl(
         _closedWorld,
         _options.disableRtiOptimization
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index de9ddca..ea27263 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -64,7 +64,6 @@
         DeferredHolderParameter,
         DeferredHolderResource,
         DeferredHolderResourceKind,
-        LegacyDeferredHolderExpressionFinalizerImpl,
         mainResourceName;
 import '../../js_backend/type_reference.dart'
     show
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 088ef9c..b0be710 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -77,12 +77,13 @@
   FeatureOption useContentSecurityPolicy = FeatureOption('csp');
 
   /// [FeatureOption]s which are shipped and cannot be toggled.
-  late final List<FeatureOption> shipped = [];
+  late final List<FeatureOption> shipped = [
+    newHolders,
+  ];
 
   /// [FeatureOption]s which default to enabled.
   late final List<FeatureOption> shipping = [
     legacyJavaScript,
-    newHolders,
     useContentSecurityPolicy
   ];
 
diff --git a/tools/VERSION b/tools/VERSION
index 49eda3a..7c980b1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 16
 PATCH 0
-PRERELEASE 114
+PRERELEASE 115
 PRERELEASE_PATCH 0
\ No newline at end of file