Skip to content

Commit 898cde7

Browse files
authored
Merge pull request #68934 from dancamarotto/castmessage-whentypenotfound
Improve cast message when type not found
2 parents 7870afb + 8a84fdd commit 898cde7

File tree

6 files changed

+33
-8
lines changed

6 files changed

+33
-8
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,6 +1057,8 @@ NOTE(single_confusable_character,none,
10571057
(bool, StringRef, StringRef, StringRef, StringRef))
10581058
ERROR(cannot_find_type_in_scope,none,
10591059
"cannot find type %0 in scope", (DeclNameRef))
1060+
ERROR(cannot_find_type_in_cast_expression,none,
1061+
"type-casting operator expects a type on its right-hand side (got: %kind0)", (const ValueDecl *))
10601062
ERROR(cannot_find_type_in_scope_did_you_mean,none,
10611063
"cannot find type %0 in scope; did you mean to use '%1'?", (DeclNameRef, StringRef))
10621064
NOTE(note_typo_candidate_implicit_member,none,

lib/Sema/TypeCheckType.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,19 @@ static Type diagnoseUnknownType(TypeResolution resolution,
14231423

14241424
return I->second;
14251425
}
1426+
1427+
// type-casting operators such as 'is' and 'as'.
1428+
if (resolution.getOptions().is(TypeResolverContext::ExplicitCastExpr)) {
1429+
auto lookupResult = TypeChecker::lookupUnqualified(
1430+
dc, repr->getNameRef(), repr->getLoc(), lookupOptions);
1431+
if (!lookupResult.empty()) {
1432+
auto first = lookupResult.front().getValueDecl();
1433+
diags.diagnose(L, diag::cannot_find_type_in_cast_expression, first)
1434+
.highlight(R);
1435+
diags.diagnose(first, diag::decl_declared_here, first);
1436+
return ErrorType::get(ctx);
1437+
}
1438+
}
14261439

14271440
diags.diagnose(L, diag::cannot_find_type_in_scope, repr->getNameRef())
14281441
.highlight(R);

test/Constraints/casts.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,3 +741,13 @@ do {
741741
assert(Set(b.map { $0 as A }) == Set(a)) // Ok
742742
}
743743
}
744+
745+
// https://github.com/apple/swift/issues/68825
746+
do {
747+
func x(a: Any) { // expected-note 2 {{'a' declared here}}
748+
_ = a is a // expected-error {{type-casting operator expects a type on its right-hand side (got: parameter 'a')}}
749+
_ = a as a // expected-error {{type-casting operator expects a type on its right-hand side (got: parameter 'a')}}
750+
_ = a is Issue68825 // expected-error {{cannot find type 'Issue68825' in scope}}
751+
_ = a is String // OK
752+
}
753+
}

test/Parse/omit_return.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1709,8 +1709,8 @@ class CImplicitIdentityExpr { func gimme() -> CImplicitIdentityExpr { self } }
17091709

17101710
class CImplicitDotSelfExpr { func gimme() -> CImplicitDotSelfExpr { self.self } }
17111711

1712-
func badIs<T>(_ value: Any, anInstanceOf type: T.Type) -> Bool {
1713-
value is type // expected-error {{cannot find type 'type' in scope}}
1712+
func badIs<T>(_ value: Any, anInstanceOf type: T.Type) -> Bool { // expected-note {{'type' declared here}}
1713+
value is type // expected-error {{type-casting operator expects a type on its right-hand side (got: parameter 'type')}}
17141714
}
17151715

17161716

test/Parse/omit_return_fail.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
// RUN: %target-swift-frontend %s -typecheck -verify
22

3-
func badIs<T>(_ value: Any, anInstanceOf type: T.Type) -> Bool {
4-
value is type // expected-error {{cannot find type 'type' in scope}}
3+
func badIs<T>(_ value: Any, anInstanceOf type: T.Type) -> Bool { // expected-note {{'type' declared here}}
4+
value is type // expected-error {{type-casting operator expects a type on its right-hand side (got: parameter 'type')}}
55
}
66

77
func foo() -> Int {
88
return // expected-error {{non-void function should return a value}}
99
}
1010

11-
func badIs_ifdecl<T>(_ value: Any, anInstanceOf type: T.Type) -> Bool {
11+
func badIs_ifdecl<T>(_ value: Any, anInstanceOf type: T.Type) -> Bool { // expected-note {{'type' declared here}}
1212
#if true
13-
value is type // expected-error {{cannot find type 'type' in scope}}
13+
value is type // expected-error {{type-casting operator expects a type on its right-hand side (got: parameter 'type')}}
1414
#endif
1515
}
1616

test/Parse/omit_return_ifdecl.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2430,9 +2430,9 @@ class CImplicitIdentityExpr { func gimme() -> CImplicitIdentityExpr { self } }
24302430

24312431
class CImplicitDotSelfExpr { func gimme() -> CImplicitDotSelfExpr { self.self } }
24322432

2433-
func badIs<T>(_ value: Any, anInstanceOf type: T.Type) -> Bool {
2433+
func badIs<T>(_ value: Any, anInstanceOf type: T.Type) -> Bool { // expected-note {{'type' declared here}}
24342434
#if true
2435-
value is type // expected-error {{cannot find type 'type' in scope}}
2435+
value is type // expected-error {{type-casting operator expects a type on its right-hand side (got: parameter 'type')}}
24362436
#endif
24372437
}
24382438

0 commit comments

Comments
 (0)