From 77fb6a0f32408925f212d1fb877e900f9736840d Mon Sep 17 00:00:00 2001 From: csmoe Date: Fri, 12 Mar 2021 01:49:27 +0800 Subject: [PATCH] fix: check before index into generated patterns --- .../src/thir/pattern/deconstruct_pat.rs | 4 +- compiler/rustc_typeck/src/check/pat.rs | 49 ------------------- .../ui/structs/struct-variant-privacy-xc.rs | 3 +- .../structs/struct-variant-privacy-xc.stderr | 8 +-- src/test/ui/structs/struct-variant-privacy.rs | 1 - .../ui/structs/struct-variant-privacy.stderr | 8 +-- src/test/ui/typeck/issue-82772.rs | 10 ++-- src/test/ui/typeck/issue-82772.stderr | 24 +++++---- 8 files changed, 26 insertions(+), 81 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 3a67eeff92c..8c740a7ec15 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -1343,7 +1343,9 @@ impl<'p, 'tcx> Fields<'p, 'tcx> { match &mut fields { Fields::Vec(pats) => { for (i, pat) in new_pats { - pats[i] = pat + if let Some(p) = pats.get_mut(i) { + *p = pat; + } } } Fields::Filtered { fields, .. } => { diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs index 733f8e3dc9d..f8ca916caf1 100644 --- a/compiler/rustc_typeck/src/check/pat.rs +++ b/compiler/rustc_typeck/src/check/pat.rs @@ -1176,7 +1176,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut no_field_errors = true; let mut inexistent_fields = vec![]; - let mut invisible_fields = vec![]; // Typecheck each field. for field in fields { let span = field.span; @@ -1192,12 +1191,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field_map .get(&ident) .map(|(i, f)| { - if !f - .vis - .is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx) - { - invisible_fields.push(field.ident); - } self.write_field_index(field.hir_id, *i); self.tcx.check_stability(f.did, Some(pat.hir_id), span); self.field_ty(span, f, substs) @@ -1288,13 +1281,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.error_tuple_variant_index_shorthand(variant, pat, fields) { err.emit(); - } else if !invisible_fields.is_empty() { - let mut err = self.error_invisible_fields( - adt.variant_descr(), - &invisible_fields, - variant, - ); - err.emit(); } } } @@ -1373,41 +1359,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .emit(); } - fn error_invisible_fields( - &self, - kind_name: &str, - invisible_fields: &[Ident], - variant: &ty::VariantDef, - ) -> DiagnosticBuilder<'tcx> { - let spans = invisible_fields.iter().map(|ident| ident.span).collect::>(); - let (field_names, t) = if invisible_fields.len() == 1 { - (format!("a field named `{}`", invisible_fields[0]), "is") - } else { - ( - format!( - "fields named {}", - invisible_fields - .iter() - .map(|ident| format!("`{}`", ident)) - .collect::>() - .join(", ") - ), - "are", - ) - }; - let err = struct_span_err!( - self.tcx.sess, - spans, - E0603, - "cannot match on {} of {} `{}`, which {} not accessible in current scope", - field_names, - kind_name, - self.tcx.def_path_str(variant.def_id), - t - ); - err - } - fn error_inexistent_fields( &self, kind_name: &str, diff --git a/src/test/ui/structs/struct-variant-privacy-xc.rs b/src/test/ui/structs/struct-variant-privacy-xc.rs index bf765be75dd..763ab952738 100644 --- a/src/test/ui/structs/struct-variant-privacy-xc.rs +++ b/src/test/ui/structs/struct-variant-privacy-xc.rs @@ -4,8 +4,7 @@ extern crate struct_variant_privacy; fn f(b: struct_variant_privacy::Bar) { //~^ ERROR enum `Bar` is private match b { - struct_variant_privacy::Bar::Baz { a: _a } => {} //~ ERROR cannot match on - //~^ ERROR enum `Bar` is private + struct_variant_privacy::Bar::Baz { a: _a } => {} //~ ERROR enum `Bar` is private } } diff --git a/src/test/ui/structs/struct-variant-privacy-xc.stderr b/src/test/ui/structs/struct-variant-privacy-xc.stderr index 03de40b488c..1c1caaef8b7 100644 --- a/src/test/ui/structs/struct-variant-privacy-xc.stderr +++ b/src/test/ui/structs/struct-variant-privacy-xc.stderr @@ -22,12 +22,6 @@ note: the enum `Bar` is defined here LL | enum Bar { | ^^^^^^^^ -error[E0603]: cannot match on a field named `a` of variant `struct_variant_privacy::Bar::Baz`, which is not accessible in current scope - --> $DIR/struct-variant-privacy-xc.rs:7:44 - | -LL | struct_variant_privacy::Bar::Baz { a: _a } => {} - | ^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0603`. diff --git a/src/test/ui/structs/struct-variant-privacy.rs b/src/test/ui/structs/struct-variant-privacy.rs index 7ce8ce9e290..fcdf9a22baf 100644 --- a/src/test/ui/structs/struct-variant-privacy.rs +++ b/src/test/ui/structs/struct-variant-privacy.rs @@ -8,7 +8,6 @@ fn f(b: foo::Bar) { //~^ ERROR enum `Bar` is private match b { foo::Bar::Baz { a: _a } => {} //~ ERROR enum `Bar` is private - //~^ ERROR cannot match on } } diff --git a/src/test/ui/structs/struct-variant-privacy.stderr b/src/test/ui/structs/struct-variant-privacy.stderr index a69a888553b..eafd26c716f 100644 --- a/src/test/ui/structs/struct-variant-privacy.stderr +++ b/src/test/ui/structs/struct-variant-privacy.stderr @@ -22,12 +22,6 @@ note: the enum `Bar` is defined here LL | enum Bar { | ^^^^^^^^ -error[E0603]: cannot match on a field named `a` of variant `Bar::Baz`, which is not accessible in current scope - --> $DIR/struct-variant-privacy.rs:10:25 - | -LL | foo::Bar::Baz { a: _a } => {} - | ^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0603`. diff --git a/src/test/ui/typeck/issue-82772.rs b/src/test/ui/typeck/issue-82772.rs index 62eb5f7a021..326273bfe92 100644 --- a/src/test/ui/typeck/issue-82772.rs +++ b/src/test/ui/typeck/issue-82772.rs @@ -1,13 +1,13 @@ // edition:2018 fn main() { - use a::LocalModPrivateStruct; - let Box { 1: _, .. }: Box<()>; //~ ERROR cannot match on - let LocalModPrivateStruct { 1: _, .. } = LocalModPrivateStruct::default(); - //~^ ERROR cannot match on + use a::ModPrivateStruct; + let Box { 0: _, .. }: Box<()>; //~ ERROR field `0` of + let Box { 1: _, .. }: Box<()>; //~ ERROR field `1` of + let ModPrivateStruct { 1: _, .. } = ModPrivateStruct::default(); //~ ERROR field `1` of } mod a { #[derive(Default)] - pub struct LocalModPrivateStruct(u8, u8); + pub struct ModPrivateStruct(u8, u8); } diff --git a/src/test/ui/typeck/issue-82772.stderr b/src/test/ui/typeck/issue-82772.stderr index 5bc6a5aa9e3..321143cb968 100644 --- a/src/test/ui/typeck/issue-82772.stderr +++ b/src/test/ui/typeck/issue-82772.stderr @@ -1,15 +1,21 @@ -error[E0603]: cannot match on a field named `1` of struct `Box`, which is not accessible in current scope +error[E0451]: field `0` of struct `Box` is private --> $DIR/issue-82772.rs:5:15 | -LL | let Box { 1: _, .. }: Box<()>; - | ^ +LL | let Box { 0: _, .. }: Box<()>; + | ^^^^ private field -error[E0603]: cannot match on a field named `1` of struct `LocalModPrivateStruct`, which is not accessible in current scope - --> $DIR/issue-82772.rs:6:33 +error[E0451]: field `1` of struct `Box` is private + --> $DIR/issue-82772.rs:6:15 | -LL | let LocalModPrivateStruct { 1: _, .. } = LocalModPrivateStruct::default(); - | ^ +LL | let Box { 1: _, .. }: Box<()>; + | ^^^^ private field -error: aborting due to 2 previous errors +error[E0451]: field `1` of struct `ModPrivateStruct` is private + --> $DIR/issue-82772.rs:7:28 + | +LL | let ModPrivateStruct { 1: _, .. } = ModPrivateStruct::default(); + | ^^^^ private field -For more information about this error, try `rustc --explain E0603`. +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0451`.