syntax: cleanup parse_visibility
.
This commit is contained in:
parent
5b80ead489
commit
66bf323a3b
1 changed files with 69 additions and 53 deletions
|
@ -1417,66 +1417,82 @@ impl<'a> Parser<'a> {
|
||||||
// `()` or a tuple might be allowed. For example, `struct Struct(pub (), pub (usize));`.
|
// `()` or a tuple might be allowed. For example, `struct Struct(pub (), pub (usize));`.
|
||||||
// Because of this, we only `bump` the `(` if we're assured it is appropriate to do so
|
// Because of this, we only `bump` the `(` if we're assured it is appropriate to do so
|
||||||
// by the following tokens.
|
// by the following tokens.
|
||||||
if self.is_keyword_ahead(1, &[kw::Crate]) &&
|
if self.is_keyword_ahead(1, &[kw::Crate])
|
||||||
self.look_ahead(2, |t| t != &token::ModSep) // account for `pub(crate::foo)`
|
&& self.look_ahead(2, |t| t != &token::ModSep) // account for `pub(crate::foo)`
|
||||||
{
|
{
|
||||||
// `pub(crate)`
|
return self.parse_vis_pub_crate(lo);
|
||||||
|
} else if self.is_keyword_ahead(1, &[kw::In]) {
|
||||||
|
return self.parse_vis_pub_in(lo);
|
||||||
|
} else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren))
|
||||||
|
&& self.is_keyword_ahead(1, &[kw::Super, kw::SelfLower])
|
||||||
|
{
|
||||||
|
return self.parse_vis_self_super(lo);
|
||||||
|
} else if !can_take_tuple { // Provide this diagnostic if this is not a tuple struct.
|
||||||
|
self.recover_incorrect_vis_restriction()?;
|
||||||
|
// Emit diagnostic, but continue with public visibility.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(respan(lo, VisibilityKind::Public))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse `pub(crate)`.
|
||||||
|
fn parse_vis_pub_crate(&mut self, lo: Span) -> PResult<'a, Visibility> {
|
||||||
self.bump(); // `(`
|
self.bump(); // `(`
|
||||||
self.bump(); // `crate`
|
self.bump(); // `crate`
|
||||||
self.expect(&token::CloseDelim(token::Paren))?; // `)`
|
self.expect(&token::CloseDelim(token::Paren))?; // `)`
|
||||||
let vis = respan(
|
Ok(respan(
|
||||||
lo.to(self.prev_span),
|
lo.to(self.prev_span),
|
||||||
VisibilityKind::Crate(CrateSugar::PubCrate),
|
VisibilityKind::Crate(CrateSugar::PubCrate),
|
||||||
);
|
))
|
||||||
return Ok(vis)
|
}
|
||||||
} else if self.is_keyword_ahead(1, &[kw::In]) {
|
|
||||||
// `pub(in path)`
|
/// Parse `pub(in path)`.
|
||||||
|
fn parse_vis_pub_in(&mut self, lo: Span) -> PResult<'a, Visibility> {
|
||||||
self.bump(); // `(`
|
self.bump(); // `(`
|
||||||
self.bump(); // `in`
|
self.bump(); // `in`
|
||||||
let path = self.parse_path(PathStyle::Mod)?; // `path`
|
let path = self.parse_path(PathStyle::Mod)?; // `path`
|
||||||
self.expect(&token::CloseDelim(token::Paren))?; // `)`
|
self.expect(&token::CloseDelim(token::Paren))?; // `)`
|
||||||
let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
|
Ok(respan(lo.to(self.prev_span), VisibilityKind::Restricted {
|
||||||
path: P(path),
|
path: P(path),
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
});
|
}))
|
||||||
return Ok(vis)
|
}
|
||||||
} else if self.look_ahead(2, |t| t == &token::CloseDelim(token::Paren)) &&
|
|
||||||
self.is_keyword_ahead(1, &[kw::Super, kw::SelfLower])
|
/// Parse `pub(self)` or `pub(super)`.
|
||||||
{
|
fn parse_vis_self_super(&mut self, lo: Span) -> PResult<'a, Visibility> {
|
||||||
// `pub(self)` or `pub(super)`
|
|
||||||
self.bump(); // `(`
|
self.bump(); // `(`
|
||||||
let path = self.parse_path(PathStyle::Mod)?; // `super`/`self`
|
let path = self.parse_path(PathStyle::Mod)?; // `super`/`self`
|
||||||
self.expect(&token::CloseDelim(token::Paren))?; // `)`
|
self.expect(&token::CloseDelim(token::Paren))?; // `)`
|
||||||
let vis = respan(lo.to(self.prev_span), VisibilityKind::Restricted {
|
Ok(respan(lo.to(self.prev_span), VisibilityKind::Restricted {
|
||||||
path: P(path),
|
path: P(path),
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
});
|
}))
|
||||||
return Ok(vis)
|
}
|
||||||
} else if !can_take_tuple { // Provide this diagnostic if this is not a tuple struct
|
|
||||||
// `pub(something) fn ...` or `struct X { pub(something) y: Z }`
|
/// Recovery for e.g. `pub(something) fn ...` or `struct X { pub(something) y: Z }`
|
||||||
|
fn recover_incorrect_vis_restriction(&mut self) -> PResult<'a, ()> {
|
||||||
self.bump(); // `(`
|
self.bump(); // `(`
|
||||||
|
let path = self.parse_path(PathStyle::Mod)?;
|
||||||
|
self.expect(&token::CloseDelim(token::Paren))?; // `)`
|
||||||
|
|
||||||
let msg = "incorrect visibility restriction";
|
let msg = "incorrect visibility restriction";
|
||||||
let suggestion = r##"some possible visibility restrictions are:
|
let suggestion = r##"some possible visibility restrictions are:
|
||||||
`pub(crate)`: visible only on the current crate
|
`pub(crate)`: visible only on the current crate
|
||||||
`pub(super)`: visible only in the current module's parent
|
`pub(super)`: visible only in the current module's parent
|
||||||
`pub(in path::to::module)`: visible only on the specified path"##;
|
`pub(in path::to::module)`: visible only on the specified path"##;
|
||||||
let path = self.parse_path(PathStyle::Mod)?;
|
|
||||||
let sp = path.span;
|
struct_span_err!(self.sess.span_diagnostic, path.span, E0704, "{}", msg)
|
||||||
let help_msg = format!("make this visible only to module `{}` with `in`", path);
|
|
||||||
self.expect(&token::CloseDelim(token::Paren))?; // `)`
|
|
||||||
struct_span_err!(self.sess.span_diagnostic, sp, E0704, "{}", msg)
|
|
||||||
.help(suggestion)
|
.help(suggestion)
|
||||||
.span_suggestion(
|
.span_suggestion(
|
||||||
sp,
|
path.span,
|
||||||
&help_msg,
|
&format!("make this visible only to module `{}` with `in`", path),
|
||||||
format!("in {}", path),
|
format!("in {}", path),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
)
|
)
|
||||||
.emit(); // Emit diagnostic, but continue with public visibility.
|
.emit();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(respan(lo, VisibilityKind::Public))
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a string as an ABI spec on an extern type or module. Consumes
|
/// Parses a string as an ABI spec on an extern type or module. Consumes
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue