Skip to content

Commit a347e9d

Browse files
committed
auto merge of #5296 : nikomatsakis/rust/region-syntax-expl-lifetimes-2, r=nikomatsakis
Modify pretty-printer to emit lifetimes and fix a few minor parser bugs that this uncovered. r? whomever.
2 parents 98ce99d + 7cbd4b2 commit a347e9d

File tree

15 files changed

+195
-245
lines changed

15 files changed

+195
-245
lines changed

src/librustc/middle/region.rs

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use std::oldmap::HashMap;
3131
use syntax::ast_map;
3232
use syntax::codemap::span;
3333
use syntax::print::pprust;
34+
use syntax::parse::token::special_idents;
3435
use syntax::{ast, visit};
3536

3637
pub type parent = Option<ast::node_id>;
@@ -546,29 +547,20 @@ pub impl DetermineRpCtxt {
546547
// with &self type, &self is also bound. We detect those last two
547548
// cases via flags (anon_implies_rp and self_implies_rp) that are
548549
// true when the anon or self region implies RP.
549-
fn region_is_relevant(&self, r: @ast::region) -> bool {
550-
match r.node {
551-
ast::re_static => false,
552-
ast::re_anon => self.anon_implies_rp,
553-
ast::re_self => self.self_implies_rp,
554-
ast::re_named(_) => false
555-
}
556-
}
557-
558-
// For named types like Foo, if there is no explicit region
559-
// parameter, then we will add the anonymous region, so there is
560-
// a dependency if the anonymous region implies rp.
561-
//
562-
// If the region is explicitly specified, then we follows the
563-
// normal rules.
564-
fn opt_region_is_relevant(&self,
565-
opt_r: Option<@ast::region>)
566-
-> bool {
567-
debug!("opt_region_is_relevant: %? (anon_implies_rp=%b)",
568-
opt_r, self.anon_implies_rp);
569-
match opt_r {
570-
None => self.anon_implies_rp,
571-
Some(r) => self.region_is_relevant(r)
550+
fn region_is_relevant(&self, r: Option<@ast::Lifetime>) -> bool {
551+
match r {
552+
None => {
553+
self.anon_implies_rp
554+
}
555+
Some(ref l) if l.ident == special_idents::static => {
556+
false
557+
}
558+
Some(ref l) if l.ident == special_idents::self_ => {
559+
self.self_implies_rp
560+
}
561+
Some(_) => {
562+
false
563+
}
572564
}
573565
}
574566

@@ -672,8 +664,8 @@ pub fn determine_rp_in_ty(ty: @ast::Ty,
672664
debug!("referenced fn type: %s",
673665
pprust::ty_to_str(ty, sess.intr()));
674666
match f.region {
675-
Some(r) => {
676-
if cx.region_is_relevant(r) {
667+
Some(_) => {
668+
if cx.region_is_relevant(f.region) {
677669
cx.add_rp(cx.item_id,
678670
cx.add_variance(rv_contravariant))
679671
}
@@ -699,7 +691,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty,
699691
match cx.def_map.find(&id) {
700692
Some(ast::def_ty(did)) | Some(ast::def_struct(did)) => {
701693
if did.crate == ast::local_crate {
702-
if cx.opt_region_is_relevant(path.rp) {
694+
if cx.region_is_relevant(path.rp) {
703695
cx.add_dep(did.node);
704696
}
705697
} else {
@@ -709,7 +701,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty,
709701
Some(variance) => {
710702
debug!("reference to external, rp'd type %s",
711703
pprust::ty_to_str(ty, sess.intr()));
712-
if cx.opt_region_is_relevant(path.rp) {
704+
if cx.region_is_relevant(path.rp) {
713705
cx.add_rp(cx.item_id, cx.add_variance(variance))
714706
}
715707
}

src/librustc/middle/typeck/astconv.rs

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ use core::result;
6565
use core::vec;
6666
use syntax::ast;
6767
use syntax::codemap::span;
68-
use syntax::print::pprust::{region_to_str, path_to_str};
68+
use syntax::print::pprust::{lifetime_to_str, path_to_str};
69+
use syntax::parse::token::special_idents;
6970
use util::common::indenter;
7071

7172
pub trait AstConv {
@@ -79,21 +80,16 @@ pub trait AstConv {
7980
pub fn get_region_reporting_err(
8081
tcx: ty::ctxt,
8182
span: span,
82-
a_r: Option<@ast::region>,
83+
a_r: Option<@ast::Lifetime>,
8384
res: Result<ty::Region, RegionError>) -> ty::Region
8485
{
8586
match res {
8687
result::Ok(r) => r,
8788
result::Err(ref e) => {
8889
let descr = match a_r {
8990
None => ~"anonymous lifetime",
90-
Some(a) if a.node == ast::re_anon => {
91-
~"anonymous lifetime"
92-
}
93-
Some(a) => {
94-
fmt!("lifetime %s",
95-
region_to_str(a, tcx.sess.intr()))
96-
}
91+
Some(a) => fmt!("lifetime %s",
92+
lifetime_to_str(a, tcx.sess.intr()))
9793
};
9894
tcx.sess.span_err(
9995
span,
@@ -105,19 +101,28 @@ pub fn get_region_reporting_err(
105101
}
106102

107103
pub fn ast_region_to_region<AC:AstConv,RS:region_scope + Copy + Durable>(
108-
self: &AC,
109-
rscope: &RS,
110-
span: span,
111-
a_r: @ast::region)
112-
-> ty::Region {
113-
let res = match a_r.node {
114-
ast::re_static => Ok(ty::re_static),
115-
ast::re_anon => rscope.anon_region(span),
116-
ast::re_self => rscope.self_region(span),
117-
ast::re_named(id) => rscope.named_region(span, id)
104+
self: &AC,
105+
rscope: &RS,
106+
default_span: span,
107+
opt_lifetime: Option<@ast::Lifetime>) -> ty::Region
108+
{
109+
let (span, res) = match opt_lifetime {
110+
None => {
111+
(default_span, rscope.anon_region(default_span))
112+
}
113+
Some(ref lifetime) if lifetime.ident == special_idents::static => {
114+
(lifetime.span, Ok(ty::re_static))
115+
}
116+
Some(ref lifetime) if lifetime.ident == special_idents::self_ => {
117+
(lifetime.span, rscope.self_region(lifetime.span))
118+
}
119+
Some(ref lifetime) => {
120+
(lifetime.span, rscope.named_region(lifetime.span,
121+
lifetime.ident))
122+
}
118123
};
119124

120-
get_region_reporting_err(self.tcx(), span, Some(a_r), res)
125+
get_region_reporting_err(self.tcx(), span, opt_lifetime, res)
121126
}
122127

123128
pub fn ast_path_to_substs_and_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
@@ -156,8 +161,8 @@ pub fn ast_path_to_substs_and_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
156161
let r = get_region_reporting_err(self.tcx(), path.span, None, res);
157162
Some(r)
158163
}
159-
(Some(_), Some(r)) => {
160-
Some(ast_region_to_region(self, rscope, path.span, r))
164+
(Some(_), Some(_)) => {
165+
Some(ast_region_to_region(self, rscope, path.span, path.rp))
161166
}
162167
};
163168

@@ -504,7 +509,7 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
504509
sigil: ast::Sigil,
505510
purity: ast::purity,
506511
onceness: ast::Onceness,
507-
opt_region: Option<@ast::region>,
512+
opt_lifetime: Option<@ast::Lifetime>,
508513
decl: &ast::fn_decl,
509514
expected_tys: Option<ty::FnSig>,
510515
span: span)
@@ -514,9 +519,9 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
514519

515520
// resolve the function bound region in the original region
516521
// scope `rscope`, not the scope of the function parameters
517-
let bound_region = match opt_region {
518-
Some(region) => {
519-
ast_region_to_region(self, rscope, span, region)
522+
let bound_region = match opt_lifetime {
523+
Some(_) => {
524+
ast_region_to_region(self, rscope, span, opt_lifetime)
520525
}
521526
None => {
522527
match sigil {
@@ -526,9 +531,8 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
526531
ty::re_static
527532
}
528533
ast::BorrowedSigil => {
529-
// &fn() defaults to an anonymous region:
530-
let r_result = rscope.anon_region(span);
531-
get_region_reporting_err(self.tcx(), span, None, r_result)
534+
// &fn() defaults as normal for an omitted lifetime:
535+
ast_region_to_region(self, rscope, span, opt_lifetime)
532536
}
533537
}
534538
}

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2950,19 +2950,19 @@ pub fn instantiate_path(fcx: @mut FnCtxt,
29502950
// determine the region bound, using the value given by the user
29512951
// (if any) and otherwise using a fresh region variable
29522952
let self_r = match pth.rp {
2953-
Some(r) => {
2953+
Some(_) => { // user supplied a lifetime parameter...
29542954
match tpt.region_param {
2955-
None => {
2955+
None => { // ...but the type is not lifetime parameterized!
29562956
fcx.ccx.tcx.sess.span_err
29572957
(span, ~"this item is not region-parameterized");
29582958
None
29592959
}
2960-
Some(_) => {
2961-
Some(ast_region_to_region(fcx, fcx, span, r))
2960+
Some(_) => { // ...and the type is lifetime parameterized, ok.
2961+
Some(ast_region_to_region(fcx, fcx, span, pth.rp))
29622962
}
29632963
}
29642964
}
2965-
None => {
2965+
None => { // no lifetime parameter supplied, insert default
29662966
fcx.region_var_if_parameterized(
29672967
tpt.region_param, span, region_lb)
29682968
}

src/libsyntax/ast.rs

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ pub struct path {
116116
span: span,
117117
global: bool,
118118
idents: ~[ident],
119-
rp: Option<@region>,
119+
rp: Option<@Lifetime>,
120120
types: ~[@Ty],
121121
}
122122
@@ -374,10 +374,10 @@ impl ToStr for Sigil {
374374
#[deriving_eq]
375375
pub enum vstore {
376376
// FIXME (#3469): Change uint to @expr (actually only constant exprs)
377-
vstore_fixed(Option<uint>), // [1,2,3,4]
378-
vstore_uniq, // ~[1,2,3,4]
379-
vstore_box, // @[1,2,3,4]
380-
vstore_slice(@region) // &[1,2,3,4](foo)?
377+
vstore_fixed(Option<uint>), // [1,2,3,4]
378+
vstore_uniq, // ~[1,2,3,4]
379+
vstore_box, // @[1,2,3,4]
380+
vstore_slice(Option<@Lifetime>) // &'foo? [1,2,3,4]
381381
}
382382
383383
#[auto_encode]
@@ -857,24 +857,6 @@ pub enum prim_ty {
857857
ty_bool,
858858
}
859859
860-
#[auto_encode]
861-
#[auto_decode]
862-
#[deriving_eq]
863-
pub struct region {
864-
id: node_id,
865-
node: region_,
866-
}
867-
868-
#[auto_encode]
869-
#[auto_decode]
870-
#[deriving_eq]
871-
pub enum region_ {
872-
re_anon,
873-
re_static,
874-
re_self,
875-
re_named(ident)
876-
}
877-
878860
#[auto_encode]
879861
#[auto_decode]
880862
#[deriving_eq]
@@ -903,7 +885,7 @@ impl to_bytes::IterBytes for Onceness {
903885
#[deriving_eq]
904886
pub struct TyClosure {
905887
sigil: Sigil,
906-
region: Option<@region>,
888+
region: Option<@Lifetime>,
907889
purity: purity,
908890
onceness: Onceness,
909891
decl: fn_decl
@@ -929,7 +911,7 @@ pub enum ty_ {
929911
ty_vec(mt),
930912
ty_fixed_length_vec(mt, uint),
931913
ty_ptr(mt),
932-
ty_rptr(@region, mt),
914+
ty_rptr(Option<@Lifetime>, mt),
933915
ty_closure(@TyClosure),
934916
ty_bare_fn(@TyBareFn),
935917
ty_tup(~[@Ty]),

src/libsyntax/ext/auto_encode.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -594,10 +594,7 @@ fn mk_ser_method(
594594
let ty_s = @ast::Ty {
595595
id: cx.next_id(),
596596
node: ast::ty_rptr(
597-
@ast::region {
598-
id: cx.next_id(),
599-
node: ast::re_anon,
600-
},
597+
None,
601598
ast::mt {
602599
ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]),
603600
mutbl: ast::m_imm
@@ -658,10 +655,7 @@ fn mk_deser_method(
658655
let ty_d = @ast::Ty {
659656
id: cx.next_id(),
660657
node: ast::ty_rptr(
661-
@ast::region {
662-
id: cx.next_id(),
663-
node: ast::re_anon,
664-
},
658+
None,
665659
ast::mt {
666660
ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]),
667661
mutbl: ast::m_imm

src/libsyntax/ext/deriving.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_};
1919
use ast::{item_enum, item_impl, item_struct, Generics};
2020
use ast::{m_imm, meta_item, method};
2121
use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn};
22-
use ast::{re_anon, stmt, struct_def, struct_variant_kind};
22+
use ast::{stmt, struct_def, struct_variant_kind};
2323
use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam};
2424
use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant};
2525
use ext::base::ext_ctxt;
@@ -147,9 +147,8 @@ fn create_eq_method(cx: ext_ctxt,
147147
span,
148148
type_ident,
149149
generics);
150-
let arg_region = @ast::region { id: cx.next_id(), node: re_anon };
151150
let arg_type = ty_rptr(
152-
arg_region,
151+
None,
153152
ast::mt { ty: arg_path_type, mutbl: m_imm }
154153
);
155154
let arg_type = @ast::Ty {

src/libsyntax/parse/obsolete.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ pub enum ObsoleteSyntax {
5252
ObsoleteRecordType,
5353
ObsoleteRecordPattern,
5454
ObsoleteAssertion,
55+
ObsoletePostFnTySigil,
5556
}
5657

5758
impl to_bytes::IterBytes for ObsoleteSyntax {
@@ -160,6 +161,11 @@ pub impl Parser {
160161
"assertion",
161162
"use `fail_unless!()` instead"
162163
),
164+
ObsoletePostFnTySigil => (
165+
"fn sigil in postfix position",
166+
"Rather than `fn@`, `fn~`, or `fn&`, \
167+
write `@fn`, `~fn`, and `&fn` respectively"
168+
),
163169
};
164170

165171
self.report(sp, kind, kind_str, desc);

0 commit comments

Comments
 (0)