From 685c3c1b4a7c1949048177409ca43fc05daefd3f Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Sun, 18 Mar 2018 23:01:11 -0700 Subject: Reduce the diagnostic span when multiple fields are missing in pattern --- src/test/ui/missing-fields-in-struct-pattern.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/ui/missing-fields-in-struct-pattern.rs (limited to 'src/test/ui/missing-fields-in-struct-pattern.rs') diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs new file mode 100644 index 00000000000..2469f245345 --- /dev/null +++ b/src/test/ui/missing-fields-in-struct-pattern.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct S(usize, usize, usize, usize); + +fn main() { + if let S { a, b, c, d } = S(1, 2, 3, 4) { + println!("hi"); + } +} -- cgit 1.4.1-3-g733a5 From f332a9ce5676859f0f07c4d6bf2d2c415be67066 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Sun, 18 Mar 2018 23:26:57 -0700 Subject: Single diagnostic for all non-mentioned fields in a pattern --- src/librustc_typeck/check/_match.rs | 22 +++++++++++++++++----- src/test/ui/missing-fields-in-struct-pattern.rs | 2 ++ .../ui/missing-fields-in-struct-pattern.stderr | 22 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/missing-fields-in-struct-pattern.stderr (limited to 'src/test/ui/missing-fields-in-struct-pattern.rs') diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 0b5383f1f8d..cc72a565ba2 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -993,13 +993,25 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); tcx.sess.span_err(span, "`..` cannot be used in union patterns"); } } else if !etc { - for field in variant.fields + let unmentioned_fields = variant.fields .iter() - .filter(|field| !used_fields.contains_key(&field.name)) { + .map(|field| field.name) + .filter(|field| !used_fields.contains_key(&field)) + .collect::>(); + if unmentioned_fields.len() > 0 { + let field_names = if unmentioned_fields.len() == 1 { + format!("field `{}`", unmentioned_fields[0]) + } else { + format!("fields {}", + unmentioned_fields.iter() + .map(|name| format!("`{}`", name)) + .collect::>() + .join(", ")) + }; let mut diag = struct_span_err!(tcx.sess, span, E0027, - "pattern does not mention field `{}`", - field.name); - diag.span_label(span, format!("missing field `{}`", field.name)); + "pattern does not mention {}", + field_names); + diag.span_label(span, format!("missing {}", field_names)); if variant.ctor_kind == CtorKind::Fn { diag.note("trying to match a tuple variant with a struct variant pattern"); } diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs index 2469f245345..28ed151b986 100644 --- a/src/test/ui/missing-fields-in-struct-pattern.rs +++ b/src/test/ui/missing-fields-in-struct-pattern.rs @@ -12,6 +12,8 @@ struct S(usize, usize, usize, usize); fn main() { if let S { a, b, c, d } = S(1, 2, 3, 4) { + //~^ ERROR struct `S` does not have fields named `a`, `b`, `c`, `d` [E0026] + //~^ ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] println!("hi"); } } diff --git a/src/test/ui/missing-fields-in-struct-pattern.stderr b/src/test/ui/missing-fields-in-struct-pattern.stderr new file mode 100644 index 00000000000..88fba19d14e --- /dev/null +++ b/src/test/ui/missing-fields-in-struct-pattern.stderr @@ -0,0 +1,22 @@ +error[E0026]: struct `S` does not have fields named `a`, `b`, `c`, `d` + --> $DIR/missing-fields-in-struct-pattern.rs:14:16 + | +LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { + | ^ ^ ^ ^ struct `S` does not have field `d` + | | | | + | | | struct `S` does not have field `c` + | | struct `S` does not have field `b` + | struct `S` does not have field `a` + +error[E0027]: pattern does not mention fields `0`, `1`, `2`, `3` + --> $DIR/missing-fields-in-struct-pattern.rs:14:12 + | +LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { + | ^^^^^^^^^^^^^^^^ missing fields `0`, `1`, `2`, `3` + | + = note: trying to match a tuple variant with a struct variant pattern + +error: aborting due to 2 previous errors + +Some errors occurred: E0026, E0027. +For more information about an error, try `rustc --explain E0026`. -- cgit 1.4.1-3-g733a5 From 062a46fdd1d49b1ccdc4f713433521463224d7d9 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Mon, 19 Mar 2018 14:13:57 -0700 Subject: Reduce diagnostic verbosity by removing labels --- src/librustc_typeck/check/_match.rs | 17 +++++++++-------- src/test/compile-fail/struct-pat-derived-error.rs | 6 ++---- src/test/ui/error-codes/E0026-teach.stderr | 2 +- src/test/ui/error-codes/E0026.stderr | 2 +- src/test/ui/missing-fields-in-struct-pattern.rs | 2 +- src/test/ui/missing-fields-in-struct-pattern.stderr | 6 +----- src/test/ui/numeric-fields.stderr | 2 +- src/test/ui/type-check/issue-41314.stderr | 2 +- src/test/ui/union/union-fields-2.stderr | 2 +- 9 files changed, 18 insertions(+), 23 deletions(-) (limited to 'src/test/ui/missing-fields-in-struct-pattern.rs') diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index cc72a565ba2..7965806af5d 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -938,14 +938,14 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); } if inexistent_fields.len() > 0 { - let field_names = if inexistent_fields.len() == 1 { - format!("a field named `{}`", inexistent_fields[0].1) + let (field_names, t, plural) = if inexistent_fields.len() == 1 { + (format!("a field named `{}`", inexistent_fields[0].1), "this", "") } else { - format!("fields named {}", - inexistent_fields.iter() + (format!("fields named {}", + inexistent_fields.iter() .map(|(_, name)| format!("`{}`", name)) .collect::>() - .join(", ")) + .join(", ")), "these", "s") }; let spans = inexistent_fields.iter().map(|(span, _)| *span).collect::>(); let mut err = struct_span_err!(tcx.sess, @@ -955,12 +955,13 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); kind_name, tcx.item_path_str(variant.did), field_names); - for (span, name) in &inexistent_fields { + if let Some((span, _)) = inexistent_fields.last() { err.span_label(*span, - format!("{} `{}` does not have field `{}`", + format!("{} `{}` does not have {} field{}", kind_name, tcx.item_path_str(variant.did), - name)); + t, + plural)); } if tcx.sess.teach(&err.get_code().unwrap()) { err.note( diff --git a/src/test/compile-fail/struct-pat-derived-error.rs b/src/test/compile-fail/struct-pat-derived-error.rs index f525ec37375..d3130c4e831 100644 --- a/src/test/compile-fail/struct-pat-derived-error.rs +++ b/src/test/compile-fail/struct-pat-derived-error.rs @@ -16,10 +16,8 @@ struct a { impl a { fn foo(&self) { let a { x, y } = self.d; //~ ERROR no field `d` on type `&a` - //~^ ERROR struct `a` does not have a field named `x` - //~^^ ERROR struct `a` does not have a field named `y` - //~^^^ ERROR pattern does not mention field `b` - //~^^^^ ERROR pattern does not mention field `c` + //~^ ERROR struct `a` does not have fields named `x`, `y` + //~| ERROR pattern does not mention fields `b`, `c` } } diff --git a/src/test/ui/error-codes/E0026-teach.stderr b/src/test/ui/error-codes/E0026-teach.stderr index 63d072fe03d..67ea32fba86 100644 --- a/src/test/ui/error-codes/E0026-teach.stderr +++ b/src/test/ui/error-codes/E0026-teach.stderr @@ -2,7 +2,7 @@ error[E0026]: struct `Thing` does not have a field named `z` --> $DIR/E0026-teach.rs:21:23 | LL | Thing { x, y, z } => {} - | ^ struct `Thing` does not have field `z` + | ^ struct `Thing` does not have this field | = note: This error indicates that a struct pattern attempted to extract a non-existent field from a struct. Struct fields are identified by the name used before the colon : so struct patterns should resemble the declaration of the struct type being matched. diff --git a/src/test/ui/error-codes/E0026.stderr b/src/test/ui/error-codes/E0026.stderr index af851951127..9dabbc8a775 100644 --- a/src/test/ui/error-codes/E0026.stderr +++ b/src/test/ui/error-codes/E0026.stderr @@ -2,7 +2,7 @@ error[E0026]: struct `Thing` does not have a field named `z` --> $DIR/E0026.rs:19:23 | LL | Thing { x, y, z } => {} - | ^ struct `Thing` does not have field `z` + | ^ struct `Thing` does not have this field error: aborting due to previous error diff --git a/src/test/ui/missing-fields-in-struct-pattern.rs b/src/test/ui/missing-fields-in-struct-pattern.rs index 28ed151b986..dfde3799499 100644 --- a/src/test/ui/missing-fields-in-struct-pattern.rs +++ b/src/test/ui/missing-fields-in-struct-pattern.rs @@ -13,7 +13,7 @@ struct S(usize, usize, usize, usize); fn main() { if let S { a, b, c, d } = S(1, 2, 3, 4) { //~^ ERROR struct `S` does not have fields named `a`, `b`, `c`, `d` [E0026] - //~^ ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] + //~| ERROR pattern does not mention fields `0`, `1`, `2`, `3` [E0027] println!("hi"); } } diff --git a/src/test/ui/missing-fields-in-struct-pattern.stderr b/src/test/ui/missing-fields-in-struct-pattern.stderr index 88fba19d14e..d1c3260f11e 100644 --- a/src/test/ui/missing-fields-in-struct-pattern.stderr +++ b/src/test/ui/missing-fields-in-struct-pattern.stderr @@ -2,11 +2,7 @@ error[E0026]: struct `S` does not have fields named `a`, `b`, `c`, `d` --> $DIR/missing-fields-in-struct-pattern.rs:14:16 | LL | if let S { a, b, c, d } = S(1, 2, 3, 4) { - | ^ ^ ^ ^ struct `S` does not have field `d` - | | | | - | | | struct `S` does not have field `c` - | | struct `S` does not have field `b` - | struct `S` does not have field `a` + | ^ ^ ^ ^ struct `S` does not have these fields error[E0027]: pattern does not mention fields `0`, `1`, `2`, `3` --> $DIR/missing-fields-in-struct-pattern.rs:14:12 diff --git a/src/test/ui/numeric-fields.stderr b/src/test/ui/numeric-fields.stderr index 607980ba3bf..68a87da8ded 100644 --- a/src/test/ui/numeric-fields.stderr +++ b/src/test/ui/numeric-fields.stderr @@ -10,7 +10,7 @@ error[E0026]: struct `S` does not have a field named `0x1` --> $DIR/numeric-fields.rs:17:17 | LL | S{0: a, 0x1: b, ..} => {} - | ^^^^^^ struct `S` does not have field `0x1` + | ^^^^^^ struct `S` does not have this field error: aborting due to 2 previous errors diff --git a/src/test/ui/type-check/issue-41314.stderr b/src/test/ui/type-check/issue-41314.stderr index bcb0f9a99a7..f7d4bb9a02f 100644 --- a/src/test/ui/type-check/issue-41314.stderr +++ b/src/test/ui/type-check/issue-41314.stderr @@ -2,7 +2,7 @@ error[E0026]: variant `X::Y` does not have a field named `number` --> $DIR/issue-41314.rs:17:16 | LL | X::Y { number } => {} //~ ERROR does not have a field named `number` - | ^^^^^^ variant `X::Y` does not have field `number` + | ^^^^^^ variant `X::Y` does not have this field error[E0027]: pattern does not mention field `0` --> $DIR/issue-41314.rs:17:9 diff --git a/src/test/ui/union/union-fields-2.stderr b/src/test/ui/union/union-fields-2.stderr index 3ea4d3426da..cfb5bc7520b 100644 --- a/src/test/ui/union/union-fields-2.stderr +++ b/src/test/ui/union/union-fields-2.stderr @@ -52,7 +52,7 @@ error[E0026]: union `U` does not have a field named `c` --> $DIR/union-fields-2.rs:28:19 | LL | let U { a, b, c } = u; //~ ERROR union patterns should have exactly one field - | ^ union `U` does not have field `c` + | ^ union `U` does not have this field error: union patterns should have exactly one field --> $DIR/union-fields-2.rs:28:9 -- cgit 1.4.1-3-g733a5