Rollup merge of #57769 - estebank:cast-suggestion-struct-field, r=matthewjasper
Suggest correct cast for struct fields with shorthand syntax ``` error[E0308]: mismatched types --> $DIR/type-mismatch-struct-field-shorthand.rs:8:19 | LL | let _ = RGB { r, g, b }; | ^ expected f64, found f32 help: you can cast an `f32` to `f64` in a lossless way | LL | let _ = RGB { r: r.into(), g, b }; | ^^^^^^^^^^^ ``` Fix #52497.
This commit is contained in:
commit
3bb9fc4007
@ -454,12 +454,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn check_for_cast(&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
expr: &hir::Expr,
|
||||
checked_ty: Ty<'tcx>,
|
||||
expected_ty: Ty<'tcx>)
|
||||
-> bool {
|
||||
pub fn check_for_cast(
|
||||
&self,
|
||||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
expr: &hir::Expr,
|
||||
checked_ty: Ty<'tcx>,
|
||||
expected_ty: Ty<'tcx>,
|
||||
) -> bool {
|
||||
let parent_id = self.tcx.hir().get_parent_node(expr.id);
|
||||
if let Some(parent) = self.tcx.hir().find(parent_id) {
|
||||
// Shouldn't suggest `.into()` on `const`s.
|
||||
@ -487,17 +488,40 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
// For now, don't suggest casting with `as`.
|
||||
let can_cast = false;
|
||||
|
||||
let mut prefix = String::new();
|
||||
if let Some(hir::Node::Expr(hir::Expr {
|
||||
node: hir::ExprKind::Struct(_, fields, _),
|
||||
..
|
||||
})) = self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.id)) {
|
||||
// `expr` is a literal field for a struct, only suggest if appropriate
|
||||
for field in fields {
|
||||
if field.expr.id == expr.id && field.is_shorthand {
|
||||
// This is a field literal
|
||||
prefix = format!("{}: ", field.ident);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if &prefix == "" {
|
||||
// Likely a field was meant, but this field wasn't found. Do not suggest anything.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
let needs_paren = expr.precedence().order() < (PREC_POSTFIX as i8);
|
||||
|
||||
if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
|
||||
let msg = format!("you can cast an `{}` to `{}`", checked_ty, expected_ty);
|
||||
let cast_suggestion = format!("{}{}{} as {}",
|
||||
if needs_paren { "(" } else { "" },
|
||||
src,
|
||||
if needs_paren { ")" } else { "" },
|
||||
expected_ty);
|
||||
let cast_suggestion = format!(
|
||||
"{}{}{}{} as {}",
|
||||
prefix,
|
||||
if needs_paren { "(" } else { "" },
|
||||
src,
|
||||
if needs_paren { ")" } else { "" },
|
||||
expected_ty,
|
||||
);
|
||||
let into_suggestion = format!(
|
||||
"{}{}{}.into()",
|
||||
"{}{}{}{}.into()",
|
||||
prefix,
|
||||
if needs_paren { "(" } else { "" },
|
||||
src,
|
||||
if needs_paren { ")" } else { "" },
|
||||
|
@ -0,0 +1,9 @@
|
||||
struct RGB { r: f64, g: f64, b: f64 }
|
||||
|
||||
fn main() {
|
||||
let (r, g, c): (f32, f32, f32) = (0., 0., 0.);
|
||||
let _ = RGB { r, g, c };
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR struct `RGB` has no field named `c`
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-mismatch-struct-field-shorthand-2.rs:5:19
|
||||
|
|
||||
LL | let _ = RGB { r, g, c };
|
||||
| ^ expected f64, found f32
|
||||
help: you can cast an `f32` to `f64` in a lossless way
|
||||
|
|
||||
LL | let _ = RGB { r: r.into(), g, c };
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-mismatch-struct-field-shorthand-2.rs:5:22
|
||||
|
|
||||
LL | let _ = RGB { r, g, c };
|
||||
| ^ expected f64, found f32
|
||||
help: you can cast an `f32` to `f64` in a lossless way
|
||||
|
|
||||
LL | let _ = RGB { r, g: g.into(), c };
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0560]: struct `RGB` has no field named `c`
|
||||
--> $DIR/type-mismatch-struct-field-shorthand-2.rs:5:25
|
||||
|
|
||||
LL | let _ = RGB { r, g, c };
|
||||
| ^ help: a field with a similar name exists: `b`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors occurred: E0308, E0560.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
@ -0,0 +1,12 @@
|
||||
// run-rustfix
|
||||
#![allow(dead_code)]
|
||||
|
||||
struct RGB { r: f64, g: f64, b: f64 }
|
||||
|
||||
fn main() {
|
||||
let (r, g, b): (f32, f32, f32) = (0., 0., 0.);
|
||||
let _ = RGB { r: r.into(), g: g.into(), b: b.into() };
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR mismatched types
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
// run-rustfix
|
||||
#![allow(dead_code)]
|
||||
|
||||
struct RGB { r: f64, g: f64, b: f64 }
|
||||
|
||||
fn main() {
|
||||
let (r, g, b): (f32, f32, f32) = (0., 0., 0.);
|
||||
let _ = RGB { r, g, b };
|
||||
//~^ ERROR mismatched types
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR mismatched types
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-mismatch-struct-field-shorthand.rs:8:19
|
||||
|
|
||||
LL | let _ = RGB { r, g, b };
|
||||
| ^ expected f64, found f32
|
||||
help: you can cast an `f32` to `f64` in a lossless way
|
||||
|
|
||||
LL | let _ = RGB { r: r.into(), g, b };
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-mismatch-struct-field-shorthand.rs:8:22
|
||||
|
|
||||
LL | let _ = RGB { r, g, b };
|
||||
| ^ expected f64, found f32
|
||||
help: you can cast an `f32` to `f64` in a lossless way
|
||||
|
|
||||
LL | let _ = RGB { r, g: g.into(), b };
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-mismatch-struct-field-shorthand.rs:8:25
|
||||
|
|
||||
LL | let _ = RGB { r, g, b };
|
||||
| ^ expected f64, found f32
|
||||
help: you can cast an `f32` to `f64` in a lossless way
|
||||
|
|
||||
LL | let _ = RGB { r, g, b: b.into() };
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user