Skip to content

Commit 602a116

Browse files
authored
Merge pull request #81421 from beccadax/just-not-my-type
2 parents a3279af + 7e7f9d0 commit 602a116

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4281,8 +4281,25 @@ void AttributeChecker::visitImplementsAttr(ImplementsAttr *attr) {
42814281
ProtocolDecl *PD = attr->getProtocol(DC);
42824282

42834283
if (!PD) {
4284-
diagnose(attr->getLocation(), diag::implements_attr_non_protocol_type)
4285-
.highlight(attr->getProtocolTypeRepr()->getSourceRange());
4284+
// `ImplementsAttr::getProtocol()` returns `nullptr` both when a type fails
4285+
// to resolve, and when it resolves to something other than a protocol.
4286+
// Due to layering concerns, it doesn't resolve in a way that emits
4287+
// diagnostics.
4288+
//
4289+
// Distinguish between these situations by trying to resolve the type again.
4290+
// If it doesn't resolve, TypeResolution will have diagnosed the problem; if
4291+
// it does, it must have resolved to a non-protocol, so emit a diagnostic to
4292+
// that effect.
4293+
TypeResolutionOptions options(TypeResolverContext::None);
4294+
auto resolvedType = TypeResolution::resolveContextualType(
4295+
attr->getProtocolTypeRepr(), DC, options,
4296+
// Unbound generics and placeholders are not allowed within this attr.
4297+
/*unboundTyOpener*/ nullptr, /*placeholderHandler*/ nullptr,
4298+
/*packElementOpener*/ nullptr);
4299+
4300+
if (resolvedType && !resolvedType->hasError())
4301+
diagnose(attr->getLocation(), diag::implements_attr_non_protocol_type)
4302+
.highlight(attr->getProtocolTypeRepr()->getSourceRange());
42864303
return;
42874304
}
42884305

test/attr/attr_implements_bad_types.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,9 @@ struct S0 : NeedsF0 { // expected-error {{type 'S0' does not conform to protoco
2121
@_implements(Equatable, ==(_:_:)) // expected-error {{containing type 'S0' does not conform to protocol 'Equatable'}}
2222
static func gg2(x:S0, y:S0) -> Bool {
2323
}
24+
25+
@_implements(NonexistentType, ff3()) // expected-error {{cannot find type 'NonexistentType' in scope}}
26+
func gg3() {
27+
}
2428
}
2529

0 commit comments

Comments
 (0)