Rollup merge of #108971 - Ezrashaw:E0532-better-binding-names, r=WaffleLapkin

error-msg: impl better suggestion for `E0532`

Fixes #106862

No test as there is already a test which is nearly identical to the example in the linked issue.
This commit is contained in:
Matthias Krüger 2023-03-16 08:57:05 +01:00 committed by GitHub
commit 1385a32b62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 169 additions and 17 deletions

View File

@ -1289,25 +1289,41 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
PathSource::Expr(_) | PathSource::TupleStruct(..) | PathSource::Pat => {
let span = find_span(&source, err);
err.span_label(self.r.def_span(def_id), &format!("`{path_str}` defined here"));
let (tail, descr, applicability) = match source {
PathSource::Pat | PathSource::TupleStruct(..) => {
("", "pattern", Applicability::MachineApplicable)
}
_ => (": val", "literal", Applicability::HasPlaceholders),
};
let (tail, descr, applicability, old_fields) = match source {
PathSource::Pat => ("", "pattern", Applicability::MachineApplicable, None),
PathSource::TupleStruct(_, args) => (
"",
"pattern",
Applicability::MachineApplicable,
Some(
args.iter()
.map(|a| self.r.tcx.sess.source_map().span_to_snippet(*a).ok())
.collect::<Vec<Option<String>>>(),
),
),
_ => (": val", "literal", Applicability::HasPlaceholders, None),
};
let field_ids = self.r.field_def_ids(def_id);
let (fields, applicability) = match field_ids {
Some(field_ids) => (
field_ids
.iter()
.map(|&field_id| {
format!("{}{tail}", self.r.tcx.item_name(field_id))
})
.collect::<Vec<String>>()
.join(", "),
applicability,
),
Some(field_ids) => {
let fields = field_ids.iter().map(|&id| self.r.tcx.item_name(id));
let fields = if let Some(old_fields) = old_fields {
fields
.enumerate()
.map(|(idx, new)| (new, old_fields.get(idx)))
.map(|(new, old)| {
let new = new.to_ident_string();
if let Some(Some(old)) = old && new != *old { format!("{}: {}", new, old) } else { new }
})
.collect::<Vec<String>>()
} else {
fields.map(|f| format!("{f}{tail}")).collect::<Vec<String>>()
};
(fields.join(", "), applicability)
}
None => ("/* fields */".to_string(), Applicability::HasPlaceholders),
};
let pad = match field_ids {

View File

@ -5,7 +5,7 @@ LL | FooB { x: i32, y: i32 }
| ----------------------- `FooB` defined here
...
LL | FooB(a, b) => println!("{} {}", a, b),
| ^^^^^^^^^^ help: use struct pattern syntax instead: `FooB { x, y }`
| ^^^^^^^^^^ help: use struct pattern syntax instead: `FooB { x: a, y: b }`
error: aborting due to previous error

View File

@ -0,0 +1,44 @@
// run-rustfix
#![allow(unused)]
use Foo::{FooB, FooA};
enum Foo {
FooA { opt_x: Option<i32>, y: i32 },
FooB { x: i32, y: i32 }
}
fn main() {
let f = FooB { x: 3, y: 4 };
match f {
FooB { x: a, y: b } => println!("{} {}", a, b),
//~^ ERROR expected tuple struct or tuple variant, found variant `FooB`
_ => (),
}
match f {
FooB { x, y } => println!("{} {}", x, y),
//~^ ERROR expected tuple struct or tuple variant, found variant `FooB`
_ => (),
}
match f {
FooA { opt_x: Some(x), y } => println!("{} {}", x, y),
//~^ ERROR expected tuple struct or tuple variant, found variant `FooA`
_ => (),
}
match f {
FooB { x: a, y: _ } => println!("{}", a),
//~^ ERROR expected tuple struct or tuple variant, found variant `FooB`
_ => (),
}
match f {
FooB { x, y } => (),
//~^ ERROR expected tuple struct or tuple variant, found variant `FooB`
_ => (),
}
}

View File

@ -0,0 +1,44 @@
// run-rustfix
#![allow(unused)]
use Foo::{FooB, FooA};
enum Foo {
FooA { opt_x: Option<i32>, y: i32 },
FooB { x: i32, y: i32 }
}
fn main() {
let f = FooB { x: 3, y: 4 };
match f {
FooB(a, b) => println!("{} {}", a, b),
//~^ ERROR expected tuple struct or tuple variant, found variant `FooB`
_ => (),
}
match f {
FooB(x, y) => println!("{} {}", x, y),
//~^ ERROR expected tuple struct or tuple variant, found variant `FooB`
_ => (),
}
match f {
FooA(Some(x), y) => println!("{} {}", x, y),
//~^ ERROR expected tuple struct or tuple variant, found variant `FooA`
_ => (),
}
match f {
FooB(a, _, _) => println!("{}", a),
//~^ ERROR expected tuple struct or tuple variant, found variant `FooB`
_ => (),
}
match f {
FooB() => (),
//~^ ERROR expected tuple struct or tuple variant, found variant `FooB`
_ => (),
}
}

View File

@ -0,0 +1,48 @@
error[E0532]: expected tuple struct or tuple variant, found variant `FooB`
--> $DIR/issue-106862.rs:16:9
|
LL | FooB { x: i32, y: i32 }
| ----------------------- `FooB` defined here
...
LL | FooB(a, b) => println!("{} {}", a, b),
| ^^^^^^^^^^ help: use struct pattern syntax instead: `FooB { x: a, y: b }`
error[E0532]: expected tuple struct or tuple variant, found variant `FooB`
--> $DIR/issue-106862.rs:22:9
|
LL | FooB { x: i32, y: i32 }
| ----------------------- `FooB` defined here
...
LL | FooB(x, y) => println!("{} {}", x, y),
| ^^^^^^^^^^ help: use struct pattern syntax instead: `FooB { x, y }`
error[E0532]: expected tuple struct or tuple variant, found variant `FooA`
--> $DIR/issue-106862.rs:28:9
|
LL | FooA { opt_x: Option<i32>, y: i32 },
| ----------------------------------- `FooA` defined here
...
LL | FooA(Some(x), y) => println!("{} {}", x, y),
| ^^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `FooA { opt_x: Some(x), y }`
error[E0532]: expected tuple struct or tuple variant, found variant `FooB`
--> $DIR/issue-106862.rs:34:9
|
LL | FooB { x: i32, y: i32 }
| ----------------------- `FooB` defined here
...
LL | FooB(a, _, _) => println!("{}", a),
| ^^^^^^^^^^^^^ help: use struct pattern syntax instead: `FooB { x: a, y: _ }`
error[E0532]: expected tuple struct or tuple variant, found variant `FooB`
--> $DIR/issue-106862.rs:40:9
|
LL | FooB { x: i32, y: i32 }
| ----------------------- `FooB` defined here
...
LL | FooB() => (),
| ^^^^^^ help: use struct pattern syntax instead: `FooB { x, y }`
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0532`.