// 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 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); }