diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 38eccd3593f..54c8acf7626 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1047,7 +1047,12 @@ impl prim_ty : cmp::Eq { type region = {id: node_id, node: region_}; #[auto_serialize] -enum region_ { re_anon, re_named(ident) } +enum region_ { + re_anon, + re_static, + re_self, + re_named(ident) +} #[auto_serialize] enum ty_ { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index c96cfdfe6bc..fa506a062b4 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4,7 +4,7 @@ use result::Result; use either::{Either, Left, Right}; use std::map::{HashMap, str_hash}; use token::{can_begin_expr, is_ident, is_ident_or_path, is_plain_ident, - INTERPOLATED}; + INTERPOLATED, special_idents}; use codemap::{span,fss_none}; use util::interner::interner; use ast_util::{spanned, respan, mk_sp, ident_to_path, operator_prec}; @@ -51,7 +51,8 @@ use ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute, pat_ident, pat_lit, pat_range, pat_rec, pat_region, pat_struct, pat_tup, pat_uniq, pat_wild, path, private, proto, proto_bare, proto_block, proto_box, proto_uniq, provided, public, pure_fn, - purity, re_anon, re_named, region, rem, required, ret_style, + purity, re_static, re_self, re_anon, re_named, region, + rem, required, ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr, stmt_semi, struct_def, struct_field, struct_variant_kind, subtract, sty_box, sty_by_ref, sty_region, sty_static, sty_uniq, @@ -432,8 +433,10 @@ impl parser { fn region_from_name(s: Option) -> @region { let r = match s { - Some (id) => re_named(id), - None => re_anon + 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 }; @{id: self.get_id(), node: r} @@ -614,7 +617,7 @@ impl parser { let name = self.parse_value_ident(); self.bump(); name - } else { token::special_idents::invalid } + } else { special_idents::invalid } }; let t = self.parse_ty(false); @@ -2388,7 +2391,7 @@ impl parser { fn is_self_ident() -> bool { match self.token { - token::IDENT(id, false) if id == token::special_idents::self_ + token::IDENT(id, false) if id == special_idents::self_ => true, _ => false } @@ -2603,7 +2606,7 @@ impl parser { // This is a new-style impl declaration. // XXX: clownshoes - let ident = token::special_idents::clownshoes_extensions; + let ident = special_idents::clownshoes_extensions; // Parse the type. let ty = self.parse_ty(false); @@ -3019,7 +3022,7 @@ impl parser { } (ast::anonymous, - token::special_idents::clownshoes_foreign_mod) + special_idents::clownshoes_foreign_mod) } }; diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 49133242d54..a4e7d12bd21 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -328,14 +328,24 @@ fn print_foreign_mod(s: ps, nmod: ast::foreign_mod, for nmod.items.each |item| { print_foreign_item(s, item); } } -fn print_region(s: ps, region: @ast::region) { +fn print_region(s: ps, region: @ast::region, sep: ~str) { match region.node { - ast::re_anon => word_space(s, ~"&"), - ast::re_named(name) => { - word(s.s, ~"&"); - print_ident(s, name); - } + ast::re_anon => { + word_space(s, ~"&"); + return; + } + ast::re_static => { + word_space(s, ~"&static") + } + ast::re_self => { + word_space(s, ~"&self") + } + ast::re_named(name) => { + word(s.s, ~"&"); + print_ident(s, name); + } } + word(s.s, sep); } fn print_type(s: ps, &&ty: @ast::ty) { @@ -362,11 +372,8 @@ fn print_type_ex(s: ps, &&ty: @ast::ty, print_colons: bool) { } ast::ty_ptr(mt) => { word(s.s, ~"*"); print_mt(s, mt); } ast::ty_rptr(region, mt) => { - match region.node { - ast::re_anon => word(s.s, ~"&"), - _ => { print_region(s, region); word(s.s, ~"/"); } - } - print_mt(s, mt); + print_region(s, region, ~"/"); + print_mt(s, mt); } ast::ty_rec(fields) => { word(s.s, ~"{"); @@ -961,18 +968,11 @@ fn print_mac(s: ps, m: ast::mac) { fn print_vstore(s: ps, t: ast::vstore) { match t { - ast::vstore_fixed(Some(i)) => word(s.s, fmt!("%u", i)), - ast::vstore_fixed(None) => word(s.s, ~"_"), - ast::vstore_uniq => word(s.s, ~"~"), - ast::vstore_box => word(s.s, ~"@"), - ast::vstore_slice(r) => match r.node { - ast::re_anon => word(s.s, ~"&"), - ast::re_named(name) => { - word(s.s, ~"&"); - print_ident(s, name); - word(s.s, ~"."); - } - } + ast::vstore_fixed(Some(i)) => word(s.s, fmt!("%u", i)), + 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, ~"/") } } @@ -1455,7 +1455,7 @@ fn print_path(s: ps, &&path: @ast::path, colons_before_params: bool) { None => { /* ok */ } Some(r) => { word(s.s, ~"/"); - print_region(s, r); + print_region(s, r, ~""); } } diff --git a/src/rustc/middle/region.rs b/src/rustc/middle/region.rs index 5fb17eb15b9..4e1e0decdef 100644 --- a/src/rustc/middle/region.rs +++ b/src/rustc/middle/region.rs @@ -522,10 +522,10 @@ impl determine_rp_ctxt { // that flag to false when we enter a method. fn region_is_relevant(r: @ast::region) -> bool { match r.node { + ast::re_static => false, ast::re_anon => self.anon_implies_rp, - ast::re_named(id) => { - id == syntax::parse::token::special_idents::self_ - } + ast::re_self => true, + ast::re_named(_) => false } } diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs index 79033156d35..620f3cad570 100644 --- a/src/rustc/middle/typeck/astconv.rs +++ b/src/rustc/middle/typeck/astconv.rs @@ -73,8 +73,10 @@ 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_anon => rscope.anon_region(span), - ast::re_named(id) => rscope.named_region(span, id) + 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) }; get_region_reporting_err(self.tcx(), span, res) diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index 63ac6154810..48410cde449 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -77,6 +77,7 @@ use syntax::ast::ty_i; use typeck::infer::{resolve_type, force_tvar}; use result::{Result, Ok, Err}; use syntax::print::pprust; +use syntax::parse::token::special_idents; use std::map::{str_hash, uint_hash}; @@ -567,22 +568,34 @@ impl @fn_ctxt: ast_conv { } } +impl @fn_ctxt { + fn search_in_scope_regions(br: ty::bound_region) + -> Result + { + match self.in_scope_regions.find(br) { + Some(r) => result::Ok(r), + None => { + let blk_br = ty::br_named(special_idents::blk); + if br == blk_br { + result::Ok(self.block_region()) + } else { + result::Err(fmt!("named region `%s` not in scope here", + bound_region_to_str(self.tcx(), br))) + } + } + } + } +} + impl @fn_ctxt: region_scope { fn anon_region(span: span) -> Result { result::Ok(self.infcx().next_region_var_nb(span)) } - fn named_region(span: span, id: ast::ident) -> Result { - do empty_rscope.named_region(span, id).chain_err |_e| { - match self.in_scope_regions.find(ty::br_named(id)) { - Some(r) => result::Ok(r), - None if id == syntax::parse::token::special_idents::blk - => result::Ok(self.block_region()), - None => { - result::Err(fmt!("named region `%s` not in scope here", - self.ccx.tcx.sess.str_of(id))) - } - } - } + fn self_region(_span: span) -> Result { + self.search_in_scope_regions(ty::br_self) + } + fn named_region(_span: span, id: ast::ident) -> Result { + self.search_in_scope_regions(ty::br_named(id)) } } diff --git a/src/rustc/middle/typeck/rscope.rs b/src/rustc/middle/typeck/rscope.rs index 0224d6933a7..9b9695088f3 100644 --- a/src/rustc/middle/typeck/rscope.rs +++ b/src/rustc/middle/typeck/rscope.rs @@ -3,6 +3,7 @@ use syntax::parse::token::special_idents; trait region_scope { fn anon_region(span: span) -> Result; + fn self_region(span: span) -> Result; fn named_region(span: span, id: ast::ident) -> Result; } @@ -11,9 +12,13 @@ impl empty_rscope: region_scope { fn anon_region(_span: span) -> Result { result::Ok(ty::re_static) } - fn named_region(_span: span, id: ast::ident) -> Result { - if id == special_idents::static { result::Ok(ty::re_static) } - else { result::Err(~"only the static region is allowed here") } + fn self_region(_span: span) -> Result { + result::Err(~"only the static region is allowed here") + } + fn named_region(_span: span, _id: ast::ident) + -> Result + { + result::Err(~"only the static region is allowed here") } } @@ -26,14 +31,13 @@ impl type_rscope: region_scope { type must be declared with a region bound") } } + fn self_region(span: span) -> Result { + self.anon_region(span) + } fn named_region(span: span, id: ast::ident) -> Result { do empty_rscope.named_region(span, id).chain_err |_e| { - if id == special_idents::self_ { - self.anon_region(span) - } else { - result::Err(~"named regions other than `self` are not \ - allowed as part of a type declaration") - } + result::Err(~"named regions other than `self` are not \ + allowed as part of a type declaration") } } } @@ -54,6 +58,9 @@ impl @anon_rscope: region_scope { fn anon_region(_span: span) -> Result { result::Ok(self.anon) } + fn self_region(span: span) -> Result { + self.base.self_region(span) + } fn named_region(span: span, id: ast::ident) -> Result { self.base.named_region(span, id) } @@ -74,6 +81,9 @@ impl @binding_rscope: region_scope { self.anon_bindings += 1; result::Ok(ty::re_bound(ty::br_anon(idx))) } + fn self_region(span: span) -> Result { + self.base.self_region(span) + } fn named_region(span: span, id: ast::ident) -> Result { do self.base.named_region(span, id).chain_err |_e| { result::Ok(ty::re_bound(ty::br_named(id)))