Skip to content

Commit 7857314

Browse files
committed
auto merge of rust-lang#9989 : luqmana/rust/mut-everywhere, r=alexcrichton
2 parents 22a5ebd + b2b2095 commit 7857314

24 files changed

+188
-56
lines changed

doc/rust.md

+11-4
Original file line numberDiff line numberDiff line change
@@ -3395,16 +3395,23 @@ a [temporary](#lvalues-rvalues-and-temporaries), or a local variable.
33953395
A _local variable_ (or *stack-local* allocation) holds a value directly,
33963396
allocated within the stack's memory. The value is a part of the stack frame.
33973397

3398-
Local variables are immutable unless declared with `let mut`. The
3399-
`mut` keyword applies to all local variables declared within that
3400-
declaration (so `let mut (x, y) = ...` declares two mutable variables, `x` and
3401-
`y`).
3398+
Local variables are immutable unless declared otherwise like: `let mut x = ...`.
34023399

34033400
Function parameters are immutable unless declared with `mut`. The
34043401
`mut` keyword applies only to the following parameter (so `|mut x, y|`
34053402
and `fn f(mut x: ~int, y: ~int)` declare one mutable variable `x` and
34063403
one immutable variable `y`).
34073404

3405+
Methods that take either `self` or `~self` can optionally place them in a
3406+
mutable slot by prefixing them with `mut` (similar to regular arguments):
3407+
3408+
~~~
3409+
trait Changer {
3410+
fn change(mut self) -> Self;
3411+
fn modify(mut ~self) -> ~Self;
3412+
}
3413+
~~~
3414+
34083415
Local variables are not initialized when allocated; the entire frame worth of
34093416
local variables are allocated at once, on frame-entry, in an uninitialized
34103417
state. Subsequent statements within a function may or may not initialize the

src/librustc/metadata/decoder.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -975,9 +975,9 @@ fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ {
975975
let explicit_self_kind = string[0];
976976
match explicit_self_kind as char {
977977
's' => { return ast::sty_static; }
978-
'v' => { return ast::sty_value; }
978+
'v' => { return ast::sty_value(get_mutability(string[1])); }
979979
'@' => { return ast::sty_box(get_mutability(string[1])); }
980-
'~' => { return ast::sty_uniq; }
980+
'~' => { return ast::sty_uniq(get_mutability(string[1])); }
981981
'&' => {
982982
// FIXME(#4846) expl. region
983983
return ast::sty_region(None, get_mutability(string[1]));

src/librustc/metadata/encoder.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,9 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic
662662
sty_static => {
663663
ebml_w.writer.write(&[ 's' as u8 ]);
664664
}
665-
sty_value => {
665+
sty_value(m) => {
666666
ebml_w.writer.write(&[ 'v' as u8 ]);
667+
encode_mutability(ebml_w, m);
667668
}
668669
sty_region(_, m) => {
669670
// FIXME(#4846) encode custom lifetime
@@ -674,8 +675,9 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic
674675
ebml_w.writer.write(&[ '@' as u8 ]);
675676
encode_mutability(ebml_w, m);
676677
}
677-
sty_uniq => {
678+
sty_uniq(m) => {
678679
ebml_w.writer.write(&[ '~' as u8 ]);
680+
encode_mutability(ebml_w, m);
679681
}
680682
}
681683

src/librustc/middle/astencode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ impl tr for ast::Def {
410410
ast::DefMethod(did0.tr(xcx), did1.map(|did1| did1.tr(xcx)))
411411
}
412412
ast::DefSelfTy(nid) => { ast::DefSelfTy(xcx.tr_id(nid)) }
413-
ast::DefSelf(nid) => { ast::DefSelf(xcx.tr_id(nid)) }
413+
ast::DefSelf(nid, m) => { ast::DefSelf(xcx.tr_id(nid), m) }
414414
ast::DefMod(did) => { ast::DefMod(did.tr(xcx)) }
415415
ast::DefForeignMod(did) => { ast::DefForeignMod(did.tr(xcx)) }
416416
ast::DefStatic(did, m) => { ast::DefStatic(did.tr(xcx), m) }

src/librustc/middle/liveness.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ fn visit_fn(v: &mut LivenessVisitor,
392392
match *fk {
393393
visit::fk_method(_, _, method) => {
394394
match method.explicit_self.node {
395-
sty_value | sty_region(*) | sty_box(_) | sty_uniq => {
395+
sty_value(_) | sty_region(*) | sty_box(_) | sty_uniq(_) => {
396396
fn_maps.add_variable(Arg(method.self_id,
397397
special_idents::self_));
398398
}

src/librustc/middle/mem_categorization.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -488,12 +488,12 @@ impl mem_categorization_ctxt {
488488
}
489489
}
490490

491-
ast::DefSelf(self_id) => {
491+
ast::DefSelf(self_id, mutbl) => {
492492
@cmt_ {
493493
id:id,
494494
span:span,
495495
cat:cat_self(self_id),
496-
mutbl: McImmutable,
496+
mutbl: if mutbl { McDeclared } else { McImmutable },
497497
ty:expr_ty
498498
}
499499
}

src/librustc/middle/moves.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ pub fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> {
227227
DefBinding(nid, _) |
228228
DefArg(nid, _) |
229229
DefLocal(nid, _) |
230-
DefSelf(nid) => Some(nid),
230+
DefSelf(nid, _) => Some(nid),
231231

232232
_ => None
233233
}

src/librustc/middle/resolve.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ enum Mutability {
150150

151151
enum SelfBinding {
152152
NoSelfBinding,
153-
HasSelfBinding(NodeId)
153+
HasSelfBinding(NodeId, explicit_self)
154154
}
155155

156156
impl Visitor<()> for Resolver {
@@ -3799,8 +3799,12 @@ impl Resolver {
37993799
NoSelfBinding => {
38003800
// Nothing to do.
38013801
}
3802-
HasSelfBinding(self_node_id) => {
3803-
let def_like = DlDef(DefSelf(self_node_id));
3802+
HasSelfBinding(self_node_id, explicit_self) => {
3803+
let mutable = match explicit_self.node {
3804+
sty_uniq(m) | sty_value(m) if m == MutMutable => true,
3805+
_ => false
3806+
};
3807+
let def_like = DlDef(DefSelf(self_node_id, mutable));
38043808
*function_value_rib.self_binding = Some(def_like);
38053809
}
38063810
}
@@ -3937,7 +3941,7 @@ impl Resolver {
39373941
// we only have self ty if it is a non static method
39383942
let self_binding = match method.explicit_self.node {
39393943
sty_static => { NoSelfBinding }
3940-
_ => { HasSelfBinding(method.self_id) }
3944+
_ => { HasSelfBinding(method.self_id, method.explicit_self) }
39413945
};
39423946

39433947
self.resolve_function(rib_kind,

src/librustc/middle/trans/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1099,7 +1099,7 @@ pub fn trans_local_var(bcx: @mut Block, def: ast::Def) -> Datum {
10991099
ast::DefLocal(nid, _) | ast::DefBinding(nid, _) => {
11001100
take_local(bcx, bcx.fcx.lllocals, nid)
11011101
}
1102-
ast::DefSelf(nid) => {
1102+
ast::DefSelf(nid, _) => {
11031103
let self_info: ValSelfData = match bcx.fcx.llself {
11041104
Some(ref self_info) => *self_info,
11051105
None => {

src/librustc/middle/trans/inline.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::DefId)
144144
debug!("calling inline trans_fn with self_ty {}",
145145
ty_to_str(ccx.tcx, self_ty));
146146
match mth.explicit_self.node {
147-
ast::sty_value => impl_self(self_ty, ty::ByRef),
147+
ast::sty_value(_) => impl_self(self_ty, ty::ByRef),
148148
_ => impl_self(self_ty, ty::ByCopy),
149149
}
150150
}

src/librustc/middle/trans/meth.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ pub fn trans_method(ccx: @mut CrateContext,
120120
debug!("calling trans_fn with self_ty {}",
121121
self_ty.repr(ccx.tcx));
122122
match method.explicit_self.node {
123-
ast::sty_value => impl_self(self_ty, ty::ByRef),
123+
ast::sty_value(_) => impl_self(self_ty, ty::ByRef),
124124
_ => impl_self(self_ty, ty::ByCopy),
125125
}
126126
}

src/librustc/middle/typeck/astconv.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:RegionScope + Clone + 'static>(
672672
{
673673
match self_info.explicit_self.node {
674674
ast::sty_static => None,
675-
ast::sty_value => {
675+
ast::sty_value(_) => {
676676
Some(self_info.untransformed_self_ty)
677677
}
678678
ast::sty_region(ref lifetime, mutability) => {
@@ -689,7 +689,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:RegionScope + Clone + 'static>(
689689
ty::mt {ty: self_info.untransformed_self_ty,
690690
mutbl: mutability}))
691691
}
692-
ast::sty_uniq => {
692+
ast::sty_uniq(_) => {
693693
Some(ty::mk_uniq(this.tcx(),
694694
ty::mt {ty: self_info.untransformed_self_ty,
695695
mutbl: ast::MutImmutable}))

src/librustc/middle/typeck/check/method.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ impl<'self> LookupContext<'self> {
10821082
ast::sty_static => {
10831083
self.bug(~"static method for object type receiver");
10841084
}
1085-
ast::sty_value => {
1085+
ast::sty_value(_) => {
10861086
ty::mk_err() // error reported in `enforce_object_limitations()`
10871087
}
10881088
ast::sty_region(*) | ast::sty_box(*) | ast::sty_uniq(*) => {
@@ -1141,7 +1141,7 @@ impl<'self> LookupContext<'self> {
11411141
through an object");
11421142
}
11431143

1144-
ast::sty_value => { // reason (a) above
1144+
ast::sty_value(_) => { // reason (a) above
11451145
self.tcx().sess.span_err(
11461146
self.expr.span,
11471147
"cannot call a method with a by-value receiver \
@@ -1198,7 +1198,7 @@ impl<'self> LookupContext<'self> {
11981198
false
11991199
}
12001200

1201-
sty_value => {
1201+
sty_value(_) => {
12021202
rcvr_matches_ty(self.fcx, rcvr_ty, candidate)
12031203
}
12041204

@@ -1236,7 +1236,7 @@ impl<'self> LookupContext<'self> {
12361236
}
12371237
}
12381238

1239-
sty_uniq => {
1239+
sty_uniq(_) => {
12401240
debug!("(is relevant?) explicit self is a unique pointer");
12411241
match ty::get(rcvr_ty).sty {
12421242
ty::ty_uniq(mt) => {
@@ -1369,7 +1369,7 @@ impl<'self> LookupContext<'self> {
13691369

13701370
pub fn get_mode_from_explicit_self(explicit_self: ast::explicit_self_) -> SelfMode {
13711371
match explicit_self {
1372-
sty_value => ty::ByRef,
1372+
sty_value(_) => ty::ByRef,
13731373
_ => ty::ByCopy,
13741374
}
13751375
}

src/librustc/middle/typeck/check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3254,7 +3254,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt,
32543254
defn: ast::Def)
32553255
-> ty_param_bounds_and_ty {
32563256
match defn {
3257-
ast::DefArg(nid, _) | ast::DefLocal(nid, _) | ast::DefSelf(nid) |
3257+
ast::DefArg(nid, _) | ast::DefLocal(nid, _) | ast::DefSelf(nid, _) |
32583258
ast::DefBinding(nid, _) => {
32593259
let typ = fcx.local_ty(sp, nid);
32603260
return no_params(typ);

src/librustc/middle/typeck/check/regionck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ fn encl_region_of_def(fcx: @mut FnCtxt, def: ast::Def) -> ty::Region {
5858
let tcx = fcx.tcx();
5959
match def {
6060
DefLocal(node_id, _) | DefArg(node_id, _) |
61-
DefSelf(node_id) | DefBinding(node_id, _) => {
61+
DefSelf(node_id, _) | DefBinding(node_id, _) => {
6262
tcx.region_maps.encl_region(node_id)
6363
}
6464
DefUpvar(_, subdef, closure_id, body_id) => {

src/librustdoc/clean.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,8 @@ impl Clean<SelfTy> for ast::explicit_self {
388388
fn clean(&self) -> SelfTy {
389389
match self.node {
390390
ast::sty_static => SelfStatic,
391-
ast::sty_value => SelfValue,
392-
ast::sty_uniq => SelfOwned,
391+
ast::sty_value(_) => SelfValue,
392+
ast::sty_uniq(_) => SelfOwned,
393393
ast::sty_region(lt, mt) => SelfBorrowed(lt.clean(), mt.clean()),
394394
ast::sty_box(mt) => SelfManaged(mt.clean()),
395395
}
@@ -1171,7 +1171,7 @@ fn resolve_type(path: Path, tpbs: Option<~[TyParamBound]>,
11711171

11721172
let (def_id, kind) = match *d {
11731173
ast::DefFn(i, _) => (i, TypeFunction),
1174-
ast::DefSelf(i) | ast::DefSelfTy(i) => return Self(i),
1174+
ast::DefSelf(i, _) | ast::DefSelfTy(i) => return Self(i),
11751175
ast::DefTy(i) => (i, TypeEnum),
11761176
ast::DefTrait(i) => {
11771177
debug!("saw DefTrait in def_to_id");

src/libsyntax/ast.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ pub enum MethodProvenance {
227227
pub enum Def {
228228
DefFn(DefId, purity),
229229
DefStaticMethod(/* method */ DefId, MethodProvenance, purity),
230-
DefSelf(NodeId),
230+
DefSelf(NodeId, bool /* is_mutbl */),
231231
DefSelfTy(/* trait id */ NodeId),
232232
DefMod(DefId),
233233
DefForeignMod(DefId),
@@ -921,10 +921,10 @@ pub enum ret_style {
921921
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
922922
pub enum explicit_self_ {
923923
sty_static, // no self
924-
sty_value, // `self`
925-
sty_region(Option<Lifetime>, Mutability), // `&'lt self`
924+
sty_value(Mutability), // `self`
925+
sty_region(Option<Lifetime>, Mutability), // `&'lt self`
926926
sty_box(Mutability), // `@self`
927-
sty_uniq // `~self`
927+
sty_uniq(Mutability) // `~self`
928928
}
929929
930930
pub type explicit_self = Spanned<explicit_self_>;

src/libsyntax/ast_util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub fn def_id_of_def(d: Def) -> DefId {
6666
DefUse(id) | DefStruct(id) | DefTrait(id) | DefMethod(id, _) => {
6767
id
6868
}
69-
DefArg(id, _) | DefLocal(id, _) | DefSelf(id) | DefSelfTy(id)
69+
DefArg(id, _) | DefLocal(id, _) | DefSelf(id, _) | DefSelfTy(id)
7070
| DefUpvar(id, _, _, _) | DefBinding(id, _) | DefRegion(id)
7171
| DefTyParamBinder(id) | DefLabel(id) => {
7272
local_def(id)

src/libsyntax/ext/deriving/ty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,13 @@ pub fn get_explicit_self(cx: @ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
240240
let self_path = cx.expr_self(span);
241241
match *self_ptr {
242242
None => {
243-
(self_path, respan(span, ast::sty_value))
243+
(self_path, respan(span, ast::sty_value(ast::MutImmutable)))
244244
}
245245
Some(ref ptr) => {
246246
let self_ty = respan(
247247
span,
248248
match *ptr {
249-
Send => ast::sty_uniq,
249+
Send => ast::sty_uniq(ast::MutImmutable),
250250
Managed(mutbl) => ast::sty_box(mutbl),
251251
Borrowed(ref lt, mutbl) => {
252252
let lt = lt.map(|s| cx.lifetime(span, cx.ident_of(s)));

src/libsyntax/parse/parser.rs

+25-15
Original file line numberDiff line numberDiff line change
@@ -3438,15 +3438,11 @@ impl Parser {
34383438

34393439
// parse the argument list and result type of a function
34403440
// that may have a self type.
3441-
fn parse_fn_decl_with_self(
3442-
&self,
3443-
parse_arg_fn:
3444-
&fn(&Parser) -> arg
3445-
) -> (explicit_self, fn_decl) {
3446-
fn maybe_parse_explicit_self(
3447-
cnstr: &fn(v: Mutability) -> ast::explicit_self_,
3448-
p: &Parser
3449-
) -> ast::explicit_self_ {
3441+
fn parse_fn_decl_with_self(&self, parse_arg_fn: &fn(&Parser) -> arg)
3442+
-> (explicit_self, fn_decl) {
3443+
3444+
fn maybe_parse_explicit_self(cnstr: &fn(v: Mutability) -> ast::explicit_self_,
3445+
p: &Parser) -> ast::explicit_self_ {
34503446
// We need to make sure it isn't a type
34513447
if p.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) ||
34523448
((p.look_ahead(1, |t| token::is_keyword(keywords::Const, t)) ||
@@ -3524,25 +3520,39 @@ impl Parser {
35243520
self.span_err(*self.last_span,
35253521
"mutability declaration not allowed here");
35263522
}
3527-
sty_uniq
3523+
sty_uniq(MutImmutable)
35283524
}, self)
35293525
}
35303526
token::IDENT(*) if self.is_self_ident() => {
35313527
self.bump();
3532-
sty_value
3528+
sty_value(MutImmutable)
35333529
}
35343530
token::BINOP(token::STAR) => {
35353531
// Possibly "*self" or "*mut self" -- not supported. Try to avoid
35363532
// emitting cryptic "unexpected token" errors.
35373533
self.bump();
3538-
if self.token_is_mutability(self.token) {
3539-
self.bump();
3540-
}
3534+
let mutability = if self.token_is_mutability(self.token) {
3535+
self.parse_mutability()
3536+
} else { MutImmutable };
35413537
if self.is_self_ident() {
35423538
self.span_err(*self.span, "cannot pass self by unsafe pointer");
35433539
self.bump();
35443540
}
3545-
sty_value
3541+
sty_value(mutability)
3542+
}
3543+
_ if self.token_is_mutability(self.token) &&
3544+
self.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) => {
3545+
let mutability = self.parse_mutability();
3546+
self.expect_self_ident();
3547+
sty_value(mutability)
3548+
}
3549+
_ if self.token_is_mutability(self.token) &&
3550+
self.look_ahead(1, |t| *t == token::TILDE) &&
3551+
self.look_ahead(2, |t| token::is_keyword(keywords::Self, t)) => {
3552+
let mutability = self.parse_mutability();
3553+
self.bump();
3554+
self.expect_self_ident();
3555+
sty_uniq(mutability)
35463556
}
35473557
_ => {
35483558
sty_static

src/libsyntax/print/pprust.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1686,8 +1686,14 @@ pub fn explicit_self_to_str(explicit_self: &ast::explicit_self_, intr: @ident_in
16861686
pub fn print_explicit_self(s: @ps, explicit_self: ast::explicit_self_) -> bool {
16871687
match explicit_self {
16881688
ast::sty_static => { return false; }
1689-
ast::sty_value => { word(s.s, "self"); }
1690-
ast::sty_uniq => { word(s.s, "~self"); }
1689+
ast::sty_value(m) => {
1690+
print_mutability(s, m);
1691+
word(s.s, "self");
1692+
}
1693+
ast::sty_uniq(m) => {
1694+
print_mutability(s, m);
1695+
word(s.s, "~self");
1696+
}
16911697
ast::sty_region(ref lt, m) => {
16921698
word(s.s, "&");
16931699
print_opt_lifetime(s, lt);

0 commit comments

Comments
 (0)