More fix on mismatched type suggestion for shorthand fields
This commit is contained in:
parent
9386e14401
commit
3a4edf0a7f
@ -626,7 +626,7 @@ pub struct SuggestConvertViaMethod<'tcx> {
|
||||
pub span: Span,
|
||||
#[suggestion_part(code = "")]
|
||||
pub borrow_removal_span: Option<Span>,
|
||||
pub sugg: &'static str,
|
||||
pub sugg: String,
|
||||
pub expected: Ty<'tcx>,
|
||||
pub found: Ty<'tcx>,
|
||||
}
|
||||
|
@ -442,12 +442,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
expected,
|
||||
)
|
||||
});
|
||||
|
||||
let prefix_wrap = |sugg: &str| {
|
||||
if let Some(name) = self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
|
||||
format!(": {}{}", name, sugg)
|
||||
} else {
|
||||
sugg.to_string()
|
||||
}
|
||||
};
|
||||
|
||||
// FIXME: This could/should be extended to suggest `as_mut` and `as_deref_mut`,
|
||||
// but those checks need to be a bit more delicate and the benefit is diminishing.
|
||||
if self.can_eq(self.param_env, found_ty_inner, peeled) && error_tys_equate_as_ref {
|
||||
let sugg = prefix_wrap(".as_ref()");
|
||||
err.subdiagnostic(errors::SuggestConvertViaMethod {
|
||||
span: expr.span.shrink_to_hi(),
|
||||
sugg: ".as_ref()",
|
||||
sugg,
|
||||
expected,
|
||||
found,
|
||||
borrow_removal_span,
|
||||
@ -458,9 +468,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
&& self.can_eq(self.param_env, deref_ty, peeled)
|
||||
&& error_tys_equate_as_ref
|
||||
{
|
||||
let sugg = prefix_wrap(".as_deref()");
|
||||
err.subdiagnostic(errors::SuggestConvertViaMethod {
|
||||
span: expr.span.shrink_to_hi(),
|
||||
sugg: ".as_deref()",
|
||||
sugg,
|
||||
expected,
|
||||
found,
|
||||
borrow_removal_span,
|
||||
@ -474,10 +485,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.can_eq(self.param_env, found, expected)
|
||||
})
|
||||
{
|
||||
let sugg = prefix_wrap(".map(|x| x.as_str())");
|
||||
err.span_suggestion_verbose(
|
||||
expr.span.shrink_to_hi(),
|
||||
fluent::hir_typeck_convert_to_str,
|
||||
".map(|x| x.as_str())",
|
||||
sugg,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
return true;
|
||||
@ -628,12 +640,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
err.help("use `Box::pin`");
|
||||
}
|
||||
_ => {
|
||||
let prefix = if let Some(name) =
|
||||
self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr)
|
||||
{
|
||||
format!("{}: ", name)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let suggestion = vec![
|
||||
(expr.span.shrink_to_lo(), format!("{prefix}Box::pin(")),
|
||||
(expr.span.shrink_to_hi(), ")".to_string()),
|
||||
];
|
||||
err.multipart_suggestion(
|
||||
"you need to pin and box this expression",
|
||||
vec![
|
||||
(expr.span.shrink_to_lo(), "Box::pin(".to_string()),
|
||||
(expr.span.shrink_to_hi(), ")".to_string()),
|
||||
],
|
||||
suggestion,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
@ -1214,7 +1234,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
span = parent_callsite;
|
||||
}
|
||||
|
||||
let sugg = if expr.precedence().order() >= PREC_POSTFIX {
|
||||
let mut sugg = if expr.precedence().order() >= PREC_POSTFIX {
|
||||
vec![(span.shrink_to_hi(), ".into()".to_owned())]
|
||||
} else {
|
||||
vec![
|
||||
@ -1222,6 +1242,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
(span.shrink_to_hi(), ").into()".to_owned()),
|
||||
]
|
||||
};
|
||||
if let Some(name) = self.tcx.hir().maybe_get_struct_pattern_shorthand_field(expr) {
|
||||
sugg.insert(0, (expr.span.shrink_to_lo(), format!("{}: ", name)));
|
||||
}
|
||||
diag.multipart_suggestion(
|
||||
format!("call `Into::into` on this expression to convert `{expr_ty}` into `{expected_ty}`"),
|
||||
sugg,
|
||||
|
@ -0,0 +1,77 @@
|
||||
// run-rustfix
|
||||
// edition:2021
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
fn test1() {
|
||||
let string = String::from("Hello, world");
|
||||
|
||||
struct Demo<'a> {
|
||||
option: Option<&'a str>,
|
||||
}
|
||||
|
||||
let option: Option<String> = Some(string.clone());
|
||||
let s = Demo { option: option.as_deref() }; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn test2() {
|
||||
let string = String::from("Hello, world");
|
||||
|
||||
struct Demo<'a> {
|
||||
option_ref: Option<&'a str>,
|
||||
}
|
||||
|
||||
let option_ref = Some(&string);
|
||||
let s = Demo { option_ref: option_ref.map(|x| x.as_str()) }; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn test3() {
|
||||
let string = String::from("Hello, world");
|
||||
|
||||
struct Demo<'a> {
|
||||
option_ref_ref: Option<&'a str>,
|
||||
}
|
||||
|
||||
let option_ref = Some(&string);
|
||||
let option_ref_ref = option_ref.as_ref();
|
||||
|
||||
let s = Demo { option_ref_ref: option_ref_ref.map(|x| x.as_str()) }; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn test4() {
|
||||
let a = 1;
|
||||
struct Demo {
|
||||
a: String,
|
||||
}
|
||||
let s = Demo { a: a.to_string() }; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
|
||||
fn test5() {
|
||||
let a = async { 42 };
|
||||
struct Demo {
|
||||
a: BoxFuture<'static, i32>,
|
||||
}
|
||||
let s = Demo { a: Box::pin(a) }; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn test6() {
|
||||
struct A;
|
||||
struct B;
|
||||
|
||||
impl From<B> for A {
|
||||
fn from(_: B) -> Self {
|
||||
A
|
||||
}
|
||||
}
|
||||
|
||||
struct Demo {
|
||||
a: A,
|
||||
}
|
||||
let a = B;
|
||||
let s = Demo { a: a.into() }; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,77 @@
|
||||
// run-rustfix
|
||||
// edition:2021
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
fn test1() {
|
||||
let string = String::from("Hello, world");
|
||||
|
||||
struct Demo<'a> {
|
||||
option: Option<&'a str>,
|
||||
}
|
||||
|
||||
let option: Option<String> = Some(string.clone());
|
||||
let s = Demo { option }; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn test2() {
|
||||
let string = String::from("Hello, world");
|
||||
|
||||
struct Demo<'a> {
|
||||
option_ref: Option<&'a str>,
|
||||
}
|
||||
|
||||
let option_ref = Some(&string);
|
||||
let s = Demo { option_ref }; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn test3() {
|
||||
let string = String::from("Hello, world");
|
||||
|
||||
struct Demo<'a> {
|
||||
option_ref_ref: Option<&'a str>,
|
||||
}
|
||||
|
||||
let option_ref = Some(&string);
|
||||
let option_ref_ref = option_ref.as_ref();
|
||||
|
||||
let s = Demo { option_ref_ref }; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn test4() {
|
||||
let a = 1;
|
||||
struct Demo {
|
||||
a: String,
|
||||
}
|
||||
let s = Demo { a }; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
|
||||
fn test5() {
|
||||
let a = async { 42 };
|
||||
struct Demo {
|
||||
a: BoxFuture<'static, i32>,
|
||||
}
|
||||
let s = Demo { a }; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn test6() {
|
||||
struct A;
|
||||
struct B;
|
||||
|
||||
impl From<B> for A {
|
||||
fn from(_: B) -> Self {
|
||||
A
|
||||
}
|
||||
}
|
||||
|
||||
struct Demo {
|
||||
a: A,
|
||||
}
|
||||
let a = B;
|
||||
let s = Demo { a }; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,80 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-sugg-for-shorthand-field.rs:16:20
|
||||
|
|
||||
LL | let s = Demo { option };
|
||||
| ^^^^^^ expected `Option<&str>`, found `Option<String>`
|
||||
|
|
||||
= note: expected enum `Option<&str>`
|
||||
found enum `Option<String>`
|
||||
help: try using `: option.as_deref()` to convert `Option<String>` to `Option<&str>`
|
||||
|
|
||||
LL | let s = Demo { option: option.as_deref() };
|
||||
| +++++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-sugg-for-shorthand-field.rs:27:20
|
||||
|
|
||||
LL | let s = Demo { option_ref };
|
||||
| ^^^^^^^^^^ expected `Option<&str>`, found `Option<&String>`
|
||||
|
|
||||
= note: expected enum `Option<&str>`
|
||||
found enum `Option<&String>`
|
||||
help: try converting the passed type into a `&str`
|
||||
|
|
||||
LL | let s = Demo { option_ref: option_ref.map(|x| x.as_str()) };
|
||||
| ++++++++++++++++++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-sugg-for-shorthand-field.rs:40:20
|
||||
|
|
||||
LL | let s = Demo { option_ref_ref };
|
||||
| ^^^^^^^^^^^^^^ expected `Option<&str>`, found `Option<&&String>`
|
||||
|
|
||||
= note: expected enum `Option<&str>`
|
||||
found enum `Option<&&String>`
|
||||
help: try converting the passed type into a `&str`
|
||||
|
|
||||
LL | let s = Demo { option_ref_ref: option_ref_ref.map(|x| x.as_str()) };
|
||||
| ++++++++++++++++++++++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-sugg-for-shorthand-field.rs:48:20
|
||||
|
|
||||
LL | let s = Demo { a };
|
||||
| ^ expected `String`, found integer
|
||||
|
|
||||
help: try using a conversion method
|
||||
|
|
||||
LL | let s = Demo { a: a.to_string() };
|
||||
| ++ ++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-sugg-for-shorthand-field.rs:57:20
|
||||
|
|
||||
LL | let a = async { 42 };
|
||||
| ------------ the found `async` block
|
||||
...
|
||||
LL | let s = Demo { a };
|
||||
| ^ expected `Pin<Box<...>>`, found `async` block
|
||||
|
|
||||
= note: expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>`
|
||||
found `async` block `{async block@$DIR/mismatch-sugg-for-shorthand-field.rs:53:13: 53:25}`
|
||||
help: you need to pin and box this expression
|
||||
|
|
||||
LL | let s = Demo { a: Box::pin(a) };
|
||||
| ++++++++++++ +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-sugg-for-shorthand-field.rs:74:20
|
||||
|
|
||||
LL | let s = Demo { a };
|
||||
| ^ expected `A`, found `B`
|
||||
|
|
||||
help: call `Into::into` on this expression to convert `B` into `A`
|
||||
|
|
||||
LL | let s = Demo { a: a.into() };
|
||||
| ++ +++++++
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
x
Reference in New Issue
Block a user