Skip to content

[Parse] [SR-5674] Add fix-it for computed 'let' declaration #11527

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
Aug 20, 2017
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
3 changes: 2 additions & 1 deletion include/swift/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,8 @@ class Parser {
SourceLoc staticLoc, ParsedAccessors &accessors);
void parseAccessorBodyDelayed(AbstractFunctionDecl *AFD);
VarDecl *parseDeclVarGetSet(Pattern *pattern, ParseDeclOptions Flags,
SourceLoc StaticLoc, bool hasInitializer,
SourceLoc StaticLoc, SourceLoc VarLoc,
bool hasInitializer,
const DeclAttributes &Attributes,
SmallVectorImpl<Decl *> &Decls);

Expand Down
15 changes: 10 additions & 5 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4035,7 +4035,8 @@ void Parser::parseAccessorBodyDelayed(AbstractFunctionDecl *AFD) {
/// \brief Parse the brace-enclosed getter and setter for a variable.
VarDecl *Parser::parseDeclVarGetSet(Pattern *pattern,
ParseDeclOptions Flags,
SourceLoc StaticLoc, bool hasInitializer,
SourceLoc StaticLoc, SourceLoc VarLoc,
bool hasInitializer,
const DeclAttributes &Attributes,
SmallVectorImpl<Decl *> &Decls) {
bool Invalid = false;
Expand Down Expand Up @@ -4090,12 +4091,15 @@ VarDecl *Parser::parseDeclVarGetSet(Pattern *pattern,

// Reject accessors on 'let's after parsing them (for better recovery).
if (PrimaryVar->isLet() && !Attributes.hasAttribute<SILStoredAttr>()) {
Diag<> DiagID;
if (accessors.WillSet || accessors.DidSet)
diagnose(accessors.LBLoc, diag::let_cannot_be_observing_property);
DiagID = diag::let_cannot_be_observing_property;
else if (accessors.Addressor || accessors.MutableAddressor)
diagnose(accessors.LBLoc, diag::let_cannot_be_addressed_property);
DiagID = diag::let_cannot_be_addressed_property;
else
diagnose(accessors.LBLoc, diag::let_cannot_be_computed_property);
DiagID = diag::let_cannot_be_computed_property;

diagnose(accessors.LBLoc, DiagID).fixItReplace(VarLoc, "var");
PrimaryVar->setSpecifier(VarDecl::Specifier::Var);
Invalid = true;
}
Expand Down Expand Up @@ -4598,7 +4602,8 @@ Parser::parseDeclVar(ParseDeclOptions Flags,
} else if (Tok.is(tok::l_brace)) {
HasAccessors = true;

if (auto *boundVar = parseDeclVarGetSet(pattern, Flags, StaticLoc,
if (auto *boundVar = parseDeclVarGetSet(pattern, Flags,
StaticLoc, VarLoc,
PatternInit != nullptr,
Attributes, Decls)) {
if (PatternInit && !boundVar->hasStorage()) {
Expand Down
4 changes: 2 additions & 2 deletions test/Sema/immutability.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

func markUsed<T>(_ t: T) {}

let bad_property_1: Int { // expected-error {{'let' declarations cannot be computed properties}}
let bad_property_1: Int { // expected-error {{'let' declarations cannot be computed properties}} {{1-4=var}}
get {
return 42
}
}
let bad_property_2: Int = 0 { // expected-error {{'let' declarations cannot be computed properties}} expected-error {{variable with getter/setter cannot have an initial value}}
let bad_property_2: Int = 0 { // expected-error {{'let' declarations cannot be computed properties}} {{1-4=var}} expected-error {{variable with getter/setter cannot have an initial value}}
get {
return 42
}
Expand Down
2 changes: 1 addition & 1 deletion test/decl/protocol/protocols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ struct X4 : P1 { // expected-error{{type 'X4' does not conform to protocol 'P1'}

protocol ShouldntCrash {
// rdar://16109996
let fullName: String { get } // expected-error {{'let' declarations cannot be computed properties}}
let fullName: String { get } // expected-error {{'let' declarations cannot be computed properties}} {{3-6=var}}

// <rdar://problem/17200672> Let in protocol causes unclear errors and crashes
let fullName2: String // expected-error {{immutable property requirement must be declared as 'var' with a '{ get }' specifier}}
Expand Down
2 changes: 1 addition & 1 deletion test/decl/var/properties.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,7 @@ struct PropertiesWithOwnershipTypes {

// <rdar://problem/16608609> Assert (and incorrect error message) when defining a constant stored property with observers
class Test16608609 {
let constantStored: Int = 0 { // expected-error {{'let' declarations cannot be observing properties}}
let constantStored: Int = 0 { // expected-error {{'let' declarations cannot be observing properties}} {{4-7=var}}
willSet {
}
didSet {
Expand Down
2 changes: 1 addition & 1 deletion test/decl/var/static_var.swift
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ extension ProtoAdopter : ProtosEvilTwin {}
public struct Foo { // expected-note {{to match this opening '{'}}}
public static let S { a // expected-error{{computed property must have an explicit type}} {{22-22=: <# Type #>}}
// expected-error@-1{{type annotation missing in pattern}}
// expected-error@-2{{'let' declarations cannot be computed properties}}
// expected-error@-2{{'let' declarations cannot be computed properties}} {{17-20=var}}
// expected-error@-3{{use of unresolved identifier 'a'}}
}

Expand Down