Auto merge of #81103 - zackmdavis:comma_trail, r=davidtwco

don't suggest erroneous trailing comma after `..`

In #76612, suggestions were added for missing fields in patterns. However, the suggestions are being inserted just at the end
of the last field in the pattern—before any trailing comma after the last field. This resulted in the "if you don't care about missing fields" suggestion to recommend code with a trailing comma after the field ellipsis (`..,`), which is actually not legal ("`..` must be at the end and cannot have a trailing comma")!

Incidentally, the doc-comment on `error_unmentioned_fields` was using `you_cant_use_this_field` as an example field name (presumably copy-paste inherited from the description of Issue #76077), but the present author found this confusing, because unmentioned fields aren't necessarily unusable.

The suggested code in the diff this commit introduces to `destructuring-assignment/struct_destructure_fail.stderr` doesn't work, but it didn't work beforehand, either (because of the "found reserved identifier `_`" thing), so you can't really call it a regression; it could be fixed in a separate PR.

Resolves #78511.

r? `@davidtwco` or `@estebank`
This commit is contained in:
bors 2021-01-19 02:54:58 +00:00
commit 94e6ea9fc9
4 changed files with 66 additions and 15 deletions

View file

@ -1486,11 +1486,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Returns a diagnostic reporting a struct pattern which does not mention some fields.
///
/// ```text
/// error[E0027]: pattern does not mention field `you_cant_use_this_field`
/// error[E0027]: pattern does not mention field `bar`
/// --> src/main.rs:15:9
/// |
/// LL | let foo::Foo {} = foo::Foo::new();
/// | ^^^^^^^^^^^ missing field `you_cant_use_this_field`
/// | ^^^^^^^^^^^ missing field `bar`
/// ```
fn error_unmentioned_fields(
&self,
@ -1524,14 +1524,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
_ => return err,
},
[.., field] => (
match pat.kind {
PatKind::Struct(_, [_, ..], _) => ", ",
_ => "",
},
"",
field.span.shrink_to_hi(),
),
[.., field] => {
// if last field has a trailing comma, use the comma
// as the span to avoid trailing comma in ultimate
// suggestion (Issue #78511)
let tail = field.span.shrink_to_hi().until(pat.span.shrink_to_hi());
let tail_through_comma = self.tcx.sess.source_map().span_through_char(tail, ',');
let sp = if tail_through_comma == tail {
field.span.shrink_to_hi()
} else {
tail_through_comma
};
(
match pat.kind {
PatKind::Struct(_, [_, ..], _) => ", ",
_ => "",
},
"",
sp,
)
}
};
err.span_suggestion(
sp,