Skip to content

Commit 9231acf

Browse files
committed
[Diagnostics] Implement a tailored diagnostic for invalid static member refs on protocol metatypes
1 parent eaabd24 commit 9231acf

File tree

5 files changed

+59
-18
lines changed

5 files changed

+59
-18
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,6 +1902,9 @@ ERROR(type_does_not_conform_owner,none,
19021902
ERROR(type_does_not_conform_in_decl_ref,none,
19031903
"referencing %0 %1 on %2 requires that %3 conform to %4",
19041904
(DescriptiveDeclKind, DeclName, Type, Type, Type))
1905+
ERROR(type_does_not_conform_in_member_ref_on_protocol_type,none,
1906+
"cannot reference %0 %1 on %2 with non-conforming result type %3",
1907+
(DescriptiveDeclKind, DeclName, Type, Type))
19051908
ERROR(type_does_not_conform_anyobject_in_decl_ref,none,
19061909
"referencing %0 %1 on %2 requires that %3 be a class type",
19071910
(DescriptiveDeclKind, DeclName, Type, Type, Type))

include/swift/Sema/CSFix.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2313,24 +2313,24 @@ class AllowUnsupportedRuntimeCheckedCast final
23132313
};
23142314

23152315
class AllowInvalidStaticMemberRefOnProtocolMetatype final
2316-
: public ConstraintFix {
2317-
Type BaseType;
2316+
: public ConstraintFix {
2317+
Type ResultType;
23182318

23192319
AllowInvalidStaticMemberRefOnProtocolMetatype(ConstraintSystem &cs,
2320-
Type baseType,
2320+
Type resultType,
23212321
ConstraintLocator *locator)
2322-
: ConstraintFix(cs,
2323-
FixKind::AllowInvalidStaticMemberRefOnProtocolMetatype,
2324-
locator),
2325-
BaseType(baseType) {}
2322+
: ConstraintFix(cs,
2323+
FixKind::AllowInvalidStaticMemberRefOnProtocolMetatype,
2324+
locator),
2325+
ResultType(resultType) {}
23262326

23272327
public:
23282328
std::string getName() const override {
23292329
return "allow invalid static member reference on a protocol metatype";
23302330
}
23312331

23322332
static AllowInvalidStaticMemberRefOnProtocolMetatype *
2333-
create(ConstraintSystem &cs, Type baseType, ConstraintLocator *locator);
2333+
create(ConstraintSystem &cs, Type resultType, ConstraintLocator *locator);
23342334
};
23352335

23362336
} // end namespace constraints

lib/Sema/CSDiagnostics.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7189,6 +7189,26 @@ bool MemberMissingExplicitBaseTypeFailure::diagnoseAsError() {
71897189
.fixItInsert(UME->getDotLoc(), baseTypeName);
71907190
});
71917191
}
7192+
7193+
return true;
7194+
}
7195+
7196+
bool InvalidMemberRefOnProtocolMetatype::diagnoseAsError() {
7197+
auto *locator = getLocator();
7198+
auto overload = getOverloadChoiceIfAvailable(locator);
7199+
if (!overload)
7200+
return false;
7201+
7202+
auto *member = overload->choice.getDeclOrNull();
7203+
assert(member);
7204+
7205+
auto *DC = member->getDeclContext()->getSelfProtocolDecl();
7206+
auto protocolTy = DC->getDeclaredInterfaceType();
7207+
7208+
emitDiagnostic(diag::type_does_not_conform_in_member_ref_on_protocol_type,
7209+
member->getDescriptiveKind(), member->getName(),
7210+
MetatypeType::get(protocolTy), ResultType);
7211+
emitDiagnosticAt(member, diag::decl_declared_here, member->getName());
71927212
return true;
71937213
}
71947214

lib/Sema/CSDiagnostics.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2472,6 +2472,30 @@ class UnsupportedRuntimeCheckedCastFailure final
24722472
bool diagnoseAsError() override;
24732473
};
24742474

2475+
/// Diagnose situations when static member reference has invalid result
2476+
/// type which disqualifies it from being used on a protocol metatype base.
2477+
///
2478+
/// \code
2479+
/// protocol Foo {
2480+
/// static var bar: Int
2481+
/// }
2482+
///
2483+
/// _ = Foo.bar
2484+
/// \endcode
2485+
///
2486+
/// `bar` can't be referenced from `P.Protocol` base because its result type
2487+
/// `Int` doesn't conform to `Foo`.
2488+
class InvalidMemberRefOnProtocolMetatype final : public FailureDiagnostic {
2489+
Type ResultType;
2490+
2491+
public:
2492+
InvalidMemberRefOnProtocolMetatype(const Solution &solution, Type resultType,
2493+
ConstraintLocator *locator)
2494+
: FailureDiagnostic(solution, locator), ResultType(resultType) {}
2495+
2496+
bool diagnoseAsError() override;
2497+
};
2498+
24752499
} // end namespace constraints
24762500
} // end namespace swift
24772501

lib/Sema/CSFix.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,20 +1941,14 @@ bool AllowUnsupportedRuntimeCheckedCast::diagnose(const Solution &solution,
19411941

19421942
bool AllowInvalidStaticMemberRefOnProtocolMetatype::diagnose(
19431943
const Solution &solution, bool asNote) const {
1944-
auto *locator = getLocator();
1945-
auto overload = solution.getOverloadChoice(locator);
1946-
1947-
auto *member = overload.choice.getDeclOrNull();
1948-
assert(member);
1949-
1950-
AllowTypeOrInstanceMemberFailure failure(solution, BaseType, member,
1951-
member->createNameRef(), locator);
1944+
InvalidMemberRefOnProtocolMetatype failure(solution, ResultType,
1945+
getLocator());
19521946
return failure.diagnose(asNote);
19531947
}
19541948

19551949
AllowInvalidStaticMemberRefOnProtocolMetatype *
19561950
AllowInvalidStaticMemberRefOnProtocolMetatype::create(
1957-
ConstraintSystem &cs, Type baseType, ConstraintLocator *locator) {
1951+
ConstraintSystem &cs, Type resultType, ConstraintLocator *locator) {
19581952
return new (cs.getAllocator())
1959-
AllowInvalidStaticMemberRefOnProtocolMetatype(cs, baseType, locator);
1953+
AllowInvalidStaticMemberRefOnProtocolMetatype(cs, resultType, locator);
19601954
}

0 commit comments

Comments
 (0)