diff --git a/docs/LangRef.html b/docs/LangRef.html
index e7804c16c09..328bd33e975 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -458,7 +458,7 @@
oneof and struct declaration extensions
- 'var' decls are not allowed in a oneof or struct,
+
'var' decls that do not have a getter or setter are not allowed in a oneof or struct,
data members should be used instead.
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index e31f6e2c6ce..973827b8b1e 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -104,7 +104,7 @@ public:
DeclKind getKind() const { return DeclKind(DeclBits.Kind); }
DeclContext *getDeclContext() const { return Context; }
- void setDeclContext(DeclContext *DC) { Context = DC; }
+ void setDeclContext(DeclContext *DC);
/// getASTContext - Return the ASTContext that this decl lives in.
ASTContext &getASTContext() const {
@@ -218,6 +218,12 @@ class PatternBindingDecl : public Decl {
Pattern *Pat; // The pattern which this decl binds
Expr *Init; // Initializer for the variables
+ friend class Decl;
+
+ /// \brief Update the DeclContext for any variables in the pattern to
+ /// refer to the same DeclContext as this declaration.
+ void updateDeclContextForVars();
+
public:
PatternBindingDecl(SourceLoc VarLoc, Pattern *Pat, Expr *E,
DeclContext *Parent)
@@ -425,6 +431,9 @@ private:
GetSetRecord *GetSet;
+ friend class Decl;
+ void updateDeclContextForGetSet();
+
public:
VarDecl(SourceLoc VarLoc, Identifier Name, Type Ty, DeclContext *DC,
bool IsModuleScope)
@@ -540,6 +549,14 @@ public:
};
+inline void Decl::setDeclContext(DeclContext *DC) {
+ Context = DC;
+ if (PatternBindingDecl *PBD = dyn_cast(this))
+ PBD->updateDeclContextForVars();
+ else if (VarDecl *Var = dyn_cast(this))
+ Var->updateDeclContextForGetSet();
+}
+
} // end namespace swift
#endif
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 694e6b78014..33b5bf78452 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -146,6 +146,16 @@ void VarDecl::setProperty(ASTContext &Context, SourceLoc LBraceLoc,
GetSet->Set = Set;
}
+void VarDecl::updateDeclContextForGetSet() {
+ if (!GetSet)
+ return;
+
+ if (GetSet->Get)
+ GetSet->Get->setDeclContext(getDeclContext());
+ if (GetSet->Set)
+ GetSet->Set->setDeclContext(getDeclContext());
+}
+
/// getExtensionType - If this is a method in a type extension for some type,
/// return that type, otherwise return Type().
Type FuncDecl::getExtensionType() const {
@@ -212,6 +222,35 @@ VarDecl *FuncDecl::getImplicitThisDecl() {
return 0;
}
+static void updateDeclContextForVarsInPattern(Pattern *P, DeclContext *DC) {
+ switch (P->getKind()) {
+ case PatternKind::Any:
+ break;
+
+ case PatternKind::Named:
+ cast(P)->getDecl()->setDeclContext(DC);
+ break;
+
+ case PatternKind::Paren:
+ updateDeclContextForVarsInPattern(cast(P)->getSubPattern(),
+ DC);
+ break;
+
+ case PatternKind::Tuple:
+ for (auto &Elt : cast(P)->getFields())
+ updateDeclContextForVarsInPattern(Elt.getPattern(), DC);
+ break;
+
+ case PatternKind::Typed:
+ updateDeclContextForVarsInPattern(cast(P)->getSubPattern(),
+ DC);
+ break;
+ }
+}
+
+void PatternBindingDecl::updateDeclContextForVars() {
+ updateDeclContextForVarsInPattern(Pat, getDeclContext());
+}
//===----------------------------------------------------------------------===//
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index c0793ecd642..6b63d37dc5c 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -349,7 +349,8 @@ bool Parser::parseDecl(SmallVectorImpl &Entries, unsigned Flags) {
// FIXME: Mark decls erroneous.
if (isa(D) && !(Flags & PD_AllowTopLevel))
diagnose(D->getLocStart(), diag::decl_inner_scope);
- if (isa(D) && (Flags & PD_DisallowVar)) {
+ if (isa(D) && (Flags & PD_DisallowVar) &&
+ !cast(D)->isProperty()) {
diagnose(D->getLocStart(), diag::disallowed_var_decl);
} else if (NamedDecl *ND = dyn_cast(D)) {
if (ND->isOperator() && (Flags & PD_DisallowOperators))
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index caace099587..e61c75f6824 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -121,6 +121,12 @@ public:
void visitVarDecl(VarDecl *VD) {
// Delay type-checking on VarDecls until we see the corresponding
// PatternBindingDecl.
+ if (VD->isProperty()) {
+ if (FuncDecl *Get = VD->getGetter())
+ visitFuncDecl(Get);
+ if (FuncDecl *Set = VD->getSetter())
+ visitFuncDecl(Set);
+ }
}
void visitFuncDecl(FuncDecl *FD) {