3137a91d3c
Bug: https://github.com/dart-lang/sdk/issues/42205 Change-Id: I7b032734b18fdb86e48270118b4dd91184594e12 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/150474 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Paul Berry <paulberry@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
127 lines
3.0 KiB
Dart
127 lines
3.0 KiB
Dart
// 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.
|
|
|
|
// Requirements=nnbd-strong
|
|
|
|
/// Test that `Never` has all members, and that as a result no extensions
|
|
/// apply to it. Also test that `Never` is inferred as the type of a
|
|
/// throw expression, and as the return type of function literals that
|
|
/// never return.
|
|
|
|
import 'package:expect/expect.dart';
|
|
|
|
/// A call of the form staticErrorIfNotNever(t) will produce a static error
|
|
/// unless `t` has type `Never`.
|
|
void staticErrorIfNotNever<T extends Never>(T t) {}
|
|
|
|
void neverHasAllMembers(Never x) {
|
|
{
|
|
// getters
|
|
var t = x.arglebargle;
|
|
staticErrorIfNotNever(t);
|
|
}
|
|
{
|
|
// setter
|
|
x.arglebargle = 3;
|
|
}
|
|
{
|
|
// operator[]
|
|
x[0] = 3;
|
|
}
|
|
{
|
|
// methods
|
|
var t = x.arglebargle(0);
|
|
staticErrorIfNotNever(t);
|
|
}
|
|
{
|
|
// methods with named parameters
|
|
var t = x.arglebargle(foo: 0);
|
|
staticErrorIfNotNever(t);
|
|
}
|
|
{
|
|
// call method
|
|
var t = x(3);
|
|
staticErrorIfNotNever(t);
|
|
}
|
|
{
|
|
// Object members
|
|
staticErrorIfNotNever(x.toString());
|
|
staticErrorIfNotNever(x.toString);
|
|
staticErrorIfNotNever(x.runtimeType);
|
|
staticErrorIfNotNever(x.noSuchMethod);
|
|
staticErrorIfNotNever(x.noSuchMethod(x));
|
|
staticErrorIfNotNever(x.hashCode);
|
|
staticErrorIfNotNever(x == x);
|
|
staticErrorIfNotNever(x == 3);
|
|
staticErrorIfNotNever(3 == x);
|
|
// ^^^^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
|
|
// [cfe] Inferred type argument 'bool' doesn't conform to the bound 'Never' of the type variable 'T' on 'staticErrorIfNotNever'.
|
|
}
|
|
}
|
|
|
|
extension NeverExt on Never {
|
|
int neverMethod() => 3;
|
|
}
|
|
|
|
extension ObjectExt on Object {
|
|
int objectMethod() => 3;
|
|
}
|
|
|
|
void extensionsDontApply(Never x) {
|
|
{
|
|
var t = x.neverMethod();
|
|
staticErrorIfNotNever(t);
|
|
}
|
|
{
|
|
var t = x.objectMethod();
|
|
staticErrorIfNotNever(t);
|
|
}
|
|
{
|
|
var t = NeverExt(x).neverMethod();
|
|
staticErrorIfNotNever(t);
|
|
// ^^^^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
|
|
// [cfe] Inferred type argument 'int' doesn't conform to the bound 'Never' of the type variable 'T' on 'staticErrorIfNotNever'.
|
|
}
|
|
{
|
|
var t = ObjectExt(x).objectMethod();
|
|
staticErrorIfNotNever(t);
|
|
// ^^^^^^^^^^^^^^^^^^^^^
|
|
// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
|
|
// [cfe] Inferred type argument 'int' doesn't conform to the bound 'Never' of the type variable 'T' on 'staticErrorIfNotNever'.
|
|
}
|
|
}
|
|
|
|
void throwHasTypeNever() {
|
|
var t = throw "hello";
|
|
staticErrorIfNotNever(t);
|
|
}
|
|
|
|
void neverReturns(bool b) {
|
|
{
|
|
var f = () => throw "Unreachable";
|
|
var t = f();
|
|
staticErrorIfNotNever(t);
|
|
}
|
|
{
|
|
var f = () {
|
|
if (b) {
|
|
throw "argle";
|
|
} else {
|
|
throw "bargle";
|
|
}
|
|
};
|
|
var t = f();
|
|
staticErrorIfNotNever(t);
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
neverHasAllMembers(throw "Unreachable");
|
|
extensionsDontApply(throw "Unreachable");
|
|
throwHasTypeNever();
|
|
neverReturns(true);
|
|
}
|