Skip to content

[NFC] Make checkReferenceOwnershipAttr a Utility #27760

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 18 additions & 20 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2684,6 +2684,7 @@ void TypeChecker::checkParameterAttributes(ParameterList *params) {

Type TypeChecker::checkReferenceOwnershipAttr(VarDecl *var, Type type,
ReferenceOwnershipAttr *attr) {
auto &Diags = var->getASTContext().Diags;
auto *dc = var->getDeclContext();

// Don't check ownership attribute if the type is invalid.
Expand All @@ -2699,18 +2700,16 @@ Type TypeChecker::checkReferenceOwnershipAttr(VarDecl *var, Type type,
switch (optionalityOf(ownershipKind)) {
case ReferenceOwnershipOptionality::Disallowed:
if (isOptional) {
diagnose(var->getStartLoc(), diag::invalid_ownership_with_optional,
ownershipKind)
.fixItReplace(attr->getRange(), "weak");
var->diagnose(diag::invalid_ownership_with_optional, ownershipKind)
.fixItReplace(attr->getRange(), "weak");
attr->setInvalid();
}
break;
case ReferenceOwnershipOptionality::Allowed:
break;
case ReferenceOwnershipOptionality::Required:
if (var->isLet()) {
diagnose(var->getStartLoc(), diag::invalid_ownership_is_let,
ownershipKind);
var->diagnose(diag::invalid_ownership_is_let, ownershipKind);
attr->setInvalid();
}

Expand All @@ -2722,10 +2721,8 @@ Type TypeChecker::checkReferenceOwnershipAttr(VarDecl *var, Type type,
if (var->getAttrs().hasAttribute<IBOutletAttr>())
break;

auto diag = diagnose(var->getStartLoc(),
diag::invalid_ownership_not_optional,
ownershipKind,
OptionalType::get(type));
auto diag = var->diagnose(diag::invalid_ownership_not_optional,
ownershipKind, OptionalType::get(type));
auto typeRange = var->getTypeSourceRangeForDiagnostics();
if (type->hasSimpleTypeRepr()) {
diag.fixItInsertAfter(typeRange.End, "?");
Expand All @@ -2750,36 +2747,37 @@ Type TypeChecker::checkReferenceOwnershipAttr(VarDecl *var, Type type,
D = diag::invalid_ownership_protocol_type;
}

diagnose(var->getStartLoc(), D, ownershipKind, underlyingType);
var->diagnose(D, ownershipKind, underlyingType);
attr->setInvalid();
}

ClassDecl *underlyingClass = underlyingType->getClassOrBoundGenericClass();
if (underlyingClass && underlyingClass->isIncompatibleWithWeakReferences()) {
diagnose(attr->getLocation(),
diag::invalid_ownership_incompatible_class,
underlyingType, ownershipKind)
.fixItRemove(attr->getRange());
Diags
.diagnose(attr->getLocation(),
diag::invalid_ownership_incompatible_class, underlyingType,
ownershipKind)
.fixItRemove(attr->getRange());
attr->setInvalid();
}

auto PDC = dyn_cast<ProtocolDecl>(dc);
if (PDC && !PDC->isObjC()) {
// Ownership does not make sense in protocols, except for "weak" on
// properties of Objective-C protocols.
auto D = Context.isSwiftVersionAtLeast(5)
? diag::ownership_invalid_in_protocols
: diag::ownership_invalid_in_protocols_compat_warning;
diagnose(attr->getLocation(), D, ownershipKind)
.fixItRemove(attr->getRange());
auto D = var->getASTContext().isSwiftVersionAtLeast(5)
? diag::ownership_invalid_in_protocols
: diag::ownership_invalid_in_protocols_compat_warning;
Diags.diagnose(attr->getLocation(), D, ownershipKind)
.fixItRemove(attr->getRange());
attr->setInvalid();
}

if (attr->isInvalid())
return type;

// Change the type to the appropriate reference storage type.
return ReferenceStorageType::get(type, ownershipKind, Context);
return ReferenceStorageType::get(type, ownershipKind, var->getASTContext());
}

Optional<Diag<>>
Expand Down
3 changes: 2 additions & 1 deletion lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4211,7 +4211,8 @@ void TypeChecker::validateDecl(ValueDecl *D) {
// In SIL mode, VarDecls are written as having reference storage types.
if (!interfaceType->is<ReferenceStorageType>()) {
if (auto *attr = VD->getAttrs().getAttribute<ReferenceOwnershipAttr>())
interfaceType = checkReferenceOwnershipAttr(VD, interfaceType, attr);
interfaceType =
TypeChecker::checkReferenceOwnershipAttr(VD, interfaceType, attr);
}
VD->setInterfaceType(interfaceType);

Expand Down
4 changes: 2 additions & 2 deletions lib/Sema/TypeChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -1020,8 +1020,8 @@ class TypeChecker final : public LazyResolver {
void checkParameterAttributes(ParameterList *params);
static ValueDecl *findReplacedDynamicFunction(const ValueDecl *d);

Type checkReferenceOwnershipAttr(VarDecl *D, Type interfaceType,
ReferenceOwnershipAttr *attr);
static Type checkReferenceOwnershipAttr(VarDecl *D, Type interfaceType,
ReferenceOwnershipAttr *attr);

virtual void resolveDeclSignature(ValueDecl *VD) override {
validateDecl(VD);
Expand Down