Auto merge of #33161 - jseyfried:parse_tuple_struct_field_vis, r=nikomatsakis
Parse `pub(restricted)` visibilities on tuple struct fields Parse `pub(restricted)` on tuple struct fields (cc #32409). r? @nikomatsakis
This commit is contained in:
commit
0f9ba99291
5 changed files with 108 additions and 7 deletions
|
@ -5218,8 +5218,25 @@ impl<'a> Parser<'a> {
|
||||||
|p| {
|
|p| {
|
||||||
let attrs = p.parse_outer_attributes()?;
|
let attrs = p.parse_outer_attributes()?;
|
||||||
let lo = p.span.lo;
|
let lo = p.span.lo;
|
||||||
let vis = p.parse_visibility(false)?;
|
let mut vis = p.parse_visibility(false)?;
|
||||||
let ty = p.parse_ty_sum()?;
|
let ty_is_interpolated =
|
||||||
|
p.token.is_interpolated() || p.look_ahead(1, |t| t.is_interpolated());
|
||||||
|
let mut ty = p.parse_ty_sum()?;
|
||||||
|
|
||||||
|
// Handle `pub(path) type`, in which `vis` will be `pub` and `ty` will be `(path)`.
|
||||||
|
if vis == Visibility::Public && !ty_is_interpolated &&
|
||||||
|
p.token != token::Comma && p.token != token::CloseDelim(token::Paren) {
|
||||||
|
ty = if let TyKind::Paren(ref path_ty) = ty.node {
|
||||||
|
if let TyKind::Path(None, ref path) = path_ty.node {
|
||||||
|
vis = Visibility::Restricted { path: P(path.clone()), id: path_ty.id };
|
||||||
|
Some(p.parse_ty_sum()?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}.unwrap_or(ty);
|
||||||
|
}
|
||||||
Ok(StructField {
|
Ok(StructField {
|
||||||
span: mk_sp(lo, p.span.hi),
|
span: mk_sp(lo, p.span.hi),
|
||||||
vis: vis,
|
vis: vis,
|
||||||
|
@ -5263,15 +5280,29 @@ impl<'a> Parser<'a> {
|
||||||
self.parse_single_struct_field(vis, attrs)
|
self.parse_single_struct_field(vis, attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_visibility(&mut self, allow_restricted: bool) -> PResult<'a, Visibility> {
|
// If `allow_path` is false, just parse the `pub` in `pub(path)` (but still parse `pub(crate)`)
|
||||||
|
fn parse_visibility(&mut self, allow_path: bool) -> PResult<'a, Visibility> {
|
||||||
|
let pub_crate = |this: &mut Self| {
|
||||||
|
let span = this.last_span;
|
||||||
|
this.expect(&token::CloseDelim(token::Paren))?;
|
||||||
|
Ok(Visibility::Crate(span))
|
||||||
|
};
|
||||||
|
|
||||||
if !self.eat_keyword(keywords::Pub) {
|
if !self.eat_keyword(keywords::Pub) {
|
||||||
Ok(Visibility::Inherited)
|
Ok(Visibility::Inherited)
|
||||||
} else if !allow_restricted || !self.eat(&token::OpenDelim(token::Paren)) {
|
} else if !allow_path {
|
||||||
|
// Look ahead to avoid eating the `(` in `pub(path)` while still parsing `pub(crate)`
|
||||||
|
if self.token == token::OpenDelim(token::Paren) &&
|
||||||
|
self.look_ahead(1, |t| t.is_keyword(keywords::Crate)) {
|
||||||
|
self.bump(); self.bump();
|
||||||
|
pub_crate(self)
|
||||||
|
} else {
|
||||||
|
Ok(Visibility::Public)
|
||||||
|
}
|
||||||
|
} else if !self.eat(&token::OpenDelim(token::Paren)) {
|
||||||
Ok(Visibility::Public)
|
Ok(Visibility::Public)
|
||||||
} else if self.eat_keyword(keywords::Crate) {
|
} else if self.eat_keyword(keywords::Crate) {
|
||||||
let span = self.last_span;
|
pub_crate(self)
|
||||||
self.expect(&token::CloseDelim(token::Paren))?;
|
|
||||||
Ok(Visibility::Crate(span))
|
|
||||||
} else {
|
} else {
|
||||||
let path = self.parse_path(PathStyle::Mod)?;
|
let path = self.parse_path(PathStyle::Mod)?;
|
||||||
self.expect(&token::CloseDelim(token::Paren))?;
|
self.expect(&token::CloseDelim(token::Paren))?;
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(pub_restricted, type_macros)]
|
||||||
|
|
||||||
|
mod foo {
|
||||||
|
type T = ();
|
||||||
|
struct S1(pub(foo) (), pub(T), pub(crate) (), pub(((), T)));
|
||||||
|
struct S2(pub((foo)) ()); //~ ERROR expected one of `+` or `,`, found `(`
|
||||||
|
//~| ERROR expected one of `+`, `;`, or `where`, found `(`
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(pub_restricted, type_macros)]
|
||||||
|
|
||||||
|
macro_rules! define_struct {
|
||||||
|
($t:ty) => {
|
||||||
|
struct S1(pub $t);
|
||||||
|
struct S2(pub (foo) ());
|
||||||
|
struct S3(pub $t ()); //~ ERROR expected one of `+` or `,`, found `(`
|
||||||
|
//~| ERROR expected one of `+`, `;`, or `where`, found `(`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod foo {
|
||||||
|
define_struct! { (foo) }
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![feature(pub_restricted, type_macros)]
|
||||||
|
|
||||||
|
macro_rules! define_struct {
|
||||||
|
($t:ty) => {
|
||||||
|
struct S1(pub($t));
|
||||||
|
struct S2(pub (foo) ());
|
||||||
|
struct S3(pub($t) ()); //~ ERROR expected one of `+` or `,`, found `(`
|
||||||
|
//~| ERROR expected one of `+`, `;`, or `where`, found `(`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod foo {
|
||||||
|
define_struct! { foo }
|
||||||
|
}
|
|
@ -17,4 +17,8 @@ macro_rules! m {
|
||||||
struct S<T>(T);
|
struct S<T>(T);
|
||||||
m!{ S<u8> } //~ ERROR type or lifetime parameters in visibility path
|
m!{ S<u8> } //~ ERROR type or lifetime parameters in visibility path
|
||||||
|
|
||||||
|
mod foo {
|
||||||
|
struct S(pub(foo<T>) ()); //~ ERROR type or lifetime parameters in visibility path
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue