libsyntax/librustc: Allow specifying mut on by-value self.
This commit is contained in:
parent
22a5ebdc6b
commit
5754848f8c
20 changed files with 53 additions and 43 deletions
|
@ -975,7 +975,7 @@ fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ {
|
||||||
let explicit_self_kind = string[0];
|
let explicit_self_kind = string[0];
|
||||||
match explicit_self_kind as char {
|
match explicit_self_kind as char {
|
||||||
's' => { return ast::sty_static; }
|
'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_box(get_mutability(string[1])); }
|
||||||
'~' => { return ast::sty_uniq; }
|
'~' => { return ast::sty_uniq; }
|
||||||
'&' => {
|
'&' => {
|
||||||
|
|
|
@ -662,8 +662,9 @@ fn encode_explicit_self(ebml_w: &mut writer::Encoder, explicit_self: ast::explic
|
||||||
sty_static => {
|
sty_static => {
|
||||||
ebml_w.writer.write(&[ 's' as u8 ]);
|
ebml_w.writer.write(&[ 's' as u8 ]);
|
||||||
}
|
}
|
||||||
sty_value => {
|
sty_value(m) => {
|
||||||
ebml_w.writer.write(&[ 'v' as u8 ]);
|
ebml_w.writer.write(&[ 'v' as u8 ]);
|
||||||
|
encode_mutability(ebml_w, m);
|
||||||
}
|
}
|
||||||
sty_region(_, m) => {
|
sty_region(_, m) => {
|
||||||
// FIXME(#4846) encode custom lifetime
|
// FIXME(#4846) encode custom lifetime
|
||||||
|
|
|
@ -410,7 +410,7 @@ impl tr for ast::Def {
|
||||||
ast::DefMethod(did0.tr(xcx), did1.map(|did1| did1.tr(xcx)))
|
ast::DefMethod(did0.tr(xcx), did1.map(|did1| did1.tr(xcx)))
|
||||||
}
|
}
|
||||||
ast::DefSelfTy(nid) => { ast::DefSelfTy(xcx.tr_id(nid)) }
|
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::DefMod(did) => { ast::DefMod(did.tr(xcx)) }
|
||||||
ast::DefForeignMod(did) => { ast::DefForeignMod(did.tr(xcx)) }
|
ast::DefForeignMod(did) => { ast::DefForeignMod(did.tr(xcx)) }
|
||||||
ast::DefStatic(did, m) => { ast::DefStatic(did.tr(xcx), m) }
|
ast::DefStatic(did, m) => { ast::DefStatic(did.tr(xcx), m) }
|
||||||
|
|
|
@ -392,7 +392,7 @@ fn visit_fn(v: &mut LivenessVisitor,
|
||||||
match *fk {
|
match *fk {
|
||||||
visit::fk_method(_, _, method) => {
|
visit::fk_method(_, _, method) => {
|
||||||
match method.explicit_self.node {
|
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,
|
fn_maps.add_variable(Arg(method.self_id,
|
||||||
special_idents::self_));
|
special_idents::self_));
|
||||||
}
|
}
|
||||||
|
|
|
@ -488,12 +488,12 @@ impl mem_categorization_ctxt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::DefSelf(self_id) => {
|
ast::DefSelf(self_id, mutbl) => {
|
||||||
@cmt_ {
|
@cmt_ {
|
||||||
id:id,
|
id:id,
|
||||||
span:span,
|
span:span,
|
||||||
cat:cat_self(self_id),
|
cat:cat_self(self_id),
|
||||||
mutbl: McImmutable,
|
mutbl: if mutbl { McDeclared } else { McImmutable },
|
||||||
ty:expr_ty
|
ty:expr_ty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,7 +227,7 @@ pub fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> {
|
||||||
DefBinding(nid, _) |
|
DefBinding(nid, _) |
|
||||||
DefArg(nid, _) |
|
DefArg(nid, _) |
|
||||||
DefLocal(nid, _) |
|
DefLocal(nid, _) |
|
||||||
DefSelf(nid) => Some(nid),
|
DefSelf(nid, _) => Some(nid),
|
||||||
|
|
||||||
_ => None
|
_ => None
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,7 +150,7 @@ enum Mutability {
|
||||||
|
|
||||||
enum SelfBinding {
|
enum SelfBinding {
|
||||||
NoSelfBinding,
|
NoSelfBinding,
|
||||||
HasSelfBinding(NodeId)
|
HasSelfBinding(NodeId, explicit_self)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Visitor<()> for Resolver {
|
impl Visitor<()> for Resolver {
|
||||||
|
@ -3799,8 +3799,12 @@ impl Resolver {
|
||||||
NoSelfBinding => {
|
NoSelfBinding => {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
HasSelfBinding(self_node_id) => {
|
HasSelfBinding(self_node_id, explicit_self) => {
|
||||||
let def_like = DlDef(DefSelf(self_node_id));
|
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);
|
*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
|
// we only have self ty if it is a non static method
|
||||||
let self_binding = match method.explicit_self.node {
|
let self_binding = match method.explicit_self.node {
|
||||||
sty_static => { NoSelfBinding }
|
sty_static => { NoSelfBinding }
|
||||||
_ => { HasSelfBinding(method.self_id) }
|
_ => { HasSelfBinding(method.self_id, method.explicit_self) }
|
||||||
};
|
};
|
||||||
|
|
||||||
self.resolve_function(rib_kind,
|
self.resolve_function(rib_kind,
|
||||||
|
|
|
@ -1099,7 +1099,7 @@ pub fn trans_local_var(bcx: @mut Block, def: ast::Def) -> Datum {
|
||||||
ast::DefLocal(nid, _) | ast::DefBinding(nid, _) => {
|
ast::DefLocal(nid, _) | ast::DefBinding(nid, _) => {
|
||||||
take_local(bcx, bcx.fcx.lllocals, nid)
|
take_local(bcx, bcx.fcx.lllocals, nid)
|
||||||
}
|
}
|
||||||
ast::DefSelf(nid) => {
|
ast::DefSelf(nid, _) => {
|
||||||
let self_info: ValSelfData = match bcx.fcx.llself {
|
let self_info: ValSelfData = match bcx.fcx.llself {
|
||||||
Some(ref self_info) => *self_info,
|
Some(ref self_info) => *self_info,
|
||||||
None => {
|
None => {
|
||||||
|
|
|
@ -144,7 +144,7 @@ pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::DefId)
|
||||||
debug!("calling inline trans_fn with self_ty {}",
|
debug!("calling inline trans_fn with self_ty {}",
|
||||||
ty_to_str(ccx.tcx, self_ty));
|
ty_to_str(ccx.tcx, self_ty));
|
||||||
match mth.explicit_self.node {
|
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),
|
_ => impl_self(self_ty, ty::ByCopy),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ pub fn trans_method(ccx: @mut CrateContext,
|
||||||
debug!("calling trans_fn with self_ty {}",
|
debug!("calling trans_fn with self_ty {}",
|
||||||
self_ty.repr(ccx.tcx));
|
self_ty.repr(ccx.tcx));
|
||||||
match method.explicit_self.node {
|
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),
|
_ => impl_self(self_ty, ty::ByCopy),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -672,7 +672,7 @@ fn ty_of_method_or_bare_fn<AC:AstConv,RS:RegionScope + Clone + 'static>(
|
||||||
{
|
{
|
||||||
match self_info.explicit_self.node {
|
match self_info.explicit_self.node {
|
||||||
ast::sty_static => None,
|
ast::sty_static => None,
|
||||||
ast::sty_value => {
|
ast::sty_value(_) => {
|
||||||
Some(self_info.untransformed_self_ty)
|
Some(self_info.untransformed_self_ty)
|
||||||
}
|
}
|
||||||
ast::sty_region(ref lifetime, mutability) => {
|
ast::sty_region(ref lifetime, mutability) => {
|
||||||
|
|
|
@ -1082,7 +1082,7 @@ impl<'self> LookupContext<'self> {
|
||||||
ast::sty_static => {
|
ast::sty_static => {
|
||||||
self.bug(~"static method for object type receiver");
|
self.bug(~"static method for object type receiver");
|
||||||
}
|
}
|
||||||
ast::sty_value => {
|
ast::sty_value(_) => {
|
||||||
ty::mk_err() // error reported in `enforce_object_limitations()`
|
ty::mk_err() // error reported in `enforce_object_limitations()`
|
||||||
}
|
}
|
||||||
ast::sty_region(*) | ast::sty_box(*) | ast::sty_uniq(*) => {
|
ast::sty_region(*) | ast::sty_box(*) | ast::sty_uniq(*) => {
|
||||||
|
@ -1141,7 +1141,7 @@ impl<'self> LookupContext<'self> {
|
||||||
through an object");
|
through an object");
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::sty_value => { // reason (a) above
|
ast::sty_value(_) => { // reason (a) above
|
||||||
self.tcx().sess.span_err(
|
self.tcx().sess.span_err(
|
||||||
self.expr.span,
|
self.expr.span,
|
||||||
"cannot call a method with a by-value receiver \
|
"cannot call a method with a by-value receiver \
|
||||||
|
@ -1198,7 +1198,7 @@ impl<'self> LookupContext<'self> {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
sty_value => {
|
sty_value(_) => {
|
||||||
rcvr_matches_ty(self.fcx, rcvr_ty, candidate)
|
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 {
|
pub fn get_mode_from_explicit_self(explicit_self: ast::explicit_self_) -> SelfMode {
|
||||||
match explicit_self {
|
match explicit_self {
|
||||||
sty_value => ty::ByRef,
|
sty_value(_) => ty::ByRef,
|
||||||
_ => ty::ByCopy,
|
_ => ty::ByCopy,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3254,7 +3254,7 @@ pub fn ty_param_bounds_and_ty_for_def(fcx: @mut FnCtxt,
|
||||||
defn: ast::Def)
|
defn: ast::Def)
|
||||||
-> ty_param_bounds_and_ty {
|
-> ty_param_bounds_and_ty {
|
||||||
match defn {
|
match defn {
|
||||||
ast::DefArg(nid, _) | ast::DefLocal(nid, _) | ast::DefSelf(nid) |
|
ast::DefArg(nid, _) | ast::DefLocal(nid, _) | ast::DefSelf(nid, _) |
|
||||||
ast::DefBinding(nid, _) => {
|
ast::DefBinding(nid, _) => {
|
||||||
let typ = fcx.local_ty(sp, nid);
|
let typ = fcx.local_ty(sp, nid);
|
||||||
return no_params(typ);
|
return no_params(typ);
|
||||||
|
|
|
@ -58,7 +58,7 @@ fn encl_region_of_def(fcx: @mut FnCtxt, def: ast::Def) -> ty::Region {
|
||||||
let tcx = fcx.tcx();
|
let tcx = fcx.tcx();
|
||||||
match def {
|
match def {
|
||||||
DefLocal(node_id, _) | DefArg(node_id, _) |
|
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)
|
tcx.region_maps.encl_region(node_id)
|
||||||
}
|
}
|
||||||
DefUpvar(_, subdef, closure_id, body_id) => {
|
DefUpvar(_, subdef, closure_id, body_id) => {
|
||||||
|
|
|
@ -388,7 +388,7 @@ impl Clean<SelfTy> for ast::explicit_self {
|
||||||
fn clean(&self) -> SelfTy {
|
fn clean(&self) -> SelfTy {
|
||||||
match self.node {
|
match self.node {
|
||||||
ast::sty_static => SelfStatic,
|
ast::sty_static => SelfStatic,
|
||||||
ast::sty_value => SelfValue,
|
ast::sty_value(_) => SelfValue,
|
||||||
ast::sty_uniq => SelfOwned,
|
ast::sty_uniq => SelfOwned,
|
||||||
ast::sty_region(lt, mt) => SelfBorrowed(lt.clean(), mt.clean()),
|
ast::sty_region(lt, mt) => SelfBorrowed(lt.clean(), mt.clean()),
|
||||||
ast::sty_box(mt) => SelfManaged(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 {
|
let (def_id, kind) = match *d {
|
||||||
ast::DefFn(i, _) => (i, TypeFunction),
|
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::DefTy(i) => (i, TypeEnum),
|
||||||
ast::DefTrait(i) => {
|
ast::DefTrait(i) => {
|
||||||
debug!("saw DefTrait in def_to_id");
|
debug!("saw DefTrait in def_to_id");
|
||||||
|
|
|
@ -227,7 +227,7 @@ pub enum MethodProvenance {
|
||||||
pub enum Def {
|
pub enum Def {
|
||||||
DefFn(DefId, purity),
|
DefFn(DefId, purity),
|
||||||
DefStaticMethod(/* method */ DefId, MethodProvenance, purity),
|
DefStaticMethod(/* method */ DefId, MethodProvenance, purity),
|
||||||
DefSelf(NodeId),
|
DefSelf(NodeId, bool /* is_mutbl */),
|
||||||
DefSelfTy(/* trait id */ NodeId),
|
DefSelfTy(/* trait id */ NodeId),
|
||||||
DefMod(DefId),
|
DefMod(DefId),
|
||||||
DefForeignMod(DefId),
|
DefForeignMod(DefId),
|
||||||
|
@ -921,8 +921,8 @@ pub enum ret_style {
|
||||||
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
#[deriving(Clone, Eq, Encodable, Decodable, IterBytes)]
|
||||||
pub enum explicit_self_ {
|
pub enum explicit_self_ {
|
||||||
sty_static, // no self
|
sty_static, // no self
|
||||||
sty_value, // `self`
|
sty_value(Mutability), // `self`
|
||||||
sty_region(Option<Lifetime>, Mutability), // `&'lt self`
|
sty_region(Option<Lifetime>, Mutability), // `&'lt self`
|
||||||
sty_box(Mutability), // `@self`
|
sty_box(Mutability), // `@self`
|
||||||
sty_uniq // `~self`
|
sty_uniq // `~self`
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ pub fn def_id_of_def(d: Def) -> DefId {
|
||||||
DefUse(id) | DefStruct(id) | DefTrait(id) | DefMethod(id, _) => {
|
DefUse(id) | DefStruct(id) | DefTrait(id) | DefMethod(id, _) => {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
DefArg(id, _) | DefLocal(id, _) | DefSelf(id) | DefSelfTy(id)
|
DefArg(id, _) | DefLocal(id, _) | DefSelf(id, _) | DefSelfTy(id)
|
||||||
| DefUpvar(id, _, _, _) | DefBinding(id, _) | DefRegion(id)
|
| DefUpvar(id, _, _, _) | DefBinding(id, _) | DefRegion(id)
|
||||||
| DefTyParamBinder(id) | DefLabel(id) => {
|
| DefTyParamBinder(id) | DefLabel(id) => {
|
||||||
local_def(id)
|
local_def(id)
|
||||||
|
|
|
@ -240,7 +240,7 @@ pub fn get_explicit_self(cx: @ExtCtxt, span: Span, self_ptr: &Option<PtrTy>)
|
||||||
let self_path = cx.expr_self(span);
|
let self_path = cx.expr_self(span);
|
||||||
match *self_ptr {
|
match *self_ptr {
|
||||||
None => {
|
None => {
|
||||||
(self_path, respan(span, ast::sty_value))
|
(self_path, respan(span, ast::sty_value(ast::MutImmutable)))
|
||||||
}
|
}
|
||||||
Some(ref ptr) => {
|
Some(ref ptr) => {
|
||||||
let self_ty = respan(
|
let self_ty = respan(
|
||||||
|
|
|
@ -3438,15 +3438,11 @@ impl Parser {
|
||||||
|
|
||||||
// parse the argument list and result type of a function
|
// parse the argument list and result type of a function
|
||||||
// that may have a self type.
|
// that may have a self type.
|
||||||
fn parse_fn_decl_with_self(
|
fn parse_fn_decl_with_self(&self, parse_arg_fn: &fn(&Parser) -> arg)
|
||||||
&self,
|
-> (explicit_self, fn_decl) {
|
||||||
parse_arg_fn:
|
|
||||||
&fn(&Parser) -> arg
|
fn maybe_parse_explicit_self(cnstr: &fn(v: Mutability) -> ast::explicit_self_,
|
||||||
) -> (explicit_self, fn_decl) {
|
p: &Parser) -> ast::explicit_self_ {
|
||||||
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
|
// We need to make sure it isn't a type
|
||||||
if p.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) ||
|
if p.look_ahead(1, |t| token::is_keyword(keywords::Self, t)) ||
|
||||||
((p.look_ahead(1, |t| token::is_keyword(keywords::Const, 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() => {
|
token::IDENT(*) if self.is_self_ident() => {
|
||||||
self.bump();
|
self.bump();
|
||||||
sty_value
|
sty_value(MutImmutable)
|
||||||
}
|
}
|
||||||
token::BINOP(token::STAR) => {
|
token::BINOP(token::STAR) => {
|
||||||
// Possibly "*self" or "*mut self" -- not supported. Try to avoid
|
// Possibly "*self" or "*mut self" -- not supported. Try to avoid
|
||||||
// emitting cryptic "unexpected token" errors.
|
// emitting cryptic "unexpected token" errors.
|
||||||
self.bump();
|
self.bump();
|
||||||
if self.token_is_mutability(self.token) {
|
let mutability = if self.token_is_mutability(self.token) {
|
||||||
self.bump();
|
self.parse_mutability()
|
||||||
}
|
} else { MutImmutable };
|
||||||
if self.is_self_ident() {
|
if self.is_self_ident() {
|
||||||
self.span_err(*self.span, "cannot pass self by unsafe pointer");
|
self.span_err(*self.span, "cannot pass self by unsafe pointer");
|
||||||
self.bump();
|
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
|
sty_static
|
||||||
|
|
|
@ -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 {
|
pub fn print_explicit_self(s: @ps, explicit_self: ast::explicit_self_) -> bool {
|
||||||
match explicit_self {
|
match explicit_self {
|
||||||
ast::sty_static => { return false; }
|
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_uniq => { word(s.s, "~self"); }
|
||||||
ast::sty_region(ref lt, m) => {
|
ast::sty_region(ref lt, m) => {
|
||||||
word(s.s, "&");
|
word(s.s, "&");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue