[cfe] If type variable is its own bound, set it to InvalidType

The motivation for this change is that we can't compute the nullability
for such type parameter types anyways.  Additionally, it stops the
cascading error in case the type variable is its own bound indirectly,
via a chain of other type variables.

Change-Id: I940f19bb47952108ac1e0d1a0ef197b373b6b8e3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/114946
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
This commit is contained in:
Dmitry Stefantsov 2019-08-30 10:11:40 +00:00 committed by commit-bot@chromium.org
parent d4342b9021
commit b8cde9347a
5 changed files with 11 additions and 53 deletions

View file

@ -1610,6 +1610,11 @@ class OutlineBuilder extends StackListener {
: templateCycleInTypeVariables.withArguments(
builder.name, via.join("', '"));
addProblem(message, builder.charOffset, builder.name.length);
builder.bound = new NamedTypeBuilder(builder.name, null)
..bind(new InvalidTypeBuilder(
builder.name,
message.withLocation(
uri, builder.charOffset, builder.name.length)));
}
}
}

View file

@ -124,8 +124,6 @@ CovariantMember/part_wrapped_script1: Fail
CovariantMember/part_wrapped_script2: Fail
CovariantMember/script1: Fail
CovariantMember/script2: Fail
CycleInTypeVariables/part_wrapped_script1: Fail
CycleInTypeVariables/script1: Fail # We report an error for each type variable involved in the cycle.
CyclicClassHierarchy/part_wrapped_script1: Fail
CyclicClassHierarchy/part_wrapped_script2: Fail
CyclicClassHierarchy/script1: Fail # We report an error for each class involved in the cycle.

View file

@ -7,21 +7,6 @@ library;
// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
// ^
//
// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:22: Error: Type 'U' is a bound of itself via 'Y', 'Z', 'T'.
// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
// ^
//
// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:28: Error: Type 'Y' is a bound of itself via 'Z', 'T', 'U'.
// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
// X extends Function(V), Y extends Z, Z extends T> {}
// ^
//
// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:41: Error: Type 'Z' is a bound of itself via 'T', 'U', 'Y'.
// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
// X extends Function(V), Y extends Z, Z extends T> {}
// ^
//
import self as self;
import "dart:core" as core;
@ -57,7 +42,7 @@ class H<S extends self::A<self::H::S*>* = self::A<dynamic>*, T extends self::B<s
synthetic constructor •() → self::H<self::H::S*, self::H::T*, self::H::U*, self::H::V*, self::H::W*, self::H::X*, self::H::Y*, self::H::Z*>*
;
}
class I<T extends self::I::U* = dynamic, U extends self::I::Y* = dynamic, V extends (self::I::W*) →* dynamic = (core::Null*) →* dynamic, W extends (self::I::X*) →* dynamic = (core::Null*) →* dynamic, X extends (self::I::V*) →* dynamic = (core::Null*) →* dynamic, Y extends self::I::Z* = dynamic, Z extends self::I::T* = dynamic> extends core::Object {
class I<T extends invalid-type = invalid-type, U extends self::I::Y* = invalid-type, V extends (self::I::W*) →* dynamic = (core::Null*) →* dynamic, W extends (self::I::X*) →* dynamic = (core::Null*) →* dynamic, X extends (self::I::V*) →* dynamic = (core::Null*) →* dynamic, Y extends self::I::Z* = invalid-type, Z extends self::I::T* = invalid-type> extends core::Object {
synthetic constructor •() → self::I<self::I::T*, self::I::U*, self::I::V*, self::I::W*, self::I::X*, self::I::Y*, self::I::Z*>*
;
}
@ -70,7 +55,7 @@ static field self::E<self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*, sel
static field self::F<core::num*, self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*, self::B<self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*>*, self::C<self::B<self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*>*, dynamic>*>* f;
static field self::G<core::num*, self::B<core::num*, dynamic>*, self::C<dynamic, core::num*>*, self::B<self::B<core::num*, dynamic>*, self::C<dynamic, core::num*>*>*, self::C<self::B<self::B<core::num*, dynamic>*, self::C<dynamic, core::num*>*>*, dynamic>*>* g;
static field self::H<self::A<dynamic>*, self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*, self::A<dynamic>*, self::A<dynamic>*, self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*, self::A<dynamic>*>* h;
static field self::I<dynamic, dynamic, (core::Null*) →* dynamic, (core::Null*) →* dynamic, (core::Null*) →* dynamic, dynamic, dynamic>* i;
static field self::I<invalid-type, invalid-type, (core::Null*) →* dynamic, (core::Null*) →* dynamic, (core::Null*) →* dynamic, invalid-type, invalid-type>* i;
static field self::J<(core::Null*) →* dynamic, (core::Null*) →* dynamic, (core::Null*) →* dynamic, dynamic, dynamic, (core::Null*) →* dynamic, dynamic, dynamic>* j;
static method main() → dynamic
;

View file

@ -7,21 +7,6 @@ library;
// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
// ^
//
// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:22: Error: Type 'U' is a bound of itself via 'Y', 'Z', 'T'.
// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
// ^
//
// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:28: Error: Type 'Y' is a bound of itself via 'Z', 'T', 'U'.
// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
// X extends Function(V), Y extends Z, Z extends T> {}
// ^
//
// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:41: Error: Type 'Z' is a bound of itself via 'T', 'U', 'Y'.
// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
// X extends Function(V), Y extends Z, Z extends T> {}
// ^
//
import self as self;
import "dart:core" as core;
@ -65,7 +50,7 @@ class H<S extends self::A<self::H::S*>* = self::A<dynamic>*, T extends self::B<s
: super core::Object::•()
;
}
class I<T extends self::I::U* = dynamic, U extends self::I::Y* = dynamic, V extends (self::I::W*) →* dynamic = (core::Null*) →* dynamic, W extends (self::I::X*) →* dynamic = (core::Null*) →* dynamic, X extends (self::I::V*) →* dynamic = (core::Null*) →* dynamic, Y extends self::I::Z* = dynamic, Z extends self::I::T* = dynamic> extends core::Object {
class I<T extends invalid-type = invalid-type, U extends self::I::Y* = invalid-type, V extends (self::I::W*) →* dynamic = (core::Null*) →* dynamic, W extends (self::I::X*) →* dynamic = (core::Null*) →* dynamic, X extends (self::I::V*) →* dynamic = (core::Null*) →* dynamic, Y extends self::I::Z* = invalid-type, Z extends self::I::T* = invalid-type> extends core::Object {
synthetic constructor •() → self::I<self::I::T*, self::I::U*, self::I::V*, self::I::W*, self::I::X*, self::I::Y*, self::I::Z*>*
: super core::Object::•()
;
@ -80,6 +65,6 @@ static field self::E<self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*, sel
static field self::F<core::num*, self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*, self::B<self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*>*, self::C<self::B<self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*>*, dynamic>*>* f;
static field self::G<core::num*, self::B<core::num*, dynamic>*, self::C<dynamic, core::num*>*, self::B<self::B<core::num*, dynamic>*, self::C<dynamic, core::num*>*>*, self::C<self::B<self::B<core::num*, dynamic>*, self::C<dynamic, core::num*>*>*, dynamic>*>* g;
static field self::H<self::A<dynamic>*, self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*, self::A<dynamic>*, self::A<dynamic>*, self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*, self::A<dynamic>*>* h;
static field self::I<dynamic, dynamic, (core::Null*) →* dynamic, (core::Null*) →* dynamic, (core::Null*) →* dynamic, dynamic, dynamic>* i;
static field self::I<invalid-type, invalid-type, (core::Null*) →* dynamic, (core::Null*) →* dynamic, (core::Null*) →* dynamic, invalid-type, invalid-type>* i;
static field self::J<(core::Null*) →* dynamic, (core::Null*) →* dynamic, (core::Null*) →* dynamic, dynamic, dynamic, (core::Null*) →* dynamic, dynamic, dynamic>* j;
static method main() → dynamic {}

View file

@ -7,21 +7,6 @@ library;
// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
// ^
//
// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:41:22: Error: Type 'U' is a bound of itself via 'Y', 'Z', 'T'.
// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
// class I<T extends U, U extends Y, V extends Function(W), W extends Function(X),
// ^
//
// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:28: Error: Type 'Y' is a bound of itself via 'Z', 'T', 'U'.
// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
// X extends Function(V), Y extends Z, Z extends T> {}
// ^
//
// pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart:42:41: Error: Type 'Z' is a bound of itself via 'T', 'U', 'Y'.
// Try breaking the cycle by removing at least on of the 'extends' clauses in the cycle.
// X extends Function(V), Y extends Z, Z extends T> {}
// ^
//
import self as self;
import "dart:core" as core;
@ -65,7 +50,7 @@ class H<S extends self::A<self::H::S*>* = self::A<dynamic>*, T extends self::B<s
: super core::Object::•()
;
}
class I<T extends self::I::U* = dynamic, U extends self::I::Y* = dynamic, V extends (self::I::W*) →* dynamic = (core::Null*) →* dynamic, W extends (self::I::X*) →* dynamic = (core::Null*) →* dynamic, X extends (self::I::V*) →* dynamic = (core::Null*) →* dynamic, Y extends self::I::Z* = dynamic, Z extends self::I::T* = dynamic> extends core::Object {
class I<T extends invalid-type = invalid-type, U extends self::I::Y* = invalid-type, V extends (self::I::W*) →* dynamic = (core::Null*) →* dynamic, W extends (self::I::X*) →* dynamic = (core::Null*) →* dynamic, X extends (self::I::V*) →* dynamic = (core::Null*) →* dynamic, Y extends self::I::Z* = invalid-type, Z extends self::I::T* = invalid-type> extends core::Object {
synthetic constructor •() → self::I<self::I::T*, self::I::U*, self::I::V*, self::I::W*, self::I::X*, self::I::Y*, self::I::Z*>*
: super core::Object::•()
;
@ -80,6 +65,6 @@ static field self::E<self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*, sel
static field self::F<core::num*, self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*, self::B<self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*>*, self::C<self::B<self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*>*, dynamic>*>* f;
static field self::G<core::num*, self::B<core::num*, dynamic>*, self::C<dynamic, core::num*>*, self::B<self::B<core::num*, dynamic>*, self::C<dynamic, core::num*>*>*, self::C<self::B<self::B<core::num*, dynamic>*, self::C<dynamic, core::num*>*>*, dynamic>*>* g;
static field self::H<self::A<dynamic>*, self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*, self::A<dynamic>*, self::A<dynamic>*, self::B<dynamic, dynamic>*, self::C<dynamic, dynamic>*, self::A<dynamic>*>* h;
static field self::I<dynamic, dynamic, (core::Null*) →* dynamic, (core::Null*) →* dynamic, (core::Null*) →* dynamic, dynamic, dynamic>* i;
static field self::I<invalid-type, invalid-type, (core::Null*) →* dynamic, (core::Null*) →* dynamic, (core::Null*) →* dynamic, invalid-type, invalid-type>* i;
static field self::J<(core::Null*) →* dynamic, (core::Null*) →* dynamic, (core::Null*) →* dynamic, dynamic, dynamic, (core::Null*) →* dynamic, dynamic, dynamic>* j;
static method main() → dynamic {}