Skip to content

Commit f556075

Browse files
committed
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.
1 parent db062de commit f556075

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

compiler/rustc_typeck/src/check/expr.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1698,15 +1698,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16981698
// Save the index of all fields regardless of their visibility in case
16991699
// of error recovery.
17001700
self.write_field_index(expr.hir_id, index);
1701+
let adjustments = self.adjust_steps(&autoderef);
17011702
if field.vis.is_accessible_from(def_scope, self.tcx) {
1702-
let adjustments = self.adjust_steps(&autoderef);
17031703
self.apply_adjustments(base, adjustments);
17041704
self.register_predicates(autoderef.into_obligations());
17051705

17061706
self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
17071707
return field_ty;
17081708
}
1709-
private_candidate = Some((base_def.did, field_ty));
1709+
private_candidate = Some((adjustments, base_def.did, field_ty));
17101710
}
17111711
}
17121712
ty::Tuple(tys) => {
@@ -1729,7 +1729,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17291729
}
17301730
self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));
17311731

1732-
if let Some((did, field_ty)) = private_candidate {
1732+
if let Some((adjustments, did, field_ty)) = private_candidate {
1733+
// (#90483) apply adjustments to avoid ExprUseVisitor from
1734+
// creating erroneous projection.
1735+
self.apply_adjustments(base, adjustments);
17331736
self.ban_private_field_access(expr, expr_t, field, did);
17341737
return field_ty;
17351738
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// edition:2021
2+
3+
mod m {
4+
pub struct S { foo: i32 }
5+
impl S {
6+
pub fn foo(&self) -> i32 { 42 }
7+
}
8+
}
9+
10+
fn bar(s: &m::S) {
11+
|| s.foo() + s.foo; //~ ERROR E0616
12+
}
13+
14+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0616]: field `foo` of struct `S` is private
2+
--> $DIR/issue-90483-inaccessible-field-adjustment.rs:11:18
3+
|
4+
LL | || s.foo() + s.foo;
5+
| ^^^ private field
6+
|
7+
help: a method `foo` also exists, call it with parentheses
8+
|
9+
LL | || s.foo() + s.foo();
10+
| ++
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0616`.

0 commit comments

Comments
 (0)