Detect more cases of unused_parens around types
This commit is contained in:
committed by
Ben Schulz
parent
e61dd437f3
commit
7d6764a45b
@@ -305,8 +305,13 @@ impl<'a> Parser<'a> {
|
||||
let removal_span = kw.span.with_hi(self.token.span.lo());
|
||||
let path = self.parse_path(PathStyle::Type)?;
|
||||
let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
|
||||
let kind =
|
||||
self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?;
|
||||
let kind = self.parse_remaining_bounds_path(
|
||||
lifetime_defs,
|
||||
path,
|
||||
lo,
|
||||
parse_plus,
|
||||
ast::Parens::No,
|
||||
)?;
|
||||
let err = self.dcx().create_err(errors::TransposeDynOrImpl {
|
||||
span: kw.span,
|
||||
kw: kw.name.as_str(),
|
||||
@@ -333,7 +338,13 @@ impl<'a> Parser<'a> {
|
||||
} else {
|
||||
let path = self.parse_path(PathStyle::Type)?;
|
||||
let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus();
|
||||
self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)?
|
||||
self.parse_remaining_bounds_path(
|
||||
lifetime_defs,
|
||||
path,
|
||||
lo,
|
||||
parse_plus,
|
||||
ast::Parens::No,
|
||||
)?
|
||||
}
|
||||
}
|
||||
} else if self.eat_keyword(exp!(Impl)) {
|
||||
@@ -413,9 +424,13 @@ impl<'a> Parser<'a> {
|
||||
let maybe_bounds = allow_plus == AllowPlus::Yes && self.token.is_like_plus();
|
||||
match ty.kind {
|
||||
// `(TY_BOUND_NOPAREN) + BOUND + ...`.
|
||||
TyKind::Path(None, path) if maybe_bounds => {
|
||||
self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true)
|
||||
}
|
||||
TyKind::Path(None, path) if maybe_bounds => self.parse_remaining_bounds_path(
|
||||
ThinVec::new(),
|
||||
path,
|
||||
lo,
|
||||
true,
|
||||
ast::Parens::Yes,
|
||||
),
|
||||
// For `('a) + …`, we know that `'a` in type position already lead to an error being
|
||||
// emitted. To reduce output, let's indirectly suppress E0178 (bad `+` in type) and
|
||||
// other irrelevant consequential errors.
|
||||
@@ -495,12 +510,14 @@ impl<'a> Parser<'a> {
|
||||
path: ast::Path,
|
||||
lo: Span,
|
||||
parse_plus: bool,
|
||||
parens: ast::Parens,
|
||||
) -> PResult<'a, TyKind> {
|
||||
let poly_trait_ref = PolyTraitRef::new(
|
||||
generic_params,
|
||||
path,
|
||||
TraitBoundModifiers::NONE,
|
||||
lo.to(self.prev_token.span),
|
||||
parens,
|
||||
);
|
||||
let bounds = vec![GenericBound::Trait(poly_trait_ref)];
|
||||
self.parse_remaining_bounds(bounds, parse_plus)
|
||||
@@ -832,7 +849,7 @@ impl<'a> Parser<'a> {
|
||||
Ok(TyKind::MacCall(P(MacCall { path, args: self.parse_delim_args()? })))
|
||||
} else if allow_plus == AllowPlus::Yes && self.check_plus() {
|
||||
// `Trait1 + Trait2 + 'a`
|
||||
self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true)
|
||||
self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true, ast::Parens::No)
|
||||
} else {
|
||||
// Just a type path.
|
||||
Ok(TyKind::Path(None, path))
|
||||
@@ -897,10 +914,10 @@ impl<'a> Parser<'a> {
|
||||
fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
|
||||
let lo = self.token.span;
|
||||
let leading_token = self.prev_token;
|
||||
let has_parens = self.eat(exp!(OpenParen));
|
||||
let parens = if self.eat(exp!(OpenParen)) { ast::Parens::Yes } else { ast::Parens::No };
|
||||
|
||||
let bound = if self.token.is_lifetime() {
|
||||
self.parse_generic_lt_bound(lo, has_parens)?
|
||||
self.parse_generic_lt_bound(lo, parens)?
|
||||
} else if self.eat_keyword(exp!(Use)) {
|
||||
// parse precise captures, if any. This is `use<'lt, 'lt, P, P>`; a list of
|
||||
// lifetimes and ident params (including SelfUpper). These are validated later
|
||||
@@ -909,7 +926,7 @@ impl<'a> Parser<'a> {
|
||||
let (args, args_span) = self.parse_precise_capturing_args()?;
|
||||
GenericBound::Use(args, use_span.to(args_span))
|
||||
} else {
|
||||
self.parse_generic_ty_bound(lo, has_parens, &leading_token)?
|
||||
self.parse_generic_ty_bound(lo, parens, &leading_token)?
|
||||
};
|
||||
|
||||
Ok(bound)
|
||||
@@ -919,10 +936,14 @@ impl<'a> Parser<'a> {
|
||||
/// ```ebnf
|
||||
/// LT_BOUND = LIFETIME
|
||||
/// ```
|
||||
fn parse_generic_lt_bound(&mut self, lo: Span, has_parens: bool) -> PResult<'a, GenericBound> {
|
||||
fn parse_generic_lt_bound(
|
||||
&mut self,
|
||||
lo: Span,
|
||||
parens: ast::Parens,
|
||||
) -> PResult<'a, GenericBound> {
|
||||
let lt = self.expect_lifetime();
|
||||
let bound = GenericBound::Outlives(lt);
|
||||
if has_parens {
|
||||
if let ast::Parens::Yes = parens {
|
||||
// FIXME(Centril): Consider not erroring here and accepting `('lt)` instead,
|
||||
// possibly introducing `GenericBound::Paren(P<GenericBound>)`?
|
||||
self.recover_paren_lifetime(lo)?;
|
||||
@@ -1078,7 +1099,7 @@ impl<'a> Parser<'a> {
|
||||
fn parse_generic_ty_bound(
|
||||
&mut self,
|
||||
lo: Span,
|
||||
has_parens: bool,
|
||||
parens: ast::Parens,
|
||||
leading_token: &Token,
|
||||
) -> PResult<'a, GenericBound> {
|
||||
let (mut lifetime_defs, binder_span) = self.parse_late_bound_lifetime_defs()?;
|
||||
@@ -1104,7 +1125,7 @@ impl<'a> Parser<'a> {
|
||||
// e.g. `T: for<'a> 'a` or `T: ~const 'a`.
|
||||
if self.token.is_lifetime() {
|
||||
let _: ErrorGuaranteed = self.error_lt_bound_with_modifiers(modifiers, binder_span);
|
||||
return self.parse_generic_lt_bound(lo, has_parens);
|
||||
return self.parse_generic_lt_bound(lo, parens);
|
||||
}
|
||||
|
||||
if let (more_lifetime_defs, Some(binder_span)) = self.parse_late_bound_lifetime_defs()? {
|
||||
@@ -1171,7 +1192,7 @@ impl<'a> Parser<'a> {
|
||||
self.recover_fn_trait_with_lifetime_params(&mut path, &mut lifetime_defs)?;
|
||||
}
|
||||
|
||||
if has_parens {
|
||||
if let ast::Parens::Yes = parens {
|
||||
// Someone has written something like `&dyn (Trait + Other)`. The correct code
|
||||
// would be `&(dyn Trait + Other)`
|
||||
if self.token.is_like_plus() && leading_token.is_keyword(kw::Dyn) {
|
||||
@@ -1191,7 +1212,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
let poly_trait =
|
||||
PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span));
|
||||
PolyTraitRef::new(lifetime_defs, path, modifiers, lo.to(self.prev_token.span), parens);
|
||||
Ok(GenericBound::Trait(poly_trait))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user