Skip to content

Commit f021a70

Browse files
author
Jennifer Messerly
committed
fixes #27586, prefer downwards context type in generic inference
fixes #27625, Object constraints were not tracked in inference fixes #27933, pin return type from downwards inference We now prefer to pick the bound (lower or upper) that had some information on, and it also improves inference error messages somewhat (still a ways to go). The way this works is we now have a type representing an unknown type: ?. We use ? when performing downward inference steps, instead of `dynamic`. This allows more accurate tracking of type constraints. For example: given: var x = await Future.wait([a, b]); Future.wait<T>'s argument type is Iterable<Future<T>>. Since we didn't know T, we previously pushed down Iterable<Future<dynamic>>. The dynamic caused loss of information. Now we push down Iterable<Future<?>>, allowing us to infer the right type there. [email protected], [email protected] Review-Url: https://codereview.chromium.org/2456803004 .
1 parent 13d6c5c commit f021a70

38 files changed

+2186
-1530
lines changed

pkg/analyzer/lib/src/dart/element/member.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,10 @@ class TypeParameterMember extends Member implements TypeParameterElement {
933933
@override
934934
TypeParameterType get type => _type;
935935

936+
@override
937+
bool operator ==(Object other) =>
938+
other is TypeParameterMember && baseElement == other.baseElement;
939+
936940
@override
937941
/*=T*/ accept/*<T>*/(ElementVisitor<dynamic/*=T*/ > visitor) =>
938942
visitor.visitTypeParameterElement(this);

pkg/analyzer/lib/src/dart/element/type.dart

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2660,9 +2660,47 @@ class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
26602660
@override
26612661
int get hashCode => element.hashCode;
26622662

2663+
/**
2664+
* Append a textual representation of this type to the given [buffer]. The set
2665+
* of [visitedTypes] is used to prevent infinite recursion.
2666+
*/
2667+
void appendTo(StringBuffer buffer, Set<TypeImpl> visitedTypes) {
2668+
super.appendTo(buffer, visitedTypes);
2669+
TypeParameterElement e = element;
2670+
if (e is TypeParameterMember &&
2671+
e.bound != e.baseElement.bound &&
2672+
!_appendingBounds) {
2673+
buffer.write(' extends ');
2674+
// If we're appending bounds already, we don't want to do it recursively.
2675+
_appendingBounds = true;
2676+
try {
2677+
(e.bound as TypeImpl).appendTo(buffer, visitedTypes);
2678+
} finally {
2679+
_appendingBounds = false;
2680+
}
2681+
}
2682+
}
2683+
26632684
@override
2664-
bool operator ==(Object object) =>
2665-
object is TypeParameterTypeImpl && (element == object.element);
2685+
bool operator ==(Object other) {
2686+
if (other is TypeParameterTypeImpl && element == other.element) {
2687+
if (_comparingBounds) {
2688+
// If we're comparing bounds already, then we only need type variable
2689+
// equality.
2690+
return true;
2691+
}
2692+
_comparingBounds = true;
2693+
try {
2694+
return bound == other.bound;
2695+
} finally {
2696+
_comparingBounds = false;
2697+
}
2698+
}
2699+
return false;
2700+
}
2701+
2702+
static bool _comparingBounds = false;
2703+
static bool _appendingBounds = false;
26662704

26672705
@override
26682706
bool isMoreSpecificThan(DartType s,

pkg/analyzer/lib/src/error/codes.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4771,7 +4771,7 @@ class StrongModeCode extends ErrorCode {
47714771
static const StrongModeCode COULD_NOT_INFER = const StrongModeCode(
47724772
ErrorType.COMPILE_TIME_ERROR,
47734773
'COULD_NOT_INFER',
4774-
"Couldn't infer type parameter '{0}'; '{1}' must be of type '{2}'.");
4774+
"Couldn't infer type parameter '{0}'.{1}");
47754775

47764776
static const StrongModeCode INFERRED_TYPE = const StrongModeCode(
47774777
ErrorType.HINT, 'INFERRED_TYPE', _inferredTypeMessage);

0 commit comments

Comments
 (0)