mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 21:31:20 +00:00
Migration: Work around null reference exception with complex type parameters.
Change-Id: Ib3f081225f9ec7cb8714ca0aa789d4dea1a378db Bug: https://github.com/dart-lang/sdk/issues/43945 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/169252 Reviewed-by: Samuel Rawlins <srawlins@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
parent
a777d2b798
commit
9181570513
|
@ -420,8 +420,21 @@ class DecoratedType implements DecoratedTypeInfo {
|
|||
var typeFormal = typeFormals[i];
|
||||
var oldDecoratedBound =
|
||||
DecoratedTypeParameterBounds.current.get(typeFormal);
|
||||
var newDecoratedBound = oldDecoratedBound._substitute(substitution,
|
||||
undecoratedResult.typeFormals[i].bound ?? oldDecoratedBound.type);
|
||||
var undecoratedResult2 = undecoratedResult.typeFormals[i].bound;
|
||||
if (undecoratedResult2 == null) {
|
||||
if (oldDecoratedBound == null) {
|
||||
assert(
|
||||
false, 'Could not find old decorated bound for type formal');
|
||||
// Recover the best we can by assuming a bound of `dynamic`.
|
||||
oldDecoratedBound = DecoratedType(
|
||||
DynamicTypeImpl.instance,
|
||||
NullabilityNode.forInferredType(
|
||||
NullabilityNodeTarget.text('Type parameter bound')));
|
||||
}
|
||||
undecoratedResult2 = oldDecoratedBound.type;
|
||||
}
|
||||
var newDecoratedBound =
|
||||
oldDecoratedBound._substitute(substitution, undecoratedResult2);
|
||||
if (identical(typeFormal, undecoratedResult.typeFormals[i])) {
|
||||
assert(oldDecoratedBound == newDecoratedBound);
|
||||
} else {
|
||||
|
|
|
@ -4583,6 +4583,33 @@ f() {
|
|||
await _checkSingleFileChanges(content, expected);
|
||||
}
|
||||
|
||||
Future<void> test_many_type_variables() async {
|
||||
try {
|
||||
assert(false);
|
||||
} catch (_) {
|
||||
// When assertions are enabled, this test fails, so skip it.
|
||||
// See https://github.com/dart-lang/sdk/issues/43945.
|
||||
return;
|
||||
}
|
||||
var content = '''
|
||||
void test(C<int> x, double Function<S>(C<S>) y) {
|
||||
x.f<double>(y);
|
||||
}
|
||||
class C<T> {
|
||||
U f<U>(U Function<V>(C<V>) z) => throw 'foo';
|
||||
}
|
||||
''';
|
||||
var expected = '''
|
||||
void test(C<int> x, double Function<S>(C<S>) y) {
|
||||
x.f<double>(y);
|
||||
}
|
||||
class C<T> {
|
||||
U f<U>(U Function<V>(C<V>) z) => throw 'foo';
|
||||
}
|
||||
''';
|
||||
await _checkSingleFileChanges(content, expected, warnOnWeakCode: true);
|
||||
}
|
||||
|
||||
Future<void> test_map_nullable_input() async {
|
||||
var content = '''
|
||||
Iterable<int> f(List<int> x) => x.map((y) => g(y));
|
||||
|
|
Loading…
Reference in a new issue