Skip to content

Commit a6187c6

Browse files
committed
Make &self permit explicit lifetimes, but don't really use them
(this will be needed for snapshotting at some point).
1 parent 087a015 commit a6187c6

File tree

13 files changed

+166
-55
lines changed

13 files changed

+166
-55
lines changed

src/librustc/metadata/decoder.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,10 @@ fn get_self_ty(item: ebml::Doc) -> ast::self_ty_ {
631631
'v' => { return ast::sty_value; }
632632
'@' => { return ast::sty_box(get_mutability(string[1])); }
633633
'~' => { return ast::sty_uniq(get_mutability(string[1])); }
634-
'&' => { return ast::sty_region(get_mutability(string[1])); }
634+
'&' => {
635+
// FIXME(#4846) expl. region
636+
return ast::sty_region(None, get_mutability(string[1]));
637+
}
635638
_ => {
636639
fail!(fmt!("unknown self type code: `%c`", self_ty_kind as char));
637640
}

src/librustc/metadata/encoder.rs

+34-19
Original file line numberDiff line numberDiff line change
@@ -406,32 +406,47 @@ fn encode_self_type(ebml_w: writer::Encoder, self_type: ast::self_ty_) {
406406
ebml_w.start_tag(tag_item_trait_method_self_ty);
407407

408408
// Encode the base self type.
409-
let ch;
410409
match self_type {
411-
sty_static => { ch = 's' as u8; }
412-
sty_by_ref => { ch = 'r' as u8; }
413-
sty_value => { ch = 'v' as u8; }
414-
sty_region(_) => { ch = '&' as u8; }
415-
sty_box(_) => { ch = '@' as u8; }
416-
sty_uniq(_) => { ch = '~' as u8; }
417-
}
418-
ebml_w.writer.write(&[ ch ]);
419-
420-
// Encode mutability.
421-
match self_type {
422-
sty_static | sty_by_ref | sty_value => { /* No-op. */ }
423-
sty_region(m_imm) | sty_box(m_imm) | sty_uniq(m_imm) => {
424-
ebml_w.writer.write(&[ 'i' as u8 ]);
410+
sty_static => {
411+
ebml_w.writer.write(&[ 's' as u8 ]);
412+
}
413+
sty_by_ref => {
414+
ebml_w.writer.write(&[ 'r' as u8 ]);
415+
}
416+
sty_value => {
417+
ebml_w.writer.write(&[ 'v' as u8 ]);
418+
}
419+
sty_region(_, m) => {
420+
// FIXME(#4846) encode custom lifetime
421+
ebml_w.writer.write(&[ '&' as u8 ]);
422+
encode_mutability(ebml_w, m);
425423
}
426-
sty_region(m_mutbl) | sty_box(m_mutbl) | sty_uniq(m_mutbl) => {
427-
ebml_w.writer.write(&[ 'm' as u8 ]);
424+
sty_box(m) => {
425+
ebml_w.writer.write(&[ '@' as u8 ]);
426+
encode_mutability(ebml_w, m);
428427
}
429-
sty_region(m_const) | sty_box(m_const) | sty_uniq(m_const) => {
430-
ebml_w.writer.write(&[ 'c' as u8 ]);
428+
sty_uniq(m) => {
429+
ebml_w.writer.write(&[ '~' as u8 ]);
430+
encode_mutability(ebml_w, m);
431431
}
432432
}
433433

434434
ebml_w.end_tag();
435+
436+
fn encode_mutability(ebml_w: writer::Encoder,
437+
m: ast::mutability) {
438+
match m {
439+
m_imm => {
440+
ebml_w.writer.write(&[ 'i' as u8 ]);
441+
}
442+
m_mutbl => {
443+
ebml_w.writer.write(&[ 'm' as u8 ]);
444+
}
445+
m_const => {
446+
ebml_w.writer.write(&[ 'c' as u8 ]);
447+
}
448+
}
449+
}
435450
}
436451

437452
fn encode_method_sort(ebml_w: writer::Encoder, sort: char) {

src/librustc/middle/liveness.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ fn visit_fn(fk: &visit::fn_kind,
472472
special_idents::self_,
473473
by_ref));
474474
}
475-
sty_value | sty_region(_) | sty_box(_) | sty_uniq(_) => {
475+
sty_value | sty_region(*) | sty_box(_) | sty_uniq(_) => {
476476
fn_maps.add_variable(Arg(method.self_id,
477477
special_idents::self_,
478478
by_copy));

src/librustc/middle/trans/meth.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -589,7 +589,7 @@ pub fn trans_trait_callee(bcx: block,
589589
let llpair = self_datum.to_ref_llval(bcx);
590590
591591
let llpair = match explicit_self {
592-
ast::sty_region(_) => Load(bcx, llpair),
592+
ast::sty_region(*) => Load(bcx, llpair),
593593
ast::sty_static | ast::sty_by_ref | ast::sty_value |
594594
ast::sty_box(_) | ast::sty_uniq(_) => llpair
595595
};
@@ -658,7 +658,7 @@ pub fn trans_trait_callee_from_llval(bcx: block,
658658
bcx.tcx().sess.bug(~"methods with by-value self should not be \
659659
called on objects");
660660
}
661-
ast::sty_region(_) => {
661+
ast::sty_region(*) => {
662662
// As before, we need to pass a pointer to a pointer to the
663663
// payload.
664664
match store {

src/librustc/middle/trans/reflect.rs

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ pub impl Reflector {
105105
v,
106106
ty::BoxTraitStore,
107107
ast::sty_region(
108+
None,
108109
ast::m_imm)),
109110
ArgVals(args), SaveIn(scratch.val), DontAutorefArg);
110111
let result = scratch.to_value_llval(bcx);

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -743,10 +743,12 @@ pub impl LookupContext/&self {
743743
sty_box(_) | sty_uniq(_) => {
744744
self_substs
745745
}
746-
sty_region(_) if self_substs.self_r.is_some() => {
746+
sty_region(*) if self_substs.self_r.is_some() => {
747+
// FIXME(#4846) ignoring expl lifetime here
747748
self_substs
748749
}
749-
sty_region(_) => {
750+
sty_region(*) => {
751+
// FIXME(#4846) ignoring expl lifetime here
750752
substs {
751753
self_r:
752754
Some(self.infcx().next_region_var(
@@ -1326,7 +1328,8 @@ pub fn transform_self_type_for_method(tcx: ty::ctxt,
13261328
sty_by_ref | sty_value => {
13271329
impl_ty
13281330
}
1329-
sty_region(mutability) => {
1331+
sty_region(_, mutability) => {
1332+
// FIXME(#4846) ignoring expl lifetime here
13301333
mk_rptr(tcx,
13311334
self_region.expect(~"self region missing for &self param"),
13321335
ty::mt { ty: impl_ty, mutbl: mutability })

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

+7-5
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ pub fn replace_bound_regions_in_fn_sig(
3030
isr: isr_alist,
3131
self_info: Option<SelfInfo>,
3232
fn_sig: &ty::FnSig,
33-
mapf: &fn(ty::bound_region) -> ty::Region) ->
34-
(isr_alist, Option<SelfInfo>, ty::FnSig) {
33+
mapf: &fn(ty::bound_region) -> ty::Region)
34+
-> (isr_alist, Option<SelfInfo>, ty::FnSig)
35+
{
3536
// Take self_info apart; the self_ty part is the only one we want
3637
// to update here.
3738
let self_ty = self_info.map(|s| s.self_ty);
@@ -41,8 +42,10 @@ pub fn replace_bound_regions_in_fn_sig(
4142

4243
match self_info {
4344
Some(SelfInfo {
44-
explicit_self: codemap::spanned { node: ast::sty_region(m),
45-
_}, _}) => {
45+
explicit_self: codemap::spanned {
46+
node: ast::sty_region(_, m),
47+
// FIXME(#4846) ------^ Use this lifetime instead of self
48+
_}, _}) => {
4649
let region = ty::re_bound(ty::br_self);
4750
let ty = ty::mk_rptr(tcx, region,
4851
ty::mt { ty: ty::mk_self(tcx), mutbl: m });
@@ -51,7 +54,6 @@ pub fn replace_bound_regions_in_fn_sig(
5154
_ => {}
5255
}
5356

54-
5557
for self_ty.each |t| { all_tys.push(*t) }
5658

5759
debug!("replace_bound_regions_in_fn_sig(self_info.self_ty=%?, fn_sig=%s, \

src/libsyntax/ast.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1002,18 +1002,18 @@ impl to_bytes::IterBytes for ret_style {
10021002
#[auto_decode]
10031003
#[deriving_eq]
10041004
pub enum self_ty_ {
1005-
sty_static, // no self: static method
1006-
sty_by_ref, // old by-reference self: ``
1007-
sty_value, // by-value self: `self`
1008-
sty_region(mutability), // by-region self: `&self`
1009-
sty_box(mutability), // by-managed-pointer self: `@self`
1010-
sty_uniq(mutability) // by-unique-pointer self: `~self`
1005+
sty_static, // no self
1006+
sty_by_ref, // ``
1007+
sty_value, // `self`
1008+
sty_region(Option<@Lifetime>, mutability), // `&'lt self`
1009+
sty_box(mutability), // `@self`
1010+
sty_uniq(mutability) // `~self`
10111011
}
10121012
10131013
impl self_ty_ {
10141014
fn is_borrowed(&self) -> bool {
10151015
match *self {
1016-
sty_region(_) => true,
1016+
sty_region(*) => true,
10171017
_ => false
10181018
}
10191019
}

src/libsyntax/ext/auto_encode.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -634,8 +634,10 @@ fn mk_ser_method(
634634
ident: cx.ident_of(~"encode"),
635635
attrs: ~[],
636636
generics: ast_util::empty_generics(),
637-
self_ty: codemap::spanned { node: ast::sty_region(ast::m_imm),
638-
span: span },
637+
self_ty: codemap::spanned {
638+
node: ast::sty_region(None, ast::m_imm),
639+
span: span
640+
},
639641
purity: ast::impure_fn,
640642
decl: ser_decl,
641643
body: ser_body,

src/libsyntax/ext/deriving.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ fn create_eq_method(cx: @ext_ctxt,
220220
let body_block = build::mk_simple_block(cx, span, body);
221221

222222
// Create the method.
223-
let self_ty = spanned { node: sty_region(m_imm), span: span };
223+
let self_ty = spanned { node: sty_region(None, m_imm), span: span };
224224
@ast::method {
225225
ident: method_ident,
226226
attrs: ~[],
@@ -398,7 +398,7 @@ fn create_iter_bytes_method(cx: @ext_ctxt,
398398
let body_block = build::mk_block_(cx, span, statements);
399399

400400
// Create the method.
401-
let self_ty = spanned { node: sty_region(m_imm), span: span };
401+
let self_ty = spanned { node: sty_region(None, m_imm), span: span };
402402
let method_ident = cx.ident_of(~"iter_bytes");
403403
@ast::method {
404404
ident: method_ident,
@@ -448,7 +448,7 @@ fn create_clone_method(cx: @ext_ctxt,
448448
let body_block = build::mk_simple_block(cx, span, expr);
449449

450450
// Create the self type and method identifier.
451-
let self_ty = spanned { node: sty_region(m_imm), span: span };
451+
let self_ty = spanned { node: sty_region(None, m_imm), span: span };
452452
let method_ident = cx.ident_of(~"clone");
453453

454454
// Create the method.

src/libsyntax/parse/parser.rs

+62-1
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,13 @@ pub impl Parser {
975975
}
976976
}
977977

978+
fn token_is_lifetime(&self, tok: &token::Token) -> bool {
979+
match *tok {
980+
token::LIFETIME(_) => true,
981+
_ => false
982+
}
983+
}
984+
978985
fn parse_lifetime(&self) -> ast::Lifetime {
979986
/*!
980987
*
@@ -1041,6 +1048,11 @@ pub impl Parser {
10411048
}
10421049
}
10431050

1051+
fn token_is_mutability(&self, tok: &token::Token) -> bool {
1052+
self.token_is_keyword(&~"mut", tok) ||
1053+
self.token_is_keyword(&~"const", tok)
1054+
}
1055+
10441056
fn parse_mutability(&self) -> mutability {
10451057
if self.eat_keyword(&~"mut") {
10461058
m_mutbl
@@ -2844,14 +2856,63 @@ pub impl Parser {
28442856
}
28452857
}
28462858

2859+
fn maybe_parse_borrowed_self_ty(
2860+
self: &Parser
2861+
) -> ast::self_ty_ {
2862+
// The following things are possible to see here:
2863+
//
2864+
// fn(&self)
2865+
// fn(&mut self)
2866+
// fn(&'lt self)
2867+
// fn(&'lt mut self)
2868+
//
2869+
// We already know that the current token is `&`.
2870+
2871+
if (
2872+
self.token_is_keyword(&~"self", &self.look_ahead(1)))
2873+
{
2874+
self.bump();
2875+
self.expect_self_ident();
2876+
sty_region(None, m_imm)
2877+
} else if (
2878+
self.token_is_mutability(&self.look_ahead(1)) &&
2879+
self.token_is_keyword(&~"self", &self.look_ahead(2)))
2880+
{
2881+
self.bump();
2882+
let mutability = self.parse_mutability();
2883+
self.expect_self_ident();
2884+
sty_region(None, mutability)
2885+
} else if (
2886+
self.token_is_lifetime(&self.look_ahead(1)) &&
2887+
self.token_is_keyword(&~"self", &self.look_ahead(2)))
2888+
{
2889+
self.bump();
2890+
let lifetime = @self.parse_lifetime();
2891+
self.expect_self_ident();
2892+
sty_region(Some(lifetime), m_imm)
2893+
} else if (
2894+
self.token_is_lifetime(&self.look_ahead(1)) &&
2895+
self.token_is_mutability(&self.look_ahead(2)) &&
2896+
self.token_is_keyword(&~"self", &self.look_ahead(3)))
2897+
{
2898+
self.bump();
2899+
let lifetime = @self.parse_lifetime();
2900+
let mutability = self.parse_mutability();
2901+
self.expect_self_ident();
2902+
sty_region(Some(lifetime), mutability)
2903+
} else {
2904+
sty_by_ref
2905+
}
2906+
}
2907+
28472908
self.expect(&token::LPAREN);
28482909

28492910
// A bit of complexity and lookahead is needed here in order to to be
28502911
// backwards compatible.
28512912
let lo = self.span.lo;
28522913
let self_ty = match *self.token {
28532914
token::BINOP(token::AND) => {
2854-
maybe_parse_self_ty(sty_region, self)
2915+
maybe_parse_borrowed_self_ty(self)
28552916
}
28562917
token::AT => {
28572918
maybe_parse_self_ty(sty_box, self)

src/libsyntax/print/pprust.rs

+14-11
Original file line numberDiff line numberDiff line change
@@ -1646,17 +1646,20 @@ pub fn print_pat(s: @ps, &&pat: @ast::pat, refutable: bool) {
16461646
// Returns whether it printed anything
16471647
pub fn print_self_ty(s: @ps, self_ty: ast::self_ty_) -> bool {
16481648
match self_ty {
1649-
ast::sty_static | ast::sty_by_ref => { return false; }
1650-
ast::sty_value => { word(s.s, ~"self"); }
1651-
ast::sty_region(m) => {
1652-
word(s.s, ~"&"); print_mutability(s, m); word(s.s, ~"self");
1653-
}
1654-
ast::sty_box(m) => {
1655-
word(s.s, ~"@"); print_mutability(s, m); word(s.s, ~"self");
1656-
}
1657-
ast::sty_uniq(m) => {
1658-
word(s.s, ~"~"); print_mutability(s, m); word(s.s, ~"self");
1659-
}
1649+
ast::sty_static | ast::sty_by_ref => { return false; }
1650+
ast::sty_value => { word(s.s, ~"self"); }
1651+
ast::sty_region(lt, m) => {
1652+
word(s.s, ~"&");
1653+
print_opt_lifetime(s, lt);
1654+
print_mutability(s, m);
1655+
word(s.s, ~"self");
1656+
}
1657+
ast::sty_box(m) => {
1658+
word(s.s, ~"@"); print_mutability(s, m); word(s.s, ~"self");
1659+
}
1660+
ast::sty_uniq(m) => {
1661+
word(s.s, ~"~"); print_mutability(s, m); word(s.s, ~"self");
1662+
}
16601663
}
16611664
return true;
16621665
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test that you can insert an explicit lifetime in explicit self.
12+
13+
struct Foo {
14+
f: uint
15+
}
16+
17+
pub impl Foo {
18+
fn foo(&'a self) {}
19+
}
20+
21+
fn main() {}

0 commit comments

Comments
 (0)