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.
This commit is contained in:
parent
db062de72b
commit
f556075459
3 changed files with 34 additions and 3 deletions
|
@ -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) => {
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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() {}
|
|
@ -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`.
|
Loading…
Add table
Add a link
Reference in a new issue