@@ -883,6 +883,12 @@ abstract interface class TypeAnalyzerOperations<
883883 /// True if [typeParameter] doesn't have an explicit bound.
884884 bool isBoundOmitted (SharedTypeParameter typeParameter);
885885
886+ SharedType substituteTypeFromIterables (
887+ SharedType typeToSubstitute,
888+ List <SharedTypeParameter > typeParameters,
889+ List <SharedType > types,
890+ );
891+
886892 /// Computes (or recomputes) a set of inferred types based on the constraints
887893 /// that have been recorded so far.
888894 List <SharedType > chooseTypes (
@@ -1460,6 +1466,85 @@ mixin TypeAnalyzerOperationsMixin<
14601466
14611467 return t;
14621468 }
1469+
1470+ @override
1471+ List <SharedType > chooseTypes (
1472+ List <SharedTypeParameter > typeParametersToInfer,
1473+ Map <
1474+ SharedTypeParameter ,
1475+ MergedTypeConstraint <
1476+ Variable ,
1477+ TypeDeclarationType ,
1478+ TypeDeclaration ,
1479+ AstNode
1480+ >
1481+ >
1482+ constraints,
1483+ List <SharedType >? previouslyInferredTypes, {
1484+ required bool preliminary,
1485+ required bool inferenceUsingBoundsIsEnabled,
1486+ required TypeConstraintGenerationDataForTesting <Variable , AstNode >?
1487+ dataForTesting,
1488+ required AstNode ? treeNodeForTesting,
1489+ }) {
1490+ List <SharedType > inferredTypes =
1491+ previouslyInferredTypes? .toList (growable: false ) ??
1492+ new List .filled (
1493+ typeParametersToInfer.length,
1494+ unknownType.unwrapTypeSchemaView (),
1495+ );
1496+
1497+ for (int i = 0 ; i < typeParametersToInfer.length; i++ ) {
1498+ SharedTypeParameter typeParam = typeParametersToInfer[i];
1499+
1500+ SharedType ? typeParamBound = typeParam.boundShared;
1501+ SharedType ? extendsConstraint;
1502+ if (typeParamBound != null && ! isBoundOmitted (typeParam)) {
1503+ extendsConstraint = substituteTypeFromIterables (
1504+ typeParamBound,
1505+ typeParametersToInfer,
1506+ inferredTypes,
1507+ );
1508+ }
1509+
1510+ MergedTypeConstraint <
1511+ Variable ,
1512+ TypeDeclarationType ,
1513+ TypeDeclaration ,
1514+ AstNode
1515+ >
1516+ constraint = constraints[typeParam]! ;
1517+ if (preliminary) {
1518+ inferredTypes[i] = inferTypeParameterFromContext (
1519+ previouslyInferredTypes? [i],
1520+ constraint,
1521+ extendsConstraint,
1522+ isContravariant: typeParam.variance == Variance .contravariant,
1523+ isLegacyCovariant: typeParam.isLegacyCovariant,
1524+ constraints: constraints,
1525+ typeParameterToInfer: typeParam,
1526+ typeParametersToInfer: typeParametersToInfer,
1527+ dataForTesting: dataForTesting,
1528+ inferenceUsingBoundsIsEnabled: inferenceUsingBoundsIsEnabled,
1529+ );
1530+ } else {
1531+ inferredTypes[i] = inferTypeParameterFromAll (
1532+ previouslyInferredTypes? [i],
1533+ constraint,
1534+ extendsConstraint,
1535+ isContravariant: typeParam.variance == Variance .contravariant,
1536+ isLegacyCovariant: typeParam.isLegacyCovariant,
1537+ constraints: constraints,
1538+ typeParameterToInfer: typeParam,
1539+ typeParametersToInfer: typeParametersToInfer,
1540+ dataForTesting: dataForTesting,
1541+ inferenceUsingBoundsIsEnabled: inferenceUsingBoundsIsEnabled,
1542+ );
1543+ }
1544+ }
1545+
1546+ return inferredTypes;
1547+ }
14631548}
14641549
14651550/// Abstract interface of a type constraint generator.
@@ -2673,136 +2758,6 @@ class TypeDeclarationMatchResult<
26732758 });
26742759}
26752760
2676- /// The variance of a type parameter `X` in a type `T` .
2677- enum Variance {
2678- /// Used when `X` does not occur free in `T` .
2679- unrelated (keyword: '' ),
2680-
2681- /// Used when `X` occurs free in `T` , and `U <: V` implies `[U/X]T <: [V/X]T` .
2682- covariant (keyword: 'out' ),
2683-
2684- /// Used when `X` occurs free in `T` , and `U <: V` implies `[V/X]T <: [U/X]T` .
2685- contravariant (keyword: 'in' ),
2686-
2687- /// Used when there exists a pair `U` and `V` such that `U <: V` , but
2688- /// `[U/X]T` and `[V/X]T` are incomparable.
2689- invariant (keyword: 'inout' );
2690-
2691- final String keyword;
2692-
2693- const Variance ({required this .keyword});
2694-
2695- /// Return the variance with the given [encoding] .
2696- factory Variance .fromEncoding (int encoding) => values[encoding];
2697-
2698- /// Return the variance associated with the string representation of variance.
2699- factory Variance .fromKeywordString (String keywordString) {
2700- Variance ? result;
2701- if (keywordString == "in" ) {
2702- result = contravariant;
2703- } else if (keywordString == "inout" ) {
2704- result = invariant;
2705- } else if (keywordString == "out" ) {
2706- result = covariant ;
2707- } else if (keywordString == "unrelated" ) {
2708- result = unrelated;
2709- }
2710- if (result != null ) {
2711- assert (result.keyword == keywordString);
2712- return result;
2713- } else {
2714- throw new ArgumentError (
2715- 'Invalid keyword string for variance: $keywordString ' ,
2716- );
2717- }
2718- }
2719-
2720- /// Return `true` if this represents the case when `X` occurs free in `T` , and
2721- /// `U <: V` implies `[V/X]T <: [U/X]T` .
2722- bool get isContravariant => this == contravariant;
2723-
2724- /// Return `true` if this represents the case when `X` occurs free in `T` , and
2725- /// `U <: V` implies `[U/X]T <: [V/X]T` .
2726- bool get isCovariant => this == covariant ;
2727-
2728- /// Return `true` if this represents the case when there exists a pair `U` and
2729- /// `V` such that `U <: V` , but `[U/X]T` and `[V/X]T` are incomparable.
2730- bool get isInvariant => this == invariant;
2731-
2732- /// Return `true` if this represents the case when `X` does not occur free in
2733- /// `T` .
2734- bool get isUnrelated => this == unrelated;
2735-
2736- /// Combines variances of `X` in `T` and `Y` in `S` into variance of `X` in
2737- /// `[Y/T]S` .
2738- ///
2739- /// Consider the following examples:
2740- ///
2741- /// * variance of `X` in `Function(X)` is contravariant, variance of `Y`
2742- /// in `List<Y>` is covariant, so variance of `X` in `List<Function(X)>` is
2743- /// contravariant;
2744- ///
2745- /// * variance of `X` in `List<X>` is covariant, variance of `Y` in
2746- /// `Function(Y)` is contravariant, so variance of `X` in
2747- /// `Function(List<X>)` is contravariant;
2748- ///
2749- /// * variance of `X` in `Function(X)` is contravariant, variance of `Y` in
2750- /// `Function(Y)` is contravariant, so variance of `X` in
2751- /// `Function(Function(X))` is covariant;
2752- ///
2753- /// * let the following be declared:
2754- ///
2755- /// typedef F<Z> = Function();
2756- ///
2757- /// then variance of `X` in `F<X>` is unrelated, variance of `Y` in
2758- /// `List<Y>` is covariant, so variance of `X` in `List<F<X>>` is
2759- /// unrelated;
2760- ///
2761- /// * let the following be declared:
2762- ///
2763- /// typedef G<Z> = Z Function(Z);
2764- ///
2765- /// then variance of `X` in `List<X>` is covariant, variance of `Y` in
2766- /// `G<Y>` is invariant, so variance of `X` in `G<List<X>>` is invariant.
2767- Variance combine (Variance other) {
2768- if (isUnrelated || other.isUnrelated) return unrelated;
2769- if (isInvariant || other.isInvariant) return invariant;
2770- return this == other ? covariant : contravariant;
2771- }
2772-
2773- /// Returns true if this variance is greater than (above) or equal to the
2774- /// [other] variance in the partial order induced by the variance lattice.
2775- ///
2776- /// unrelated
2777- /// covariant contravariant
2778- /// invariant
2779- bool greaterThanOrEqual (Variance other) {
2780- if (isUnrelated) {
2781- return true ;
2782- } else if (isCovariant) {
2783- return other.isCovariant || other.isInvariant;
2784- } else if (isContravariant) {
2785- return other.isContravariant || other.isInvariant;
2786- } else {
2787- assert (isInvariant);
2788- return other.isInvariant;
2789- }
2790- }
2791-
2792- /// Variance values form a lattice where unrelated is the top, invariant is
2793- /// the bottom, and covariant and contravariant are incomparable. [meet]
2794- /// calculates the meet of two elements of such lattice. It can be used, for
2795- /// example, to calculate the variance of a typedef type parameter if it's
2796- /// encountered on the RHS of the typedef multiple times.
2797- ///
2798- /// unrelated
2799- /// covariant contravariant
2800- /// invariant
2801- Variance meet (Variance other) {
2802- return new Variance .fromEncoding (index | other.index);
2803- }
2804- }
2805-
28062761/// Representation of the state of [TypeConstraintGenerator] .
28072762///
28082763/// The state can be obtained via [TypeConstraintGenerator.currentState] . A
0 commit comments