syntax: put helpers of parse_self_param
in the method.
This commit is contained in:
parent
df298b49f2
commit
30647d1a85
@ -1268,27 +1268,71 @@ impl<'a> Parser<'a> {
|
|||||||
///
|
///
|
||||||
/// See `parse_self_param_with_attrs` to collect attributes.
|
/// See `parse_self_param_with_attrs` to collect attributes.
|
||||||
fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
|
fn parse_self_param(&mut self) -> PResult<'a, Option<Param>> {
|
||||||
|
// Extract an identifier *after* having confirmed that the token is one.
|
||||||
|
let expect_self_ident = |this: &mut Self| {
|
||||||
|
match this.token.kind {
|
||||||
|
// Preserve hygienic context.
|
||||||
|
token::Ident(name, _) => {
|
||||||
|
let span = this.token.span;
|
||||||
|
this.bump();
|
||||||
|
Ident::new(name, span)
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Is `self` `n` tokens ahead?
|
||||||
|
let is_isolated_self = |this: &Self, n| {
|
||||||
|
this.is_keyword_ahead(n, &[kw::SelfLower])
|
||||||
|
&& this.look_ahead(n + 1, |t| t != &token::ModSep)
|
||||||
|
};
|
||||||
|
// Is `mut self` `n` tokens ahead?
|
||||||
|
let is_isolated_mut_self = |this: &Self, n| {
|
||||||
|
this.is_keyword_ahead(n, &[kw::Mut])
|
||||||
|
&& is_isolated_self(this, n + 1)
|
||||||
|
};
|
||||||
|
// Parse `self` or `self: TYPE`. We already know the current token is `self`.
|
||||||
|
let parse_self_possibly_typed = |this: &mut Self, m| {
|
||||||
|
let eself_ident = expect_self_ident(this);
|
||||||
|
let eself_hi = this.prev_span;
|
||||||
|
let eself = if this.eat(&token::Colon) {
|
||||||
|
SelfKind::Explicit(this.parse_ty()?, m)
|
||||||
|
} else {
|
||||||
|
SelfKind::Value(m)
|
||||||
|
};
|
||||||
|
Ok((eself, eself_ident, eself_hi))
|
||||||
|
};
|
||||||
|
// Recover for the grammar `*self`, `*const self`, and `*mut self`.
|
||||||
|
let recover_self_ptr = |this: &mut Self| {
|
||||||
|
let msg = "cannot pass `self` by raw pointer";
|
||||||
|
let span = this.token.span;
|
||||||
|
this.struct_span_err(span, msg)
|
||||||
|
.span_label(span, msg)
|
||||||
|
.emit();
|
||||||
|
|
||||||
|
Ok((SelfKind::Value(Mutability::Immutable), expect_self_ident(this), this.prev_span))
|
||||||
|
};
|
||||||
|
|
||||||
// Parse optional `self` parameter of a method.
|
// Parse optional `self` parameter of a method.
|
||||||
// Only a limited set of initial token sequences is considered `self` parameters; anything
|
// Only a limited set of initial token sequences is considered `self` parameters; anything
|
||||||
// else is parsed as a normal function parameter list, so some lookahead is required.
|
// else is parsed as a normal function parameter list, so some lookahead is required.
|
||||||
let eself_lo = self.token.span;
|
let eself_lo = self.token.span;
|
||||||
let (eself, eself_ident, eself_hi) = match self.token.kind {
|
let (eself, eself_ident, eself_hi) = match self.token.kind {
|
||||||
token::BinOp(token::And) => {
|
token::BinOp(token::And) => {
|
||||||
let eself = if self.is_isolated_self(1) {
|
let eself = if is_isolated_self(self, 1) {
|
||||||
// `&self`
|
// `&self`
|
||||||
self.bump();
|
self.bump();
|
||||||
SelfKind::Region(None, Mutability::Immutable)
|
SelfKind::Region(None, Mutability::Immutable)
|
||||||
} else if self.is_isolated_mut_self(1) {
|
} else if is_isolated_mut_self(self, 1) {
|
||||||
// `&mut self`
|
// `&mut self`
|
||||||
self.bump();
|
self.bump();
|
||||||
self.bump();
|
self.bump();
|
||||||
SelfKind::Region(None, Mutability::Mutable)
|
SelfKind::Region(None, Mutability::Mutable)
|
||||||
} else if self.look_ahead(1, |t| t.is_lifetime()) && self.is_isolated_self(2) {
|
} else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) {
|
||||||
// `&'lt self`
|
// `&'lt self`
|
||||||
self.bump();
|
self.bump();
|
||||||
let lt = self.expect_lifetime();
|
let lt = self.expect_lifetime();
|
||||||
SelfKind::Region(Some(lt), Mutability::Immutable)
|
SelfKind::Region(Some(lt), Mutability::Immutable)
|
||||||
} else if self.look_ahead(1, |t| t.is_lifetime()) && self.is_isolated_mut_self(2) {
|
} else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) {
|
||||||
// `&'lt mut self`
|
// `&'lt mut self`
|
||||||
self.bump();
|
self.bump();
|
||||||
let lt = self.expect_lifetime();
|
let lt = self.expect_lifetime();
|
||||||
@ -1298,30 +1342,30 @@ impl<'a> Parser<'a> {
|
|||||||
// `¬_self`
|
// `¬_self`
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
(eself, self.expect_self_ident(), self.prev_span)
|
(eself, expect_self_ident(self), self.prev_span)
|
||||||
}
|
}
|
||||||
// `*self`
|
// `*self`
|
||||||
token::BinOp(token::Star) if self.is_isolated_self(1) => {
|
token::BinOp(token::Star) if is_isolated_self(self, 1) => {
|
||||||
self.bump();
|
self.bump();
|
||||||
self.recover_self_ptr()?
|
recover_self_ptr(self)?
|
||||||
}
|
}
|
||||||
// `*mut self` and `*const self`
|
// `*mut self` and `*const self`
|
||||||
token::BinOp(token::Star) if
|
token::BinOp(token::Star) if
|
||||||
self.look_ahead(1, |t| t.is_mutability())
|
self.look_ahead(1, |t| t.is_mutability())
|
||||||
&& self.is_isolated_self(2) =>
|
&& is_isolated_self(self, 2) =>
|
||||||
{
|
{
|
||||||
self.bump();
|
self.bump();
|
||||||
self.bump();
|
self.bump();
|
||||||
self.recover_self_ptr()?
|
recover_self_ptr(self)?
|
||||||
}
|
}
|
||||||
// `self` and `self: TYPE`
|
// `self` and `self: TYPE`
|
||||||
token::Ident(..) if self.is_isolated_self(0) => {
|
token::Ident(..) if is_isolated_self(self, 0) => {
|
||||||
self.parse_self_possibly_typed(Mutability::Immutable)?
|
parse_self_possibly_typed(self, Mutability::Immutable)?
|
||||||
}
|
}
|
||||||
// `mut self` and `mut self: TYPE`
|
// `mut self` and `mut self: TYPE`
|
||||||
token::Ident(..) if self.is_isolated_mut_self(0) => {
|
token::Ident(..) if is_isolated_mut_self(self, 0) => {
|
||||||
self.bump();
|
self.bump();
|
||||||
self.parse_self_possibly_typed(Mutability::Mutable)?
|
parse_self_possibly_typed(self, Mutability::Mutable)?
|
||||||
}
|
}
|
||||||
_ => return Ok(None),
|
_ => return Ok(None),
|
||||||
};
|
};
|
||||||
@ -1345,51 +1389,6 @@ impl<'a> Parser<'a> {
|
|||||||
self.look_ahead(offset + 1, |t| t == &token::Colon)
|
self.look_ahead(offset + 1, |t| t == &token::Colon)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_isolated_self(&self, n: usize) -> bool {
|
|
||||||
self.is_keyword_ahead(n, &[kw::SelfLower])
|
|
||||||
&& self.look_ahead(n + 1, |t| t != &token::ModSep)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_isolated_mut_self(&self, n: usize) -> bool {
|
|
||||||
self.is_keyword_ahead(n, &[kw::Mut])
|
|
||||||
&& self.is_isolated_self(n + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expect_self_ident(&mut self) -> Ident {
|
|
||||||
match self.token.kind {
|
|
||||||
// Preserve hygienic context.
|
|
||||||
token::Ident(name, _) => {
|
|
||||||
let span = self.token.span;
|
|
||||||
self.bump();
|
|
||||||
Ident::new(name, span)
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Recover for the grammar `*self`, `*const self`, and `*mut self`.
|
|
||||||
fn recover_self_ptr(&mut self) -> PResult<'a, (ast::SelfKind, Ident, Span)> {
|
|
||||||
let msg = "cannot pass `self` by raw pointer";
|
|
||||||
let span = self.token.span;
|
|
||||||
self.struct_span_err(span, msg)
|
|
||||||
.span_label(span, msg)
|
|
||||||
.emit();
|
|
||||||
|
|
||||||
Ok((SelfKind::Value(Mutability::Immutable), self.expect_self_ident(), self.prev_span))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parse `self` or `self: TYPE`. We already know the current token is `self`.
|
|
||||||
fn parse_self_possibly_typed(&mut self, m: Mutability) -> PResult<'a, (SelfKind, Ident, Span)> {
|
|
||||||
let eself_ident = self.expect_self_ident();
|
|
||||||
let eself_hi = self.prev_span;
|
|
||||||
let eself = if self.eat(&token::Colon) {
|
|
||||||
SelfKind::Explicit(self.parse_ty()?, m)
|
|
||||||
} else {
|
|
||||||
SelfKind::Value(m)
|
|
||||||
};
|
|
||||||
Ok((eself, eself_ident, eself_hi))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_crate_vis(&self) -> bool {
|
fn is_crate_vis(&self) -> bool {
|
||||||
self.token.is_keyword(kw::Crate) && self.look_ahead(1, |t| t != &token::ModSep)
|
self.token.is_keyword(kw::Crate) && self.look_ahead(1, |t| t != &token::ModSep)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user