Make &self permit explicit lifetimes, but don't really use them
(this will be needed for snapshotting at some point).
This commit is contained in:
parent
087a015a72
commit
a6187c62e9
@ -631,7 +631,10 @@ fn get_self_ty(item: ebml::Doc) -> ast::self_ty_ {
|
||||
'v' => { return ast::sty_value; }
|
||||
'@' => { return ast::sty_box(get_mutability(string[1])); }
|
||||
'~' => { return ast::sty_uniq(get_mutability(string[1])); }
|
||||
'&' => { return ast::sty_region(get_mutability(string[1])); }
|
||||
'&' => {
|
||||
// FIXME(#4846) expl. region
|
||||
return ast::sty_region(None, get_mutability(string[1]));
|
||||
}
|
||||
_ => {
|
||||
fail!(fmt!("unknown self type code: `%c`", self_ty_kind as char));
|
||||
}
|
||||
|
@ -406,32 +406,47 @@ fn encode_self_type(ebml_w: writer::Encoder, self_type: ast::self_ty_) {
|
||||
ebml_w.start_tag(tag_item_trait_method_self_ty);
|
||||
|
||||
// Encode the base self type.
|
||||
let ch;
|
||||
match self_type {
|
||||
sty_static => { ch = 's' as u8; }
|
||||
sty_by_ref => { ch = 'r' as u8; }
|
||||
sty_value => { ch = 'v' as u8; }
|
||||
sty_region(_) => { ch = '&' as u8; }
|
||||
sty_box(_) => { ch = '@' as u8; }
|
||||
sty_uniq(_) => { ch = '~' as u8; }
|
||||
}
|
||||
ebml_w.writer.write(&[ ch ]);
|
||||
|
||||
// Encode mutability.
|
||||
match self_type {
|
||||
sty_static | sty_by_ref | sty_value => { /* No-op. */ }
|
||||
sty_region(m_imm) | sty_box(m_imm) | sty_uniq(m_imm) => {
|
||||
ebml_w.writer.write(&[ 'i' as u8 ]);
|
||||
sty_static => {
|
||||
ebml_w.writer.write(&[ 's' as u8 ]);
|
||||
}
|
||||
sty_region(m_mutbl) | sty_box(m_mutbl) | sty_uniq(m_mutbl) => {
|
||||
ebml_w.writer.write(&[ 'm' as u8 ]);
|
||||
sty_by_ref => {
|
||||
ebml_w.writer.write(&[ 'r' as u8 ]);
|
||||
}
|
||||
sty_region(m_const) | sty_box(m_const) | sty_uniq(m_const) => {
|
||||
ebml_w.writer.write(&[ 'c' as u8 ]);
|
||||
sty_value => {
|
||||
ebml_w.writer.write(&[ 'v' as u8 ]);
|
||||
}
|
||||
sty_region(_, m) => {
|
||||
// FIXME(#4846) encode custom lifetime
|
||||
ebml_w.writer.write(&[ '&' as u8 ]);
|
||||
encode_mutability(ebml_w, m);
|
||||
}
|
||||
sty_box(m) => {
|
||||
ebml_w.writer.write(&[ '@' as u8 ]);
|
||||
encode_mutability(ebml_w, m);
|
||||
}
|
||||
sty_uniq(m) => {
|
||||
ebml_w.writer.write(&[ '~' as u8 ]);
|
||||
encode_mutability(ebml_w, m);
|
||||
}
|
||||
}
|
||||
|
||||
ebml_w.end_tag();
|
||||
|
||||
fn encode_mutability(ebml_w: writer::Encoder,
|
||||
m: ast::mutability) {
|
||||
match m {
|
||||
m_imm => {
|
||||
ebml_w.writer.write(&[ 'i' as u8 ]);
|
||||
}
|
||||
m_mutbl => {
|
||||
ebml_w.writer.write(&[ 'm' as u8 ]);
|
||||
}
|
||||
m_const => {
|
||||
ebml_w.writer.write(&[ 'c' as u8 ]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_method_sort(ebml_w: writer::Encoder, sort: char) {
|
||||
|
@ -472,7 +472,7 @@ fn visit_fn(fk: &visit::fn_kind,
|
||||
special_idents::self_,
|
||||
by_ref));
|
||||
}
|
||||
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_,
|
||||
by_copy));
|
||||
|
@ -589,7 +589,7 @@ pub fn trans_trait_callee(bcx: block,
|
||||
let llpair = self_datum.to_ref_llval(bcx);
|
||||
|
||||
let llpair = match explicit_self {
|
||||
ast::sty_region(_) => Load(bcx, llpair),
|
||||
ast::sty_region(*) => Load(bcx, llpair),
|
||||
ast::sty_static | ast::sty_by_ref | ast::sty_value |
|
||||
ast::sty_box(_) | ast::sty_uniq(_) => llpair
|
||||
};
|
||||
@ -658,7 +658,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
|
||||
bcx.tcx().sess.bug(~"methods with by-value self should not be \
|
||||
called on objects");
|
||||
}
|
||||
ast::sty_region(_) => {
|
||||
ast::sty_region(*) => {
|
||||
// As before, we need to pass a pointer to a pointer to the
|
||||
// payload.
|
||||
match store {
|
||||
|
@ -105,6 +105,7 @@ pub impl Reflector {
|
||||
v,
|
||||
ty::BoxTraitStore,
|
||||
ast::sty_region(
|
||||
None,
|
||||
ast::m_imm)),
|
||||
ArgVals(args), SaveIn(scratch.val), DontAutorefArg);
|
||||
let result = scratch.to_value_llval(bcx);
|
||||
|
@ -743,10 +743,12 @@ pub impl LookupContext/&self {
|
||||
sty_box(_) | sty_uniq(_) => {
|
||||
self_substs
|
||||
}
|
||||
sty_region(_) if self_substs.self_r.is_some() => {
|
||||
sty_region(*) if self_substs.self_r.is_some() => {
|
||||
// FIXME(#4846) ignoring expl lifetime here
|
||||
self_substs
|
||||
}
|
||||
sty_region(_) => {
|
||||
sty_region(*) => {
|
||||
// FIXME(#4846) ignoring expl lifetime here
|
||||
substs {
|
||||
self_r:
|
||||
Some(self.infcx().next_region_var(
|
||||
@ -1326,7 +1328,8 @@ pub fn transform_self_type_for_method(tcx: ty::ctxt,
|
||||
sty_by_ref | sty_value => {
|
||||
impl_ty
|
||||
}
|
||||
sty_region(mutability) => {
|
||||
sty_region(_, mutability) => {
|
||||
// FIXME(#4846) ignoring expl lifetime here
|
||||
mk_rptr(tcx,
|
||||
self_region.expect(~"self region missing for &self param"),
|
||||
ty::mt { ty: impl_ty, mutbl: mutability })
|
||||
|
@ -30,8 +30,9 @@ pub fn replace_bound_regions_in_fn_sig(
|
||||
isr: isr_alist,
|
||||
self_info: Option<SelfInfo>,
|
||||
fn_sig: &ty::FnSig,
|
||||
mapf: &fn(ty::bound_region) -> ty::Region) ->
|
||||
(isr_alist, Option<SelfInfo>, ty::FnSig) {
|
||||
mapf: &fn(ty::bound_region) -> ty::Region)
|
||||
-> (isr_alist, Option<SelfInfo>, ty::FnSig)
|
||||
{
|
||||
// Take self_info apart; the self_ty part is the only one we want
|
||||
// to update here.
|
||||
let self_ty = self_info.map(|s| s.self_ty);
|
||||
@ -41,8 +42,10 @@ pub fn replace_bound_regions_in_fn_sig(
|
||||
|
||||
match self_info {
|
||||
Some(SelfInfo {
|
||||
explicit_self: codemap::spanned { node: ast::sty_region(m),
|
||||
_}, _}) => {
|
||||
explicit_self: codemap::spanned {
|
||||
node: ast::sty_region(_, m),
|
||||
// FIXME(#4846) ------^ Use this lifetime instead of self
|
||||
_}, _}) => {
|
||||
let region = ty::re_bound(ty::br_self);
|
||||
let ty = ty::mk_rptr(tcx, region,
|
||||
ty::mt { ty: ty::mk_self(tcx), mutbl: m });
|
||||
@ -51,7 +54,6 @@ pub fn replace_bound_regions_in_fn_sig(
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
||||
for self_ty.each |t| { all_tys.push(*t) }
|
||||
|
||||
debug!("replace_bound_regions_in_fn_sig(self_info.self_ty=%?, fn_sig=%s, \
|
||||
|
@ -1002,18 +1002,18 @@ impl to_bytes::IterBytes for ret_style {
|
||||
#[auto_decode]
|
||||
#[deriving_eq]
|
||||
pub enum self_ty_ {
|
||||
sty_static, // no self: static method
|
||||
sty_by_ref, // old by-reference self: ``
|
||||
sty_value, // by-value self: `self`
|
||||
sty_region(mutability), // by-region self: `&self`
|
||||
sty_box(mutability), // by-managed-pointer self: `@self`
|
||||
sty_uniq(mutability) // by-unique-pointer self: `~self`
|
||||
sty_static, // no self
|
||||
sty_by_ref, // ``
|
||||
sty_value, // `self`
|
||||
sty_region(Option<@Lifetime>, mutability), // `&'lt self`
|
||||
sty_box(mutability), // `@self`
|
||||
sty_uniq(mutability) // `~self`
|
||||
}
|
||||
|
||||
impl self_ty_ {
|
||||
fn is_borrowed(&self) -> bool {
|
||||
match *self {
|
||||
sty_region(_) => true,
|
||||
sty_region(*) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -634,8 +634,10 @@ fn mk_ser_method(
|
||||
ident: cx.ident_of(~"encode"),
|
||||
attrs: ~[],
|
||||
generics: ast_util::empty_generics(),
|
||||
self_ty: codemap::spanned { node: ast::sty_region(ast::m_imm),
|
||||
span: span },
|
||||
self_ty: codemap::spanned {
|
||||
node: ast::sty_region(None, ast::m_imm),
|
||||
span: span
|
||||
},
|
||||
purity: ast::impure_fn,
|
||||
decl: ser_decl,
|
||||
body: ser_body,
|
||||
|
@ -220,7 +220,7 @@ fn create_eq_method(cx: @ext_ctxt,
|
||||
let body_block = build::mk_simple_block(cx, span, body);
|
||||
|
||||
// Create the method.
|
||||
let self_ty = spanned { node: sty_region(m_imm), span: span };
|
||||
let self_ty = spanned { node: sty_region(None, m_imm), span: span };
|
||||
@ast::method {
|
||||
ident: method_ident,
|
||||
attrs: ~[],
|
||||
@ -398,7 +398,7 @@ fn create_iter_bytes_method(cx: @ext_ctxt,
|
||||
let body_block = build::mk_block_(cx, span, statements);
|
||||
|
||||
// Create the method.
|
||||
let self_ty = spanned { node: sty_region(m_imm), span: span };
|
||||
let self_ty = spanned { node: sty_region(None, m_imm), span: span };
|
||||
let method_ident = cx.ident_of(~"iter_bytes");
|
||||
@ast::method {
|
||||
ident: method_ident,
|
||||
@ -448,7 +448,7 @@ fn create_clone_method(cx: @ext_ctxt,
|
||||
let body_block = build::mk_simple_block(cx, span, expr);
|
||||
|
||||
// Create the self type and method identifier.
|
||||
let self_ty = spanned { node: sty_region(m_imm), span: span };
|
||||
let self_ty = spanned { node: sty_region(None, m_imm), span: span };
|
||||
let method_ident = cx.ident_of(~"clone");
|
||||
|
||||
// Create the method.
|
||||
|
@ -975,6 +975,13 @@ pub impl Parser {
|
||||
}
|
||||
}
|
||||
|
||||
fn token_is_lifetime(&self, tok: &token::Token) -> bool {
|
||||
match *tok {
|
||||
token::LIFETIME(_) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_lifetime(&self) -> ast::Lifetime {
|
||||
/*!
|
||||
*
|
||||
@ -1041,6 +1048,11 @@ pub impl Parser {
|
||||
}
|
||||
}
|
||||
|
||||
fn token_is_mutability(&self, tok: &token::Token) -> bool {
|
||||
self.token_is_keyword(&~"mut", tok) ||
|
||||
self.token_is_keyword(&~"const", tok)
|
||||
}
|
||||
|
||||
fn parse_mutability(&self) -> mutability {
|
||||
if self.eat_keyword(&~"mut") {
|
||||
m_mutbl
|
||||
@ -2844,6 +2856,55 @@ pub impl Parser {
|
||||
}
|
||||
}
|
||||
|
||||
fn maybe_parse_borrowed_self_ty(
|
||||
self: &Parser
|
||||
) -> ast::self_ty_ {
|
||||
// The following things are possible to see here:
|
||||
//
|
||||
// fn(&self)
|
||||
// fn(&mut self)
|
||||
// fn(&'lt self)
|
||||
// fn(&'lt mut self)
|
||||
//
|
||||
// We already know that the current token is `&`.
|
||||
|
||||
if (
|
||||
self.token_is_keyword(&~"self", &self.look_ahead(1)))
|
||||
{
|
||||
self.bump();
|
||||
self.expect_self_ident();
|
||||
sty_region(None, m_imm)
|
||||
} else if (
|
||||
self.token_is_mutability(&self.look_ahead(1)) &&
|
||||
self.token_is_keyword(&~"self", &self.look_ahead(2)))
|
||||
{
|
||||
self.bump();
|
||||
let mutability = self.parse_mutability();
|
||||
self.expect_self_ident();
|
||||
sty_region(None, mutability)
|
||||
} else if (
|
||||
self.token_is_lifetime(&self.look_ahead(1)) &&
|
||||
self.token_is_keyword(&~"self", &self.look_ahead(2)))
|
||||
{
|
||||
self.bump();
|
||||
let lifetime = @self.parse_lifetime();
|
||||
self.expect_self_ident();
|
||||
sty_region(Some(lifetime), m_imm)
|
||||
} else if (
|
||||
self.token_is_lifetime(&self.look_ahead(1)) &&
|
||||
self.token_is_mutability(&self.look_ahead(2)) &&
|
||||
self.token_is_keyword(&~"self", &self.look_ahead(3)))
|
||||
{
|
||||
self.bump();
|
||||
let lifetime = @self.parse_lifetime();
|
||||
let mutability = self.parse_mutability();
|
||||
self.expect_self_ident();
|
||||
sty_region(Some(lifetime), mutability)
|
||||
} else {
|
||||
sty_by_ref
|
||||
}
|
||||
}
|
||||
|
||||
self.expect(&token::LPAREN);
|
||||
|
||||
// A bit of complexity and lookahead is needed here in order to to be
|
||||
@ -2851,7 +2912,7 @@ pub impl Parser {
|
||||
let lo = self.span.lo;
|
||||
let self_ty = match *self.token {
|
||||
token::BINOP(token::AND) => {
|
||||
maybe_parse_self_ty(sty_region, self)
|
||||
maybe_parse_borrowed_self_ty(self)
|
||||
}
|
||||
token::AT => {
|
||||
maybe_parse_self_ty(sty_box, self)
|
||||
|
@ -1646,17 +1646,20 @@ pub fn print_pat(s: @ps, &&pat: @ast::pat, refutable: bool) {
|
||||
// Returns whether it printed anything
|
||||
pub fn print_self_ty(s: @ps, self_ty: ast::self_ty_) -> bool {
|
||||
match self_ty {
|
||||
ast::sty_static | ast::sty_by_ref => { return false; }
|
||||
ast::sty_value => { word(s.s, ~"self"); }
|
||||
ast::sty_region(m) => {
|
||||
word(s.s, ~"&"); print_mutability(s, m); word(s.s, ~"self");
|
||||
}
|
||||
ast::sty_box(m) => {
|
||||
word(s.s, ~"@"); print_mutability(s, m); word(s.s, ~"self");
|
||||
}
|
||||
ast::sty_uniq(m) => {
|
||||
word(s.s, ~"~"); print_mutability(s, m); word(s.s, ~"self");
|
||||
}
|
||||
ast::sty_static | ast::sty_by_ref => { return false; }
|
||||
ast::sty_value => { word(s.s, ~"self"); }
|
||||
ast::sty_region(lt, m) => {
|
||||
word(s.s, ~"&");
|
||||
print_opt_lifetime(s, lt);
|
||||
print_mutability(s, m);
|
||||
word(s.s, ~"self");
|
||||
}
|
||||
ast::sty_box(m) => {
|
||||
word(s.s, ~"@"); print_mutability(s, m); word(s.s, ~"self");
|
||||
}
|
||||
ast::sty_uniq(m) => {
|
||||
word(s.s, ~"~"); print_mutability(s, m); word(s.s, ~"self");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
21
src/test/run-pass/regions-expl-self.rs
Normal file
21
src/test/run-pass/regions-expl-self.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// 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.
|
||||
|
||||
// Test that you can insert an explicit lifetime in explicit self.
|
||||
|
||||
struct Foo {
|
||||
f: uint
|
||||
}
|
||||
|
||||
pub impl Foo {
|
||||
fn foo(&'a self) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user