Improve suggest construct with literal syntax instead of calling
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
This commit is contained in:
parent
d0353f5c7a
commit
4648650d89
2 changed files with 88 additions and 35 deletions
|
@ -1681,41 +1681,81 @@ 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());
|
||||||
let (fields, applicability) = match fields {
|
|
||||||
Some(fields) => {
|
|
||||||
let fields = if let Some(old_fields) = old_fields {
|
|
||||||
fields
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(idx, new)| (new, old_fields.get(idx)))
|
|
||||||
.map(|(new, old)| {
|
|
||||||
if let Some(Some(old)) = old
|
|
||||||
&& new.as_str() != old
|
|
||||||
{
|
|
||||||
format!("{new}: {old}")
|
|
||||||
} else {
|
|
||||||
new.to_string()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
} else {
|
|
||||||
fields
|
|
||||||
.iter()
|
|
||||||
.map(|f| format!("{f}{tail}"))
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
};
|
|
||||||
|
|
||||||
(fields.join(", "), applicability)
|
if let PathSource::Expr(Some(Expr {
|
||||||
}
|
kind: ExprKind::Call(path, args),
|
||||||
None => ("/* fields */".to_string(), Applicability::HasPlaceholders),
|
|
||||||
};
|
|
||||||
let pad = if has_fields { " " } else { "" };
|
|
||||||
err.span_suggestion(
|
|
||||||
span,
|
span,
|
||||||
format!("use struct {descr} syntax instead"),
|
..
|
||||||
format!("{path_str} {{{pad}{fields}{pad}}}"),
|
})) = source
|
||||||
applicability,
|
&& !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 {
|
||||||
|
Some(fields) => {
|
||||||
|
let fields = if let Some(old_fields) = old_fields {
|
||||||
|
fields
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(idx, new)| (new, old_fields.get(idx)))
|
||||||
|
.map(|(new, old)| {
|
||||||
|
if let Some(Some(old)) = old
|
||||||
|
&& new.as_str() != old
|
||||||
|
{
|
||||||
|
format!("{new}: {old}")
|
||||||
|
} else {
|
||||||
|
new.to_string()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
} else {
|
||||||
|
fields
|
||||||
|
.iter()
|
||||||
|
.map(|f| format!("{f}{tail}"))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
};
|
||||||
|
|
||||||
|
(fields.join(", "), applicability)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
("/* fields */".to_string(), Applicability::HasPlaceholders)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let pad = if has_fields { " " } else { "" };
|
||||||
|
err.span_suggestion(
|
||||||
|
span,
|
||||||
|
format!("use struct {descr} syntax instead"),
|
||||||
|
format!("{path_str} {{{pad}{fields}{pad}}}"),
|
||||||
|
applicability,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let PathSource::Expr(Some(Expr {
|
if let PathSource::Expr(Some(Expr {
|
||||||
kind: ExprKind::Call(path, args),
|
kind: ExprKind::Call(path, args),
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue