@@ -610,14 +610,47 @@ IsSetterMutatingRequest::evaluate(Evaluator &evaluator,
610610 llvm_unreachable (" bad storage kind" );
611611}
612612
613+ /*
614+ // An accessor that uses borrowed ownership cannot have effects, as the
615+ // coroutine accessor doesn't support `async` or `throws`
616+ if (auto accessor = dyn_cast<AccessorDecl>(FD)) {
617+ if (accessor->hasThrows() || accessor->hasAsync())
618+ if (accessor->)
619+ if (accessor->getResultInterfaceType()->isPureMoveOnly())
620+ accessor->diagnose(diag::moveonly_effectful_getter);
621+ }
622+ */
623+
613624OpaqueReadOwnership
614625OpaqueReadOwnershipRequest::evaluate (Evaluator &evaluator,
615626 AbstractStorageDecl *storage) const {
616- if (storage->getAttrs ().hasAttribute <BorrowedAttr>())
627+ enum class DiagKind {
628+ BorrowedAttr,
629+ NoncopyableType
630+ };
631+
632+ auto usesBorrowed = [&](DiagKind kind) -> OpaqueReadOwnership {
633+ // Check for effects on the getter.
634+ if (auto *getter = storage->getEffectfulGetAccessor ()) {
635+ switch (kind) {
636+ case DiagKind::NoncopyableType:
637+ getter->diagnose (diag::moveonly_effectful_getter,
638+ getter->getDescriptiveKind ());
639+ break ;
640+ case DiagKind::BorrowedAttr:
641+ getter->diagnose (diag::borrowed_with_effect,
642+ getter->getDescriptiveKind ());
643+ break ;
644+ }
645+ }
617646 return OpaqueReadOwnership::Borrowed;
647+ };
648+
649+ if (storage->getAttrs ().hasAttribute <BorrowedAttr>())
650+ return usesBorrowed (DiagKind::BorrowedAttr);
618651
619652 if (storage->getValueInterfaceType ()->isPureMoveOnly ())
620- return OpaqueReadOwnership::Borrowed ;
653+ return usesBorrowed (DiagKind::NoncopyableType) ;
621654
622655 return OpaqueReadOwnership::Owned;
623656}
0 commit comments