Skip to content

Commit 506c98f

Browse files
committed
Suggest wrapping expressions in single-field record variants
1 parent e568261 commit 506c98f

File tree

1 file changed

+30
-13
lines changed

1 file changed

+30
-13
lines changed

compiler/rustc_typeck/src/check/demand.rs

+30-13
Original file line numberDiff line numberDiff line change
@@ -363,11 +363,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
363363
}
364364
}
365365

366-
let compatible_variants: Vec<(String, Option<String>)> = expected_adt
366+
let compatible_variants: Vec<(String, _, _, Option<String>)> = expected_adt
367367
.variants()
368368
.iter()
369369
.filter(|variant| {
370-
variant.fields.len() == 1 && variant.ctor_kind == hir::def::CtorKind::Fn
370+
variant.fields.len() == 1
371371
})
372372
.filter_map(|variant| {
373373
let sole_field = &variant.fields[0];
@@ -391,9 +391,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
391391
if let Some(path) = variant_path.strip_prefix("std::prelude::")
392392
&& let Some((_, path)) = path.split_once("::")
393393
{
394-
return Some((path.to_string(), note_about_variant_field_privacy));
394+
return Some((path.to_string(), variant.ctor_kind, sole_field.name, note_about_variant_field_privacy));
395395
}
396-
Some((variant_path, note_about_variant_field_privacy))
396+
Some((variant_path, variant.ctor_kind, sole_field.name, note_about_variant_field_privacy))
397397
} else {
398398
None
399399
}
@@ -405,18 +405,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
405405
None => String::new(),
406406
};
407407

408+
fn brackets_for(
409+
ctor: hir::def::CtorKind,
410+
field_name: Symbol,
411+
) -> (String, &'static str) {
412+
match ctor {
413+
hir::def::CtorKind::Fn => ("(".to_owned(), ")"),
414+
hir::def::CtorKind::Fictive => (format!(" {{ {field_name}: "), " }"),
415+
hir::def::CtorKind::Const => unreachable!(),
416+
}
417+
}
418+
408419
match &compatible_variants[..] {
409420
[] => { /* No variants to format */ }
410-
[(variant, note)] => {
421+
[(variant, ctor_kind, field_name, note)] => {
422+
let (open, close) = brackets_for(*ctor_kind, *field_name);
423+
411424
// Just a single matching variant.
412425
err.multipart_suggestion_verbose(
413426
&format!(
414427
"try wrapping the expression in `{variant}`{note}",
415428
note = note.as_deref().unwrap_or("")
416429
),
417430
vec![
418-
(expr.span.shrink_to_lo(), format!("{prefix}{variant}(")),
419-
(expr.span.shrink_to_hi(), ")".to_string()),
431+
(expr.span.shrink_to_lo(), format!("{prefix}{variant}{open}")),
432+
(expr.span.shrink_to_hi(), close.to_owned()),
420433
],
421434
Applicability::MaybeIncorrect,
422435
);
@@ -428,12 +441,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
428441
"try wrapping the expression in a variant of `{}`",
429442
self.tcx.def_path_str(expected_adt.did())
430443
),
431-
compatible_variants.into_iter().map(|(variant, _)| {
432-
vec![
433-
(expr.span.shrink_to_lo(), format!("{prefix}{variant}(")),
434-
(expr.span.shrink_to_hi(), ")".to_string()),
435-
]
436-
}),
444+
compatible_variants.into_iter().map(
445+
|(variant, ctor_kind, field_name, _)| {
446+
let (open, close) = brackets_for(ctor_kind, field_name);
447+
448+
vec![
449+
(expr.span.shrink_to_lo(), format!("{prefix}{variant}{open}")),
450+
(expr.span.shrink_to_hi(), close.to_owned()),
451+
]
452+
},
453+
),
437454
Applicability::MaybeIncorrect,
438455
);
439456
}

0 commit comments

Comments
 (0)