mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Improve error messages for super in illegal context
This commit is contained in:
@@ -4315,10 +4315,16 @@ ERROR(no_MaxBuiltinFloatType_found,none,
|
||||
ERROR(no_member_of_module,none,
|
||||
"module %0 has no member named %1", (Identifier, DeclNameRef))
|
||||
|
||||
ERROR(super_with_no_base_class,none,
|
||||
"'super' members cannot be referenced in a root class", ())
|
||||
ERROR(super_not_in_class_method,none,
|
||||
"'super' cannot be used outside of class members", ())
|
||||
ERROR(super_no_superclass,none,
|
||||
"'super' cannot be used in %select{|extension of }0class %1 because it "
|
||||
"has no superclass",
|
||||
(bool, const ClassDecl *))
|
||||
ERROR(super_invalid_context,none,
|
||||
"'super' cannot be used outside of a class computed property, method, "
|
||||
"initializer, deinitializer, or subscript", ())
|
||||
ERROR(super_in_nonclass_type,none,
|
||||
"'super' cannot be used in non-class type %0",
|
||||
(const NominalTypeDecl *))
|
||||
|
||||
ERROR(unqualified_init,none,
|
||||
"initializer expression requires explicit access"
|
||||
|
||||
@@ -1608,8 +1608,8 @@ namespace {
|
||||
|
||||
// Resolve the super type of 'self'.
|
||||
return getSuperType(E->getSelf(), E->getLoc(),
|
||||
diag::super_not_in_class_method,
|
||||
diag::super_with_no_base_class);
|
||||
diag::super_invalid_context,
|
||||
diag::super_no_superclass);
|
||||
}
|
||||
|
||||
Type
|
||||
@@ -3298,10 +3298,9 @@ namespace {
|
||||
return resultType;
|
||||
}
|
||||
|
||||
Type getSuperType(VarDecl *selfDecl,
|
||||
SourceLoc diagLoc,
|
||||
Type getSuperType(VarDecl *selfDecl, SourceLoc diagLoc,
|
||||
Diag<> diag_not_in_class,
|
||||
Diag<> diag_no_base_class) {
|
||||
Diag<bool, const ClassDecl *> diag_no_superclass) {
|
||||
DeclContext *typeContext = selfDecl->getDeclContext()->getParent();
|
||||
assert(typeContext && "constructor without parent context?!");
|
||||
|
||||
@@ -3312,7 +3311,10 @@ namespace {
|
||||
return Type();
|
||||
}
|
||||
if (!classDecl->hasSuperclass()) {
|
||||
de.diagnose(diagLoc, diag_no_base_class);
|
||||
de.diagnose(
|
||||
diagLoc, diag_no_superclass,
|
||||
/*isExtension*/ isa<ExtensionDecl>(typeContext->getAsDecl()),
|
||||
classDecl);
|
||||
return Type();
|
||||
}
|
||||
|
||||
|
||||
@@ -1810,8 +1810,20 @@ void PreCheckExpression::markAcceptableDiscardExprs(Expr *E) {
|
||||
|
||||
VarDecl *PreCheckExpression::getImplicitSelfDeclForSuperContext(SourceLoc Loc) {
|
||||
auto *methodContext = DC->getInnermostMethodContext();
|
||||
if (!methodContext) {
|
||||
Ctx.Diags.diagnose(Loc, diag::super_not_in_class_method);
|
||||
|
||||
if (auto *typeContext = DC->getInnermostTypeContext()) {
|
||||
auto *nominal = typeContext->getSelfNominalTypeDecl();
|
||||
auto *classDecl = dyn_cast<ClassDecl>(nominal);
|
||||
|
||||
if (!classDecl) {
|
||||
Ctx.Diags.diagnose(Loc, diag::super_in_nonclass_type, nominal);
|
||||
return nullptr;
|
||||
} else if (!methodContext) {
|
||||
Ctx.Diags.diagnose(Loc, diag::super_invalid_context);
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
Ctx.Diags.diagnose(Loc, diag::super_invalid_context);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
// RUN: %target-typecheck-verify-swift -parse-as-library
|
||||
|
||||
struct S {
|
||||
init() {
|
||||
super.init() // expected-error{{'super' cannot be used outside of class members}}
|
||||
}
|
||||
}
|
||||
|
||||
class D : B {
|
||||
func foo() {
|
||||
super.init() // expected-error{{'super.init' cannot be called outside of an initializer}}
|
||||
@@ -46,10 +40,6 @@ class B {
|
||||
}
|
||||
init(b:UnicodeScalar) { // expected-note {{candidate expects value of type 'UnicodeScalar' (aka 'Unicode.Scalar') for parameter #1}}
|
||||
}
|
||||
|
||||
init(z:Float) { // expected-note{{candidate expects value of type 'Float' for parameter #1}}
|
||||
super.init() // expected-error{{'super' members cannot be referenced in a root class}}
|
||||
}
|
||||
}
|
||||
|
||||
/// https://github.com/apple/swift/issues/45089
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
// RUN: %target-typecheck-verify-swift -parse-as-library
|
||||
|
||||
struct S {
|
||||
func foo() {
|
||||
super.foo() // expected-error{{'super' cannot be used outside of class members}}
|
||||
}
|
||||
}
|
||||
|
||||
class D : B {
|
||||
func b_foo() -> Int { return super.foo }
|
||||
|
||||
@@ -33,9 +27,6 @@ class B {
|
||||
func zung() -> String {}
|
||||
|
||||
var zippity : Int { return 123 }
|
||||
|
||||
func zoo() { super.zoo() } // expected-error{{'super' members cannot be referenced in a root class}}
|
||||
|
||||
}
|
||||
|
||||
class X<T> {
|
||||
@@ -57,7 +48,7 @@ func use_d(_ d: D) -> Int {
|
||||
}
|
||||
|
||||
func not_method() {
|
||||
super.foo() // expected-error{{'super' cannot be used outside of class members}}
|
||||
super.foo() // expected-error{{'super' cannot be used outside of a class computed property, method, initializer, deinitializer, or subscript}}
|
||||
}
|
||||
|
||||
// rdar://problem/50819554 - inability to properly resolve superclass shouldn't crash the solver
|
||||
|
||||
@@ -27,8 +27,6 @@ func foo() {
|
||||
// expected-error @-1 {{cannot find 'skview' in scope}}
|
||||
}
|
||||
|
||||
super.init() // expected-error {{'super' cannot be used outside of class members}}
|
||||
|
||||
switch state { // expected-error {{cannot find 'state' in scope}}
|
||||
let duration : Int = 0 // expected-error {{all statements inside a switch must be covered by a 'case' or 'default'}}
|
||||
case 1:
|
||||
|
||||
104
test/expr/primary/super/invalid_context.swift
Normal file
104
test/expr/primary/super/invalid_context.swift
Normal file
@@ -0,0 +1,104 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
class Root {
|
||||
let x = 0
|
||||
|
||||
// expected-error@+1 {{'super' cannot be used outside of a class computed property, method, initializer, deinitializer, or subscript}}
|
||||
let testStoredRoot = super.x
|
||||
|
||||
var testComputedRoot: Int {
|
||||
// expected-error@+1 {{'super' cannot be used in class 'Root' because it has no superclass}}
|
||||
let _ = super.x
|
||||
}
|
||||
|
||||
init(root: Void) {
|
||||
// expected-error@+1 {{'super' cannot be used in class 'Root' because it has no superclass}}
|
||||
super.x
|
||||
// expected-error@+1 {{'super' cannot be used in class 'Root' because it has no superclass}}
|
||||
super.init()
|
||||
}
|
||||
|
||||
func testMethodRoot(
|
||||
// expected-error@+1 {{'super' cannot be used in class 'Root' because it has no superclass}}
|
||||
_: Int = super.x
|
||||
) {
|
||||
// expected-error@+1 {{'super' cannot be used in class 'Root' because it has no superclass}}
|
||||
super.testMethodRoot()
|
||||
}
|
||||
|
||||
deinit {
|
||||
// expected-error@+1 {{'super' cannot be used in class 'Root' because it has no superclass}}
|
||||
super.x
|
||||
}
|
||||
}
|
||||
|
||||
extension Root {
|
||||
func testMethodRootExtension() {
|
||||
// expected-error@+1 {{'super' cannot be used in extension of class 'Root' because it has no superclass}}
|
||||
super.x
|
||||
}
|
||||
}
|
||||
|
||||
class Derived: Root {
|
||||
// expected-error@+1 {{'super' cannot be used outside of a class computed property, method, initializer, deinitializer, or subscript}}
|
||||
let testStoredDerived = super.x
|
||||
|
||||
var testComputedDerived: Int {
|
||||
super.x
|
||||
}
|
||||
|
||||
init(derived: Void) {
|
||||
let _ = super.x
|
||||
}
|
||||
|
||||
func testMethodDerived(_: Int = super.x) -> Int {
|
||||
super.x
|
||||
}
|
||||
|
||||
deinit {
|
||||
let _ = super.x
|
||||
}
|
||||
}
|
||||
|
||||
protocol P: Derived {}
|
||||
extension P {
|
||||
func test() {
|
||||
// expected-error@+1 {{'super' cannot be used in non-class type 'P'}}
|
||||
super.x
|
||||
}
|
||||
}
|
||||
|
||||
enum E {
|
||||
case a(
|
||||
// expected-error@+1 {{'super' cannot be used in non-class type 'E'}}
|
||||
_: Int = super.undef
|
||||
)
|
||||
|
||||
func test() {
|
||||
// expected-error@+1 {{'super' cannot be used in non-class type 'E'}}
|
||||
super.undef
|
||||
}
|
||||
}
|
||||
|
||||
struct S {
|
||||
// expected-error@+1 {{'super' cannot be used in non-class type 'S'}}
|
||||
let testStoredRoot = super.undef
|
||||
|
||||
init() {
|
||||
// expected-error@+1 {{'super' cannot be used in non-class type 'S'}}
|
||||
super.init()
|
||||
}
|
||||
|
||||
func test() {
|
||||
// expected-error@+1 {{'super' cannot be used in non-class type 'S'}}
|
||||
super.undef
|
||||
}
|
||||
}
|
||||
|
||||
func test() {
|
||||
// expected-error@+1 {{'super' cannot be used outside of a class computed property, method, initializer, deinitializer, or subscript}}
|
||||
super.undef
|
||||
}
|
||||
|
||||
// expected-error@+1 {{'super' cannot be used outside of a class computed property, method, initializer, deinitializer, or subscript}}
|
||||
super.init()
|
||||
Reference in New Issue
Block a user