Skip to content

Commit 2fd2796

Browse files
committed
add ui testcase for issue 82772
1 parent 45b3c28 commit 2fd2796

File tree

7 files changed

+101
-8
lines changed

7 files changed

+101
-8
lines changed

compiler/rustc_typeck/src/check/pat.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11761176
let mut no_field_errors = true;
11771177

11781178
let mut inexistent_fields = vec![];
1179+
let mut invisible_fields = vec![];
11791180
// Typecheck each field.
11801181
for field in fields {
11811182
let span = field.span;
@@ -1191,6 +1192,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11911192
field_map
11921193
.get(&ident)
11931194
.map(|(i, f)| {
1195+
if !f
1196+
.vis
1197+
.is_accessible_from(tcx.parent_module(pat.hir_id).to_def_id(), tcx)
1198+
{
1199+
invisible_fields.push(field.ident);
1200+
}
11941201
self.write_field_index(field.hir_id, *i);
11951202
self.tcx.check_stability(f.did, Some(pat.hir_id), span);
11961203
self.field_ty(span, f, substs)
@@ -1281,6 +1288,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12811288
self.error_tuple_variant_index_shorthand(variant, pat, fields)
12821289
{
12831290
err.emit();
1291+
} else if !invisible_fields.is_empty() {
1292+
let mut err = self.error_invisible_fields(
1293+
adt.variant_descr(),
1294+
&invisible_fields,
1295+
variant,
1296+
);
1297+
err.emit();
12841298
}
12851299
}
12861300
}
@@ -1359,6 +1373,41 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13591373
.emit();
13601374
}
13611375

1376+
fn error_invisible_fields(
1377+
&self,
1378+
kind_name: &str,
1379+
invisible_fields: &[Ident],
1380+
variant: &ty::VariantDef,
1381+
) -> DiagnosticBuilder<'tcx> {
1382+
let spans = invisible_fields.iter().map(|ident| ident.span).collect::<Vec<_>>();
1383+
let (field_names, t) = if invisible_fields.len() == 1 {
1384+
(format!("a field named `{}`", invisible_fields[0]), "is")
1385+
} else {
1386+
(
1387+
format!(
1388+
"fields named {}",
1389+
invisible_fields
1390+
.iter()
1391+
.map(|ident| format!("`{}`", ident))
1392+
.collect::<Vec<String>>()
1393+
.join(", ")
1394+
),
1395+
"are",
1396+
)
1397+
};
1398+
let err = struct_span_err!(
1399+
self.tcx.sess,
1400+
spans,
1401+
E0603,
1402+
"cannot match on {} of {} `{}`, which {} not accessible in current scope",
1403+
field_names,
1404+
kind_name,
1405+
self.tcx.def_path_str(variant.def_id),
1406+
t
1407+
);
1408+
err
1409+
}
1410+
13621411
fn error_inexistent_fields(
13631412
&self,
13641413
kind_name: &str,

src/test/ui/structs/struct-variant-privacy-xc.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// aux-build:struct_variant_privacy.rs
22
extern crate struct_variant_privacy;
33

4-
fn f(b: struct_variant_privacy::Bar) { //~ ERROR enum `Bar` is private
4+
fn f(b: struct_variant_privacy::Bar) {
5+
//~^ ERROR enum `Bar` is private
56
match b {
6-
struct_variant_privacy::Bar::Baz { a: _a } => {} //~ ERROR enum `Bar` is private
7+
struct_variant_privacy::Bar::Baz { a: _a } => {} //~ ERROR cannot match on
8+
//~^ ERROR enum `Bar` is private
79
}
810
}
911

src/test/ui/structs/struct-variant-privacy-xc.stderr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | enum Bar {
1111
| ^^^^^^^^
1212

1313
error[E0603]: enum `Bar` is private
14-
--> $DIR/struct-variant-privacy-xc.rs:6:33
14+
--> $DIR/struct-variant-privacy-xc.rs:7:33
1515
|
1616
LL | struct_variant_privacy::Bar::Baz { a: _a } => {}
1717
| ^^^ private enum
@@ -22,6 +22,12 @@ note: the enum `Bar` is defined here
2222
LL | enum Bar {
2323
| ^^^^^^^^
2424

25-
error: aborting due to 2 previous errors
25+
error[E0603]: cannot match on a field named `a` of variant `struct_variant_privacy::Bar::Baz`, which is not accessible in current scope
26+
--> $DIR/struct-variant-privacy-xc.rs:7:44
27+
|
28+
LL | struct_variant_privacy::Bar::Baz { a: _a } => {}
29+
| ^
30+
31+
error: aborting due to 3 previous errors
2632

2733
For more information about this error, try `rustc --explain E0603`.

src/test/ui/structs/struct-variant-privacy.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
mod foo {
22
enum Bar {
3-
Baz { a: isize }
3+
Baz { a: isize },
44
}
55
}
66

7-
fn f(b: foo::Bar) { //~ ERROR enum `Bar` is private
7+
fn f(b: foo::Bar) {
8+
//~^ ERROR enum `Bar` is private
89
match b {
910
foo::Bar::Baz { a: _a } => {} //~ ERROR enum `Bar` is private
11+
//~^ ERROR cannot match on
1012
}
1113
}
1214

src/test/ui/structs/struct-variant-privacy.stderr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | enum Bar {
1111
| ^^^^^^^^
1212

1313
error[E0603]: enum `Bar` is private
14-
--> $DIR/struct-variant-privacy.rs:9:14
14+
--> $DIR/struct-variant-privacy.rs:10:14
1515
|
1616
LL | foo::Bar::Baz { a: _a } => {}
1717
| ^^^ private enum
@@ -22,6 +22,12 @@ note: the enum `Bar` is defined here
2222
LL | enum Bar {
2323
| ^^^^^^^^
2424

25-
error: aborting due to 2 previous errors
25+
error[E0603]: cannot match on a field named `a` of variant `Bar::Baz`, which is not accessible in current scope
26+
--> $DIR/struct-variant-privacy.rs:10:25
27+
|
28+
LL | foo::Bar::Baz { a: _a } => {}
29+
| ^
30+
31+
error: aborting due to 3 previous errors
2632

2733
For more information about this error, try `rustc --explain E0603`.

src/test/ui/typeck/issue-82772.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// edition:2018
2+
3+
fn main() {
4+
use a::LocalModPrivateStruct;
5+
let Box { 1: _, .. }: Box<()>; //~ ERROR cannot match on
6+
let LocalModPrivateStruct { 1: _, .. } = LocalModPrivateStruct::default();
7+
//~^ ERROR cannot match on
8+
}
9+
10+
mod a {
11+
#[derive(Default)]
12+
pub struct LocalModPrivateStruct(u8, u8);
13+
}

src/test/ui/typeck/issue-82772.stderr

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0603]: cannot match on a field named `1` of struct `Box`, which is not accessible in current scope
2+
--> $DIR/issue-82772.rs:5:15
3+
|
4+
LL | let Box { 1: _, .. }: Box<()>;
5+
| ^
6+
7+
error[E0603]: cannot match on a field named `1` of struct `LocalModPrivateStruct`, which is not accessible in current scope
8+
--> $DIR/issue-82772.rs:6:33
9+
|
10+
LL | let LocalModPrivateStruct { 1: _, .. } = LocalModPrivateStruct::default();
11+
| ^
12+
13+
error: aborting due to 2 previous errors
14+
15+
For more information about this error, try `rustc --explain E0603`.

0 commit comments

Comments
 (0)