auto merge of #7615 : Aatch/rust/syntax-deshare, r=graydon
In an ideal world, the AST would be completely sendable, this gets us a step closer. It removes the local heap allocations for `view_item`, `Path`, `Lifetime` `trait_ref` `OptVec<TyParamBounds>` and `Ty`. There are also a few other smaller changes I made as things went along.
This commit is contained in:
commit
0f2515583d
61 changed files with 751 additions and 768 deletions
|
@ -115,7 +115,7 @@ pub enum item_or_view_item {
|
|||
iovi_none,
|
||||
iovi_item(@item),
|
||||
iovi_foreign_item(@foreign_item),
|
||||
iovi_view_item(@view_item)
|
||||
iovi_view_item(view_item)
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
|
@ -130,20 +130,28 @@ The important thing is to make sure that lookahead doesn't balk
|
|||
at INTERPOLATED tokens */
|
||||
macro_rules! maybe_whole_expr (
|
||||
($p:expr) => (
|
||||
match *($p).token {
|
||||
INTERPOLATED(token::nt_expr(e)) => {
|
||||
$p.bump();
|
||||
return e;
|
||||
{
|
||||
// This horrible convolution is brought to you by
|
||||
// @mut, have a terrible day
|
||||
let ret = match *($p).token {
|
||||
INTERPOLATED(token::nt_expr(e)) => {
|
||||
Some(e)
|
||||
}
|
||||
INTERPOLATED(token::nt_path(ref pt)) => {
|
||||
Some($p.mk_expr(
|
||||
($p).span.lo,
|
||||
($p).span.hi,
|
||||
expr_path(/* bad */ copy *pt)))
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
match ret {
|
||||
Some(e) => {
|
||||
$p.bump();
|
||||
return e;
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
INTERPOLATED(token::nt_path(pt)) => {
|
||||
$p.bump();
|
||||
return $p.mk_expr(
|
||||
($p).span.lo,
|
||||
($p).span.hi,
|
||||
expr_path(pt)
|
||||
);
|
||||
}
|
||||
_ => ()
|
||||
}
|
||||
)
|
||||
)
|
||||
|
@ -208,7 +216,7 @@ fn maybe_append(lhs: ~[attribute], rhs: Option<~[attribute]>)
|
|||
|
||||
struct ParsedItemsAndViewItems {
|
||||
attrs_remaining: ~[attribute],
|
||||
view_items: ~[@view_item],
|
||||
view_items: ~[view_item],
|
||||
items: ~[@item],
|
||||
foreign_items: ~[@foreign_item]
|
||||
}
|
||||
|
@ -637,7 +645,7 @@ impl Parser {
|
|||
// parse a ty_closure type
|
||||
pub fn parse_ty_closure(&self,
|
||||
sigil: ast::Sigil,
|
||||
region: Option<@ast::Lifetime>)
|
||||
region: Option<ast::Lifetime>)
|
||||
-> ty_ {
|
||||
/*
|
||||
|
||||
|
@ -815,7 +823,7 @@ impl Parser {
|
|||
// parse a possibly mutable type
|
||||
pub fn parse_mt(&self) -> mt {
|
||||
let mutbl = self.parse_mutability();
|
||||
let t = self.parse_ty(false);
|
||||
let t = ~self.parse_ty(false);
|
||||
mt { ty: t, mutbl: mutbl }
|
||||
}
|
||||
|
||||
|
@ -826,7 +834,7 @@ impl Parser {
|
|||
let mutbl = self.parse_mutability();
|
||||
let id = self.parse_ident();
|
||||
self.expect(&token::COLON);
|
||||
let ty = self.parse_ty(false);
|
||||
let ty = ~self.parse_ty(false);
|
||||
spanned(
|
||||
lo,
|
||||
ty.span.hi,
|
||||
|
@ -838,13 +846,13 @@ impl Parser {
|
|||
}
|
||||
|
||||
// parse optional return type [ -> TY ] in function decl
|
||||
pub fn parse_ret_ty(&self) -> (ret_style, @Ty) {
|
||||
pub fn parse_ret_ty(&self) -> (ret_style, Ty) {
|
||||
return if self.eat(&token::RARROW) {
|
||||
let lo = self.span.lo;
|
||||
if self.eat(&token::NOT) {
|
||||
(
|
||||
noreturn,
|
||||
@Ty {
|
||||
Ty {
|
||||
id: self.get_id(),
|
||||
node: ty_bot,
|
||||
span: mk_sp(lo, self.last_span.hi)
|
||||
|
@ -857,7 +865,7 @@ impl Parser {
|
|||
let pos = self.span.lo;
|
||||
(
|
||||
return_val,
|
||||
@Ty {
|
||||
Ty {
|
||||
id: self.get_id(),
|
||||
node: ty_nil,
|
||||
span: mk_sp(pos, pos),
|
||||
|
@ -869,7 +877,7 @@ impl Parser {
|
|||
// parse a type.
|
||||
// Useless second parameter for compatibility with quasiquote macros.
|
||||
// Bleh!
|
||||
pub fn parse_ty(&self, _: bool) -> @Ty {
|
||||
pub fn parse_ty(&self, _: bool) -> Ty {
|
||||
maybe_whole!(self, nt_ty);
|
||||
|
||||
let lo = self.span.lo;
|
||||
|
@ -959,14 +967,14 @@ impl Parser {
|
|||
|| is_ident_or_path(self.token) {
|
||||
// NAMED TYPE
|
||||
let (path, bounds) = self.parse_type_path();
|
||||
ty_path(path, @bounds, self.get_id())
|
||||
ty_path(path, bounds, self.get_id())
|
||||
} else {
|
||||
self.fatal(fmt!("expected type, found token %?",
|
||||
*self.token));
|
||||
};
|
||||
|
||||
let sp = mk_sp(lo, self.last_span.hi);
|
||||
@Ty {id: self.get_id(), node: t, span: sp}
|
||||
Ty {id: self.get_id(), node: t, span: sp}
|
||||
}
|
||||
|
||||
// parse the type following a @ or a ~
|
||||
|
@ -976,7 +984,7 @@ impl Parser {
|
|||
// @'foo fn() or @foo/fn() or @fn() are parsed directly as fn types:
|
||||
match *self.token {
|
||||
token::LIFETIME(*) => {
|
||||
let lifetime = @self.parse_lifetime();
|
||||
let lifetime = self.parse_lifetime();
|
||||
self.bump();
|
||||
return self.parse_ty_closure(sigil, Some(lifetime));
|
||||
}
|
||||
|
@ -985,7 +993,7 @@ impl Parser {
|
|||
if self.look_ahead(1u) == token::BINOP(token::SLASH) &&
|
||||
self.token_is_closure_keyword(&self.look_ahead(2u))
|
||||
{
|
||||
let lifetime = @self.parse_lifetime();
|
||||
let lifetime = self.parse_lifetime();
|
||||
self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
|
||||
return self.parse_ty_closure(sigil, Some(lifetime));
|
||||
} else if self.token_is_closure_keyword(© *self.token) {
|
||||
|
@ -1107,7 +1115,7 @@ impl Parser {
|
|||
let t = if self.eat(&token::COLON) {
|
||||
self.parse_ty(false)
|
||||
} else {
|
||||
@Ty {
|
||||
Ty {
|
||||
id: self.get_id(),
|
||||
node: ty_infer,
|
||||
span: mk_sp(self.span.lo, self.span.hi),
|
||||
|
@ -1217,10 +1225,10 @@ impl Parser {
|
|||
}
|
||||
|
||||
// parse a path that doesn't have type parameters attached
|
||||
pub fn parse_path_without_tps(&self) -> @ast::Path {
|
||||
pub fn parse_path_without_tps(&self) -> ast::Path {
|
||||
maybe_whole!(self, nt_path);
|
||||
let (ids,is_global,sp) = self.parse_path();
|
||||
@ast::Path { span: sp,
|
||||
ast::Path { span: sp,
|
||||
global: is_global,
|
||||
idents: ids,
|
||||
rp: None,
|
||||
|
@ -1228,7 +1236,7 @@ impl Parser {
|
|||
}
|
||||
|
||||
pub fn parse_bounded_path_with_tps(&self, colons: bool,
|
||||
before_tps: Option<&fn()>) -> @ast::Path {
|
||||
before_tps: Option<&fn()>) -> ast::Path {
|
||||
debug!("parse_path_with_tps(colons=%b)", colons);
|
||||
|
||||
maybe_whole!(self, nt_path);
|
||||
|
@ -1254,7 +1262,7 @@ impl Parser {
|
|||
token::IDENT(sid, _) => {
|
||||
let span = copy self.span;
|
||||
self.bump();
|
||||
Some(@ast::Lifetime {
|
||||
Some(ast::Lifetime {
|
||||
id: self.get_id(),
|
||||
span: *span,
|
||||
ident: sid
|
||||
|
@ -1279,7 +1287,7 @@ impl Parser {
|
|||
if v.len() == 0 {
|
||||
None
|
||||
} else if v.len() == 1 {
|
||||
Some(@*v.get(0))
|
||||
Some(*v.get(0))
|
||||
} else {
|
||||
self.fatal(fmt!("Expected at most one \
|
||||
lifetime name (for now)"));
|
||||
|
@ -1287,22 +1295,22 @@ impl Parser {
|
|||
}
|
||||
};
|
||||
|
||||
@ast::Path { span: mk_sp(lo, hi),
|
||||
ast::Path { span: mk_sp(lo, hi),
|
||||
rp: rp,
|
||||
types: tps,
|
||||
.. copy *path }
|
||||
.. path }
|
||||
}
|
||||
|
||||
// parse a path optionally with type parameters. If 'colons'
|
||||
// is true, then type parameters must be preceded by colons,
|
||||
// as in a::t::<t1,t2>
|
||||
pub fn parse_path_with_tps(&self, colons: bool) -> @ast::Path {
|
||||
pub fn parse_path_with_tps(&self, colons: bool) -> ast::Path {
|
||||
self.parse_bounded_path_with_tps(colons, None)
|
||||
}
|
||||
|
||||
// Like the above, but can also parse kind bounds in the case of a
|
||||
// path to be used as a type that might be a trait.
|
||||
pub fn parse_type_path(&self) -> (@ast::Path, Option<OptVec<TyParamBound>>) {
|
||||
pub fn parse_type_path(&self) -> (ast::Path, Option<OptVec<TyParamBound>>) {
|
||||
let mut bounds = None;
|
||||
let path = self.parse_bounded_path_with_tps(false, Some(|| {
|
||||
// Note: this closure might not even get called in the case of a
|
||||
|
@ -1313,17 +1321,17 @@ impl Parser {
|
|||
}
|
||||
|
||||
/// parses 0 or 1 lifetime
|
||||
pub fn parse_opt_lifetime(&self) -> Option<@ast::Lifetime> {
|
||||
pub fn parse_opt_lifetime(&self) -> Option<ast::Lifetime> {
|
||||
match *self.token {
|
||||
token::LIFETIME(*) => {
|
||||
Some(@self.parse_lifetime())
|
||||
Some(self.parse_lifetime())
|
||||
}
|
||||
|
||||
// Also accept the (obsolete) syntax `foo/`
|
||||
token::IDENT(*) => {
|
||||
if self.look_ahead(1u) == token::BINOP(token::SLASH) {
|
||||
self.obsolete(*self.last_span, ObsoleteLifetimeNotation);
|
||||
Some(@self.parse_lifetime())
|
||||
Some(self.parse_lifetime())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -1454,7 +1462,7 @@ impl Parser {
|
|||
pub fn mk_method_call(&self,
|
||||
rcvr: @expr,
|
||||
ident: ident,
|
||||
tps: ~[@Ty],
|
||||
tps: ~[Ty],
|
||||
args: ~[@expr],
|
||||
sugar: CallSugar) -> ast::expr_ {
|
||||
expr_method_call(self.get_id(), rcvr, ident, tps, args, sugar)
|
||||
|
@ -1464,7 +1472,7 @@ impl Parser {
|
|||
expr_index(self.get_id(), expr, idx)
|
||||
}
|
||||
|
||||
pub fn mk_field(&self, expr: @expr, ident: ident, tys: ~[@Ty]) -> ast::expr_ {
|
||||
pub fn mk_field(&self, expr: @expr, ident: ident, tys: ~[Ty]) -> ast::expr_ {
|
||||
expr_field(expr, ident, tys)
|
||||
}
|
||||
|
||||
|
@ -2206,7 +2214,7 @@ impl Parser {
|
|||
// No argument list - `do foo {`
|
||||
ast::fn_decl {
|
||||
inputs: ~[],
|
||||
output: @Ty {
|
||||
output: Ty {
|
||||
id: self.get_id(),
|
||||
node: ty_infer,
|
||||
span: *self.span
|
||||
|
@ -2817,7 +2825,7 @@ impl Parser {
|
|||
self.obsolete(*self.span, ObsoleteMutWithMultipleBindings)
|
||||
}
|
||||
|
||||
let mut ty = @Ty {
|
||||
let mut ty = Ty {
|
||||
id: self.get_id(),
|
||||
node: ty_infer,
|
||||
span: mk_sp(lo, lo),
|
||||
|
@ -3204,7 +3212,7 @@ impl Parser {
|
|||
let ident = self.parse_ident();
|
||||
let opt_bounds = self.parse_optional_ty_param_bounds();
|
||||
// For typarams we don't care about the difference b/w "<T>" and "<T:>".
|
||||
let bounds = @opt_bounds.get_or_default(opt_vec::Empty);
|
||||
let bounds = opt_bounds.get_or_default(opt_vec::Empty);
|
||||
ast::TyParam { ident: ident, id: self.get_id(), bounds: bounds }
|
||||
}
|
||||
|
||||
|
@ -3226,7 +3234,7 @@ impl Parser {
|
|||
|
||||
// parse a generic use site
|
||||
fn parse_generic_values(
|
||||
&self) -> (OptVec<ast::Lifetime>, ~[@Ty])
|
||||
&self) -> (OptVec<ast::Lifetime>, ~[Ty])
|
||||
{
|
||||
if !self.eat(&token::LT) {
|
||||
(opt_vec::Empty, ~[])
|
||||
|
@ -3236,7 +3244,7 @@ impl Parser {
|
|||
}
|
||||
|
||||
fn parse_generic_values_after_lt(
|
||||
&self) -> (OptVec<ast::Lifetime>, ~[@Ty])
|
||||
&self) -> (OptVec<ast::Lifetime>, ~[Ty])
|
||||
{
|
||||
let lifetimes = self.parse_lifetimes();
|
||||
let result = self.parse_seq_to_gt(
|
||||
|
@ -3334,14 +3342,14 @@ impl Parser {
|
|||
} else if (this.token_is_lifetime(&this.look_ahead(1)) &&
|
||||
token::is_keyword(keywords::Self, &this.look_ahead(2))) {
|
||||
this.bump();
|
||||
let lifetime = @this.parse_lifetime();
|
||||
let lifetime = this.parse_lifetime();
|
||||
this.expect_self_ident();
|
||||
sty_region(Some(lifetime), m_imm)
|
||||
} else if (this.token_is_lifetime(&this.look_ahead(1)) &&
|
||||
this.token_is_mutability(&this.look_ahead(2)) &&
|
||||
token::is_keyword(keywords::Self, &this.look_ahead(3))) {
|
||||
this.bump();
|
||||
let lifetime = @this.parse_lifetime();
|
||||
let lifetime = this.parse_lifetime();
|
||||
let mutability = this.parse_mutability();
|
||||
this.expect_self_ident();
|
||||
sty_region(Some(lifetime), mutability)
|
||||
|
@ -3446,7 +3454,7 @@ impl Parser {
|
|||
let output = if self.eat(&token::RARROW) {
|
||||
self.parse_ty(false)
|
||||
} else {
|
||||
@Ty { id: self.get_id(), node: ty_infer, span: *self.span }
|
||||
Ty { id: self.get_id(), node: ty_infer, span: *self.span }
|
||||
};
|
||||
|
||||
ast::fn_decl {
|
||||
|
@ -3556,9 +3564,9 @@ impl Parser {
|
|||
let opt_trait = if could_be_trait && self.eat_keyword(keywords::For) {
|
||||
// New-style trait. Reinterpret the type as a trait.
|
||||
let opt_trait_ref = match ty.node {
|
||||
ty_path(path, @None, node_id) => {
|
||||
Some(@trait_ref {
|
||||
path: path,
|
||||
ty_path(ref path, None, node_id) => {
|
||||
Some(trait_ref {
|
||||
path: /* bad */ copy *path,
|
||||
ref_id: node_id
|
||||
})
|
||||
}
|
||||
|
@ -3599,15 +3607,15 @@ impl Parser {
|
|||
}
|
||||
|
||||
// parse a::B<~str,int>
|
||||
fn parse_trait_ref(&self) -> @trait_ref {
|
||||
@ast::trait_ref {
|
||||
fn parse_trait_ref(&self) -> trait_ref {
|
||||
ast::trait_ref {
|
||||
path: self.parse_path_with_tps(false),
|
||||
ref_id: self.get_id(),
|
||||
}
|
||||
}
|
||||
|
||||
// parse B + C<~str,int> + D
|
||||
fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[@trait_ref] {
|
||||
fn parse_trait_ref_list(&self, ket: &token::Token) -> ~[trait_ref] {
|
||||
self.parse_seq_to_before_end(
|
||||
ket,
|
||||
seq_sep_trailing_disallowed(token::BINOP(token::PLUS)),
|
||||
|
@ -4091,7 +4099,7 @@ impl Parser {
|
|||
// extern mod foo;
|
||||
let metadata = self.parse_optional_meta();
|
||||
self.expect(&token::SEMI);
|
||||
iovi_view_item(@ast::view_item {
|
||||
iovi_view_item(ast::view_item {
|
||||
node: view_item_extern_mod(ident, metadata, self.get_id()),
|
||||
attrs: copy attrs,
|
||||
vis: visibility,
|
||||
|
@ -4164,9 +4172,9 @@ impl Parser {
|
|||
seq_sep_trailing_disallowed(token::COMMA),
|
||||
|p| p.parse_ty(false)
|
||||
);
|
||||
for arg_tys.iter().advance |ty| {
|
||||
for arg_tys.consume_iter().advance |ty| {
|
||||
args.push(ast::variant_arg {
|
||||
ty: *ty,
|
||||
ty: ty,
|
||||
id: self.get_id(),
|
||||
});
|
||||
}
|
||||
|
@ -4325,7 +4333,7 @@ impl Parser {
|
|||
// USE ITEM (iovi_view_item)
|
||||
let view_item = self.parse_use();
|
||||
self.expect(&token::SEMI);
|
||||
return iovi_view_item(@ast::view_item {
|
||||
return iovi_view_item(ast::view_item {
|
||||
node: view_item,
|
||||
attrs: attrs,
|
||||
vis: visibility,
|
||||
|
@ -4575,7 +4583,7 @@ impl Parser {
|
|||
let id = self.parse_ident();
|
||||
path.push(id);
|
||||
}
|
||||
let path = @ast::Path { span: mk_sp(lo, self.span.hi),
|
||||
let path = ast::Path { span: mk_sp(lo, self.span.hi),
|
||||
global: false,
|
||||
idents: path,
|
||||
rp: None,
|
||||
|
@ -4605,7 +4613,7 @@ impl Parser {
|
|||
seq_sep_trailing_allowed(token::COMMA),
|
||||
|p| p.parse_path_list_ident()
|
||||
);
|
||||
let path = @ast::Path { span: mk_sp(lo, self.span.hi),
|
||||
let path = ast::Path { span: mk_sp(lo, self.span.hi),
|
||||
global: false,
|
||||
idents: path,
|
||||
rp: None,
|
||||
|
@ -4617,7 +4625,7 @@ impl Parser {
|
|||
// foo::bar::*
|
||||
token::BINOP(token::STAR) => {
|
||||
self.bump();
|
||||
let path = @ast::Path { span: mk_sp(lo, self.span.hi),
|
||||
let path = ast::Path { span: mk_sp(lo, self.span.hi),
|
||||
global: false,
|
||||
idents: path,
|
||||
rp: None,
|
||||
|
@ -4633,7 +4641,7 @@ impl Parser {
|
|||
_ => ()
|
||||
}
|
||||
let last = path[path.len() - 1u];
|
||||
let path = @ast::Path { span: mk_sp(lo, self.span.hi),
|
||||
let path = ast::Path { span: mk_sp(lo, self.span.hi),
|
||||
global: false,
|
||||
idents: path,
|
||||
rp: None,
|
||||
|
@ -4673,7 +4681,7 @@ impl Parser {
|
|||
&self,
|
||||
attrs: ~[attribute],
|
||||
vis: visibility
|
||||
) -> @view_item {
|
||||
) -> view_item {
|
||||
let lo = self.span.lo;
|
||||
let node = if self.eat_keyword(keywords::Use) {
|
||||
self.parse_use()
|
||||
|
@ -4686,7 +4694,7 @@ impl Parser {
|
|||
self.bug("expected view item");
|
||||
};
|
||||
self.expect(&token::SEMI);
|
||||
@ast::view_item { node: node,
|
||||
ast::view_item { node: node,
|
||||
attrs: attrs,
|
||||
vis: vis,
|
||||
span: mk_sp(lo, self.last_span.hi) }
|
||||
|
@ -4704,7 +4712,7 @@ impl Parser {
|
|||
let mut attrs = vec::append(first_item_attrs,
|
||||
self.parse_outer_attributes());
|
||||
// First, parse view items.
|
||||
let mut view_items = ~[];
|
||||
let mut view_items : ~[ast::view_item] = ~[];
|
||||
let mut items = ~[];
|
||||
let mut done = false;
|
||||
// I think this code would probably read better as a single
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue