From 8ebdb3d0abefc5359e4fb986a0ecb17733f0f74a Mon Sep 17 00:00:00 2001
From: Seth Pink <sethpink@gmail.com>
Date: Sat, 9 Feb 2013 23:00:55 +1000
Subject: [PATCH] Issue #4830 fix

---
 src/libsyntax/parse/obsolete.rs          |  5 --
 src/libsyntax/parse/parser.rs            | 71 ++++++++----------------
 src/test/compile-fail/obsolete-syntax.rs |  8 ---
 src/test/run-pass/issue-4830.rs          | 16 ++++++
 4 files changed, 40 insertions(+), 60 deletions(-)
 create mode 100644 src/test/run-pass/issue-4830.rs

diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index cdde542bb1f32..66ce36fa476cb 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -39,7 +39,6 @@ pub enum ObsoleteSyntax {
     ObsoleteFieldTerminator,
     ObsoleteStructCtor,
     ObsoleteWith,
-    ObsoleteClassMethod,
     ObsoleteClassTraits,
     ObsoletePrivSection,
     ObsoleteModeInFnType,
@@ -85,10 +84,6 @@ pub impl Parser {
                 "record update is done with `..`, e.g. \
                  `MyStruct { foo: bar, .. baz }`"
             ),
-            ObsoleteClassMethod => (
-                "class method",
-                "methods should be defined inside impls"
-            ),
             ObsoleteClassTraits => (
                 "class traits",
                 "implemented traits are specified on the impl, as in \
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 7fb3064c388f1..6382413b08169 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -72,7 +72,7 @@ use parse::lexer::TokenAndSpan;
 use parse::obsolete::{ObsoleteClassTraits, ObsoleteModeInFnType};
 use parse::obsolete::{ObsoleteLet, ObsoleteFieldTerminator};
 use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove};
-use parse::obsolete::{ObsoleteStructCtor, ObsoleteWith, ObsoleteClassMethod};
+use parse::obsolete::{ObsoleteStructCtor, ObsoleteWith};
 use parse::obsolete::{ObsoleteSyntax, ObsoleteLowerCaseKindBounds};
 use parse::obsolete::{ObsoleteUnsafeBlock};
 use parse::prec::{as_prec, token_to_binop};
@@ -3002,52 +3002,29 @@ pub impl Parser {
     }
 
     fn parse_single_class_item(vis: visibility) -> @struct_field {
-        let obsolete_let = self.eat_obsolete_ident("let");
-        if obsolete_let { self.obsolete(copy self.last_span, ObsoleteLet) }
-
-        let parse_obsolete_method =
-            !((obsolete_let || self.is_keyword(~"mut") ||
-               !self.is_any_keyword(copy self.token))
-              && !self.token_is_pound_or_doc_comment(copy self.token));
+        if self.eat_obsolete_ident("let") {
+            self.obsolete(copy self.last_span, ObsoleteLet);
+        }
 
-        if !parse_obsolete_method {
-            let a_var = self.parse_instance_var(vis);
-            match self.token {
-              token::SEMI => {
-                self.obsolete(copy self.span, ObsoleteFieldTerminator);
-                self.bump();
-              }
-              token::COMMA => {
-                self.bump();
-              }
-              token::RBRACE => {}
-              _ => {
-                self.span_fatal(copy self.span,
-                                fmt!("expected `;`, `,`, or '}' but \
-                                      found `%s`",
-                                     token_to_str(self.reader,
-                                                  self.token)));
-              }
-            }
-            a_var
-        } else {
-            self.obsolete(copy self.span, ObsoleteClassMethod);
-            self.parse_method();
-            // bogus value
-            @spanned(
-                self.span.lo,
-                self.span.hi,
-                ast::struct_field_ {
-                    kind: unnamed_field,
-                    id: self.get_id(),
-                    ty: @ast::Ty {
-                        id: self.get_id(),
-                        node: ty_nil,
-                        span: copy self.span,
-                    }
-                }
-            )
+        let a_var = self.parse_instance_var(vis);
+        match self.token {
+          token::SEMI => {
+            self.obsolete(copy self.span, ObsoleteFieldTerminator);
+            self.bump();
+          }
+          token::COMMA => {
+            self.bump();
+          }
+          token::RBRACE => {}
+          _ => {
+            self.span_fatal(copy self.span,
+                            fmt!("expected `;`, `,`, or '}' but \
+                                  found `%s`",
+                                 token_to_str(self.reader,
+                                              self.token)));
+          }
         }
+        a_var
     }
 
     fn parse_dtor(attrs: ~[attribute]) -> class_contents {
@@ -3062,6 +3039,8 @@ pub impl Parser {
             return members(~[]);
         }
 
+        let attrs = self.parse_outer_attributes();
+
         if self.eat_keyword(~"priv") {
             return members(~[self.parse_single_class_item(private)])
         }
@@ -3070,8 +3049,6 @@ pub impl Parser {
            return members(~[self.parse_single_class_item(public)]);
         }
 
-        let attrs = self.parse_outer_attributes();
-
         if self.try_parse_obsolete_struct_ctor() {
             return members(~[]);
         }
diff --git a/src/test/compile-fail/obsolete-syntax.rs b/src/test/compile-fail/obsolete-syntax.rs
index 9001ca99ef287..d92b545d1701f 100644
--- a/src/test/compile-fail/obsolete-syntax.rs
+++ b/src/test/compile-fail/obsolete-syntax.rs
@@ -29,14 +29,6 @@ struct s {
     //~^ ERROR obsolete syntax: struct constructor
 }
 
-struct ss {
-    fn foo() { }
-    //~^ ERROR obsolete syntax: class method
-    #[whatever]
-    fn foo() { }
-    //~^ ERROR obsolete syntax: class method
-}
-
 struct q : r {
     //~^ ERROR obsolete syntax: class traits
 }
diff --git a/src/test/run-pass/issue-4830.rs b/src/test/run-pass/issue-4830.rs
new file mode 100644
index 0000000000000..e8147a2ce8237
--- /dev/null
+++ b/src/test/run-pass/issue-4830.rs
@@ -0,0 +1,16 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct Scheduler {
+    /// The event loop used to drive the scheduler and perform I/O
+    priv event_loop: ~int
+}
+
+pub fn main() { }