Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit aa67099

Browse files
kallentucommit-bot@chromium.org
authored andcommitted
[cfe] Fix inference for variant parameters leaking UnknownTypes.
Change-Id: I056535cbfc74554de408ce4f9d89c142c4c860cf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/128771 Reviewed-by: Leaf Petersen <[email protected]> Reviewed-by: Dmitry Stefantsov <[email protected]> Commit-Queue: Kallen Tu <[email protected]>
1 parent efe76bd commit aa67099

8 files changed

+149
-12
lines changed

pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -291,16 +291,17 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment
291291
}
292292

293293
TypeConstraint constraint = constraints[typeParam];
294-
if (downwardsInferPhase || !typeParam.isLegacyCovariant) {
294+
if (downwardsInferPhase) {
295295
inferredTypes[i] = _inferTypeParameterFromContext(
296-
constraint, extendsConstraint, clientLibrary,
297-
isContravariant: typeParam.variance == Variance.contravariant);
296+
constraint, extendsConstraint, clientLibrary);
298297
} else {
299298
inferredTypes[i] = _inferTypeParameterFromAll(
300299
typesFromDownwardsInference[i],
301300
constraint,
302301
extendsConstraint,
303-
clientLibrary);
302+
clientLibrary,
303+
isContravariant: typeParam.variance == Variance.contravariant,
304+
preferUpwardsInference: !typeParam.isLegacyCovariant);
304305
}
305306
}
306307

@@ -451,10 +452,13 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment
451452
DartType typeFromContextInference,
452453
TypeConstraint constraint,
453454
DartType extendsConstraint,
454-
Library clientLibrary) {
455+
Library clientLibrary,
456+
{bool isContravariant: false,
457+
bool preferUpwardsInference: false}) {
455458
// See if we already fixed this type from downwards inference.
456-
// If so, then we aren't allowed to change it based on argument types.
457-
if (isKnown(typeFromContextInference)) {
459+
// If so, then we aren't allowed to change it based on argument types unless
460+
// [preferUpwardsInference] is true.
461+
if (!preferUpwardsInference && isKnown(typeFromContextInference)) {
458462
return typeFromContextInference;
459463
}
460464

@@ -463,14 +467,13 @@ class TypeSchemaEnvironment extends HierarchyBasedTypeEnvironment
463467
addUpperBound(constraint, extendsConstraint, clientLibrary);
464468
}
465469

466-
return solveTypeConstraint(constraint, grounded: true);
470+
return solveTypeConstraint(constraint,
471+
grounded: true, isContravariant: isContravariant);
467472
}
468473

469474
DartType _inferTypeParameterFromContext(TypeConstraint constraint,
470-
DartType extendsConstraint, Library clientLibrary,
471-
{bool isContravariant: false}) {
472-
DartType t =
473-
solveTypeConstraint(constraint, isContravariant: isContravariant);
475+
DartType extendsConstraint, Library clientLibrary) {
476+
DartType t = solveTypeConstraint(constraint);
474477
if (!isKnown(t)) {
475478
return t;
476479
}

pkg/front_end/test/spell_checking_list_tests.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ consts
8989
contract
9090
conversion
9191
conversions
92+
cov
9293
crashes
9394
cumulative
9495
dacoharkes

pkg/front_end/testcases/text_serialization.status

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,3 +1225,4 @@ unified_collections/mixed_entries: TextSerializationFailure
12251225
variance/class_type_parameter_modifier: TextSerializationFailure
12261226
variance/generic_covariance_sound_variance: TextSerializationFailure
12271227
variance/mixin_type_parameter_modifier: TextSerializationFailure
1228+
variance/unconstrained_inference: TextSerializationFailure
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
class Covariant<out T> {}
6+
class Contravariant<in T> {}
7+
class Invariant<inout T> {}
8+
9+
void covariantListInfer<T>(Covariant<List<T>> x) {}
10+
void contravariantListInfer<T>(Contravariant<List<T>> x) {}
11+
void invariantListInfer<T>(Invariant<List<T>> x) {}
12+
13+
main() {
14+
var cov = new Covariant();
15+
covariantListInfer(Covariant());
16+
17+
var contra = new Contravariant();
18+
contravariantListInfer(Contravariant());
19+
20+
var inv = new Invariant();
21+
invariantListInfer(Invariant());
22+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class Covariant<T extends core::Object* = dynamic> extends core::Object {
6+
synthetic constructor •() → self::Covariant<self::Covariant::T*>*
7+
;
8+
}
9+
class Contravariant<contravariant T extends core::Object* = dynamic> extends core::Object {
10+
synthetic constructor •() → self::Contravariant<self::Contravariant::T*>*
11+
;
12+
}
13+
class Invariant<invariant T extends core::Object* = dynamic> extends core::Object {
14+
synthetic constructor •() → self::Invariant<self::Invariant::T*>*
15+
;
16+
}
17+
static method covariantListInfer<T extends core::Object* = dynamic>(self::Covariant<core::List<self::covariantListInfer::T*>*>* x) → void
18+
;
19+
static method contravariantListInfer<T extends core::Object* = dynamic>(self::Contravariant<core::List<self::contravariantListInfer::T*>*>* x) → void
20+
;
21+
static method invariantListInfer<T extends core::Object* = dynamic>(self::Invariant<core::List<self::invariantListInfer::T*>*>* x) → void
22+
;
23+
static method main() → dynamic
24+
;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class Covariant<T extends core::Object* = dynamic> extends core::Object {
6+
synthetic constructor •() → self::Covariant<self::Covariant::T*>*
7+
: super core::Object::•()
8+
;
9+
}
10+
class Contravariant<contravariant T extends core::Object* = dynamic> extends core::Object {
11+
synthetic constructor •() → self::Contravariant<self::Contravariant::T*>*
12+
: super core::Object::•()
13+
;
14+
}
15+
class Invariant<invariant T extends core::Object* = dynamic> extends core::Object {
16+
synthetic constructor •() → self::Invariant<self::Invariant::T*>*
17+
: super core::Object::•()
18+
;
19+
}
20+
static method covariantListInfer<T extends core::Object* = dynamic>(self::Covariant<core::List<self::covariantListInfer::T*>*>* x) → void {}
21+
static method contravariantListInfer<T extends core::Object* = dynamic>(self::Contravariant<core::List<self::contravariantListInfer::T*>*>* x) → void {}
22+
static method invariantListInfer<T extends core::Object* = dynamic>(self::Invariant<core::List<self::invariantListInfer::T*>*>* x) → void {}
23+
static method main() → dynamic {
24+
self::Covariant<dynamic>* cov = new self::Covariant::•<dynamic>();
25+
self::covariantListInfer<dynamic>(new self::Covariant::•<core::List<dynamic>*>());
26+
self::Contravariant<core::Null?>* contra = new self::Contravariant::•<core::Null?>();
27+
self::contravariantListInfer<core::Null?>(new self::Contravariant::•<core::List<core::Null?>*>());
28+
self::Invariant<dynamic>* inv = new self::Invariant::•<dynamic>();
29+
self::invariantListInfer<core::Null?>(new self::Invariant::•<core::List<core::Null?>*>());
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class Covariant<T extends core::Object* = dynamic> extends core::Object {
6+
synthetic constructor •() → self::Covariant<self::Covariant::T*>*
7+
: super core::Object::•()
8+
;
9+
}
10+
class Contravariant<contravariant T extends core::Object* = dynamic> extends core::Object {
11+
synthetic constructor •() → self::Contravariant<self::Contravariant::T*>*
12+
: super core::Object::•()
13+
;
14+
}
15+
class Invariant<invariant T extends core::Object* = dynamic> extends core::Object {
16+
synthetic constructor •() → self::Invariant<self::Invariant::T*>*
17+
: super core::Object::•()
18+
;
19+
}
20+
static method covariantListInfer<T extends core::Object* = dynamic>(self::Covariant<core::List<self::covariantListInfer::T*>*>* x) → void {}
21+
static method contravariantListInfer<T extends core::Object* = dynamic>(self::Contravariant<core::List<self::contravariantListInfer::T*>*>* x) → void {}
22+
static method invariantListInfer<T extends core::Object* = dynamic>(self::Invariant<core::List<self::invariantListInfer::T*>*>* x) → void {}
23+
static method main() → dynamic {
24+
self::Covariant<dynamic>* cov = new self::Covariant::•<dynamic>();
25+
self::covariantListInfer<dynamic>(new self::Covariant::•<core::List<dynamic>*>());
26+
self::Contravariant<core::Null?>* contra = new self::Contravariant::•<core::Null?>();
27+
self::contravariantListInfer<core::Null?>(new self::Contravariant::•<core::List<core::Null?>*>());
28+
self::Invariant<dynamic>* inv = new self::Invariant::•<dynamic>();
29+
self::invariantListInfer<core::Null?>(new self::Invariant::•<core::List<core::Null?>*>());
30+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
// Tests unconstrained inferencing with sound variance.
6+
7+
// SharedOptions=--enable-experiment=variance
8+
9+
class Covariant<out T> {}
10+
class Contravariant<in T> {}
11+
class Invariant<inout T> {}
12+
13+
void covariantListInfer<T>(Covariant<List<T>> x) {}
14+
void contravariantListInfer<T>(Contravariant<List<T>> x) {}
15+
void invariantListInfer<T>(Invariant<List<T>> x) {}
16+
17+
main() {
18+
var cov = new Covariant();
19+
covariantListInfer(Covariant());
20+
21+
var contra = new Contravariant();
22+
contravariantListInfer(Contravariant());
23+
24+
var inv = new Invariant();
25+
invariantListInfer(Invariant());
26+
}

0 commit comments

Comments
 (0)