Skip to content
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

Allow mut on self/~self like other args. #9989

Merged
merged 4 commits into from
Oct 23, 2013
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
libsyntax/librustc: Allow specifying mut on by-value self.
  • Loading branch information
luqmana committed Oct 23, 2013
commit 5754848f8cd06bd3fc2bb084b5ca7bd41974e1b5
2 changes: 1 addition & 1 deletion src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
'&' => {
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_));
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/mem_categorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/moves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
12 changes: 8 additions & 4 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ enum Mutability {

enum SelfBinding {
NoSelfBinding,
HasSelfBinding(NodeId)
HasSelfBinding(NodeId, explicit_self)
}

impl Visitor<()> for Resolver {
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/typeck/check/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(*) => {
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -1198,7 +1198,7 @@ impl<'self> LookupContext<'self> {
false
}

sty_value => {
sty_value(_) => {
rcvr_matches_ty(self.fcx, rcvr_ty, candidate)
}

Expand Down Expand Up @@ -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,
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/check/regionck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/clean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()),
Expand Down Expand Up @@ -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");
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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`
}
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ast_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/deriving/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
30 changes: 16 additions & 14 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)) ||
Expand Down Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion src/libsyntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, "&");
Expand Down