add ui testcase for issue 82772

This commit is contained in:
csmoe 2021-03-05 13:54:35 +08:00
parent 45b3c28518
commit 2fd2796aae
7 changed files with 101 additions and 8 deletions

View File

@ -1176,6 +1176,7 @@ fn check_struct_pat_fields(
let mut no_field_errors = true; let mut no_field_errors = true;
let mut inexistent_fields = vec![]; let mut inexistent_fields = vec![];
let mut invisible_fields = vec![];
// Typecheck each field. // Typecheck each field.
for field in fields { for field in fields {
let span = field.span; let span = field.span;
@ -1191,6 +1192,12 @@ fn check_struct_pat_fields(
field_map field_map
.get(&ident) .get(&ident)
.map(|(i, f)| { .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.write_field_index(field.hir_id, *i);
self.tcx.check_stability(f.did, Some(pat.hir_id), span); self.tcx.check_stability(f.did, Some(pat.hir_id), span);
self.field_ty(span, f, substs) self.field_ty(span, f, substs)
@ -1281,6 +1288,13 @@ fn check_struct_pat_fields(
self.error_tuple_variant_index_shorthand(variant, pat, fields) self.error_tuple_variant_index_shorthand(variant, pat, fields)
{ {
err.emit(); err.emit();
} else if !invisible_fields.is_empty() {
let mut err = self.error_invisible_fields(
adt.variant_descr(),
&invisible_fields,
variant,
);
err.emit();
} }
} }
} }
@ -1359,6 +1373,41 @@ fn error_field_already_bound(&self, span: Span, ident: Ident, other_field: Span)
.emit(); .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::<Vec<_>>();
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::<Vec<String>>()
.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( fn error_inexistent_fields(
&self, &self,
kind_name: &str, kind_name: &str,

View File

@ -1,9 +1,11 @@
// aux-build:struct_variant_privacy.rs // aux-build:struct_variant_privacy.rs
extern crate struct_variant_privacy; extern crate struct_variant_privacy;
fn f(b: struct_variant_privacy::Bar) { //~ ERROR enum `Bar` is private fn f(b: struct_variant_privacy::Bar) {
//~^ ERROR enum `Bar` is private
match b { match b {
struct_variant_privacy::Bar::Baz { a: _a } => {} //~ ERROR enum `Bar` is private struct_variant_privacy::Bar::Baz { a: _a } => {} //~ ERROR cannot match on
//~^ ERROR enum `Bar` is private
} }
} }

View File

@ -11,7 +11,7 @@ LL | enum Bar {
| ^^^^^^^^ | ^^^^^^^^
error[E0603]: enum `Bar` is private error[E0603]: enum `Bar` is private
--> $DIR/struct-variant-privacy-xc.rs:6:33 --> $DIR/struct-variant-privacy-xc.rs:7:33
| |
LL | struct_variant_privacy::Bar::Baz { a: _a } => {} LL | struct_variant_privacy::Bar::Baz { a: _a } => {}
| ^^^ private enum | ^^^ private enum
@ -22,6 +22,12 @@ note: the enum `Bar` is defined here
LL | enum Bar { LL | enum Bar {
| ^^^^^^^^ | ^^^^^^^^
error: aborting due to 2 previous errors 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
For more information about this error, try `rustc --explain E0603`. For more information about this error, try `rustc --explain E0603`.

View File

@ -1,12 +1,14 @@
mod foo { mod foo {
enum Bar { enum Bar {
Baz { a: isize } Baz { a: isize },
} }
} }
fn f(b: foo::Bar) { //~ ERROR enum `Bar` is private fn f(b: foo::Bar) {
//~^ ERROR enum `Bar` is private
match b { match b {
foo::Bar::Baz { a: _a } => {} //~ ERROR enum `Bar` is private foo::Bar::Baz { a: _a } => {} //~ ERROR enum `Bar` is private
//~^ ERROR cannot match on
} }
} }

View File

@ -11,7 +11,7 @@ LL | enum Bar {
| ^^^^^^^^ | ^^^^^^^^
error[E0603]: enum `Bar` is private error[E0603]: enum `Bar` is private
--> $DIR/struct-variant-privacy.rs:9:14 --> $DIR/struct-variant-privacy.rs:10:14
| |
LL | foo::Bar::Baz { a: _a } => {} LL | foo::Bar::Baz { a: _a } => {}
| ^^^ private enum | ^^^ private enum
@ -22,6 +22,12 @@ note: the enum `Bar` is defined here
LL | enum Bar { LL | enum Bar {
| ^^^^^^^^ | ^^^^^^^^
error: aborting due to 2 previous errors 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
For more information about this error, try `rustc --explain E0603`. For more information about this error, try `rustc --explain E0603`.

View File

@ -0,0 +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
}
mod a {
#[derive(Default)]
pub struct LocalModPrivateStruct(u8, u8);
}

View File

@ -0,0 +1,15 @@
error[E0603]: cannot match on a field named `1` of struct `Box`, which is not accessible in current scope
--> $DIR/issue-82772.rs:5:15
|
LL | let Box { 1: _, .. }: Box<()>;
| ^
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
|
LL | let LocalModPrivateStruct { 1: _, .. } = LocalModPrivateStruct::default();
| ^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0603`.