Skip to content

Commit

Permalink
[cfe] Avoid crash on Never as bound
Browse files Browse the repository at this point in the history
Change-Id: Ia7dc56774599a17d4a29d03ec8ec07cb01995fdb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/137300
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
  • Loading branch information
johnniwinther committed Feb 26, 2020
1 parent 6262e8f commit 4189237
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 1 deletion.
Expand Up @@ -3359,7 +3359,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
}
if (nnbdIssues != null) {
if (legacyIssues != null) {
nnbdIssues = nnbdIssues.where((issue) => !legacyIssues.contains(issue));
nnbdIssues =
nnbdIssues.where((issue) => !legacyIssues.contains(issue)).toSet();
}
reportTypeArgumentIssues(nnbdIssues, fileUri, offset,
inferred: inferred, areWarnings: loader.nnbdMode == NnbdMode.Weak);
Expand Down
15 changes: 15 additions & 0 deletions pkg/front_end/testcases/nnbd/never_bound.dart
@@ -0,0 +1,15 @@
// Copyright (c) 2020, 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.

class GenericNever<T extends Never> {
dynamic getParamType() => T;
}

errors() {
GenericNever<Null>();
GenericNever<void>();
GenericNever<int>();
}

main() {}
14 changes: 14 additions & 0 deletions pkg/front_end/testcases/nnbd/never_bound.dart.outline.expect
@@ -0,0 +1,14 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;

class GenericNever<T extends Never = Never> extends core::Object {
synthetic constructor •() → self::GenericNever<self::GenericNever::T>
;
method getParamType() → dynamic
;
}
static method errors() → dynamic
;
static method main() → dynamic
;
44 changes: 44 additions & 0 deletions pkg/front_end/testcases/nnbd/never_bound.dart.strong.expect
@@ -0,0 +1,44 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null?' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<Null>();
// ^
// pkg/front_end/testcases/nnbd/never_bound.dart:5:20: Context: This is the type variable whose bound isn't conformed to.
// class GenericNever<T extends Never> {
// ^
//
// pkg/front_end/testcases/nnbd/never_bound.dart:11:3: Error: Type argument 'void' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<void>();
// ^
// pkg/front_end/testcases/nnbd/never_bound.dart:5:20: Context: This is the type variable whose bound isn't conformed to.
// class GenericNever<T extends Never> {
// ^
//
// pkg/front_end/testcases/nnbd/never_bound.dart:12:3: Error: Type argument 'int' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<int>();
// ^
// pkg/front_end/testcases/nnbd/never_bound.dart:5:20: Context: This is the type variable whose bound isn't conformed to.
// class GenericNever<T extends Never> {
// ^
//
import self as self;
import "dart:core" as core;

class GenericNever<T extends Never = Never> extends core::Object {
synthetic constructor •() → self::GenericNever<self::GenericNever::T>
: super core::Object::•()
;
method getParamType() → dynamic
return self::GenericNever::T;
}
static method errors() → dynamic {
new self::GenericNever::•<core::Null?>();
new self::GenericNever::•<void>();
new self::GenericNever::•<core::int>();
}
static method main() → dynamic {}
@@ -0,0 +1,44 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null?' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<Null>();
// ^
// pkg/front_end/testcases/nnbd/never_bound.dart:5:20: Context: This is the type variable whose bound isn't conformed to.
// class GenericNever<T extends Never> {
// ^
//
// pkg/front_end/testcases/nnbd/never_bound.dart:11:3: Error: Type argument 'void' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<void>();
// ^
// pkg/front_end/testcases/nnbd/never_bound.dart:5:20: Context: This is the type variable whose bound isn't conformed to.
// class GenericNever<T extends Never> {
// ^
//
// pkg/front_end/testcases/nnbd/never_bound.dart:12:3: Error: Type argument 'int' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<int>();
// ^
// pkg/front_end/testcases/nnbd/never_bound.dart:5:20: Context: This is the type variable whose bound isn't conformed to.
// class GenericNever<T extends Never> {
// ^
//
import self as self;
import "dart:core" as core;

class GenericNever<T extends Never = Never> extends core::Object {
synthetic constructor •() → self::GenericNever<self::GenericNever::T>
: super core::Object::•()
;
method getParamType() → dynamic
return self::GenericNever::T;
}
static method errors() → dynamic {
new self::GenericNever::•<core::Null?>();
new self::GenericNever::•<void>();
new self::GenericNever::•<core::int>();
}
static method main() → dynamic {}
44 changes: 44 additions & 0 deletions pkg/front_end/testcases/nnbd/never_bound.dart.weak.expect
@@ -0,0 +1,44 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null?' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<Null>();
// ^
// pkg/front_end/testcases/nnbd/never_bound.dart:5:20: Context: This is the type variable whose bound isn't conformed to.
// class GenericNever<T extends Never> {
// ^
//
// pkg/front_end/testcases/nnbd/never_bound.dart:11:3: Error: Type argument 'void' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<void>();
// ^
// pkg/front_end/testcases/nnbd/never_bound.dart:5:20: Context: This is the type variable whose bound isn't conformed to.
// class GenericNever<T extends Never> {
// ^
//
// pkg/front_end/testcases/nnbd/never_bound.dart:12:3: Error: Type argument 'int' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<int>();
// ^
// pkg/front_end/testcases/nnbd/never_bound.dart:5:20: Context: This is the type variable whose bound isn't conformed to.
// class GenericNever<T extends Never> {
// ^
//
import self as self;
import "dart:core" as core;

class GenericNever<T extends Never = Never> extends core::Object {
synthetic constructor •() → self::GenericNever<self::GenericNever::T>
: super core::Object::•()
;
method getParamType() → dynamic
return self::GenericNever::T;
}
static method errors() → dynamic {
new self::GenericNever::•<core::Null?>();
new self::GenericNever::•<void>();
new self::GenericNever::•<core::int>();
}
static method main() → dynamic {}
@@ -0,0 +1,44 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/nnbd/never_bound.dart:10:3: Error: Type argument 'Null?' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<Null>();
// ^
// pkg/front_end/testcases/nnbd/never_bound.dart:5:20: Context: This is the type variable whose bound isn't conformed to.
// class GenericNever<T extends Never> {
// ^
//
// pkg/front_end/testcases/nnbd/never_bound.dart:11:3: Error: Type argument 'void' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<void>();
// ^
// pkg/front_end/testcases/nnbd/never_bound.dart:5:20: Context: This is the type variable whose bound isn't conformed to.
// class GenericNever<T extends Never> {
// ^
//
// pkg/front_end/testcases/nnbd/never_bound.dart:12:3: Error: Type argument 'int' doesn't conform to the bound 'Never' of the type variable 'T' on 'GenericNever'.
// Try changing type arguments so that they conform to the bounds.
// GenericNever<int>();
// ^
// pkg/front_end/testcases/nnbd/never_bound.dart:5:20: Context: This is the type variable whose bound isn't conformed to.
// class GenericNever<T extends Never> {
// ^
//
import self as self;
import "dart:core" as core;

class GenericNever<T extends Never = Never> extends core::Object {
synthetic constructor •() → self::GenericNever<self::GenericNever::T>
: super core::Object::•()
;
method getParamType() → dynamic
return self::GenericNever::T;
}
static method errors() → dynamic {
new self::GenericNever::•<core::Null?>();
new self::GenericNever::•<void>();
new self::GenericNever::•<core::int>();
}
static method main() → dynamic {}
1 change: 1 addition & 0 deletions pkg/front_end/testcases/text_serialization.status
Expand Up @@ -1268,6 +1268,7 @@ nnbd/missing_required_named_parameter: TextSerializationFailure
nnbd/mixed_mode_hierarchy_generic_methods: TextSerializationFailure
nnbd/mixin_from_opt_in: TextSerializationFailure
nnbd/mixin_from_opt_out: TextSerializationFailure
nnbd/never_bound: TextSerializationFailure
nnbd/never_opt_out: TypeCheckError
nnbd/never_receiver: TextSerializationFailure
nnbd/nnbd_opt_out_language_version: TextSerializationFailure
Expand Down

0 comments on commit 4189237

Please sign in to comment.