Skip to content

[Diag] Formalize SelfAccessKind printing #23538

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
Mar 25, 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
10 changes: 6 additions & 4 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -5561,12 +5561,14 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {

class OperatorDecl;

/// Note: These align with '%select's in diagnostics.
enum class SelfAccessKind : uint8_t {
NonMutating = 0,
Mutating = 1,
__Consuming = 2,
NonMutating,
Mutating,
__Consuming,
};

/// Diagnostic printing of \c SelfAccessKind.
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SelfAccessKind SAK);

/// FuncDecl - 'func' declaration.
class FuncDecl : public AbstractFunctionDecl {
Expand Down
12 changes: 12 additions & 0 deletions include/swift/AST/DiagnosticEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace swift {
class ValueDecl;

enum class PatternKind : uint8_t;
enum class SelfAccessKind : uint8_t;
enum class ReferenceOwnership : uint8_t;
enum class StaticSpellingKind : uint8_t;
enum class DescriptiveDeclKind : uint8_t;
Expand Down Expand Up @@ -77,6 +78,7 @@ namespace swift {
Type,
TypeRepr,
PatternKind,
SelfAccessKind,
ReferenceOwnership,
StaticSpellingKind,
DescriptiveDeclKind,
Expand Down Expand Up @@ -105,6 +107,7 @@ namespace swift {
Type TypeVal;
TypeRepr *TyR;
PatternKind PatternKindVal;
SelfAccessKind SelfAccessKindVal;
ReferenceOwnership ReferenceOwnershipVal;
StaticSpellingKind StaticSpellingKindVal;
DescriptiveDeclKind DescriptiveDeclKindVal;
Expand Down Expand Up @@ -169,6 +172,10 @@ namespace swift {
: Kind(DiagnosticArgumentKind::ReferenceOwnership),
ReferenceOwnershipVal(RO) {}

DiagnosticArgument(SelfAccessKind SAK)
: Kind(DiagnosticArgumentKind::SelfAccessKind),
SelfAccessKindVal(SAK) {}

DiagnosticArgument(StaticSpellingKind SSK)
: Kind(DiagnosticArgumentKind::StaticSpellingKind),
StaticSpellingKindVal(SSK) {}
Expand Down Expand Up @@ -249,6 +256,11 @@ namespace swift {
return ReferenceOwnershipVal;
}

SelfAccessKind getAsSelfAccessKind() const {
assert(Kind == DiagnosticArgumentKind::SelfAccessKind);
return SelfAccessKindVal;
}

StaticSpellingKind getAsStaticSpellingKind() const {
assert(Kind == DiagnosticArgumentKind::StaticSpellingKind);
return StaticSpellingKindVal;
Expand Down
24 changes: 10 additions & 14 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1108,24 +1108,20 @@ ERROR(attribute_requires_operator_identifier,none,
ERROR(attribute_requires_single_argument,none,
"'%0' requires a function with one argument", (StringRef))

ERROR(mutating_invalid_global_scope,none,
"'%select{nonmutating|mutating|__consuming}0' is only valid on methods",
(unsigned))
ERROR(mutating_invalid_classes,none,
"'%select{nonmutating|mutating|__consuming}0' isn't valid on methods in "
"classes or class-bound protocols", (bool))
ERROR(mutating_invalid_global_scope,none, "%0 is only valid on methods",
(SelfAccessKind))
ERROR(mutating_invalid_classes,none, "%0 isn't valid on methods in "
"classes or class-bound protocols", (SelfAccessKind))

ERROR(functions_mutating_and_not,none,
"method must not be declared both "
"%select{nonmutating|mutating|__consuming}0 and "
"%select{nonmutating|mutating|__consuming}1",
(unsigned, unsigned))
"method must not be declared both %0 and %1",
(SelfAccessKind, SelfAccessKind))
ERROR(static_functions_not_mutating,none,
"static functions must not be declared mutating", ())

ERROR(modify_mutatingness_differs_from_setter,none,
"'modify' accessor cannot be %select{nonmutating|mutating}0 "
"when the setter is %select{mutating|nonmutating}0", (bool))
"'modify' accessor cannot be %0 when the setter is %1",
(SelfAccessKind, SelfAccessKind))

ERROR(transparent_in_protocols_not_supported,none,
"'@_transparent' attribute is not supported on declarations within protocols", ())
Expand Down Expand Up @@ -1871,8 +1867,8 @@ NOTE(protocol_witness_prefix_postfix_conflict,none,
"candidate is %select{|prefix, |postfix, }1not "
"%select{prefix|postfix}0 as required", (bool, unsigned))
NOTE(protocol_witness_mutation_modifier_conflict,none,
"candidate is marked '%select{nonmutating|mutating|__consuming}0' but "
"protocol does not allow it", (unsigned))
"candidate is marked %0 but protocol does not allow it",
(SelfAccessKind))
NOTE(protocol_witness_settable_conflict,none,
"candidate is not settable, but protocol requires it", ())
NOTE(protocol_witness_rethrows_conflict,none,
Expand Down
10 changes: 10 additions & 0 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,16 @@ llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &OS,
return OS << "'" << keywordOf(RO) << "'";
}

llvm::raw_ostream &swift::operator<<(llvm::raw_ostream &OS,
SelfAccessKind SAK) {
switch (SAK) {
case SelfAccessKind::NonMutating: return OS << "'nonmutating'";
case SelfAccessKind::Mutating: return OS << "'mutating'";
case SelfAccessKind::__Consuming: return OS << "'__consuming'";
}
llvm_unreachable("Unknown SelfAccessKind");
}

DeclContext *Decl::getInnermostDeclContext() const {
if (auto func = dyn_cast<AbstractFunctionDecl>(this))
return const_cast<AbstractFunctionDecl*>(func);
Expand Down
12 changes: 12 additions & 0 deletions lib/AST/DiagnosticEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,18 @@ static void formatDiagnosticArgument(StringRef Modifier,
Out << Arg.getAsPatternKind();
break;

case DiagnosticArgumentKind::SelfAccessKind:
if (Modifier == "select") {
formatSelectionArgument(ModifierArguments, Args,
unsigned(Arg.getAsSelfAccessKind()),
FormatOpts, Out);
} else {
assert(Modifier.empty() &&
"Improper modifier for SelfAccessKind argument");
Out << Arg.getAsSelfAccessKind();
}
break;

case DiagnosticArgumentKind::ReferenceOwnership:
if (Modifier == "select") {
formatSelectionArgument(ModifierArguments, Args,
Expand Down
13 changes: 5 additions & 8 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,11 @@ void AttributeEarlyChecker::visitMutationAttr(DeclAttribute *attr) {
if (contextTy->hasReferenceSemantics()) {
if (attrModifier != SelfAccessKind::__Consuming)
diagnoseAndRemoveAttr(attr, diag::mutating_invalid_classes,
unsigned(attrModifier));
attrModifier);
}
} else {
diagnoseAndRemoveAttr(attr, diag::mutating_invalid_global_scope,
unsigned(attrModifier));
attrModifier);
}

// Verify we don't have more than one of mutating, nonmutating,
Expand All @@ -294,24 +294,21 @@ void AttributeEarlyChecker::visitMutationAttr(DeclAttribute *attr) {
if (auto *NMA = FD->getAttrs().getAttribute<NonMutatingAttr>()) {
if (attrModifier != SelfAccessKind::NonMutating) {
diagnoseAndRemoveAttr(NMA, diag::functions_mutating_and_not,
unsigned(SelfAccessKind::NonMutating),
unsigned(attrModifier));
SelfAccessKind::NonMutating, attrModifier);
}
}

if (auto *MUA = FD->getAttrs().getAttribute<MutatingAttr>()) {
if (attrModifier != SelfAccessKind::Mutating) {
diagnoseAndRemoveAttr(MUA, diag::functions_mutating_and_not,
unsigned(SelfAccessKind::Mutating),
unsigned(attrModifier));
SelfAccessKind::Mutating, attrModifier);
}
}

if (auto *CSA = FD->getAttrs().getAttribute<ConsumingAttr>()) {
if (attrModifier != SelfAccessKind::__Consuming) {
diagnoseAndRemoveAttr(CSA, diag::functions_mutating_and_not,
unsigned(SelfAccessKind::__Consuming),
unsigned(attrModifier));
SelfAccessKind::__Consuming, attrModifier);
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1975,7 +1975,10 @@ static bool computeIsSetterMutating(TypeChecker &TC,
if ((result || storage->isGetterMutating()) != modifyResult) {
TC.diagnose(modifyAccessor,
diag::modify_mutatingness_differs_from_setter,
modifyResult);
modifyResult ? SelfAccessKind::Mutating
: SelfAccessKind::NonMutating,
modifyResult ? SelfAccessKind::NonMutating
: SelfAccessKind::Mutating);
TC.diagnose(storage->getSetter(), diag::previous_accessor, "setter", 0);
modifyAccessor->setInvalid();
}
Expand Down
6 changes: 3 additions & 3 deletions lib/Sema/TypeCheckProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2193,19 +2193,19 @@ diagnoseMatch(ModuleDecl *module, NormalProtocolConformance *conformance,
// FIXME: Could emit a Fix-It here.
diags.diagnose(match.Witness,
diag::protocol_witness_mutation_modifier_conflict,
unsigned(SelfAccessKind::Mutating));
SelfAccessKind::Mutating);
break;
case MatchKind::NonMutatingConflict:
// FIXME: Could emit a Fix-It here.
diags.diagnose(match.Witness,
diag::protocol_witness_mutation_modifier_conflict,
unsigned(SelfAccessKind::NonMutating));
SelfAccessKind::NonMutating);
break;
case MatchKind::ConsumingConflict:
// FIXME: Could emit a Fix-It here.
diags.diagnose(match.Witness,
diag::protocol_witness_mutation_modifier_conflict,
unsigned(SelfAccessKind::__Consuming));
SelfAccessKind::__Consuming);
break;
case MatchKind::RethrowsConflict:
// FIXME: Could emit a Fix-It here.
Expand Down
4 changes: 2 additions & 2 deletions test/Sema/generalized_accessors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ struct Modify {

var getAndNonMutatingModifyAndSet: Int {
get {}
nonmutating _modify {} // expected-error {{'modify' accessor cannot be nonmutating when the setter is mutating}}
nonmutating _modify {} // expected-error {{'modify' accessor cannot be 'nonmutating' when the setter is 'mutating'}}
set {} // expected-note {{setter defined here}}
}

var getAndModifyAndNonMutatingSet: Int {
get {}
_modify {}// expected-error {{'modify' accessor cannot be mutating when the setter is nonmutating}}
_modify {}// expected-error {{'modify' accessor cannot be 'mutating' when the setter is 'nonmutating'}}
nonmutating set {} // expected-note {{setter defined here}}
}
}
Expand Down
10 changes: 5 additions & 5 deletions test/Sema/immutability.swift
Original file line number Diff line number Diff line change
Expand Up @@ -509,11 +509,11 @@ struct F { // expected-note 1 {{in declaration of 'F'}}
mutating mutating mutating f() { // expected-error 2 {{duplicate modifier}} expected-note 2 {{modifier already specified here}} expected-error {{expected declaration}}
}

mutating nonmutating func g() {} // expected-error {{method must not be declared both mutating and nonmutating}}
__consuming nonmutating func h() {} // expected-error {{method must not be declared both __consuming and nonmutating}}
__consuming mutating func i() {} // expected-error {{method must not be declared both __consuming and mutating}}
nonmutating mutating func j() {} // expected-error {{method must not be declared both nonmutating and mutating}}
__consuming nonmutating mutating func k() {} // expected-error {{method must not be declared both __consuming and mutating}} expected-error {{method must not be declared both nonmutating and mutating}}
mutating nonmutating func g() {} // expected-error {{method must not be declared both 'mutating' and 'nonmutating'}}
__consuming nonmutating func h() {} // expected-error {{method must not be declared both '__consuming' and 'nonmutating'}}
__consuming mutating func i() {} // expected-error {{method must not be declared both '__consuming' and 'mutating'}}
nonmutating mutating func j() {} // expected-error {{method must not be declared both 'nonmutating' and 'mutating'}}
__consuming nonmutating mutating func k() {} // expected-error {{method must not be declared both '__consuming' and 'mutating'}} expected-error {{method must not be declared both 'nonmutating' and 'mutating'}}
}

protocol SingleIntProperty {
Expand Down