add ui testcase for issue 82772
This commit is contained in:
parent
45b3c28518
commit
2fd2796aae
@ -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,
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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`.
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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`.
|
||||||
|
13
src/test/ui/typeck/issue-82772.rs
Normal file
13
src/test/ui/typeck/issue-82772.rs
Normal 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);
|
||||||
|
}
|
15
src/test/ui/typeck/issue-82772.stderr
Normal file
15
src/test/ui/typeck/issue-82772.stderr
Normal 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`.
|
Loading…
Reference in New Issue
Block a user