about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLuqman Aden <laden@csclub.uwaterloo.ca>2013-10-20 01:55:23 -0400
committerLuqman Aden <laden@csclub.uwaterloo.ca>2013-10-22 21:21:21 -0400
commit5754848f8cd06bd3fc2bb084b5ca7bd41974e1b5 (patch)
tree05694bcbc6960d255e8fb022e8015e8d4f7f0417 /src
parent22a5ebdc6b13089d2322d9944bdec1507d21eec2 (diff)
libsyntax/librustc: Allow specifying mut on by-value self.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/metadata/decoder.rs2
-rw-r--r--src/librustc/metadata/encoder.rs3
-rw-r--r--src/librustc/middle/astencode.rs2
-rw-r--r--src/librustc/middle/liveness.rs2
-rw-r--r--src/librustc/middle/mem_categorization.rs4
-rw-r--r--src/librustc/middle/moves.rs2
-rw-r--r--src/librustc/middle/resolve.rs12
-rw-r--r--src/librustc/middle/trans/expr.rs2
-rw-r--r--src/librustc/middle/trans/inline.rs2
-rw-r--r--src/librustc/middle/trans/meth.rs2
-rw-r--r--src/librustc/middle/typeck/astconv.rs2
-rw-r--r--src/librustc/middle/typeck/check/method.rs8
-rw-r--r--src/librustc/middle/typeck/check/mod.rs2
-rw-r--r--src/librustc/middle/typeck/check/regionck.rs2
-rw-r--r--src/librustdoc/clean.rs4
-rw-r--r--src/libsyntax/ast.rs6
-rw-r--r--src/libsyntax/ast_util.rs2
-rw-r--r--src/libsyntax/ext/deriving/ty.rs2
-rw-r--r--src/libsyntax/parse/parser.rs30
-rw-r--r--src/libsyntax/print/pprust.rs5
20 files changed, 53 insertions, 43 deletions
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index aa1c4c1eb7e..ca1912c8347 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -975,7 +975,7 @@ fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ {
     let explicit_self_kind = string[0];
     match explicit_self_kind as char {
         's' => { return ast::sty_static; }
-        'v' => { return ast::sty_value; }
+        'v' => { return ast::sty_value(get_mutability(string[1])); }
         '@' => { return ast::sty_box(get_mutability(string[1])); }
         '~' => { return ast::sty_uniq; }
         '&' => {
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index 9f40593a93a..0f5ce06a7da 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -662,8 +662,9 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic
         sty_static => {
             ebml_w.writer.write(&[ 's' as u8 ]);
         }
-        sty_value => {
+        sty_value(m) => {
             ebml_w.writer.write(&[ 'v' as u8 ]);
+            encode_mutability(ebml_w, m);
         }
         sty_region(_, m) => {
             // FIXME(#4846) encode custom lifetime
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index 294bbcb46f7..3d7f28b8b30 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -410,7 +410,7 @@ impl tr for ast::Def {
             ast::DefMethod(did0.tr(xcx), did1.map(|did1| did1.tr(xcx)))
           }
           ast::DefSelfTy(nid) => { ast::DefSelfTy(xcx.tr_id(nid)) }
-          ast::DefSelf(nid) => { ast::DefSelf(xcx.tr_id(nid)) }
+          ast::DefSelf(nid, m) => { ast::DefSelf(xcx.tr_id(nid), m) }
           ast::DefMod(did) => { ast::DefMod(did.tr(xcx)) }
           ast::DefForeignMod(did) => { ast::DefForeignMod(did.tr(xcx)) }
           ast::DefStatic(did, m) => { ast::DefStatic(did.tr(xcx), m) }
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 6c53fc1602f..a235d7395a6 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -392,7 +392,7 @@ fn visit_fn(v: &mut LivenessVisitor,
     match *fk {
         visit::fk_method(_, _, method) => {
             match method.explicit_self.node {
-                sty_value | sty_region(*) | sty_box(_) | sty_uniq => {
+                sty_value(_) | sty_region(*) | sty_box(_) | sty_uniq => {
                     fn_maps.add_variable(Arg(method.self_id,
                                              special_idents::self_));
                 }
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 37e89e58fa5..eb03027ad71 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -488,12 +488,12 @@ impl mem_categorization_ctxt {
             }
           }
 
-          ast::DefSelf(self_id) => {
+          ast::DefSelf(self_id, mutbl) => {
             @cmt_ {
                 id:id,
                 span:span,
                 cat:cat_self(self_id),
-                mutbl: McImmutable,
+                mutbl: if mutbl { McDeclared } else { McImmutable },
                 ty:expr_ty
             }
           }
diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs
index 1ed517c9512..5001614647a 100644
--- a/src/librustc/middle/moves.rs
+++ b/src/librustc/middle/moves.rs
@@ -227,7 +227,7 @@ pub fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> {
       DefBinding(nid, _) |
       DefArg(nid, _) |
       DefLocal(nid, _) |
-      DefSelf(nid) => Some(nid),
+      DefSelf(nid, _) => Some(nid),
 
       _ => None
     }
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index b480aaac1ac..4c5d2f86a1b 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -150,7 +150,7 @@ enum Mutability {
 
 enum SelfBinding {
     NoSelfBinding,
-    HasSelfBinding(NodeId)
+    HasSelfBinding(NodeId, explicit_self)
 }
 
 impl Visitor<()> for Resolver {
@@ -3799,8 +3799,12 @@ impl Resolver {
                 NoSelfBinding => {
                     // Nothing to do.
                 }
-                HasSelfBinding(self_node_id) => {
-                    let def_like = DlDef(DefSelf(self_node_id));
+                HasSelfBinding(self_node_id, explicit_self) => {
+                    let mutable = match explicit_self.node {
+                        sty_value(m) if m == MutMutable => true,
+                        _ => false
+                    };
+                    let def_like = DlDef(DefSelf(self_node_id, mutable));
                     *function_value_rib.self_binding = Some(def_like);
                 }
             }
@@ -3937,7 +3941,7 @@ impl Resolver {
         // we only have self ty if it is a non static method
         let self_binding = match method.explicit_self.node {
           sty_static => { NoSelfBinding }
-          _ => { HasSelfBinding(method.self_id) }
+          _ => { HasSelfBinding(method.self_id, method.explicit_self) }
         };
 
         self.resolve_function(rib_kind,
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 238b15fe597..56f1e047841 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -1099,7 +1099,7 @@ pub fn trans_local_var(bcx: @mut Block, def: ast::Def) -> Datum {
         ast::DefLocal(nid, _) | ast::DefBinding(nid, _) => {
             take_local(bcx, bcx.fcx.lllocals, nid)
         }
-        ast::DefSelf(nid) => {
+        ast::DefSelf(nid, _) => {
             let self_info: ValSelfData = match bcx.fcx.llself {
                 Some(ref self_info) => *self_info,
                 None => {
diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs
index a5be9a3ca5e..d9f7cdeeb2e 100644
--- a/src/librustc/middle/trans/inline.rs
+++ b/src/librustc/middle/trans/inline.rs
@@ -144,7 +144,7 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::DefId)
                       debug!("calling inline trans_fn with self_ty {}",
                              ty_to_str(ccx.tcx, self_ty));
                       match mth.explicit_self.node {
-                          ast::sty_value => impl_self(self_ty, ty::ByRef),
+                          ast::sty_value(_) => impl_self(self_ty, ty::ByRef),
                           _ => impl_self(self_ty, ty::ByCopy),
                       }
                   }
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index a8c18c72167..61384c72efa 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -120,7 +120,7 @@ pub fn trans_method(ccx: @mut CrateContext,
         debug!("calling trans_fn with self_ty {}",
                self_ty.repr(ccx.tcx));
         match method.explicit_self.node {
-          ast::sty_value => impl_self(self_ty, ty::ByRef),
+          ast::sty_value(_) => impl_self(self_ty, ty::ByRef),
           _ => impl_self(self_ty, ty::ByCopy),
         }
       }
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index ccda6bbaf9d..e703f6da416 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -672,7 +672,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:RegionScope + Clone + 'static>(
     {
         match self_info.explicit_self.node {
             ast::sty_static => None,
-            ast::sty_value => {
+            ast::sty_value(_) => {
                 Some(self_info.untransformed_self_ty)
             }
             ast::sty_region(ref lifetime, mutability) => {
diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs
index f6efd3aa5ad..b48e1f7fcf1 100644
--- a/src/librustc/middle/typeck/check/method.rs
+++ b/src/librustc/middle/typeck/check/method.rs
@@ -1082,7 +1082,7 @@ impl<'self> LookupContext<'self> {
             ast::sty_static => {
                 self.bug(~"static method for object type receiver");
             }
-            ast::sty_value => {
+            ast::sty_value(_) => {
                 ty::mk_err() // error reported in `enforce_object_limitations()`
             }
             ast::sty_region(*) | ast::sty_box(*) | ast::sty_uniq(*) => {
@@ -1141,7 +1141,7 @@ impl<'self> LookupContext<'self> {
                      through an object");
             }
 
-            ast::sty_value => { // reason (a) above
+            ast::sty_value(_) => { // reason (a) above
                 self.tcx().sess.span_err(
                     self.expr.span,
                     "cannot call a method with a by-value receiver \
@@ -1198,7 +1198,7 @@ impl<'self> LookupContext<'self> {
                 false
             }
 
-            sty_value => {
+            sty_value(_) => {
                 rcvr_matches_ty(self.fcx, rcvr_ty, candidate)
             }
 
@@ -1369,7 +1369,7 @@ impl<'self> LookupContext<'self> {
 
 pub fn get_mode_from_explicit_self(explicit_self: ast::explicit_self_) -> SelfMode {
     match explicit_self {
-        sty_value => ty::ByRef,
+        sty_value(_) => ty::ByRef,
         _ => ty::ByCopy,
     }
 }
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index eddf8aa5185..4514564ff1f 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -3254,7 +3254,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt,
                                       defn: ast::Def)
                                    -> ty_param_bounds_and_ty {
     match defn {
-      ast::DefArg(nid, _) | ast::DefLocal(nid, _) | ast::DefSelf(nid) |
+      ast::DefArg(nid, _) | ast::DefLocal(nid, _) | ast::DefSelf(nid, _) |
       ast::DefBinding(nid, _) => {
           let typ = fcx.local_ty(sp, nid);
           return no_params(typ);
diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs
index 06a13059462..09fc7b5c15c 100644
--- a/src/librustc/middle/typeck/check/regionck.rs
+++ b/src/librustc/middle/typeck/check/regionck.rs
@@ -58,7 +58,7 @@ fn encl_region_of_def(fcx: @mut FnCtxt, def: ast::Def) -> ty::Region {
     let tcx = fcx.tcx();
     match def {
         DefLocal(node_id, _) | DefArg(node_id, _) |
-        DefSelf(node_id) | DefBinding(node_id, _) => {
+        DefSelf(node_id, _) | DefBinding(node_id, _) => {
             tcx.region_maps.encl_region(node_id)
         }
         DefUpvar(_, subdef, closure_id, body_id) => {
diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs
index 6ee7f8c1727..90fc71aa863 100644
--- a/src/librustdoc/clean.rs
+++ b/src/librustdoc/clean.rs
@@ -388,7 +388,7 @@ impl Clean<SelfTy> for ast::explicit_self {
     fn clean(&self) -> SelfTy {
         match self.node {
             ast::sty_static => SelfStatic,
-            ast::sty_value => SelfValue,
+            ast::sty_value(_) => SelfValue,
             ast::sty_uniq => SelfOwned,
             ast::sty_region(lt, mt) => SelfBorrowed(lt.clean(), mt.clean()),
             ast::sty_box(mt) => SelfManaged(mt.clean()),
@@ -1171,7 +1171,7 @@ fn resolve_type(path: Path, tpbs: Option<~[TyParamBound]>,
 
     let (def_id, kind) = match *d {
         ast::DefFn(i, _) => (i, TypeFunction),
-        ast::DefSelf(i) | ast::DefSelfTy(i) => return Self(i),
+        ast::DefSelf(i, _) | ast::DefSelfTy(i) => return Self(i),
         ast::DefTy(i) => (i, TypeEnum),
         ast::DefTrait(i) => {
             debug!("saw DefTrait in def_to_id");
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 01033e829f6..6631924239d 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -227,7 +227,7 @@ pub enum MethodProvenance {
 pub enum Def {
     DefFn(DefId, purity),
     DefStaticMethod(/* method */ DefId, MethodProvenance, purity),
-    DefSelf(NodeId),
+    DefSelf(NodeId, bool /* is_mutbl */),
     DefSelfTy(/* trait id */ NodeId),
     DefMod(DefId),
     DefForeignMod(DefId),
@@ -921,8 +921,8 @@ pub enum ret_style {
 #[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
 pub enum explicit_self_ {
     sty_static,                                // no self
-    sty_value,                                 // `self`
-    sty_region(Option<Lifetime>, Mutability), // `&'lt self`
+    sty_value(Mutability),                     // `self`
+    sty_region(Option<Lifetime>, Mutability),  // `&'lt self`
     sty_box(Mutability),                       // `@self`
     sty_uniq                                   // `~self`
 }
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index bdebc9872e6..1d9d5512ff4 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -66,7 +66,7 @@ pub fn def_id_of_def(d: Def) -> DefId {
       DefUse(id) | DefStruct(id) | DefTrait(id) | DefMethod(id, _) => {
         id
       }
-      DefArg(id, _) | DefLocal(id, _) | DefSelf(id) | DefSelfTy(id)
+      DefArg(id, _) | DefLocal(id, _) | DefSelf(id, _) | DefSelfTy(id)
       | DefUpvar(id, _, _, _) | DefBinding(id, _) | DefRegion(id)
       | DefTyParamBinder(id) | DefLabel(id) => {
         local_def(id)
diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs
index 83c73e3d85f..a9fdafc8014 100644
--- a/src/libsyntax/ext/deriving/ty.rs
+++ b/src/libsyntax/ext/deriving/ty.rs
@@ -240,7 +240,7 @@ pub fn get_explicit_self(cx: @ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
     let self_path = cx.expr_self(span);
     match *self_ptr {
         None => {
-            (self_path, respan(span, ast::sty_value))
+            (self_path, respan(span, ast::sty_value(ast::MutImmutable)))
         }
         Some(ref ptr) => {
             let self_ty = respan(
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index ed6019e1a55..133934a746a 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3438,15 +3438,11 @@ impl Parser {
 
     // parse the argument list and result type of a function
     // that may have a self type.
-    fn parse_fn_decl_with_self(
-        &self,
-        parse_arg_fn:
-        &fn(&Parser) -> arg
-    ) -> (explicit_self, fn_decl) {
-        fn maybe_parse_explicit_self(
-            cnstr: &fn(v: Mutability) -> ast::explicit_self_,
-            p: &Parser
-        ) -> ast::explicit_self_ {
+    fn parse_fn_decl_with_self(&self, parse_arg_fn: &fn(&Parser) -> arg)
+        -> (explicit_self, fn_decl) {
+
+        fn maybe_parse_explicit_self(cnstr: &fn(v: Mutability) -> ast::explicit_self_,
+                                     p: &Parser) -> ast::explicit_self_ {
             // We need to make sure it isn't a type
             if p.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) ||
                 ((p.look_ahead(1, |t| token::is_keyword(keywords::Const, t)) ||
@@ -3529,20 +3525,26 @@ impl Parser {
           }
           token::IDENT(*) if self.is_self_ident() => {
             self.bump();
-            sty_value
+            sty_value(MutImmutable)
           }
           token::BINOP(token::STAR) => {
             // Possibly "*self" or "*mut self" -- not supported. Try to avoid
             // emitting cryptic "unexpected token" errors.
             self.bump();
-            if self.token_is_mutability(self.token) {
-                self.bump();
-            }
+            let mutability = if self.token_is_mutability(self.token) {
+                self.parse_mutability()
+            } else { MutImmutable };
             if self.is_self_ident() {
                 self.span_err(*self.span, "cannot pass self by unsafe pointer");
                 self.bump();
             }
-            sty_value
+            sty_value(mutability)
+          }
+          _ if self.token_is_mutability(self.token) &&
+               self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
+            let mutability = self.parse_mutability();
+            self.expect_self_ident();
+            sty_value(mutability)
           }
           _ => {
             sty_static
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index b245bd75ace..9ce28e4d55a 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1686,7 +1686,10 @@ pub fn explicit_self_to_str(explicit_self: &ast::explicit_self_, intr: @ident_in
 pub fn print_explicit_self(s: @ps, explicit_self: ast::explicit_self_) -> bool {
     match explicit_self {
         ast::sty_static => { return false; }
-        ast::sty_value => { word(s.s, "self"); }
+        ast::sty_value(m) => {
+            print_mutability(s, m);
+            word(s.s, "self");
+        }
         ast::sty_uniq => { word(s.s, "~self"); }
         ast::sty_region(ref lt, m) => {
             word(s.s, "&");