diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 12c08ffb43585..a96ed9b8fa6da 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -31,6 +31,7 @@ use std::oldmap::HashMap; use syntax::ast_map; use syntax::codemap::span; use syntax::print::pprust; +use syntax::parse::token::special_idents; use syntax::{ast, visit}; pub type parent = Option; @@ -546,29 +547,20 @@ pub impl DetermineRpCtxt { // with &self type, &self is also bound. We detect those last two // cases via flags (anon_implies_rp and self_implies_rp) that are // true when the anon or self region implies RP. - fn region_is_relevant(&self, r: @ast::region) -> bool { - match r.node { - ast::re_static => false, - ast::re_anon => self.anon_implies_rp, - ast::re_self => self.self_implies_rp, - ast::re_named(_) => false - } - } - - // For named types like Foo, if there is no explicit region - // parameter, then we will add the anonymous region, so there is - // a dependency if the anonymous region implies rp. - // - // If the region is explicitly specified, then we follows the - // normal rules. - fn opt_region_is_relevant(&self, - opt_r: Option<@ast::region>) - -> bool { - debug!("opt_region_is_relevant: %? (anon_implies_rp=%b)", - opt_r, self.anon_implies_rp); - match opt_r { - None => self.anon_implies_rp, - Some(r) => self.region_is_relevant(r) + fn region_is_relevant(&self, r: Option<@ast::Lifetime>) -> bool { + match r { + None => { + self.anon_implies_rp + } + Some(ref l) if l.ident == special_idents::static => { + false + } + Some(ref l) if l.ident == special_idents::self_ => { + self.self_implies_rp + } + Some(_) => { + false + } } } @@ -672,8 +664,8 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, debug!("referenced fn type: %s", pprust::ty_to_str(ty, sess.intr())); match f.region { - Some(r) => { - if cx.region_is_relevant(r) { + Some(_) => { + if cx.region_is_relevant(f.region) { cx.add_rp(cx.item_id, cx.add_variance(rv_contravariant)) } @@ -699,7 +691,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, match cx.def_map.find(&id) { Some(ast::def_ty(did)) | Some(ast::def_struct(did)) => { if did.crate == ast::local_crate { - if cx.opt_region_is_relevant(path.rp) { + if cx.region_is_relevant(path.rp) { cx.add_dep(did.node); } } else { @@ -709,7 +701,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty, Some(variance) => { debug!("reference to external, rp'd type %s", pprust::ty_to_str(ty, sess.intr())); - if cx.opt_region_is_relevant(path.rp) { + if cx.region_is_relevant(path.rp) { cx.add_rp(cx.item_id, cx.add_variance(variance)) } } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index 0b6c07832f634..8152200bf0476 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -65,7 +65,8 @@ use core::result; use core::vec; use syntax::ast; use syntax::codemap::span; -use syntax::print::pprust::{region_to_str, path_to_str}; +use syntax::print::pprust::{lifetime_to_str, path_to_str}; +use syntax::parse::token::special_idents; use util::common::indenter; pub trait AstConv { @@ -79,7 +80,7 @@ pub trait AstConv { pub fn get_region_reporting_err( tcx: ty::ctxt, span: span, - a_r: Option<@ast::region>, + a_r: Option<@ast::Lifetime>, res: Result) -> ty::Region { match res { @@ -87,13 +88,8 @@ pub fn get_region_reporting_err( result::Err(ref e) => { let descr = match a_r { None => ~"anonymous lifetime", - Some(a) if a.node == ast::re_anon => { - ~"anonymous lifetime" - } - Some(a) => { - fmt!("lifetime %s", - region_to_str(a, tcx.sess.intr())) - } + Some(a) => fmt!("lifetime %s", + lifetime_to_str(a, tcx.sess.intr())) }; tcx.sess.span_err( span, @@ -105,19 +101,28 @@ pub fn get_region_reporting_err( } pub fn ast_region_to_region( - self: &AC, - rscope: &RS, - span: span, - a_r: @ast::region) - -> ty::Region { - let res = match a_r.node { - ast::re_static => Ok(ty::re_static), - ast::re_anon => rscope.anon_region(span), - ast::re_self => rscope.self_region(span), - ast::re_named(id) => rscope.named_region(span, id) + self: &AC, + rscope: &RS, + default_span: span, + opt_lifetime: Option<@ast::Lifetime>) -> ty::Region +{ + let (span, res) = match opt_lifetime { + None => { + (default_span, rscope.anon_region(default_span)) + } + Some(ref lifetime) if lifetime.ident == special_idents::static => { + (lifetime.span, Ok(ty::re_static)) + } + Some(ref lifetime) if lifetime.ident == special_idents::self_ => { + (lifetime.span, rscope.self_region(lifetime.span)) + } + Some(ref lifetime) => { + (lifetime.span, rscope.named_region(lifetime.span, + lifetime.ident)) + } }; - get_region_reporting_err(self.tcx(), span, Some(a_r), res) + get_region_reporting_err(self.tcx(), span, opt_lifetime, res) } pub fn ast_path_to_substs_and_ty( @@ -156,8 +161,8 @@ pub fn ast_path_to_substs_and_ty( let r = get_region_reporting_err(self.tcx(), path.span, None, res); Some(r) } - (Some(_), Some(r)) => { - Some(ast_region_to_region(self, rscope, path.span, r)) + (Some(_), Some(_)) => { + Some(ast_region_to_region(self, rscope, path.span, path.rp)) } }; @@ -504,7 +509,7 @@ pub fn ty_of_closure( sigil: ast::Sigil, purity: ast::purity, onceness: ast::Onceness, - opt_region: Option<@ast::region>, + opt_lifetime: Option<@ast::Lifetime>, decl: &ast::fn_decl, expected_tys: Option, span: span) @@ -514,9 +519,9 @@ pub fn ty_of_closure( // resolve the function bound region in the original region // scope `rscope`, not the scope of the function parameters - let bound_region = match opt_region { - Some(region) => { - ast_region_to_region(self, rscope, span, region) + let bound_region = match opt_lifetime { + Some(_) => { + ast_region_to_region(self, rscope, span, opt_lifetime) } None => { match sigil { @@ -526,9 +531,8 @@ pub fn ty_of_closure( ty::re_static } ast::BorrowedSigil => { - // &fn() defaults to an anonymous region: - let r_result = rscope.anon_region(span); - get_region_reporting_err(self.tcx(), span, None, r_result) + // &fn() defaults as normal for an omitted lifetime: + ast_region_to_region(self, rscope, span, opt_lifetime) } } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 6efa62c55cc24..0798e2b7afe6e 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2950,19 +2950,19 @@ pub fn instantiate_path(fcx: @mut FnCtxt, // determine the region bound, using the value given by the user // (if any) and otherwise using a fresh region variable let self_r = match pth.rp { - Some(r) => { + Some(_) => { // user supplied a lifetime parameter... match tpt.region_param { - None => { + None => { // ...but the type is not lifetime parameterized! fcx.ccx.tcx.sess.span_err (span, ~"this item is not region-parameterized"); None } - Some(_) => { - Some(ast_region_to_region(fcx, fcx, span, r)) + Some(_) => { // ...and the type is lifetime parameterized, ok. + Some(ast_region_to_region(fcx, fcx, span, pth.rp)) } } } - None => { + None => { // no lifetime parameter supplied, insert default fcx.region_var_if_parameterized( tpt.region_param, span, region_lb) } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a6ccd69dd0655..3782208eb851c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -116,7 +116,7 @@ pub struct path { span: span, global: bool, idents: ~[ident], - rp: Option<@region>, + rp: Option<@Lifetime>, types: ~[@Ty], } @@ -374,10 +374,10 @@ impl ToStr for Sigil { #[deriving_eq] pub enum vstore { // FIXME (#3469): Change uint to @expr (actually only constant exprs) - vstore_fixed(Option), // [1,2,3,4] - vstore_uniq, // ~[1,2,3,4] - vstore_box, // @[1,2,3,4] - vstore_slice(@region) // &[1,2,3,4](foo)? + vstore_fixed(Option), // [1,2,3,4] + vstore_uniq, // ~[1,2,3,4] + vstore_box, // @[1,2,3,4] + vstore_slice(Option<@Lifetime>) // &'foo? [1,2,3,4] } #[auto_encode] @@ -857,24 +857,6 @@ pub enum prim_ty { ty_bool, } -#[auto_encode] -#[auto_decode] -#[deriving_eq] -pub struct region { - id: node_id, - node: region_, -} - -#[auto_encode] -#[auto_decode] -#[deriving_eq] -pub enum region_ { - re_anon, - re_static, - re_self, - re_named(ident) -} - #[auto_encode] #[auto_decode] #[deriving_eq] @@ -903,7 +885,7 @@ impl to_bytes::IterBytes for Onceness { #[deriving_eq] pub struct TyClosure { sigil: Sigil, - region: Option<@region>, + region: Option<@Lifetime>, purity: purity, onceness: Onceness, decl: fn_decl @@ -929,7 +911,7 @@ pub enum ty_ { ty_vec(mt), ty_fixed_length_vec(mt, uint), ty_ptr(mt), - ty_rptr(@region, mt), + ty_rptr(Option<@Lifetime>, mt), ty_closure(@TyClosure), ty_bare_fn(@TyBareFn), ty_tup(~[@Ty]), diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs index 644afaff37c5c..ecb5be6cc3c61 100644 --- a/src/libsyntax/ext/auto_encode.rs +++ b/src/libsyntax/ext/auto_encode.rs @@ -594,10 +594,7 @@ fn mk_ser_method( let ty_s = @ast::Ty { id: cx.next_id(), node: ast::ty_rptr( - @ast::region { - id: cx.next_id(), - node: ast::re_anon, - }, + None, ast::mt { ty: cx.ty_path(span, ~[cx.ident_of(~"__S")], ~[]), mutbl: ast::m_imm @@ -658,10 +655,7 @@ fn mk_deser_method( let ty_d = @ast::Ty { id: cx.next_id(), node: ast::ty_rptr( - @ast::region { - id: cx.next_id(), - node: ast::re_anon, - }, + None, ast::mt { ty: cx.ty_path(span, ~[cx.ident_of(~"__D")], ~[]), mutbl: ast::m_imm diff --git a/src/libsyntax/ext/deriving.rs b/src/libsyntax/ext/deriving.rs index a1514bc3eabdb..efea962a0892d 100644 --- a/src/libsyntax/ext/deriving.rs +++ b/src/libsyntax/ext/deriving.rs @@ -19,7 +19,7 @@ use ast::{enum_variant_kind, expr, expr_match, ident, impure_fn, item, item_}; use ast::{item_enum, item_impl, item_struct, Generics}; use ast::{m_imm, meta_item, method}; use ast::{named_field, or, pat, pat_ident, pat_wild, public, pure_fn}; -use ast::{re_anon, stmt, struct_def, struct_variant_kind}; +use ast::{stmt, struct_def, struct_variant_kind}; use ast::{sty_by_ref, sty_region, tuple_variant_kind, ty_nil, TyParam}; use ast::{TyParamBound, ty_path, ty_rptr, unnamed_field, variant}; use ext::base::ext_ctxt; @@ -147,9 +147,8 @@ fn create_eq_method(cx: ext_ctxt, span, type_ident, generics); - let arg_region = @ast::region { id: cx.next_id(), node: re_anon }; let arg_type = ty_rptr( - arg_region, + None, ast::mt { ty: arg_path_type, mutbl: m_imm } ); let arg_type = @ast::Ty { diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs index 6f2d2c554aa93..97ff175da07fe 100644 --- a/src/libsyntax/parse/obsolete.rs +++ b/src/libsyntax/parse/obsolete.rs @@ -52,6 +52,7 @@ pub enum ObsoleteSyntax { ObsoleteRecordType, ObsoleteRecordPattern, ObsoleteAssertion, + ObsoletePostFnTySigil, } impl to_bytes::IterBytes for ObsoleteSyntax { @@ -160,6 +161,11 @@ pub impl Parser { "assertion", "use `fail_unless!()` instead" ), + ObsoletePostFnTySigil => ( + "fn sigil in postfix position", + "Rather than `fn@`, `fn~`, or `fn&`, \ + write `@fn`, `~fn`, and `&fn` respectively" + ), }; self.report(sp, kind, kind_str, desc); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 384cf4f0e9517..adcaa006247fa 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -14,7 +14,7 @@ use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil, RustAbi}; use ast::{CallSugar, NoSugar, DoSugar, ForSugar}; use ast::{TyBareFn, TyClosure}; use ast::{RegionTyParamBound, TraitTyParamBound}; -use ast::{provided, public, pure_fn, purity, re_static}; +use ast::{provided, public, pure_fn, purity}; use ast::{_mod, add, arg, arm, attribute, bind_by_ref, bind_infer}; use ast::{bind_by_copy, bitand, bitor, bitxor, blk}; use ast::{blk_check_mode, box, by_copy, by_ref, by_val}; @@ -40,9 +40,9 @@ use ast::{lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, m_const}; use ast::{m_imm, m_mutbl, mac_, mac_invoc_tt, matcher, match_nonterminal}; use ast::{match_seq, match_tok, method, mode, module_ns, mt, mul, mutability}; use ast::{named_field, neg, node_id, noreturn, not, pat, pat_box, pat_enum}; -use ast::{pat_ident, pat_lit, pat_range, pat_region, pat_struct, pat_tup}; -use ast::{pat_uniq, pat_wild, path, private}; -use ast::{re_self, re_anon, re_named, region, rem, required}; +use ast::{pat_ident, pat_lit, pat_range, pat_region, pat_struct}; +use ast::{pat_tup, pat_uniq, pat_wild, path, private}; +use ast::{rem, required}; use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl}; use ast::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field}; use ast::{struct_immutable, struct_mutable, struct_variant_kind, subtract}; @@ -76,7 +76,7 @@ use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax}; use parse::obsolete::{ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer}; use parse::obsolete::{ObsoleteMutVector, ObsoleteTraitImplVisibility}; use parse::obsolete::{ObsoleteRecordType, ObsoleteRecordPattern}; -use parse::obsolete::{ObsoleteAssertion}; +use parse::obsolete::{ObsoleteAssertion, ObsoletePostFnTySigil}; use parse::prec::{as_prec, token_to_binop}; use parse::token::{can_begin_expr, is_ident, is_ident_or_path}; use parse::token::{is_plain_ident, INTERPOLATED, special_idents}; @@ -363,12 +363,13 @@ pub impl Parser { }); } - fn parse_ty_closure(&self, pre_sigil: Option, - pre_region_name: Option) -> ty_ + fn parse_ty_closure(&self, + sigil: ast::Sigil, + region: Option<@ast::Lifetime>) -> ty_ { /* - (&|~|@) [r/] [pure|unsafe] [once] fn <'lt> (S) -> T + (&|~|@) ['r] [pure|unsafe] [once] fn <'lt> (S) -> T ^~~~~~^ ^~~^ ^~~~~~~~~~~~^ ^~~~~^ ^~~~^ ^~^ ^ | | | | | | | | | | | | | Return type @@ -388,13 +389,10 @@ pub impl Parser { let onceness = parse_onceness(self); self.expect_keyword(&~"fn"); - let sigil = match pre_sigil { None => BorrowedSigil, Some(p) => p }; - - let region = if pre_region_name.is_some() { - Some(self.region_from_name(pre_region_name)) - } else { - None - }; + if self.parse_fn_ty_sigil().is_some() { + self.obsolete(*self.span, + ObsoletePostFnTySigil); + } return ty_closure(@TyClosure { sigil: sigil, @@ -432,7 +430,7 @@ pub impl Parser { */ if self.eat(&token::LT) { let _lifetimes = self.parse_lifetimes(); - self.expect(&token::GT); + self.expect_gt(); } let inputs = self.parse_unspanned_seq( &token::LPAREN, @@ -575,38 +573,6 @@ pub impl Parser { } } - fn region_from_name(&self, s: Option) -> @region { - let r = match s { - Some(id) if id == special_idents::static => ast::re_static, - Some(id) if id == special_idents::self_ => re_self, - Some(id) => re_named(id), - None => re_anon - }; - - @ast::region { id: self.get_id(), node: r } - } - - // Parses something like "&x" - fn parse_region(&self) -> @region { - self.expect(&token::BINOP(token::AND)); - - match *self.token { - token::IDENT(sid, _) => { - self.bump(); - self.region_from_name(Some(sid)) - } - _ => { - self.region_from_name(None) - } - } - } - - fn region_from_lifetime(&self, l: &ast::Lifetime) -> @region { - // eventually `ast::region` should go away in favor of - // `ast::Lifetime`. For now we convert between them. - self.region_from_name(Some(l.ident)) - } - fn parse_ty(&self, colons_before_params: bool) -> @Ty { maybe_whole!(self, nt_ty); @@ -681,7 +647,8 @@ pub impl Parser { } else if self.eat_keyword(&~"extern") { self.parse_ty_bare_fn() } else if self.token_is_closure_keyword(© *self.token) { - self.parse_ty_closure(None, None) + // self.warn(fmt!("Old-school closure keyword")); + self.parse_ty_closure(ast::BorrowedSigil, None) } else if *self.token == token::MOD_SEP || is_ident_or_path(&*self.token) { let path = self.parse_path_with_tps(colons_before_params); @@ -701,20 +668,20 @@ pub impl Parser { { // @'foo fn() or @foo/fn() or @fn() are parsed directly as fn types: match *self.token { - token::LIFETIME(rname) => { + token::LIFETIME(*) => { + let lifetime = @self.parse_lifetime(); self.bump(); - return self.parse_ty_closure(Some(sigil), Some(rname)); + return self.parse_ty_closure(sigil, Some(lifetime)); } - token::IDENT(rname, _) => { + token::IDENT(*) => { if self.look_ahead(1u) == token::BINOP(token::SLASH) && self.token_is_closure_keyword(&self.look_ahead(2u)) { - self.bump(); - self.bump(); - return self.parse_ty_closure(Some(sigil), Some(rname)); + let lifetime = @self.parse_lifetime(); + return self.parse_ty_closure(sigil, Some(lifetime)); } else if self.token_is_closure_keyword(© *self.token) { - return self.parse_ty_closure(Some(sigil), None); + return self.parse_ty_closure(sigil, None); } } _ => {} @@ -735,31 +702,14 @@ pub impl Parser { fn parse_borrowed_pointee(&self) -> ty_ { // look for `&'lt` or `&foo/` and interpret `foo` as the region name: - let rname = match *self.token { - token::LIFETIME(sid) => { - self.bump(); - Some(sid) - } - - token::IDENT(sid, _) => { - if self.look_ahead(1u) == token::BINOP(token::SLASH) { - self.bump(); self.bump(); - Some(sid) - } else { - None - } - } - - _ => { None } - }; + let opt_lifetime = self.parse_opt_lifetime(); if self.token_is_closure_keyword(© *self.token) { - return self.parse_ty_closure(Some(BorrowedSigil), rname); + return self.parse_ty_closure(BorrowedSigil, opt_lifetime); } - let r = self.region_from_name(rname); let mt = self.parse_mt(); - return ty_rptr(r, mt); + return ty_rptr(opt_lifetime, mt); } fn parse_arg_mode(&self) -> mode { @@ -939,19 +889,27 @@ pub impl Parser { return path; } - // Parse the region parameter, if any, which will + // Parse the (obsolete) trailing region parameter, if any, which will // be written "foo/&x" let rp_slash = { - // Hack: avoid parsing vstores like /@ and /~. This is painful - // because the notation for region bounds and the notation for - // vstores is... um... the same. I guess that's my fault. This - // is still not ideal as for &str we end up parsing more than we - // ought to and have to sort it out later. if *self.token == token::BINOP(token::SLASH) - && self.look_ahead(1u) == token::BINOP(token::AND) { - - self.expect(&token::BINOP(token::SLASH)); - Some(self.parse_region()) + && self.look_ahead(1u) == token::BINOP(token::AND) + { + self.bump(); self.bump(); + match *self.token { + token::IDENT(sid, _) => { + let span = copy self.span; + self.bump(); + Some(@ast::Lifetime { + id: self.get_id(), + span: *span, + ident: sid + }) + } + _ => { + self.fatal(fmt!("Expected a lifetime name")); + } + } } else { None } @@ -967,7 +925,7 @@ pub impl Parser { if v.len() == 0 { None } else if v.len() == 1 { - Some(self.region_from_lifetime(v.get(0))) + Some(@*v.get(0)) } else { self.fatal(fmt!("Expected at most one \ lifetime name (for now)")); @@ -981,16 +939,26 @@ pub impl Parser { .. copy *path } } - fn parse_opt_lifetime(&self) -> Option { + fn parse_opt_lifetime(&self) -> Option<@ast::Lifetime> { /*! * * Parses 0 or 1 lifetime. */ match *self.token { - token::LIFETIME(_) => { - Some(self.parse_lifetime()) + token::LIFETIME(*) => { + Some(@self.parse_lifetime()) + } + + // Also accept the (obsolete) syntax `foo/` + token::IDENT(*) => { + if self.look_ahead(1u) == token::BINOP(token::SLASH) { + Some(@self.parse_lifetime()) + } else { + None + } } + _ => { None } @@ -1005,13 +973,27 @@ pub impl Parser { match *self.token { token::LIFETIME(i) => { + let span = copy self.span; + self.bump(); + return ast::Lifetime { + id: self.get_id(), + span: *span, + ident: i + }; + } + + // Also accept the (obsolete) syntax `foo/` + token::IDENT(i, _) => { + let span = copy self.span; self.bump(); + self.expect(&token::BINOP(token::SLASH)); return ast::Lifetime { id: self.get_id(), - span: *self.span, + span: *span, ident: i }; } + _ => { self.fatal(fmt!("Expected a lifetime name")); } @@ -1041,6 +1023,7 @@ pub impl Parser { match *self.token { token::COMMA => { self.bump();} token::GT => { return res; } + token::BINOP(token::SHR) => { return res; } _ => { self.fatal(~"expected `,` or `>` after lifetime name"); } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c68341c20fa4c..3744b7a8f6c03 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -146,8 +146,8 @@ pub fn expr_to_str(e: @ast::expr, intr: @ident_interner) -> ~str { to_str(e, print_expr, intr) } -pub fn region_to_str(e: @ast::region, intr: @ident_interner) -> ~str { - to_str(e, |s, e| print_region(s, ~"&", e, ~""), intr) +pub fn lifetime_to_str(e: &ast::Lifetime, intr: @ident_interner) -> ~str { + to_str(e, print_lifetime, intr) } pub fn tt_to_str(tt: ast::token_tree, intr: @ident_interner) -> ~str { @@ -355,23 +355,11 @@ pub fn print_foreign_mod(s: @ps, nmod: ast::foreign_mod, for nmod.items.each |item| { print_foreign_item(s, *item); } } -pub fn print_region(s: @ps, prefix: ~str, region: @ast::region, sep: ~str) { - word(s.s, prefix); - match region.node { - ast::re_anon => { - return; - } - ast::re_static => { - word_space(s, ~"static") - } - ast::re_self => { - word_space(s, ~"self") - } - ast::re_named(name) => { - print_ident(s, name); - } +pub fn print_opt_lifetime(s: @ps, lifetime: Option<@ast::Lifetime>) { + for lifetime.each |l| { + print_lifetime(s, *l); + nbsp(s); } - word(s.s, sep); } pub fn print_type(s: @ps, &&ty: @ast::Ty) { @@ -397,8 +385,9 @@ pub fn print_type_ex(s: @ps, &&ty: @ast::Ty, print_colons: bool) { word(s.s, ~"]"); } ast::ty_ptr(mt) => { word(s.s, ~"*"); print_mt(s, mt); } - ast::ty_rptr(region, mt) => { - print_region(s, ~"&", region, ~"/"); + ast::ty_rptr(lifetime, mt) => { + word(s.s, ~"&"); + print_opt_lifetime(s, lifetime); print_mt(s, mt); } ast::ty_tup(elts) => { @@ -1048,7 +1037,10 @@ pub fn print_vstore(s: @ps, t: ast::vstore) { ast::vstore_fixed(None) => word(s.s, ~"_"), ast::vstore_uniq => word(s.s, ~"~"), ast::vstore_box => word(s.s, ~"@"), - ast::vstore_slice(r) => print_region(s, ~"&", r, ~"/") + ast::vstore_slice(r) => { + word(s.s, ~"&"); + print_opt_lifetime(s, r); + } } } @@ -1501,17 +1493,18 @@ pub fn print_path(s: @ps, &&path: @ast::path, colons_before_params: bool) { if path.rp.is_some() || !path.types.is_empty() { if colons_before_params { word(s.s, ~"::"); } - match path.rp { - None => { /* ok */ } - Some(r) => { - word(s.s, ~"/"); - print_region(s, ~"&", r, ~""); - } - } - - if !path.types.is_empty() { + if path.rp.is_some() || !path.types.is_empty() { word(s.s, ~"<"); + + for path.rp.each |r| { + print_lifetime(s, *r); + if !path.types.is_empty() { + word_space(s, ~","); + } + } + commasep(s, inconsistent, path.types, print_type); + word(s.s, ~">"); } } @@ -1749,7 +1742,7 @@ pub fn print_bounds(s: @ps, bounds: @OptVec) { } } -pub fn print_lifetime(s: @ps, lifetime: &ast::Lifetime) { +pub fn print_lifetime(s: @ps, &&lifetime: &ast::Lifetime) { word(s.s, ~"'"); print_ident(s, lifetime.ident); } @@ -1908,7 +1901,7 @@ pub fn print_arg(s: @ps, input: ast::arg) { pub fn print_ty_fn(s: @ps, opt_abi: Option, opt_sigil: Option, - opt_region: Option<@ast::region>, + opt_region: Option<@ast::Lifetime>, purity: ast::purity, onceness: ast::Onceness, decl: &ast::fn_decl, id: Option, @@ -1921,7 +1914,7 @@ pub fn print_ty_fn(s: @ps, print_self_ty_if_static(s, opt_self_ty); print_opt_abi(s, opt_abi); print_opt_sigil(s, opt_sigil); - for opt_region.each |r| { print_region(s, ~"", *r, ~"/"); } + print_opt_lifetime(s, opt_region); print_purity(s, purity); print_onceness(s, onceness); word(s.s, ~"fn"); diff --git a/src/test/compile-fail/prim-with-args.rs b/src/test/compile-fail/prim-with-args.rs index be57f88fd0a98..40d5a44124177 100644 --- a/src/test/compile-fail/prim-with-args.rs +++ b/src/test/compile-fail/prim-with-args.rs @@ -23,17 +23,17 @@ let x: u64; //~ ERROR type parameters are not allowed on this type let x: float; //~ ERROR type parameters are not allowed on this type let x: char; //~ ERROR type parameters are not allowed on this type -let x: int/&; //~ ERROR region parameters are not allowed on this type -let x: i8/&; //~ ERROR region parameters are not allowed on this type -let x: i16/&; //~ ERROR region parameters are not allowed on this type -let x: i32/&; //~ ERROR region parameters are not allowed on this type -let x: i64/&; //~ ERROR region parameters are not allowed on this type -let x: uint/&; //~ ERROR region parameters are not allowed on this type -let x: u8/&; //~ ERROR region parameters are not allowed on this type -let x: u16/&; //~ ERROR region parameters are not allowed on this type -let x: u32/&; //~ ERROR region parameters are not allowed on this type -let x: u64/&; //~ ERROR region parameters are not allowed on this type -let x: float/&; //~ ERROR region parameters are not allowed on this type -let x: char/&; //~ ERROR region parameters are not allowed on this type +let x: int<'static>; //~ ERROR region parameters are not allowed on this type +let x: i8<'static>; //~ ERROR region parameters are not allowed on this type +let x: i16<'static>; //~ ERROR region parameters are not allowed on this type +let x: i32<'static>; //~ ERROR region parameters are not allowed on this type +let x: i64<'static>; //~ ERROR region parameters are not allowed on this type +let x: uint<'static>; //~ ERROR region parameters are not allowed on this type +let x: u8<'static>; //~ ERROR region parameters are not allowed on this type +let x: u16<'static>; //~ ERROR region parameters are not allowed on this type +let x: u32<'static>; //~ ERROR region parameters are not allowed on this type +let x: u64<'static>; //~ ERROR region parameters are not allowed on this type +let x: float<'static>; //~ ERROR region parameters are not allowed on this type +let x: char<'static>; //~ ERROR region parameters are not allowed on this type } diff --git a/src/test/compile-fail/regions-in-consts.rs b/src/test/compile-fail/regions-in-consts.rs index 19dea9a57ee49..2ba27e888cbe0 100644 --- a/src/test/compile-fail/regions-in-consts.rs +++ b/src/test/compile-fail/regions-in-consts.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -const c_x: &'blk int = &22; //~ ERROR Illegal lifetime &blk: only 'static is allowed here +const c_x: &'blk int = &22; //~ ERROR Illegal lifetime 'blk: only 'static is allowed here const c_y: &int = &22; //~ ERROR Illegal anonymous lifetime: only 'static is allowed here const c_z: &'static int = &22; diff --git a/src/test/compile-fail/regions-in-enums.rs b/src/test/compile-fail/regions-in-enums.rs index 5c2269977d194..0adfaccdc0174 100644 --- a/src/test/compile-fail/regions-in-enums.rs +++ b/src/test/compile-fail/regions-in-enums.rs @@ -10,7 +10,7 @@ enum yes0<'lt> { // This will eventually be legal (and in fact the only way): - X3(&'lt uint) //~ ERROR Illegal lifetime <: only 'self is allowed allowed as part of a type declaration + X3(&'lt uint) //~ ERROR Illegal lifetime 'lt: only 'self is allowed allowed as part of a type declaration } enum yes1 { @@ -18,7 +18,7 @@ enum yes1 { } enum yes2 { - X5(&'foo uint) //~ ERROR Illegal lifetime &foo: only 'self is allowed allowed as part of a type declaration + X5(&'foo uint) //~ ERROR Illegal lifetime 'foo: only 'self is allowed allowed as part of a type declaration } fn main() {} diff --git a/src/test/compile-fail/regions-in-structs.rs b/src/test/compile-fail/regions-in-structs.rs index 10d7a921ed031..b425a40114a3d 100644 --- a/src/test/compile-fail/regions-in-structs.rs +++ b/src/test/compile-fail/regions-in-structs.rs @@ -17,7 +17,7 @@ struct yes1<'self> { } struct yes2<'self> { - x: &'foo uint, //~ ERROR Illegal lifetime &foo: only 'self is allowed allowed as part of a type declaration + x: &'foo uint, //~ ERROR Illegal lifetime 'foo: only 'self is allowed allowed as part of a type declaration } fn main() {} diff --git a/src/test/compile-fail/regions-infer-not-param.rs b/src/test/compile-fail/regions-infer-not-param.rs index b5f8d99829870..a0ecb08a08957 100644 --- a/src/test/compile-fail/regions-infer-not-param.rs +++ b/src/test/compile-fail/regions-infer-not-param.rs @@ -13,19 +13,16 @@ struct direct<'self> { } struct indirect1 { + // Here the lifetime parameter of direct is bound by the fn() g: @fn(direct) } -struct indirect2 { - g: @fn(direct/&) -} - -struct indirect3 { +struct indirect2<'self> { + // But here it is set to 'self g: @fn(direct<'self>) } fn take_direct(p: direct) -> direct { p } //~ ERROR mismatched types fn take_indirect1(p: indirect1) -> indirect1 { p } -fn take_indirect2(p: indirect2) -> indirect2 { p } -fn take_indirect3(p: indirect3) -> indirect3 { p } //~ ERROR mismatched types +fn take_indirect2(p: indirect2) -> indirect2 { p } //~ ERROR mismatched types fn main() {} diff --git a/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs b/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs index 11414a1110847..fe37d8990985d 100644 --- a/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs +++ b/src/test/compile-fail/regions-infer-region-in-fn-but-not-type.rs @@ -13,7 +13,7 @@ // contains region pointers enum foo = ~fn(x: &int); -fn take_foo(x: foo/&) {} //~ ERROR no region bound is allowed on `foo` +fn take_foo(x: foo<'static>) {} //~ ERROR no region bound is allowed on `foo` fn main() { }