Skip to content

Commit 62c814a

Browse files
authored
Merge pull request #4078 from rudkx/fix-27639935
Add a fixit for attempting member lookup on Any.
2 parents c3fb541 + 56a5ef0 commit 62c814a

File tree

4 files changed

+20
-0
lines changed

4 files changed

+20
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ ERROR(could_not_find_enum_case,none,
7878
NOTE(did_you_mean_raw_type,none,
7979
"did you mean to specify a raw type on the enum declaration?", ())
8080

81+
NOTE(any_as_anyobject_fixit, none,
82+
"cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members", ())
83+
8184
ERROR(expected_argument_in_contextual_member,none,
8285
"contextual member %0 expects argument of type %1", (DeclName, Type))
8386

lib/Sema/CSDiag.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2523,6 +2523,14 @@ diagnoseUnviableLookupResults(MemberLookupResult &result, Type baseObjTy,
25232523
diagnose(loc, diag::did_you_mean_raw_type);
25242524
return; // Always prefer this over typo corrections.
25252525
}
2526+
} else if (baseObjTy->isAny()) {
2527+
if (auto DRE = dyn_cast<DeclRefExpr>(baseExpr)) {
2528+
auto name = DRE->getDecl()->getName().str().str();
2529+
std::string replacement = "(" + name + " as AnyObject)";
2530+
diagnose(loc, diag::any_as_anyobject_fixit)
2531+
.fixItReplace(baseExpr->getSourceRange(), replacement);
2532+
return;
2533+
}
25262534
}
25272535
}
25282536

test/Constraints/dynamic_lookup.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,9 @@ uopt.wibble!()
219219
// Should not be able to see private or internal @objc methods.
220220
uopt.privateFoo!() // expected-error{{'privateFoo' is inaccessible due to 'private' protection level}}
221221
uopt.internalFoo!() // expected-error{{'internalFoo' is inaccessible due to 'internal' protection level}}
222+
223+
let anyValue: Any = X()
224+
_ = anyValue.bar() // expected-error {{value of type 'Any' has no member 'bar'}}
225+
// expected-note@-1 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}}{{5-13=(anyValue as AnyObject)}}
226+
_ = (anyValue as AnyObject).bar()
227+
_ = (anyValue as! X).bar()

test/Constraints/tuple.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ any = (label: 4)
6161
// Scalars don't have .0/.1/etc
6262
i = j.0 // expected-error{{value of type 'Int' has no member '0'}}
6363
any.1 // expected-error{{value of type 'Any' has no member '1'}}
64+
// expected-note@-1{{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}}
65+
any = (5.0, 6.0) as (Float, Float)
66+
_ = (any as! (Float, Float)).1
6467

6568
// Fun with tuples
6669
protocol PosixErrorReturn {

0 commit comments

Comments
 (0)