Update `visibility` rule for stabilized `pub(restricted)` syntax.
Fixes #118
diff --git a/src/data.rs b/src/data.rs
index f21bfd8..69df303 100644
--- a/src/data.rs
+++ b/src/data.rs
@@ -77,7 +77,7 @@
/// Crate-visible, i.e. `pub(crate)`.
Crate,
- /// Restricted, e.g. `pub(some::module)`.
+ /// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`.
Restricted(Box<Path>),
/// Inherited, i.e. private.
@@ -97,7 +97,7 @@
use expr::parsing::expr;
use generics::parsing::where_clause;
use ident::parsing::ident;
- use ty::parsing::{path, ty};
+ use ty::parsing::{mod_style_path, ty};
named!(pub struct_body -> (WhereClause, VariantData), alt!(
do_parse!(
@@ -212,7 +212,24 @@
do_parse!(
keyword!("pub") >>
punct!("(") >>
- restricted: path >>
+ keyword!("self") >>
+ punct!(")") >>
+ (Visibility::Restricted(Box::new("self".into())))
+ )
+ |
+ do_parse!(
+ keyword!("pub") >>
+ punct!("(") >>
+ keyword!("super") >>
+ punct!(")") >>
+ (Visibility::Restricted(Box::new("super".into())))
+ )
+ |
+ do_parse!(
+ keyword!("pub") >>
+ punct!("(") >>
+ keyword!("in") >>
+ restricted: mod_style_path >>
punct!(")") >>
(Visibility::Restricted(Box::new(restricted)))
)
@@ -227,6 +244,7 @@
mod printing {
use super::*;
use quote::{Tokens, ToTokens};
+ use ty::PathParameters;
impl ToTokens for Variant {
fn to_tokens(&self, tokens: &mut Tokens) {
@@ -287,6 +305,17 @@
Visibility::Restricted(ref path) => {
tokens.append("pub");
tokens.append("(");
+
+ if !path.global &&
+ path.segments.len() == 1 &&
+ (path.segments[0].ident == "self" || path.segments[0].ident == "super") &&
+ path.segments[0].parameters == PathParameters::none() {
+
+ // Don't emit preceding `in` if path is `self` or `super`
+ } else {
+ tokens.append("in");
+ }
+
path.to_tokens(tokens);
tokens.append(")");
}
diff --git a/tests/test_macro_input.rs b/tests/test_macro_input.rs
index 6f40a00..126ed34 100644
--- a/tests/test_macro_input.rs
+++ b/tests/test_macro_input.rs
@@ -316,3 +316,85 @@
assert!(actual.attrs[0].meta_item().is_none());
}
+
+#[test]
+fn test_pub_restricted() {
+ // Taken from tests/rust/src/test/ui/resolve/auxiliary/privacy-struct-ctor.rs
+ let raw =r#"
+ pub(in m) struct Z(pub(in m::n) u8);
+ "#;
+
+ let expected = MacroInput {
+ ident: "Z".into(),
+ vis: Visibility::Restricted(Box::new("m".into())),
+ attrs: vec![],
+ generics: Generics::default(),
+ body: Body::Struct(VariantData::Tuple(vec![Field {
+ ident: None,
+ vis: Visibility::Restricted(Box::new(Path { global: false, segments: vec!["m".into(), "n".into()] })),
+ attrs: vec![],
+ ty: Ty::Path(None, "u8".into()),
+ }])),
+ };
+
+ let actual = parse_macro_input(raw).unwrap();
+
+ assert_eq!(expected, actual);
+}
+
+#[test]
+fn test_pub_restricted_crate() {
+ let raw =r#"
+ pub(crate) struct S;
+ "#;
+
+ let expected = MacroInput {
+ ident: "S".into(),
+ vis: Visibility::Crate,
+ attrs: vec![],
+ generics: Generics::default(),
+ body: Body::Struct(VariantData::Unit),
+ };
+
+ let actual = parse_macro_input(raw).unwrap();
+
+ assert_eq!(expected, actual);
+}
+
+#[test]
+fn test_pub_restricted_super() {
+ let raw =r#"
+ pub(super) struct S;
+ "#;
+
+ let expected = MacroInput {
+ ident: "S".into(),
+ vis: Visibility::Restricted(Box::new("super".into())),
+ attrs: vec![],
+ generics: Generics::default(),
+ body: Body::Struct(VariantData::Unit),
+ };
+
+ let actual = parse_macro_input(raw).unwrap();
+
+ assert_eq!(expected, actual);
+}
+
+#[test]
+fn test_pub_restricted_in_super() {
+ let raw =r#"
+ pub(in super) struct S;
+ "#;
+
+ let expected = MacroInput {
+ ident: "S".into(),
+ vis: Visibility::Restricted(Box::new("super".into())),
+ attrs: vec![],
+ generics: Generics::default(),
+ body: Body::Struct(VariantData::Unit),
+ };
+
+ let actual = parse_macro_input(raw).unwrap();
+
+ assert_eq!(expected, actual);
+}
diff --git a/tests/test_round_trip.rs b/tests/test_round_trip.rs
index 9b44115..d77bf06 100644
--- a/tests/test_round_trip.rs
+++ b/tests/test_round_trip.rs
@@ -91,9 +91,7 @@
// TODO precedence issue with binop vs poly trait ref
"tests/rust/src/test/run-pass/try-macro.rs" |
// TODO 128-bit integer literals
- "tests/rust/src/test/run-pass/u128.rs" |
- // TODO pub(restricted) syntax
- "tests/rust/src/test/ui/resolve/auxiliary/privacy-struct-ctor.rs" => false,
+ "tests/rust/src/test/run-pass/u128.rs" => false,
_ => true,
}
}