1
Fork 0

Improve suggest construct with literal syntax instead of calling

Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
This commit is contained in:
xizheyin 2025-03-27 17:28:15 +08:00
parent d0353f5c7a
commit 4648650d89
No known key found for this signature in database
GPG key ID: 0A0D90BE99CEDEAD
2 changed files with 88 additions and 35 deletions

View file

@ -1681,6 +1681,43 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
// the struct literal syntax at all, as that will cause a subsequent error. // the struct literal syntax at all, as that will cause a subsequent error.
let fields = this.r.field_idents(def_id); let fields = this.r.field_idents(def_id);
let has_fields = fields.as_ref().is_some_and(|f| !f.is_empty()); let has_fields = fields.as_ref().is_some_and(|f| !f.is_empty());
if let PathSource::Expr(Some(Expr {
kind: ExprKind::Call(path, args),
span,
..
})) = source
&& !args.is_empty()
&& let Some(fields) = &fields
&& args.len() == fields.len()
// Make sure we have same number of args as fields
{
let path_span = path.span;
let mut parts = Vec::new();
// Start with the opening brace
parts.push((
path_span.shrink_to_hi().until(args[0].span),
"{".to_owned(),
));
for (field, arg) in fields.iter().zip(args.iter()) {
// Add the field name before the argument
parts.push((arg.span.shrink_to_lo(), format!("{}: ", field)));
}
// Add the closing brace
parts.push((
args.last().unwrap().span.shrink_to_hi().until(span.shrink_to_hi()),
"}".to_owned(),
));
err.multipart_suggestion_verbose(
format!("use struct {descr} syntax instead of calling"),
parts,
applicability,
);
} else {
let (fields, applicability) = match fields { let (fields, applicability) = match fields {
Some(fields) => { Some(fields) => {
let fields = if let Some(old_fields) = old_fields { let fields = if let Some(old_fields) = old_fields {
@ -1707,7 +1744,9 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
(fields.join(", "), applicability) (fields.join(", "), applicability)
} }
None => ("/* fields */".to_string(), Applicability::HasPlaceholders), None => {
("/* fields */".to_string(), Applicability::HasPlaceholders)
}
}; };
let pad = if has_fields { " " } else { "" }; let pad = if has_fields { " " } else { "" };
err.span_suggestion( err.span_suggestion(
@ -1717,6 +1756,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
applicability, applicability,
); );
} }
}
if let PathSource::Expr(Some(Expr { if let PathSource::Expr(Some(Expr {
kind: ExprKind::Call(path, args), kind: ExprKind::Call(path, args),
span: call_span, span: call_span,

View file

@ -7,7 +7,13 @@ LL | | }
| |_- `PersonOnlyName` defined here | |_- `PersonOnlyName` defined here
... ...
LL | let wilfred = PersonOnlyName("Name1".to_owned()); LL | let wilfred = PersonOnlyName("Name1".to_owned());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use struct literal syntax instead: `PersonOnlyName { name: val }` | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: use struct literal syntax instead of calling
|
LL - let wilfred = PersonOnlyName("Name1".to_owned());
LL + let wilfred = PersonOnlyName{name: "Name1".to_owned()};
|
error[E0423]: expected function, tuple struct or tuple variant, found struct `PersonWithAge` error[E0423]: expected function, tuple struct or tuple variant, found struct `PersonWithAge`
--> $DIR/struct-construct-with-call-issue-138931.rs:17:16 --> $DIR/struct-construct-with-call-issue-138931.rs:17:16
@ -25,7 +31,14 @@ LL | | "Name2".to_owned(),
LL | | 20, LL | | 20,
LL | | 180, LL | | 180,
LL | | ); LL | | );
| |_____^ help: use struct literal syntax instead: `PersonWithAge { name: val, age: val, height: val }` | |_____^
|
help: use struct literal syntax instead of calling
|
LL ~ let bill = PersonWithAge{name: "Name2".to_owned(),
LL ~ age: 20,
LL ~ height: 180};
|
error[E0423]: expected function, tuple struct or tuple variant, found struct `PersonWithAge` error[E0423]: expected function, tuple struct or tuple variant, found struct `PersonWithAge`
--> $DIR/struct-construct-with-call-issue-138931.rs:23:18 --> $DIR/struct-construct-with-call-issue-138931.rs:23:18