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
|
.suggestion_open_range = use `..` instead
|
||||||
.note = inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
.note = inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
|
||||||
|
|
||||||
parse_incorrect_braces_trait_bounds = incorrect braces around trait bounds
|
parse_incorrect_parens_trait_bounds = incorrect parentheses around trait bounds
|
||||||
.suggestion = remove the parentheses
|
parse_incorrect_parens_trait_bounds_sugg = fix the parentheses
|
||||||
|
|
||||||
parse_incorrect_semicolon =
|
parse_incorrect_semicolon =
|
||||||
expected item, found `;`
|
expected item, found `;`
|
||||||
|
@ -2636,21 +2636,24 @@ pub(crate) struct MissingPlusBounds {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(parse_incorrect_braces_trait_bounds)]
|
#[diag(parse_incorrect_parens_trait_bounds)]
|
||||||
pub(crate) struct IncorrectBracesTraitBounds {
|
pub(crate) struct IncorrectParensTraitBounds {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Vec<Span>,
|
pub span: Vec<Span>,
|
||||||
#[subdiagnostic]
|
#[subdiagnostic]
|
||||||
pub sugg: IncorrectBracesTraitBoundsSugg,
|
pub sugg: IncorrectParensTraitBoundsSugg,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subdiagnostic)]
|
#[derive(Subdiagnostic)]
|
||||||
#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
|
#[multipart_suggestion(
|
||||||
pub(crate) struct IncorrectBracesTraitBoundsSugg {
|
parse_incorrect_parens_trait_bounds_sugg,
|
||||||
|
applicability = "machine-applicable"
|
||||||
|
)]
|
||||||
|
pub(crate) struct IncorrectParensTraitBoundsSugg {
|
||||||
#[suggestion_part(code = " ")]
|
#[suggestion_part(code = " ")]
|
||||||
pub l: Span,
|
pub wrong_span: Span,
|
||||||
#[suggestion_part(code = "")]
|
#[suggestion_part(code = "(")]
|
||||||
pub r: Span,
|
pub new_span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
|
@ -714,6 +714,7 @@ fn can_begin_bound(&mut self) -> bool {
|
|||||||
/// ```
|
/// ```
|
||||||
fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
|
fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> {
|
||||||
let lo = self.token.span;
|
let lo = self.token.span;
|
||||||
|
let leading_token = self.prev_token.clone();
|
||||||
let has_parens = self.eat(&token::OpenDelim(Delimiter::Parenthesis));
|
let has_parens = self.eat(&token::OpenDelim(Delimiter::Parenthesis));
|
||||||
let inner_lo = self.token.span;
|
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.error_lt_bound_with_modifiers(modifiers);
|
||||||
self.parse_generic_lt_bound(lo, inner_lo, has_parens)?
|
self.parse_generic_lt_bound(lo, inner_lo, has_parens)?
|
||||||
} else {
|
} else {
|
||||||
self.parse_generic_ty_bound(lo, has_parens, modifiers)?
|
self.parse_generic_ty_bound(lo, has_parens, modifiers, &leading_token)?
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(bound)
|
Ok(bound)
|
||||||
@ -827,6 +828,7 @@ fn parse_generic_ty_bound(
|
|||||||
lo: Span,
|
lo: Span,
|
||||||
has_parens: bool,
|
has_parens: bool,
|
||||||
modifiers: BoundModifiers,
|
modifiers: BoundModifiers,
|
||||||
|
leading_token: &Token,
|
||||||
) -> PResult<'a, GenericBound> {
|
) -> PResult<'a, GenericBound> {
|
||||||
let mut lifetime_defs = self.parse_late_bound_lifetime_defs()?;
|
let mut lifetime_defs = self.parse_late_bound_lifetime_defs()?;
|
||||||
let mut path = if self.token.is_keyword(kw::Fn)
|
let mut path = if self.token.is_keyword(kw::Fn)
|
||||||
@ -873,18 +875,18 @@ fn parse_generic_ty_bound(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if has_parens {
|
if has_parens {
|
||||||
if self.token.is_like_plus() {
|
// Someone has written something like `&dyn (Trait + Other)`. The correct code
|
||||||
// Someone has written something like `&dyn (Trait + Other)`. The correct code
|
// would be `&(dyn Trait + Other)`
|
||||||
// would be `&(dyn Trait + Other)`, but we don't have access to the appropriate
|
if self.token.is_like_plus() && leading_token.is_keyword(kw::Dyn) {
|
||||||
// span to suggest that. When written as `&dyn Trait + Other`, an appropriate
|
|
||||||
// suggestion is given.
|
|
||||||
let bounds = vec![];
|
let bounds = vec![];
|
||||||
self.parse_remaining_bounds(bounds, true)?;
|
self.parse_remaining_bounds(bounds, true)?;
|
||||||
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
|
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
|
||||||
let sp = vec![lo, self.prev_token.span];
|
self.sess.emit_err(errors::IncorrectParensTraitBounds {
|
||||||
self.sess.emit_err(errors::IncorrectBracesTraitBounds {
|
span: vec![lo, self.prev_token.span],
|
||||||
span: sp,
|
sugg: errors::IncorrectParensTraitBoundsSugg {
|
||||||
sugg: errors::IncorrectBracesTraitBoundsSugg { l: lo, r: self.prev_token.span },
|
wrong_span: leading_token.span.shrink_to_hi().to(lo),
|
||||||
|
new_span: leading_token.span.shrink_to_lo(),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
|
self.expect(&token::CloseDelim(Delimiter::Parenthesis))?;
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
fn foo1(_: &dyn Drop + AsRef<str>) {} //~ ERROR ambiguous `+` in a type
|
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
|
//~^ 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 `{`
|
fn foo3(_: &dyn {Drop + AsRef<str>}) {} //~ ERROR expected parameter name, found `{`
|
||||||
//~^ ERROR expected one of `!`, `(`, `)`, `*`, `,`, `?`, `for`, `~`, lifetime, or path, 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>) {}
|
LL | fn foo1(_: &dyn Drop + AsRef<str>) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(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
|
--> $DIR/trait-object-delimiters.rs:6:17
|
||||||
|
|
|
|
||||||
LL | fn foo2(_: &dyn (Drop + AsRef<str>)) {}
|
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>) {}
|
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
|
--> $DIR/trait-object-delimiters.rs:8:25
|
||||||
|
|
|
|
||||||
LL | fn foo2_no_space(_: &dyn(Drop + AsRef<str>)) {}
|
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>) {}
|
LL + fn foo2_no_space(_: &(dyn Drop + AsRef<str>)) {}
|
||||||
|
|
|
|
||||||
|
|
||||||
error: expected parameter name, found `{`
|
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