typeck/expr: inaccessible private fields
This commit adjusts the missing field diagnostic logic for struct expressions in typeck to improve the diagnostic when the missing fields are inaccessible. Signed-off-by: David Wood <david@davidtw.co>
This commit is contained in:
parent
a18b34d979
commit
c0894e7232
|
@ -1241,6 +1241,55 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
tcx.sess.span_err(span, "union expressions should have exactly one field");
|
tcx.sess.span_err(span, "union expressions should have exactly one field");
|
||||||
}
|
}
|
||||||
} else if check_completeness && !error_happened && !remaining_fields.is_empty() {
|
} else if check_completeness && !error_happened && !remaining_fields.is_empty() {
|
||||||
|
let no_accessible_remaining_fields = remaining_fields
|
||||||
|
.iter()
|
||||||
|
.filter(|(_, (_, field))| {
|
||||||
|
field.vis.is_accessible_from(tcx.parent_module(expr_id).to_def_id(), tcx)
|
||||||
|
})
|
||||||
|
.next()
|
||||||
|
.is_none();
|
||||||
|
|
||||||
|
if no_accessible_remaining_fields {
|
||||||
|
self.report_no_accessible_fields(adt_ty, span);
|
||||||
|
} else {
|
||||||
|
self.report_missing_field(adt_ty, span, remaining_fields);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
error_happened
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_struct_fields_on_error(
|
||||||
|
&self,
|
||||||
|
fields: &'tcx [hir::Field<'tcx>],
|
||||||
|
base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
|
||||||
|
) {
|
||||||
|
for field in fields {
|
||||||
|
self.check_expr(&field.expr);
|
||||||
|
}
|
||||||
|
if let Some(ref base) = *base_expr {
|
||||||
|
self.check_expr(&base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Report an error for a struct field expression when there are fields which aren't provided.
|
||||||
|
///
|
||||||
|
/// ```ignore (diagnostic)
|
||||||
|
/// error: missing field `you_can_use_this_field` in initializer of `foo::Foo`
|
||||||
|
/// --> src/main.rs:8:5
|
||||||
|
/// |
|
||||||
|
/// 8 | foo::Foo {};
|
||||||
|
/// | ^^^^^^^^ missing `you_can_use_this_field`
|
||||||
|
///
|
||||||
|
/// error: aborting due to previous error
|
||||||
|
/// ```
|
||||||
|
fn report_missing_field(
|
||||||
|
&self,
|
||||||
|
adt_ty: Ty<'tcx>,
|
||||||
|
span: Span,
|
||||||
|
remaining_fields: FxHashMap<Ident, (usize, &ty::FieldDef)>,
|
||||||
|
) {
|
||||||
|
let tcx = self.tcx;
|
||||||
let len = remaining_fields.len();
|
let len = remaining_fields.len();
|
||||||
|
|
||||||
let mut displayable_field_names =
|
let mut displayable_field_names =
|
||||||
|
@ -1271,26 +1320,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
truncated_fields_error,
|
truncated_fields_error,
|
||||||
adt_ty
|
adt_ty
|
||||||
)
|
)
|
||||||
.span_label(
|
.span_label(span, format!("missing {}{}", remaining_fields_names, truncated_fields_error))
|
||||||
span,
|
|
||||||
format!("missing {}{}", remaining_fields_names, truncated_fields_error),
|
|
||||||
)
|
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
error_happened
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_struct_fields_on_error(
|
/// Report an error for a struct field expression when there are no visible fields.
|
||||||
&self,
|
///
|
||||||
fields: &'tcx [hir::Field<'tcx>],
|
/// ```ignore (diagnostic)
|
||||||
base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>,
|
/// error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
|
||||||
) {
|
/// --> src/main.rs:8:5
|
||||||
for field in fields {
|
/// |
|
||||||
self.check_expr(&field.expr);
|
/// 8 | foo::Foo {};
|
||||||
}
|
/// | ^^^^^^^^
|
||||||
if let Some(ref base) = *base_expr {
|
///
|
||||||
self.check_expr(&base);
|
/// error: aborting due to previous error
|
||||||
}
|
/// ```
|
||||||
|
fn report_no_accessible_fields(&self, adt_ty: Ty<'tcx>, span: Span) {
|
||||||
|
self.tcx.sess.span_err(
|
||||||
|
span,
|
||||||
|
&format!(
|
||||||
|
"cannot construct `{}` with struct literal syntax due to inaccessible fields",
|
||||||
|
adt_ty,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_unknown_field(
|
fn report_unknown_field(
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
pub mod foo {
|
||||||
|
pub struct Foo {
|
||||||
|
you_cant_use_this_field: bool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo::Foo {};
|
||||||
|
//~^ ERROR cannot construct `Foo` with struct literal syntax due to inaccessible fields
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
error: cannot construct `Foo` with struct literal syntax due to inaccessible fields
|
||||||
|
--> $DIR/issue-76077.rs:8:5
|
||||||
|
|
|
||||||
|
LL | foo::Foo {};
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
Loading…
Reference in New Issue