Skip to content

Commit 3c5290c

Browse files
committed
[Diagnostics] Diagnose inability to infer contextual base type for member ref
1 parent ac1ab1d commit 3c5290c

File tree

4 files changed

+40
-2
lines changed

4 files changed

+40
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3044,6 +3044,8 @@ ERROR(collection_literal_empty,none,
30443044
ERROR(unresolved_member_no_inference,none,
30453045
"reference to member %0 cannot be resolved without a contextual type",
30463046
(DeclName))
3047+
ERROR(cannot_infer_base_of_unresolved_member,none,
3048+
"cannot infer contextual base in reference to member %0", (DeclName))
30473049
ERROR(unresolved_collection_literal,none,
30483050
"cannot infer type for empty collection literal without a "
30493051
"contextual type", ())

lib/Sema/CSDiagnostics.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5976,3 +5976,26 @@ bool AssignmentTypeMismatchFailure::diagnoseAsNote() {
59765976
return false;
59775977
}
59785978

5979+
bool MissingContextualBaseInMemberRefFailure::diagnoseAsError() {
5980+
auto *anchor = getAnchor();
5981+
auto &cs = getConstraintSystem();
5982+
5983+
// Member reference could be wrapped into a number of parens
5984+
// e.g. `((.foo))`.
5985+
auto *parentExpr = findParentExpr(anchor);
5986+
do {
5987+
// If we have found something which isn't a paren let's stop,
5988+
// otherwise let's keep unwrapping until there are either no
5989+
// more parens or no more parents...
5990+
if (!parentExpr || !isa<ParenExpr>(parentExpr))
5991+
break;
5992+
} while ((parentExpr = findParentExpr(parentExpr)));
5993+
5994+
auto diagnostic = parentExpr || cs.getContextualType(anchor)
5995+
? diag::cannot_infer_base_of_unresolved_member
5996+
: diag::unresolved_member_no_inference;
5997+
5998+
emitDiagnostic(anchor->getLoc(), diagnostic, MemberName)
5999+
.highlight(anchor->getSourceRange());
6000+
return true;
6001+
}

lib/Sema/CSDiagnostics.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2010,7 +2010,7 @@ class NonEphemeralConversionFailure final : public ArgumentMismatchFailure {
20102010
/// valid for the duration of the call, and suggests an alternative to use.
20112011
void emitSuggestionNotes() const;
20122012
};
2013-
2013+
20142014
class AssignmentTypeMismatchFailure final : public ContextualFailure {
20152015
public:
20162016
AssignmentTypeMismatchFailure(ConstraintSystem &cs,
@@ -2025,6 +2025,17 @@ class AssignmentTypeMismatchFailure final : public ContextualFailure {
20252025
bool diagnoseMissingConformance() const;
20262026
};
20272027

2028+
class MissingContextualBaseInMemberRefFailure final : public FailureDiagnostic {
2029+
DeclName MemberName;
2030+
2031+
public:
2032+
MissingContextualBaseInMemberRefFailure(ConstraintSystem &cs, DeclName member,
2033+
ConstraintLocator *locator)
2034+
: FailureDiagnostic(cs, locator), MemberName(member) {}
2035+
2036+
bool diagnoseAsError();
2037+
};
2038+
20282039
} // end namespace constraints
20292040
} // end namespace swift
20302041

lib/Sema/CSFix.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,9 @@ std::string TreatEphemeralAsNonEphemeral::getName() const {
10501050
}
10511051

10521052
bool SpecifyBaseTypeForContextualMember::diagnose(bool asNote) const {
1053-
return false;
1053+
auto &cs = getConstraintSystem();
1054+
MissingContextualBaseInMemberRefFailure failure(cs, MemberName, getLocator());
1055+
return failure.diagnose(asNote);
10541056
}
10551057

10561058
SpecifyBaseTypeForContextualMember *SpecifyBaseTypeForContextualMember::create(

0 commit comments

Comments
 (0)