Skip to content

Commit 1e4e823

Browse files
authored
Rollup merge of rust-lang#90508 - nbdd0121:issue-90483, r=davidtwco
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
2 parents dad5a31 + f556075 commit 1e4e823

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)