Skip to content

Commit 17d1ce9

Browse files
committed
[Typechecker] Diagnose the original wrapped property instead of the nearest non-implicit decl context
1 parent 51183c2 commit 17d1ce9

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,8 @@ ERROR(invalid_redecl_init,none,
756756
"invalid redeclaration of synthesized %select{|memberwise }1%0",
757757
(DeclName, bool))
758758
ERROR(invalid_redecl_implicit,none,
759-
"invalid redeclaration of synthesized %select{%0|witness for protocol requirement}1 %2",
759+
"invalid redeclaration of synthesized "
760+
"%select{%0|implementation for protocol requirement}1 %2",
760761
(DescriptiveDeclKind, bool, DeclName))
761762
WARNING(invalid_redecl_swift5_warning,none,
762763
"redeclaration of %0 is deprecated and will be an error in Swift 5",
@@ -765,7 +766,9 @@ WARNING(invalid_redecl_swift5_warning,none,
765766
NOTE(invalid_redecl_prev,none,
766767
"%0 previously declared here", (DeclName))
767768
NOTE(invalid_redecl_implicit_wrapper,none,
768-
"%0 synthesized for property wrapper %select{projected value|backing storage}1", (DeclName, bool))
769+
"%0 synthesized for property wrapper "
770+
"%select{projected value|backing storage}1",
771+
(DeclName, bool))
769772

770773
ERROR(ambiguous_type_base,none,
771774
"%0 is ambiguous for type lookup in this context", (DeclNameRef))

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -722,10 +722,20 @@ CheckRedeclarationRequest::evaluate(Evaluator &eval, ValueDecl *current) const {
722722
// 'other' is implicit, we diagnose 'current'.
723723
const auto *declToDiagnose = currentDC->getAsDecl();
724724
if (current->isImplicit() && other->isImplicit()) {
725-
// Get the nearest non-implicit decl context
726-
while (declToDiagnose && declToDiagnose->isImplicit() &&
727-
declToDiagnose->getDeclContext()) {
728-
declToDiagnose = declToDiagnose->getDeclContext()->getAsDecl();
725+
// If 'current' is a property wrapper backing storage property
726+
// or projected value property, then diagnose the wrapped
727+
// property instead of the nearest non-implicit DC.
728+
if (auto VD = dyn_cast<VarDecl>(current)) {
729+
if (auto originalWrappedProperty =
730+
VD->getOriginalWrappedProperty()) {
731+
declToDiagnose = originalWrappedProperty;
732+
}
733+
} else {
734+
// Get the nearest non-implicit decl context
735+
while (declToDiagnose && declToDiagnose->isImplicit() &&
736+
declToDiagnose->getDeclContext()) {
737+
declToDiagnose = declToDiagnose->getDeclContext()->getAsDecl();
738+
}
729739
}
730740
} else {
731741
declToDiagnose = current->isImplicit() ? other : current;
@@ -748,7 +758,7 @@ CheckRedeclarationRequest::evaluate(Evaluator &eval, ValueDecl *current) const {
748758
// Emit a specialized note if the one of the declarations is
749759
// the backing storage property ('_foo') or projected value
750760
// property ('$foo') for a wrapped property. The backing or
751-
// storage var has the same source location as the wrapped
761+
// projected var has the same source location as the wrapped
752762
// property we diagnosed above, so we don't need to extract
753763
// the original property.
754764
const VarDecl *varToDiagnose = nullptr;

0 commit comments

Comments
 (0)