Skip to content

Commit 31a430b

Browse files
committed
Sema: Tweak assertion in CustomAttrTypeRequest to allow generic typealiases
If the typealias here is generic, we return an UnboundGenericType where getAnyNominal() returns nullptr. This would fail by returning an ErrorType to the caller without diagnosing anything. This was a regression after some recent refactoring to remove code duplication and some TypeLoc usages, because one of the copies of this code did not have this check, so it happened to work for property wrappers. Relax the check by looking through a TypeAliasDecl explicitly. I believe we can't end up here anyway, because if the type was not a nominal we would fail earlier in CustomAttrNominalRequest, and we wouldn't attempt to compute the type of the property wrapper at all. However it's better to keep the assertion in place just in case. Fixes https://bugs.swift.org/browse/SR-14143 / rdar://problem/73888684.
1 parent 927a2b3 commit 31a430b

File tree

3 files changed

+56
-3
lines changed

3 files changed

+56
-3
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3970,12 +3970,26 @@ Type CustomAttrTypeRequest::evaluate(Evaluator &eval, CustomAttr *attr,
39703970
};
39713971
}
39723972

3973-
ASTContext &ctx = dc->getASTContext();
39743973
const auto type = TypeResolution::forContextual(dc, options, unboundTyOpener)
39753974
.resolveType(attr->getTypeRepr());
39763975

3977-
// We always require the type to resolve to a nominal type.
3978-
if (!type->getAnyNominal()) {
3976+
// We always require the type to resolve to a nominal type. If the type was
3977+
// not a nominal type, we should have already diagnosed an error via
3978+
// CustomAttrNominalRequest.
3979+
auto checkType = [](Type type) -> bool {
3980+
while (auto *genericDecl = type->getAnyGeneric()) {
3981+
if (isa<NominalTypeDecl>(genericDecl))
3982+
return true;
3983+
3984+
auto *aliasDecl = cast<TypeAliasDecl>(genericDecl);
3985+
type = aliasDecl->getUnderlyingType();
3986+
}
3987+
3988+
return false;
3989+
};
3990+
3991+
if (!checkType(type)) {
3992+
ASTContext &ctx = dc->getASTContext();
39793993
assert(ctx.Diags.hadAnyError());
39803994
return ErrorType::get(ctx);
39813995
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// https://bugs.swift.org/browse/SR-14143
4+
5+
@propertyWrapper
6+
struct SomeLongFooName<Holder, T> {
7+
var wrappedValue: T
8+
9+
init(wrappedValue: T) {
10+
self.wrappedValue = wrappedValue
11+
}
12+
}
13+
14+
15+
struct Bar {
16+
typealias Foo<T> = SomeLongFooName<Self, T>
17+
18+
@Foo var baz: Bool = false
19+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
@propertyWrapper
4+
struct SomeStruct<T> {
5+
var wrappedValue: T
6+
7+
init(wrappedValue: T) {
8+
self.wrappedValue = wrappedValue
9+
}
10+
}
11+
12+
typealias Invalid1<T> = (T) -> ()
13+
typealias Invalid2<T> = SomeStruct<T>.Type
14+
typealias Invalid3 = SomeStruct<Bool>.Type
15+
16+
struct Bar {
17+
@Invalid1 var badWrapper1: Bool = false // expected-error {{unknown attribute 'Invalid1'}}
18+
@Invalid2 var badWrapper2: Bool = false // expected-error {{unknown attribute 'Invalid2'}}
19+
@Invalid3 var badWrapper3: Bool = false // expected-error {{unknown attribute 'Invalid3'}}
20+
}

0 commit comments

Comments
 (0)