Skip to content

Commit e7e1bab

Browse files
Bleicatamorphism
authored andcommitted
libsyntax: refactor the parser to consider foreign items as items
parse_item_or_view_item() would drop visibility if none of the conditions following it would hold. This was the case when parsing extern {} blocks, where the function was only used to parse view items, but discarded the visibility of the first not-view item.
1 parent 7dde840 commit e7e1bab

File tree

3 files changed

+65
-27
lines changed

3 files changed

+65
-27
lines changed

src/libcore/str.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1952,7 +1952,7 @@ pub mod raw {
19521952
}
19531953

19541954
/// Converts a vector of bytes to a string.
1955-
pub pub unsafe fn from_bytes(v: &[const u8]) -> ~str {
1955+
pub unsafe fn from_bytes(v: &[const u8]) -> ~str {
19561956
do vec::as_const_buf(v) |buf, len| {
19571957
from_buf_len(buf, len)
19581958
}

src/libsyntax/parse/parser.rs

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,13 @@ type item_info = (ident, item_, Option<~[attribute]>);
124124
enum item_or_view_item {
125125
iovi_none,
126126
iovi_item(@item),
127+
iovi_foreign_item(@foreign_item),
127128
iovi_view_item(@view_item)
128129
}
129130

130131
enum view_item_parse_mode {
131132
VIEW_ITEMS_AND_ITEMS_ALLOWED,
132-
VIEW_ITEMS_ALLOWED,
133+
VIEW_ITEMS_AND_FOREIGN_ITEMS_ALLOWED,
133134
IMPORTS_AND_ITEMS_ALLOWED
134135
}
135136

@@ -2184,7 +2185,7 @@ impl Parser {
21842185

21852186
let item_attrs = vec::append(first_item_attrs, item_attrs);
21862187

2187-
match self.parse_item_or_view_item(item_attrs, true) {
2188+
match self.parse_item_or_view_item(item_attrs, true, false) {
21882189
iovi_item(i) => {
21892190
let mut hi = i.span.hi;
21902191
let decl = @spanned(lo, hi, decl_item(i));
@@ -2194,6 +2195,9 @@ impl Parser {
21942195
self.span_fatal(vi.span, ~"view items must be declared at \
21952196
the top of the block");
21962197
}
2198+
iovi_foreign_item(_) => {
2199+
self.fatal(~"foreign items are not allowed here");
2200+
}
21972201
iovi_none() => { /* fallthrough */ }
21982202
}
21992203

@@ -2259,7 +2263,7 @@ impl Parser {
22592263
let mut stmts = ~[];
22602264
let mut expr = None;
22612265

2262-
let {attrs_remaining, view_items, items: items} =
2266+
let {attrs_remaining, view_items, items: items, _} =
22632267
self.parse_items_and_view_items(first_item_attrs,
22642268
IMPORTS_AND_ITEMS_ALLOWED);
22652269

@@ -2844,7 +2848,7 @@ impl Parser {
28442848
fn parse_mod_items(term: token::Token,
28452849
+first_item_attrs: ~[attribute]) -> _mod {
28462850
// Shouldn't be any view items since we've already parsed an item attr
2847-
let {attrs_remaining, view_items, items: starting_items} =
2851+
let {attrs_remaining, view_items, items: starting_items, _} =
28482852
self.parse_items_and_view_items(first_item_attrs,
28492853
VIEW_ITEMS_AND_ITEMS_ALLOWED);
28502854
let mut items: ~[@item] = move starting_items;
@@ -2858,7 +2862,7 @@ impl Parser {
28582862
}
28592863
debug!("parse_mod_items: parse_item_or_view_item(attrs=%?)",
28602864
attrs);
2861-
match self.parse_item_or_view_item(attrs, true) {
2865+
match self.parse_item_or_view_item(attrs, true, false) {
28622866
iovi_item(item) => items.push(item),
28632867
iovi_view_item(view_item) => {
28642868
self.span_fatal(view_item.span, ~"view items must be \
@@ -2958,11 +2962,11 @@ impl Parser {
29582962
+first_item_attrs: ~[attribute]) ->
29592963
foreign_mod {
29602964
// Shouldn't be any view items since we've already parsed an item attr
2961-
let {attrs_remaining, view_items, items: _} =
2965+
let {attrs_remaining, view_items, items: _, foreign_items} =
29622966
self.parse_items_and_view_items(first_item_attrs,
2963-
VIEW_ITEMS_ALLOWED);
2967+
VIEW_ITEMS_AND_FOREIGN_ITEMS_ALLOWED);
29642968

2965-
let mut items: ~[@foreign_item] = ~[];
2969+
let mut items: ~[@foreign_item] = move foreign_items;
29662970
let mut initial_attrs = attrs_remaining;
29672971
while self.token != token::RBRACE {
29682972
let attrs = vec::append(initial_attrs,
@@ -2971,7 +2975,7 @@ impl Parser {
29712975
items.push(self.parse_foreign_item(attrs));
29722976
}
29732977
return {sort: sort, view_items: view_items,
2974-
items: items};
2978+
items: items};
29752979
}
29762980

29772981
fn parse_item_foreign_mod(lo: uint,
@@ -3229,8 +3233,11 @@ impl Parser {
32293233
}
32303234
}
32313235

3232-
fn parse_item_or_view_item(+attrs: ~[attribute], items_allowed: bool)
3236+
fn parse_item_or_view_item(+attrs: ~[attribute], items_allowed: bool,
3237+
foreign_items_allowed: bool)
32333238
-> item_or_view_item {
3239+
assert items_allowed != foreign_items_allowed;
3240+
32343241
maybe_whole!(iovi self,nt_item);
32353242
let lo = self.span.lo;
32363243

@@ -3248,6 +3255,9 @@ impl Parser {
32483255
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
32493256
visibility,
32503257
maybe_append(attrs, extra_attrs)));
3258+
} else if foreign_items_allowed && self.is_keyword(~"const") {
3259+
let item = self.parse_item_foreign_const(visibility, attrs);
3260+
return iovi_foreign_item(item);
32513261
} else if items_allowed &&
32523262
self.is_keyword(~"fn") &&
32533263
!self.fn_expr_lookahead(self.look_ahead(1u)) {
@@ -3262,6 +3272,10 @@ impl Parser {
32623272
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
32633273
visibility,
32643274
maybe_append(attrs, extra_attrs)));
3275+
} else if foreign_items_allowed &&
3276+
(self.is_keyword(~"fn") || self.is_keyword(~"pure")) {
3277+
let item = self.parse_item_foreign_fn(visibility, attrs);
3278+
return iovi_foreign_item(item);
32653279
} else if items_allowed && self.is_keyword(~"unsafe")
32663280
&& self.look_ahead(1u) != token::LBRACE {
32673281
self.bump();
@@ -3348,16 +3362,24 @@ impl Parser {
33483362
return iovi_item(self.mk_item(lo, self.last_span.hi, id, item_,
33493363
visibility, attrs));
33503364
} else {
3365+
if visibility != inherited {
3366+
let mut s = ~"unmatched visibility `";
3367+
s += if visibility == public { ~"pub" } else { ~"priv" };
3368+
s += ~"`";
3369+
self.span_fatal(copy self.last_span, s);
3370+
}
33513371
return iovi_none;
33523372
};
33533373
}
33543374

33553375
fn parse_item(+attrs: ~[attribute]) -> Option<@ast::item> {
3356-
match self.parse_item_or_view_item(attrs, true) {
3376+
match self.parse_item_or_view_item(attrs, true, false) {
33573377
iovi_none =>
33583378
None,
33593379
iovi_view_item(_) =>
33603380
self.fatal(~"view items are not allowed here"),
3381+
iovi_foreign_item(_) =>
3382+
self.fatal(~"foreign items are not allowed here"),
33613383
iovi_item(item) =>
33623384
Some(item)
33633385
}
@@ -3492,28 +3514,35 @@ impl Parser {
34923514
mode: view_item_parse_mode)
34933515
-> {attrs_remaining: ~[attribute],
34943516
view_items: ~[@view_item],
3495-
items: ~[@item]} {
3517+
items: ~[@item],
3518+
foreign_items: ~[@foreign_item]} {
34963519
let mut attrs = vec::append(first_item_attrs,
34973520
self.parse_outer_attributes());
34983521

3499-
let items_allowed;
3500-
match mode {
3501-
VIEW_ITEMS_AND_ITEMS_ALLOWED | IMPORTS_AND_ITEMS_ALLOWED =>
3502-
items_allowed = true,
3503-
VIEW_ITEMS_ALLOWED =>
3504-
items_allowed = false
3505-
}
3522+
let items_allowed = match mode {
3523+
VIEW_ITEMS_AND_ITEMS_ALLOWED | IMPORTS_AND_ITEMS_ALLOWED => true,
3524+
VIEW_ITEMS_AND_FOREIGN_ITEMS_ALLOWED => false
3525+
};
35063526

3507-
let (view_items, items) = (DVec(), DVec());
3527+
let restricted_to_imports = match mode {
3528+
IMPORTS_AND_ITEMS_ALLOWED => true,
3529+
VIEW_ITEMS_AND_ITEMS_ALLOWED |
3530+
VIEW_ITEMS_AND_FOREIGN_ITEMS_ALLOWED => false
3531+
};
3532+
3533+
let foreign_items_allowed = match mode {
3534+
VIEW_ITEMS_AND_FOREIGN_ITEMS_ALLOWED => true,
3535+
VIEW_ITEMS_AND_ITEMS_ALLOWED | IMPORTS_AND_ITEMS_ALLOWED => false
3536+
};
3537+
3538+
let (view_items, items, foreign_items) = (DVec(), DVec(), DVec());
35083539
loop {
3509-
match self.parse_item_or_view_item(attrs, items_allowed) {
3540+
match self.parse_item_or_view_item(attrs, items_allowed,
3541+
foreign_items_allowed) {
35103542
iovi_none =>
35113543
break,
35123544
iovi_view_item(view_item) => {
3513-
match mode {
3514-
VIEW_ITEMS_AND_ITEMS_ALLOWED |
3515-
VIEW_ITEMS_ALLOWED => {}
3516-
IMPORTS_AND_ITEMS_ALLOWED =>
3545+
if restricted_to_imports {
35173546
match view_item.node {
35183547
view_item_import(_) => {}
35193548
view_item_export(_) | view_item_use(*) =>
@@ -3528,13 +3557,18 @@ impl Parser {
35283557
assert items_allowed;
35293558
items.push(item)
35303559
}
3560+
iovi_foreign_item(foreign_item) => {
3561+
assert foreign_items_allowed;
3562+
foreign_items.push(foreign_item);
3563+
}
35313564
}
35323565
attrs = self.parse_outer_attributes();
35333566
}
35343567

35353568
{attrs_remaining: attrs,
35363569
view_items: dvec::unwrap(move view_items),
3537-
items: dvec::unwrap(move items)}
3570+
items: dvec::unwrap(move items),
3571+
foreign_items: dvec::unwrap(move foreign_items)}
35383572
}
35393573

35403574
// Parses a source module as a crate
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// error-pattern:unmatched visibility `pub`
2+
extern {
3+
pub pub fn foo();
4+
}

0 commit comments

Comments
 (0)