Skip to content

Commit

Permalink
Rollup merge of rust-lang#90508 - nbdd0121:issue-90483, r=davidtwco
Browse files Browse the repository at this point in the history
Apply adjustments for field expression even if inaccessible

The adjustments are used later by ExprUseVisitor to build Place projections and without adjustments it can produce invalid result.

Fix rust-lang#90483

`@rustbot` label: T-compiler
  • Loading branch information
matthiaskrgr committed Nov 6, 2021
2 parents dad5a31 + f556075 commit 1e4e823
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
9 changes: 6 additions & 3 deletions compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1698,15 +1698,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Save the index of all fields regardless of their visibility in case
// of error recovery.
self.write_field_index(expr.hir_id, index);
let adjustments = self.adjust_steps(&autoderef);
if field.vis.is_accessible_from(def_scope, self.tcx) {
let adjustments = self.adjust_steps(&autoderef);
self.apply_adjustments(base, adjustments);
self.register_predicates(autoderef.into_obligations());

self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
return field_ty;
}
private_candidate = Some((base_def.did, field_ty));
private_candidate = Some((adjustments, base_def.did, field_ty));
}
}
ty::Tuple(tys) => {
Expand All @@ -1729,7 +1729,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));

if let Some((did, field_ty)) = private_candidate {
if let Some((adjustments, did, field_ty)) = private_candidate {
// (#90483) apply adjustments to avoid ExprUseVisitor from
// creating erroneous projection.
self.apply_adjustments(base, adjustments);
self.ban_private_field_access(expr, expr_t, field, did);
return field_ty;
}
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/typeck/issue-90483-inaccessible-field-adjustment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// edition:2021

mod m {
pub struct S { foo: i32 }
impl S {
pub fn foo(&self) -> i32 { 42 }
}
}

fn bar(s: &m::S) {
|| s.foo() + s.foo; //~ ERROR E0616
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0616]: field `foo` of struct `S` is private
--> $DIR/issue-90483-inaccessible-field-adjustment.rs:11:18
|
LL | || s.foo() + s.foo;
| ^^^ private field
|
help: a method `foo` also exists, call it with parentheses
|
LL | || s.foo() + s.foo();
| ++

error: aborting due to previous error

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

0 comments on commit 1e4e823

Please sign in to comment.