diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index d93a4052cd393..d687a5084e231 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -676,18 +676,35 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } else { // Pattern has wrong number of fields. - self.e0023(pat.span, res, &subpats, &variant.fields); + self.e0023(pat.span, res, &subpats, &variant.fields, expected); on_error(); return tcx.types.err; } pat_ty } - fn e0023(&self, pat_span: Span, res: Res, subpats: &'tcx [P], fields: &[ty::FieldDef]) { + fn e0023( + &self, + pat_span: Span, + res: Res, + subpats: &'tcx [P], + fields: &[ty::FieldDef], + expected: Ty<'tcx> + ) { let subpats_ending = pluralise!(subpats.len()); let fields_ending = pluralise!(fields.len()); + let missing_parenthesis = match expected.sty { + ty::Adt(_, substs) if fields.len() == 1 => { + let field_ty = fields[0].ty(self.tcx, substs); + match field_ty.sty { + ty::Tuple(_) => field_ty.tuple_fields().count() == subpats.len(), + _ => false, + } + } + _ => false, + }; let res_span = self.tcx.def_span(res.def_id()); - struct_span_err!( + let mut err = struct_span_err!( self.tcx.sess, pat_span, E0023, @@ -697,15 +714,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { res.descr(), fields.len(), fields_ending, - ) - .span_label(pat_span, format!( + ); + err.span_label(pat_span, format!( "expected {} field{}, found {}", fields.len(), fields_ending, subpats.len(), )) - .span_label(res_span, format!("{} defined here", res.descr())) - .emit(); + .span_label(res_span, format!("{} defined here", res.descr())); + + if missing_parenthesis { + err.multipart_suggestion( + "missing parenthesis", + vec![(subpats[0].span.shrink_to_lo(), "(".to_string()), + (subpats[subpats.len()-1].span.shrink_to_hi(), ")".to_string())], + Applicability::MachineApplicable, + ); + } + + err.emit(); } fn check_pat_tuple( diff --git a/src/test/ui/error-codes/E0023.rs b/src/test/ui/error-codes/E0023.rs index 2a97e9048a490..dc421e060e86f 100644 --- a/src/test/ui/error-codes/E0023.rs +++ b/src/test/ui/error-codes/E0023.rs @@ -1,6 +1,7 @@ enum Fruit { Apple(String, String), Pear(u32), + Orange((String, String)), } @@ -10,5 +11,6 @@ fn main() { Fruit::Apple(a) => {}, //~ ERROR E0023 Fruit::Apple(a, b, c) => {}, //~ ERROR E0023 Fruit::Pear(1, 2) => {}, //~ ERROR E0023 + Fruit::Orange(a, b) => {}, //~ ERROR E0023 } } diff --git a/src/test/ui/error-codes/E0023.stderr b/src/test/ui/error-codes/E0023.stderr index d04e494c2585c..8ae7d01ed5f7e 100644 --- a/src/test/ui/error-codes/E0023.stderr +++ b/src/test/ui/error-codes/E0023.stderr @@ -1,5 +1,5 @@ error[E0023]: this pattern has 1 field, but the corresponding tuple variant has 2 fields - --> $DIR/E0023.rs:10:9 + --> $DIR/E0023.rs:11:9 | LL | Apple(String, String), | --------------------- tuple variant defined here @@ -8,7 +8,7 @@ LL | Fruit::Apple(a) => {}, | ^^^^^^^^^^^^^^^ expected 2 fields, found 1 error[E0023]: this pattern has 3 fields, but the corresponding tuple variant has 2 fields - --> $DIR/E0023.rs:11:9 + --> $DIR/E0023.rs:12:9 | LL | Apple(String, String), | --------------------- tuple variant defined here @@ -17,7 +17,7 @@ LL | Fruit::Apple(a, b, c) => {}, | ^^^^^^^^^^^^^^^^^^^^^ expected 2 fields, found 3 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field - --> $DIR/E0023.rs:12:9 + --> $DIR/E0023.rs:13:9 | LL | Pear(u32), | --------- tuple variant defined here @@ -25,6 +25,19 @@ LL | Pear(u32), LL | Fruit::Pear(1, 2) => {}, | ^^^^^^^^^^^^^^^^^ expected 1 field, found 2 -error: aborting due to 3 previous errors +error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field + --> $DIR/E0023.rs:14:9 + | +LL | Orange((String, String)), + | ------------------------ tuple variant defined here +... +LL | Fruit::Orange(a, b) => {}, + | ^^^^^^^^^^^^^^^^^^^ expected 1 field, found 2 +help: missing parenthesis + | +LL | Fruit::Orange((a, b)) => {}, + | ^ ^ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0023`.