Skip to content

Commit 8229701

Browse files
authored
Fix let_unit_value suggests wrongly for field init shorthand (#15791)
Closes #15789 changelog: [`let_unit_value`] fix wrong suggestions for field init shorthand
2 parents aa1fa10 + 089fbd3 commit 8229701

File tree

4 files changed

+69
-15
lines changed

4 files changed

+69
-15
lines changed

clippy_lints/src/unit_types/let_unit_value.rs

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,12 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, format_args: &FormatArgsStorag
9090

9191
let mut has_in_format_capture = false;
9292
suggestions.extend(visitor.spans.into_iter().filter_map(|span| match span {
93-
MaybeInFormatCapture::Yes => {
93+
VariableUsage::FormatCapture => {
9494
has_in_format_capture = true;
9595
None
9696
},
97-
MaybeInFormatCapture::No(span) => Some((span, "()".to_string())),
97+
VariableUsage::Normal(span) => Some((span, "()".to_string())),
98+
VariableUsage::FieldShorthand(span) => Some((span.shrink_to_hi(), ": ()".to_string())),
9899
}));
99100

100101
if has_in_format_capture {
@@ -141,19 +142,30 @@ struct UnitVariableCollector<'a, 'tcx> {
141142
cx: &'a LateContext<'tcx>,
142143
format_args: &'a FormatArgsStorage,
143144
id: HirId,
144-
spans: Vec<MaybeInFormatCapture>,
145+
spans: Vec<VariableUsage>,
145146
macro_call: Option<&'a FormatArgs>,
146147
}
147148

148-
/// Whether the unit variable is captured in a `format!`:
149-
///
150-
/// ```ignore
151-
/// let unit = ();
152-
/// eprintln!("{unit}");
153-
/// ```
154-
enum MaybeInFormatCapture {
155-
Yes,
156-
No(Span),
149+
/// How the unit variable is used
150+
enum VariableUsage {
151+
Normal(Span),
152+
/// Captured in a `format!`:
153+
///
154+
/// ```ignore
155+
/// let unit = ();
156+
/// eprintln!("{unit}");
157+
/// ```
158+
FormatCapture,
159+
/// In a field shorthand init:
160+
///
161+
/// ```ignore
162+
/// struct Foo {
163+
/// unit: (),
164+
/// }
165+
/// let unit = ();
166+
/// Foo { unit };
167+
/// ```
168+
FieldShorthand(Span),
157169
}
158170

159171
impl<'a, 'tcx> UnitVariableCollector<'a, 'tcx> {
@@ -193,9 +205,17 @@ impl<'tcx> Visitor<'tcx> for UnitVariableCollector<'_, 'tcx> {
193205
matches!(arg.kind, FormatArgumentKind::Captured(_)) && find_format_arg_expr(ex, arg).is_some()
194206
})
195207
{
196-
self.spans.push(MaybeInFormatCapture::Yes);
208+
self.spans.push(VariableUsage::FormatCapture);
197209
} else {
198-
self.spans.push(MaybeInFormatCapture::No(path.span));
210+
let parent = self.cx.tcx.parent_hir_node(ex.hir_id);
211+
match parent {
212+
Node::ExprField(expr_field) if expr_field.is_shorthand => {
213+
self.spans.push(VariableUsage::FieldShorthand(ex.span));
214+
},
215+
_ => {
216+
self.spans.push(VariableUsage::Normal(path.span));
217+
},
218+
}
199219
}
200220
}
201221

tests/ui/let_unit.fixed

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,13 @@ fn issue_15784() {
229229
takes_unit(());
230230
println!("{res:?}");
231231
}
232+
233+
fn issue15789() {
234+
struct Foo {
235+
value: (),
236+
}
237+
println!();
238+
//~^ let_unit_value
239+
240+
Foo { value: () };
241+
}

tests/ui/let_unit.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,13 @@ fn issue_15784() {
227227
takes_unit(res);
228228
println!("{res:?}");
229229
}
230+
231+
fn issue15789() {
232+
struct Foo {
233+
value: (),
234+
}
235+
let value = println!();
236+
//~^ let_unit_value
237+
238+
Foo { value };
239+
}

tests/ui/let_unit.stderr

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,19 @@ LL |
114114
LL ~ takes_unit(());
115115
|
116116

117-
error: aborting due to 8 previous errors
117+
error: this let-binding has unit value
118+
--> tests/ui/let_unit.rs:235:5
119+
|
120+
LL | let value = println!();
121+
| ^^^^^^^^^^^^^^^^^^^^^^^
122+
|
123+
help: omit the `let` binding and replace variable usages with `()`
124+
|
125+
LL ~ println!();
126+
LL |
127+
LL |
128+
LL ~ Foo { value: () };
129+
|
130+
131+
error: aborting due to 9 previous errors
118132

0 commit comments

Comments
 (0)