Skip to content

Commit

Permalink
[vm/aot] Visit TypeParameterType.promotedBound in tree shaker
Browse files Browse the repository at this point in the history
If tree shaker doesn't visit TypeParameterType.promotedBound which
contains the only reference to a particular class it may remove that
class, leaving a dangling reference from promotedBound. After that
kernel AST serialization would crash with "Missing canonical name for
Reference" error.

This change also fixes TypeParameterType.visitChildren.

TEST=pkg/vm/testcases/transformations/type_flow/transformer/regress_47878.dart
Fixes #47878

Change-Id: I555261713240bf0be412db27efb68f32cfd8008b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/222781
Reviewed-by: Johnni Winther <[email protected]>
Commit-Queue: Alexander Markov <[email protected]>
  • Loading branch information
alexmarkov authored and whesse committed Dec 14, 2021
1 parent 286f637 commit bb7fb3e
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 1 deletion.
4 changes: 3 additions & 1 deletion pkg/kernel/lib/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11888,7 +11888,9 @@ class TypeParameterType extends DartType {
v.visitTypeParameterType(this, arg);

@override
void visitChildren(Visitor v) {}
void visitChildren(Visitor v) {
promotedBound?.accept(v);
}

@override
bool operator ==(Object other) => equals(other, null);
Expand Down
1 change: 1 addition & 0 deletions pkg/vm/lib/transformations/type_flow/transformer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,7 @@ class _TreeShakerTypeVisitor extends RecursiveVisitor {
if (parent is Class) {
shaker.addClassUsedInType(parent);
}
node.visitChildren(this);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Regression test for https://github.com/dart-lang/sdk/issues/47878

abstract class Disposable {}

class A {}

class Data<T> {
T? value;
}

class DataStream<T> {
DataStream({newValue, Data<T>? stream}) {
var lastValue = stream!.value;

if (lastValue != null &&
lastValue is Disposable &&
lastValue != newValue) {}
}
}

void main() {
DataStream<A>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
library #lib /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

abstract class Disposable extends core::Object {
}
abstract class A extends core::Object {
}
abstract class Data<T extends core::Object? = dynamic> extends core::Object {
}
class DataStream<T extends core::Object? = dynamic> extends core::Object {
constructor •() → self::DataStream<self::DataStream::T%>
: super core::Object::•() {
self::DataStream::T? lastValue = block {
#C1!;
} =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
if(!(throw "Attempt to execute code removed by Dart AOT compiler (TFA)") && false && !([@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] lastValue{self::DataStream::T & self::Disposable /* '!' & '!' = '!' */} =={core::Object::==}{(core::Object) → core::bool} #C1)) {
}
}
}
static method main() → void {
new self::DataStream::•<self::A>();
}
constants {
#C1 = null
}

0 comments on commit bb7fb3e

Please sign in to comment.