Have parser recognize static, self region.
Fixes a bug in methods that &self couldn't be referenced in the body. Also fixes #2479.
This commit is contained in:
parent
34cece99cc
commit
7107b4eff5
|
@ -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_ {
|
||||
|
|
|
@ -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<ident>) -> @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)
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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, ~"");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,8 +73,10 @@ fn ast_region_to_region<AC: ast_conv, RS: region_scope Copy Owned>(
|
|||
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)
|
||||
|
|
|
@ -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<ty::region, ~str>
|
||||
{
|
||||
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<ty::region, ~str> {
|
||||
result::Ok(self.infcx().next_region_var_nb(span))
|
||||
}
|
||||
fn named_region(span: span, id: ast::ident) -> Result<ty::region, ~str> {
|
||||
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<ty::region, ~str> {
|
||||
self.search_in_scope_regions(ty::br_self)
|
||||
}
|
||||
fn named_region(_span: span, id: ast::ident) -> Result<ty::region, ~str> {
|
||||
self.search_in_scope_regions(ty::br_named(id))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ use syntax::parse::token::special_idents;
|
|||
|
||||
trait region_scope {
|
||||
fn anon_region(span: span) -> Result<ty::region, ~str>;
|
||||
fn self_region(span: span) -> Result<ty::region, ~str>;
|
||||
fn named_region(span: span, id: ast::ident) -> Result<ty::region, ~str>;
|
||||
}
|
||||
|
||||
|
@ -11,9 +12,13 @@ impl empty_rscope: region_scope {
|
|||
fn anon_region(_span: span) -> Result<ty::region, ~str> {
|
||||
result::Ok(ty::re_static)
|
||||
}
|
||||
fn named_region(_span: span, id: ast::ident) -> Result<ty::region, ~str> {
|
||||
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<ty::region, ~str> {
|
||||
result::Err(~"only the static region is allowed here")
|
||||
}
|
||||
fn named_region(_span: span, _id: ast::ident)
|
||||
-> Result<ty::region, ~str>
|
||||
{
|
||||
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<ty::region, ~str> {
|
||||
self.anon_region(span)
|
||||
}
|
||||
fn named_region(span: span, id: ast::ident) -> Result<ty::region, ~str> {
|
||||
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<ty::region, ~str> {
|
||||
result::Ok(self.anon)
|
||||
}
|
||||
fn self_region(span: span) -> Result<ty::region, ~str> {
|
||||
self.base.self_region(span)
|
||||
}
|
||||
fn named_region(span: span, id: ast::ident) -> Result<ty::region, ~str> {
|
||||
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<ty::region, ~str> {
|
||||
self.base.self_region(span)
|
||||
}
|
||||
fn named_region(span: span, id: ast::ident) -> Result<ty::region, ~str> {
|
||||
do self.base.named_region(span, id).chain_err |_e| {
|
||||
result::Ok(ty::re_bound(ty::br_named(id)))
|
||||
|
|
Loading…
Reference in New Issue