Skip to content

Commit

Permalink
Rollup merge of rust-lang#40340 - petrochenkov:restricted, r=nikomats…
Browse files Browse the repository at this point in the history
…akis

Update syntax for `pub(restricted)`

Update the syntax before stabilization.

cc rust-lang#32409
r? @nikomatsakis
  • Loading branch information
Ariel Ben-Yehuda authored and alexcrichton committed Mar 10, 2017
2 parents cb71358 + eaa706d commit 008bbd3
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 54 deletions.
72 changes: 40 additions & 32 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4605,7 +4605,7 @@ impl<'a> Parser<'a> {

let mut attrs = self.parse_outer_attributes()?;
let lo = self.span.lo;
let vis = self.parse_visibility(true)?;
let vis = self.parse_visibility()?;
let defaultness = self.parse_defaultness()?;
let (name, node) = if self.eat_keyword(keywords::Type) {
let name = self.parse_ident()?;
Expand Down Expand Up @@ -4936,7 +4936,7 @@ impl<'a> Parser<'a> {
|p| {
let attrs = p.parse_outer_attributes()?;
let lo = p.span.lo;
let mut vis = p.parse_visibility(false)?;
let mut vis = p.parse_visibility()?;
let ty_is_interpolated =
p.token.is_interpolated() || p.look_ahead(1, |t| t.is_interpolated());
let mut ty = p.parse_ty()?;
Expand Down Expand Up @@ -4993,38 +4993,46 @@ impl<'a> Parser<'a> {
fn parse_struct_decl_field(&mut self) -> PResult<'a, StructField> {
let attrs = self.parse_outer_attributes()?;
let lo = self.span.lo;
let vis = self.parse_visibility(true)?;
let vis = self.parse_visibility()?;
self.parse_single_struct_field(lo, vis, attrs)
}

// 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.prev_span;
this.expect(&token::CloseDelim(token::Paren))?;
Ok(Visibility::Crate(span))
};

// Parse `pub`, `pub(crate)` and `pub(in path)` plus shortcuts
// `pub(self)` for `pub(in self)` and `pub(super)` for `pub(in super)`.
fn parse_visibility(&mut self) -> PResult<'a, Visibility> {
if !self.eat_keyword(keywords::Pub) {
Ok(Visibility::Inherited)
} 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)
} else if self.eat_keyword(keywords::Crate) {
pub_crate(self)
} else {
let path = self.parse_path(PathStyle::Mod)?.default_to_global();
self.expect(&token::CloseDelim(token::Paren))?;
Ok(Visibility::Restricted { path: P(path), id: ast::DUMMY_NODE_ID })
}
return Ok(Visibility::Inherited)
}

if self.check(&token::OpenDelim(token::Paren)) {
if self.look_ahead(1, |t| t.is_keyword(keywords::Crate)) {
// `pub(crate)`
self.bump(); // `(`
self.bump(); // `crate`
let vis = Visibility::Crate(self.prev_span);
self.expect(&token::CloseDelim(token::Paren))?; // `)`
return Ok(vis)
} else if self.look_ahead(1, |t| t.is_keyword(keywords::In)) {
// `pub(in path)`
self.bump(); // `(`
self.bump(); // `in`
let path = self.parse_path(PathStyle::Mod)?.default_to_global(); // `path`
let vis = Visibility::Restricted { path: P(path), id: ast::DUMMY_NODE_ID };
self.expect(&token::CloseDelim(token::Paren))?; // `)`
return Ok(vis)
} else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren)) &&
self.look_ahead(1, |t| t.is_keyword(keywords::Super) ||
t.is_keyword(keywords::SelfValue)) {
// `pub(self)` or `pub(super)`
self.bump(); // `(`
let path = self.parse_path(PathStyle::Mod)?.default_to_global(); // `super`/`self`
let vis = Visibility::Restricted { path: P(path), id: ast::DUMMY_NODE_ID };
self.expect(&token::CloseDelim(token::Paren))?; // `)`
return Ok(vis)
}
}

Ok(Visibility::Public)
}

/// Parse defaultness: DEFAULT or nothing
Expand Down Expand Up @@ -5499,7 +5507,7 @@ impl<'a> Parser<'a> {

let lo = self.span.lo;

let visibility = self.parse_visibility(true)?;
let visibility = self.parse_visibility()?;

if self.eat_keyword(keywords::Use) {
// USE ITEM
Expand Down Expand Up @@ -5774,7 +5782,7 @@ impl<'a> Parser<'a> {
fn parse_foreign_item(&mut self) -> PResult<'a, Option<ForeignItem>> {
let attrs = self.parse_outer_attributes()?;
let lo = self.span.lo;
let visibility = self.parse_visibility(true)?;
let visibility = self.parse_visibility()?;

if self.check_keyword(keywords::Static) {
// FOREIGN STATIC ITEM
Expand Down
8 changes: 4 additions & 4 deletions src/test/compile-fail-fulldeps/auxiliary/pub_and_stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ mod m {
#[unstable(feature = "unstable_undeclared", issue = "38412")] // SILLY
pub(crate) b_crate: i32,
#[unstable(feature = "unstable_declared", issue = "38412")] // SILLY
pub(m) c_mod: i32,
pub(in m) c_mod: i32,
#[stable(feature = "unit_test", since = "0.0.0")] // SILLY
d_priv: i32
}
Expand All @@ -71,7 +71,7 @@ mod m {
pub i32,

pub(crate) i32,
pub(m) i32,
pub(in m) i32,
i32);

impl Record {
Expand Down Expand Up @@ -124,7 +124,7 @@ mod m {
#[unstable(feature = "unstable_undeclared", issue = "38412")] // SILLY
pub(crate) fn pub_crate(&self) -> i32 { self.d_priv }
#[unstable(feature = "unstable_declared", issue = "38412")] // SILLY
pub(m) fn pub_mod(&self) -> i32 { self.d_priv }
pub(in m) fn pub_mod(&self) -> i32 { self.d_priv }
#[stable(feature = "unit_test", since = "0.0.0")] // SILLY
fn private(&self) -> i32 { self.d_priv }
}
Expand All @@ -138,7 +138,7 @@ mod m {
pub fn stable(&self) -> i32 { self.0 }

pub(crate) fn pub_crate(&self) -> i32 { self.0 }
pub(m) fn pub_mod(&self) -> i32 { self.0 }
pub(in m) fn pub_mod(&self) -> i32 { self.0 }
fn private(&self) -> i32 { self.0 }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ mod foo {
mod bar {
#[derive(Default)]
pub struct S {
pub(foo) x: i32,
pub(in foo) x: i32,
}
impl S {
pub(foo) fn f(&self) -> i32 { 0 }
pub(in foo) fn f(&self) -> i32 { 0 }
}

pub struct S2 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
mod foo {
pub mod bar {
pub struct S {
pub(foo) x: i32,
pub(in foo) x: i32,
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/privacy/restricted/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ fn main() {
}

mod pathological {
pub(bad::path) mod m1 {} //~ ERROR failed to resolve. Maybe a missing `extern crate bad;`?
pub(foo) mod m2 {} //~ ERROR visibilities can only be restricted to ancestor modules
pub(in bad::path) mod m1 {} //~ ERROR failed to resolve. Maybe a missing `extern crate bad;`?
pub(in foo) mod m2 {} //~ ERROR visibilities can only be restricted to ancestor modules
}
7 changes: 1 addition & 6 deletions src/test/compile-fail/privacy/restricted/ty-params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,11 @@
#![feature(pub_restricted)]

macro_rules! m {
($p: path) => (pub($p) struct Z;)
($p: path) => (pub(in $p) struct Z;)
}

struct S<T>(T);
m!{ S<u8> } //~ ERROR type or lifetime parameters in visibility path
//~^ ERROR expected module, found struct `S`

mod foo {
struct S(pub(foo<T>) ()); //~ ERROR type or lifetime parameters in visibility path
//~^ ERROR cannot find type `T` in this scope
}

fn main() {}
10 changes: 5 additions & 5 deletions src/test/compile-fail/resolve-bad-visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
enum E {}
trait Tr {}

pub(E) struct S; //~ ERROR expected module, found enum `E`
pub(Tr) struct Z; //~ ERROR expected module, found trait `Tr`
pub(std::vec) struct F; //~ ERROR visibilities can only be restricted to ancestor modules
pub(nonexistent) struct G; //~ ERROR cannot find module `nonexistent` in the crate root
pub(too_soon) struct H; //~ ERROR cannot find module `too_soon` in the crate root
pub(in E) struct S; //~ ERROR expected module, found enum `E`
pub(in Tr) struct Z; //~ ERROR expected module, found trait `Tr`
pub(in std::vec) struct F; //~ ERROR visibilities can only be restricted to ancestor modules
pub(in nonexistent) struct G; //~ ERROR cannot find module `nonexistent` in the crate root
pub(in too_soon) struct H; //~ ERROR cannot find module `too_soon` in the crate root

// Visibilities are resolved eagerly without waiting for modules becoming fully populated.
// Visibilities can only use ancestor modules legally which are always available in time,
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/resolve/auxiliary/privacy-struct-ctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub mod m {
pub struct S(u8);

pub mod n {
pub(m) struct Z(pub(m::n) u8);
pub(in m) struct Z(pub(in m::n) u8);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/resolve/privacy-struct-ctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ mod m {
pub struct S(u8);

pub mod n {
pub(m) struct Z(pub(m::n) u8);
pub(in m) struct Z(pub(in m::n) u8);
}

use m::n::Z; // OK, only the type is imported
Expand Down

0 comments on commit 008bbd3

Please sign in to comment.