Fix suggestions span for when expr is from macro expansions
This commit is contained in:
parent
08fd6f719e
commit
25d065b2d4
@ -982,17 +982,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
let ty = self.normalize(expr.span, ty);
|
let ty = self.normalize(expr.span, ty);
|
||||||
if self.can_coerce(found, ty) {
|
if self.can_coerce(found, ty) {
|
||||||
|
if let Some(node) = self.tcx.hir().find(fn_id)
|
||||||
|
&& let Some(owner_node) = node.as_owner()
|
||||||
|
&& let Some(span) = expr.span.find_ancestor_inside(owner_node.span())
|
||||||
|
{
|
||||||
err.multipart_suggestion(
|
err.multipart_suggestion(
|
||||||
"you might have meant to return this value",
|
"you might have meant to return this value",
|
||||||
vec![
|
vec![
|
||||||
(expr.span.shrink_to_lo(), "return ".to_string()),
|
(span.shrink_to_lo(), "return ".to_string()),
|
||||||
(expr.span.shrink_to_hi(), ";".to_string()),
|
(span.shrink_to_hi(), ";".to_string()),
|
||||||
],
|
],
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(in super::super) fn suggest_missing_parentheses(
|
pub(in super::super) fn suggest_missing_parentheses(
|
||||||
&self,
|
&self,
|
||||||
@ -1177,10 +1182,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
),
|
),
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
|
let mut span = expr.span;
|
||||||
|
while expr.span.eq_ctxt(span) && let Some(parent_callsite) = span.parent_callsite()
|
||||||
|
{
|
||||||
|
span = parent_callsite;
|
||||||
|
}
|
||||||
|
|
||||||
let sugg = if expr.precedence().order() >= PREC_POSTFIX {
|
let sugg = if expr.precedence().order() >= PREC_POSTFIX {
|
||||||
vec![(expr.span.shrink_to_hi(), ".into()".to_owned())]
|
vec![(span.shrink_to_hi(), ".into()".to_owned())]
|
||||||
} else {
|
} else {
|
||||||
vec![(expr.span.shrink_to_lo(), "(".to_owned()), (expr.span.shrink_to_hi(), ").into()".to_owned())]
|
vec![(span.shrink_to_lo(), "(".to_owned()), (span.shrink_to_hi(), ").into()".to_owned())]
|
||||||
};
|
};
|
||||||
diag.multipart_suggestion(
|
diag.multipart_suggestion(
|
||||||
format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"),
|
format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"),
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
// run-rustfix
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
pub fn foo(x: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
Err(format!("error: {x}").into())
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! outer {
|
||||||
|
($x: expr) => {
|
||||||
|
inner!($x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! inner {
|
||||||
|
($x: expr) => {
|
||||||
|
format!("error: {}", $x).into()
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(x: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
Err(outer!(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! entire_fn_outer {
|
||||||
|
() => {
|
||||||
|
entire_fn!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! entire_fn {
|
||||||
|
() => {
|
||||||
|
pub fn baz(x: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
Err(format!("error: {x}").into())
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entire_fn_outer!();
|
||||||
|
|
||||||
|
macro_rules! nontrivial {
|
||||||
|
($x: expr) => {
|
||||||
|
Err(format!("error: {}", $x).into())
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn qux(x: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
nontrivial!(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,55 @@
|
|||||||
|
// run-rustfix
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
pub fn foo(x: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
Err(format!("error: {x}"))
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! outer {
|
||||||
|
($x: expr) => {
|
||||||
|
inner!($x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! inner {
|
||||||
|
($x: expr) => {
|
||||||
|
format!("error: {}", $x)
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar(x: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
Err(outer!(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! entire_fn_outer {
|
||||||
|
() => {
|
||||||
|
entire_fn!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! entire_fn {
|
||||||
|
() => {
|
||||||
|
pub fn baz(x: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
Err(format!("error: {x}"))
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entire_fn_outer!();
|
||||||
|
|
||||||
|
macro_rules! nontrivial {
|
||||||
|
($x: expr) => {
|
||||||
|
Err(format!("error: {}", $x))
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn qux(x: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
nontrivial!(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,59 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-110017-format-into-help-deletes-macro.rs:5:10
|
||||||
|
|
|
||||||
|
LL | Err(format!("error: {x}"))
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ expected `Box<dyn Error>`, found `String`
|
||||||
|
|
|
||||||
|
= note: expected struct `Box<dyn std::error::Error>`
|
||||||
|
found struct `String`
|
||||||
|
= note: this error originates in the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
help: call `Into::into` on this expression to convert `String` into `Box<dyn std::error::Error>`
|
||||||
|
|
|
||||||
|
LL | Err(format!("error: {x}").into())
|
||||||
|
| +++++++
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-110017-format-into-help-deletes-macro.rs:23:10
|
||||||
|
|
|
||||||
|
LL | Err(outer!(x))
|
||||||
|
| ^^^^^^^^^ expected `Box<dyn Error>`, found `String`
|
||||||
|
|
|
||||||
|
= note: expected struct `Box<dyn std::error::Error>`
|
||||||
|
found struct `String`
|
||||||
|
= note: this error originates in the macro `format` which comes from the expansion of the macro `outer` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
help: call `Into::into` on this expression to convert `String` into `Box<dyn std::error::Error>`
|
||||||
|
|
|
||||||
|
LL | format!("error: {}", $x).into()
|
||||||
|
| +++++++
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-110017-format-into-help-deletes-macro.rs:41:2
|
||||||
|
|
|
||||||
|
LL | entire_fn_outer!();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ expected `Box<dyn Error>`, found `String`
|
||||||
|
|
|
||||||
|
= note: expected struct `Box<dyn std::error::Error>`
|
||||||
|
found struct `String`
|
||||||
|
= note: this error originates in the macro `format` which comes from the expansion of the macro `entire_fn_outer` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
help: call `Into::into` on this expression to convert `String` into `Box<dyn std::error::Error>`
|
||||||
|
|
|
||||||
|
LL | Err(format!("error: {x}").into())
|
||||||
|
| +++++++
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-110017-format-into-help-deletes-macro.rs:51:5
|
||||||
|
|
|
||||||
|
LL | nontrivial!(x)
|
||||||
|
| ^^^^^^^^^^^^^^ expected `Box<dyn Error>`, found `String`
|
||||||
|
|
|
||||||
|
= note: expected struct `Box<dyn std::error::Error>`
|
||||||
|
found struct `String`
|
||||||
|
= note: this error originates in the macro `format` which comes from the expansion of the macro `nontrivial` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
help: call `Into::into` on this expression to convert `String` into `Box<dyn std::error::Error>`
|
||||||
|
|
|
||||||
|
LL | Err(format!("error: {}", $x).into())
|
||||||
|
| +++++++
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
@ -0,0 +1,37 @@
|
|||||||
|
// run-rustfix
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
// https://github.com/rust-lang/rust/issues/112007
|
||||||
|
fn bug_report<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
|
||||||
|
if true {
|
||||||
|
writeln!(w, "`;?` here ->")?;
|
||||||
|
} else {
|
||||||
|
return writeln!(w, "but not here");
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! baz {
|
||||||
|
($w: expr) => {
|
||||||
|
bar!($w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! bar {
|
||||||
|
($w: expr) => {
|
||||||
|
writeln!($w, "but not here")
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
|
||||||
|
if true {
|
||||||
|
writeln!(w, "`;?` here ->")?;
|
||||||
|
} else {
|
||||||
|
return baz!(w);
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,37 @@
|
|||||||
|
// run-rustfix
|
||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
// https://github.com/rust-lang/rust/issues/112007
|
||||||
|
fn bug_report<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
|
||||||
|
if true {
|
||||||
|
writeln!(w, "`;?` here ->")?;
|
||||||
|
} else {
|
||||||
|
writeln!(w, "but not here")
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! baz {
|
||||||
|
($w: expr) => {
|
||||||
|
bar!($w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! bar {
|
||||||
|
($w: expr) => {
|
||||||
|
writeln!($w, "but not here")
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<W: std::fmt::Write>(w: &mut W) -> std::fmt::Result {
|
||||||
|
if true {
|
||||||
|
writeln!(w, "`;?` here ->")?;
|
||||||
|
} else {
|
||||||
|
baz!(w)
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,50 @@
|
|||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-112007-leaked-writeln-macro-internals.rs:9:9
|
||||||
|
|
|
||||||
|
LL | / if true {
|
||||||
|
LL | | writeln!(w, "`;?` here ->")?;
|
||||||
|
LL | | } else {
|
||||||
|
LL | | writeln!(w, "but not here")
|
||||||
|
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `Result<(), Error>`
|
||||||
|
LL | |
|
||||||
|
LL | | }
|
||||||
|
| |_____- expected this to be `()`
|
||||||
|
|
|
||||||
|
= note: expected unit type `()`
|
||||||
|
found enum `Result<(), std::fmt::Error>`
|
||||||
|
= note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
help: consider using a semicolon here
|
||||||
|
|
|
||||||
|
LL | };
|
||||||
|
| +
|
||||||
|
help: you might have meant to return this value
|
||||||
|
|
|
||||||
|
LL | return writeln!(w, "but not here");
|
||||||
|
| ++++++ +
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/issue-112007-leaked-writeln-macro-internals.rs:32:9
|
||||||
|
|
|
||||||
|
LL | / if true {
|
||||||
|
LL | | writeln!(w, "`;?` here ->")?;
|
||||||
|
LL | | } else {
|
||||||
|
LL | | baz!(w)
|
||||||
|
| | ^^^^^^^ expected `()`, found `Result<(), Error>`
|
||||||
|
LL | | }
|
||||||
|
| |_____- expected this to be `()`
|
||||||
|
|
|
||||||
|
= note: expected unit type `()`
|
||||||
|
found enum `Result<(), std::fmt::Error>`
|
||||||
|
= note: this error originates in the macro `writeln` which comes from the expansion of the macro `baz` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
help: consider using a semicolon here
|
||||||
|
|
|
||||||
|
LL | };
|
||||||
|
| +
|
||||||
|
help: you might have meant to return this value
|
||||||
|
|
|
||||||
|
LL | return baz!(w);
|
||||||
|
| ++++++ +
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
Loading…
x
Reference in New Issue
Block a user