Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/rust/syn/restriction.rs
38271 views
1
// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3
use crate::path::Path;
4
use crate::token;
5
6
ast_enum! {
7
/// The visibility level of an item: inherited or `pub` or
8
/// `pub(restricted)`.
9
///
10
/// # Syntax tree enum
11
///
12
/// This type is a [syntax tree enum].
13
///
14
/// [syntax tree enum]: crate::expr::Expr#syntax-tree-enums
15
#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
16
pub enum Visibility {
17
/// A public visibility level: `pub`.
18
Public(Token![pub]),
19
20
/// A visibility level restricted to some path: `pub(self)` or
21
/// `pub(super)` or `pub(crate)` or `pub(in some::module)`.
22
Restricted(VisRestricted),
23
24
/// An inherited visibility, which usually means private.
25
Inherited,
26
}
27
}
28
29
ast_struct! {
30
/// A visibility level restricted to some path: `pub(self)` or
31
/// `pub(super)` or `pub(crate)` or `pub(in some::module)`.
32
#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
33
pub struct VisRestricted {
34
pub pub_token: Token![pub],
35
pub paren_token: token::Paren,
36
pub in_token: Option<Token![in]>,
37
pub path: Box<Path>,
38
}
39
}
40
41
ast_enum! {
42
/// Unused, but reserved for RFC 3323 restrictions.
43
#[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
44
#[non_exhaustive]
45
pub enum FieldMutability {
46
None,
47
48
// TODO: https://rust-lang.github.io/rfcs/3323-restrictions.html
49
//
50
// FieldMutability::Restricted(MutRestricted)
51
//
52
// pub struct MutRestricted {
53
// pub mut_token: Token![mut],
54
// pub paren_token: token::Paren,
55
// pub in_token: Option<Token![in]>,
56
// pub path: Box<Path>,
57
// }
58
}
59
}
60
61
#[cfg(feature = "parsing")]
62
pub(crate) mod parsing {
63
use crate::error::Result;
64
use crate::ext::IdentExt as _;
65
use crate::ident::Ident;
66
use crate::parse::discouraged::Speculative as _;
67
use crate::parse::{Parse, ParseStream};
68
use crate::path::Path;
69
use crate::restriction::{VisRestricted, Visibility};
70
use crate::token;
71
72
#[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
73
impl Parse for Visibility {
74
fn parse(input: ParseStream) -> Result<Self> {
75
// Recognize an empty None-delimited group, as produced by a $:vis
76
// matcher that matched no tokens.
77
if input.peek(token::Group) {
78
let ahead = input.fork();
79
let group = crate::group::parse_group(&ahead)?;
80
if group.content.is_empty() {
81
input.advance_to(&ahead);
82
return Ok(Visibility::Inherited);
83
}
84
}
85
86
if input.peek(Token![pub]) {
87
Self::parse_pub(input)
88
} else {
89
Ok(Visibility::Inherited)
90
}
91
}
92
}
93
94
impl Visibility {
95
fn parse_pub(input: ParseStream) -> Result<Self> {
96
let pub_token = input.parse::<Token![pub]>()?;
97
98
if input.peek(token::Paren) {
99
let ahead = input.fork();
100
101
let content;
102
let paren_token = parenthesized!(content in ahead);
103
if content.peek(Token![crate])
104
|| content.peek(Token![self])
105
|| content.peek(Token![super])
106
{
107
let path = content.call(Ident::parse_any)?;
108
109
// Ensure there are no additional tokens within `content`.
110
// Without explicitly checking, we may misinterpret a tuple
111
// field as a restricted visibility, causing a parse error.
112
// e.g. `pub (crate::A, crate::B)` (Issue #720).
113
if content.is_empty() {
114
input.advance_to(&ahead);
115
return Ok(Visibility::Restricted(VisRestricted {
116
pub_token,
117
paren_token,
118
in_token: None,
119
path: Box::new(Path::from(path)),
120
}));
121
}
122
} else if content.peek(Token![in]) {
123
let in_token: Token![in] = content.parse()?;
124
let path = content.call(Path::parse_mod_style)?;
125
126
input.advance_to(&ahead);
127
return Ok(Visibility::Restricted(VisRestricted {
128
pub_token,
129
paren_token,
130
in_token: Some(in_token),
131
path: Box::new(path),
132
}));
133
}
134
}
135
136
Ok(Visibility::Public(pub_token))
137
}
138
139
#[cfg(feature = "full")]
140
pub(crate) fn is_some(&self) -> bool {
141
match self {
142
Visibility::Inherited => false,
143
_ => true,
144
}
145
}
146
}
147
}
148
149
#[cfg(feature = "printing")]
150
mod printing {
151
use crate::path;
152
use crate::path::printing::PathStyle;
153
use crate::restriction::{VisRestricted, Visibility};
154
use proc_macro2::TokenStream;
155
use quote::ToTokens;
156
157
#[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
158
impl ToTokens for Visibility {
159
fn to_tokens(&self, tokens: &mut TokenStream) {
160
match self {
161
Visibility::Public(pub_token) => pub_token.to_tokens(tokens),
162
Visibility::Restricted(vis_restricted) => vis_restricted.to_tokens(tokens),
163
Visibility::Inherited => {}
164
}
165
}
166
}
167
168
#[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
169
impl ToTokens for VisRestricted {
170
fn to_tokens(&self, tokens: &mut TokenStream) {
171
self.pub_token.to_tokens(tokens);
172
self.paren_token.surround(tokens, |tokens| {
173
// TODO: If we have a path which is not "self" or "super" or
174
// "crate", automatically add the "in" token.
175
self.in_token.to_tokens(tokens);
176
path::printing::print_path(tokens, &self.path, PathStyle::Mod);
177
});
178
}
179
}
180
}
181
182