Fix bad suggestion when wrong parentheses around a dyn trait
This commit is contained in:
parent
fd9525adb0
commit
ddcd7cac41
@ -310,8 +310,8 @@ parse_inclusive_range_no_end = inclusive range with no end
|
||||
.suggestion_open_range = use `..` instead
|
||||
.note = inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||
|
||||
parse_incorrect_braces_trait_bounds = incorrect braces around trait bounds
|
||||
.suggestion = remove the parentheses
|
||||
parse_incorrect_parens_trait_bounds = incorrect parentheses around trait bounds
|
||||
parse_incorrect_parens_trait_bounds_sugg = fix the parentheses
|
||||
|
||||
parse_incorrect_semicolon =
|
||||
expected item, found `;`
|
||||
|
@ -2636,21 +2636,24 @@ pub(crate) struct MissingPlusBounds {
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_incorrect_braces_trait_bounds)]
|
||||
pub(crate) struct IncorrectBracesTraitBounds {
|
||||
#[diag(parse_incorrect_parens_trait_bounds)]
|
||||
pub(crate) struct IncorrectParensTraitBounds {
|
||||
#[primary_span]
|
||||
pub span: Vec<Span>,
|
||||
#[subdiagnostic]
|
||||
pub sugg: IncorrectBracesTraitBoundsSugg,
|
||||
pub sugg: IncorrectParensTraitBoundsSugg,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
|
||||
pub(crate) struct IncorrectBracesTraitBoundsSugg {
|
||||
#[multipart_suggestion(
|
||||
parse_incorrect_parens_trait_bounds_sugg,
|
||||
applicability = "machine-applicable"
|
||||
)]
|
||||
pub(crate) struct IncorrectParensTraitBoundsSugg {
|
||||
#[suggestion_part(code = " ")]
|
||||
pub l: Span,
|
||||
#[suggestion_part(code = "")]
|
||||
pub r: Span,
|
||||
pub wrong_span: Span,
|
||||
#[suggestion_part(code = "(")]
|
||||
pub new_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -714,6 +714,7 @@ fn can_begin_bound(&mut self) -> bool {
|
||||
/// ```
|
||||
fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
|
||||
let lo = self.token.span;
|
||||
let leading_token = self.prev_token.clone();
|
||||
let has_parens = self.eat(&token::OpenDelim(Delimiter::Parenthesis));
|
||||
let inner_lo = self.token.span;
|
||||
|
||||
@ -722,7 +723,7 @@ fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
|
||||
self.error_lt_bound_with_modifiers(modifiers);
|
||||
self.parse_generic_lt_bound(lo, inner_lo, has_parens)?
|
||||
} else {
|
||||
self.parse_generic_ty_bound(lo, has_parens, modifiers)?
|
||||
self.parse_generic_ty_bound(lo, has_parens, modifiers, &leading_token)?
|
||||
};
|
||||
|
||||
Ok(bound)
|
||||
@ -827,6 +828,7 @@ fn parse_generic_ty_bound(
|
||||
lo: Span,
|
||||
has_parens: bool,
|
||||
modifiers: BoundModifiers,
|
||||
leading_token: &Token,
|
||||
) -> PResult<'a, GenericBound> {
|
||||
let mut lifetime_defs = self.parse_late_bound_lifetime_defs()?;
|
||||
let mut path = if self.token.is_keyword(kw::Fn)
|
||||
@ -873,18 +875,18 @@ fn parse_generic_ty_bound(
|
||||
}
|
||||
|
||||
if has_parens {
|
||||
if self.token.is_like_plus() {
|
||||
// Someone has written something like `&dyn (Trait + Other)`. The correct code
|
||||
// would be `&(dyn Trait + Other)`, but we don't have access to the appropriate
|
||||
// span to suggest that. When written as `&dyn Trait + Other`, an appropriate
|
||||
// suggestion is given.
|
||||
// would be `&(dyn Trait + Other)`
|
||||
if self.token.is_like_plus() && leading_token.is_keyword(kw::Dyn) {
|
||||
let bounds = vec![];
|
||||
self.parse_remaining_bounds(bounds, true)?;
|
||||
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
|
||||
let sp = vec![lo, self.prev_token.span];
|
||||
self.sess.emit_err(errors::IncorrectBracesTraitBounds {
|
||||
span: sp,
|
||||
sugg: errors::IncorrectBracesTraitBoundsSugg { l: lo, r: self.prev_token.span },
|
||||
self.sess.emit_err(errors::IncorrectParensTraitBounds {
|
||||
span: vec![lo, self.prev_token.span],
|
||||
sugg: errors::IncorrectParensTraitBoundsSugg {
|
||||
wrong_span: leading_token.span.shrink_to_hi().to(lo),
|
||||
new_span: leading_token.span.shrink_to_lo(),
|
||||
},
|
||||
});
|
||||
} else {
|
||||
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
|
||||
|
@ -3,9 +3,9 @@
|
||||
fn foo1(_: &dyn Drop + AsRef<str>) {} //~ ERROR ambiguous `+` in a type
|
||||
//~^ ERROR only auto traits can be used as additional traits in a trait object
|
||||
|
||||
fn foo2(_: &dyn (Drop + AsRef<str>)) {} //~ ERROR incorrect braces around trait bounds
|
||||
fn foo2(_: &dyn (Drop + AsRef<str>)) {} //~ ERROR incorrect parentheses around trait bounds
|
||||
|
||||
fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {} //~ ERROR incorrect braces around trait bounds
|
||||
fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {} //~ ERROR incorrect parentheses around trait bounds
|
||||
|
||||
fn foo3(_: &dyn {Drop + AsRef<str>}) {} //~ ERROR expected parameter name, found `{`
|
||||
//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, found `{`
|
||||
|
@ -4,28 +4,28 @@ error: ambiguous `+` in a type
|
||||
LL | fn foo1(_: &dyn Drop + AsRef<str>) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(dyn Drop + AsRef<str>)`
|
||||
|
||||
error: incorrect braces around trait bounds
|
||||
error: incorrect parentheses around trait bounds
|
||||
--> $DIR/trait-object-delimiters.rs:6:17
|
||||
|
|
||||
LL | fn foo2(_: &dyn (Drop + AsRef<str>)) {}
|
||||
| ^ ^
|
||||
|
|
||||
help: remove the parentheses
|
||||
help: fix the parentheses
|
||||
|
|
||||
LL - fn foo2(_: &dyn (Drop + AsRef<str>)) {}
|
||||
LL + fn foo2(_: &dyn Drop + AsRef<str>) {}
|
||||
LL + fn foo2(_: &(dyn Drop + AsRef<str>)) {}
|
||||
|
|
||||
|
||||
error: incorrect braces around trait bounds
|
||||
error: incorrect parentheses around trait bounds
|
||||
--> $DIR/trait-object-delimiters.rs:8:25
|
||||
|
|
||||
LL | fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {}
|
||||
| ^ ^
|
||||
|
|
||||
help: remove the parentheses
|
||||
help: fix the parentheses
|
||||
|
|
||||
LL - fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {}
|
||||
LL + fn foo2_no_space(_: &dyn Drop + AsRef<str>) {}
|
||||
LL + fn foo2_no_space(_: &(dyn Drop + AsRef<str>)) {}
|
||||
|
|
||||
|
||||
error: expected parameter name, found `{`
|
||||
|
@ -0,0 +1,17 @@
|
||||
//run-rustfix
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Trait {}
|
||||
|
||||
fn assert_send(ptr: *mut dyn Trait) -> *mut (dyn Trait + Send) {
|
||||
//~^ ERROR incorrect parentheses around trait bounds
|
||||
ptr as _
|
||||
}
|
||||
|
||||
fn foo2(_: &(dyn Trait + Send)) {}
|
||||
//~^ ERROR incorrect parentheses around trait bounds
|
||||
|
||||
fn foo3(_: &(dyn Trait + Send)) {}
|
||||
//~^ ERROR incorrect parentheses around trait bounds
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,17 @@
|
||||
//run-rustfix
|
||||
#![allow(dead_code)]
|
||||
|
||||
trait Trait {}
|
||||
|
||||
fn assert_send(ptr: *mut dyn Trait) -> *mut dyn (Trait + Send) {
|
||||
//~^ ERROR incorrect parentheses around trait bounds
|
||||
ptr as _
|
||||
}
|
||||
|
||||
fn foo2(_: &dyn (Trait + Send)) {}
|
||||
//~^ ERROR incorrect parentheses around trait bounds
|
||||
|
||||
fn foo3(_: &dyn(Trait + Send)) {}
|
||||
//~^ ERROR incorrect parentheses around trait bounds
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,38 @@
|
||||
error: incorrect parentheses around trait bounds
|
||||
--> $DIR/issue-114797-bad-parentheses-dyn-trait.rs:6:49
|
||||
|
|
||||
LL | fn assert_send(ptr: *mut dyn Trait) -> *mut dyn (Trait + Send) {
|
||||
| ^ ^
|
||||
|
|
||||
help: fix the parentheses
|
||||
|
|
||||
LL - fn assert_send(ptr: *mut dyn Trait) -> *mut dyn (Trait + Send) {
|
||||
LL + fn assert_send(ptr: *mut dyn Trait) -> *mut (dyn Trait + Send) {
|
||||
|
|
||||
|
||||
error: incorrect parentheses around trait bounds
|
||||
--> $DIR/issue-114797-bad-parentheses-dyn-trait.rs:11:17
|
||||
|
|
||||
LL | fn foo2(_: &dyn (Trait + Send)) {}
|
||||
| ^ ^
|
||||
|
|
||||
help: fix the parentheses
|
||||
|
|
||||
LL - fn foo2(_: &dyn (Trait + Send)) {}
|
||||
LL + fn foo2(_: &(dyn Trait + Send)) {}
|
||||
|
|
||||
|
||||
error: incorrect parentheses around trait bounds
|
||||
--> $DIR/issue-114797-bad-parentheses-dyn-trait.rs:14:16
|
||||
|
|
||||
LL | fn foo3(_: &dyn(Trait + Send)) {}
|
||||
| ^ ^
|
||||
|
|
||||
help: fix the parentheses
|
||||
|
|
||||
LL - fn foo3(_: &dyn(Trait + Send)) {}
|
||||
LL + fn foo3(_: &(dyn Trait + Send)) {}
|
||||
|
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
Loading…
Reference in New Issue
Block a user