Skip to content

Commit

Permalink
Unrolled build for rust-lang#134148
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#134148 - dev-ardi:cleanup_check_field_expr, r=compiler-errors

add comments in check_expr_field

Nothing special, just a few comments and a couple of small cleanups.
  • Loading branch information
rust-timer authored Dec 11, 2024
2 parents 1f3bf23 + 55806e5 commit c6f9444
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,7 @@ impl<'a> DiagCtxtHandle<'a> {
Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).emit()
}

/// Ensures that an error is printed. See `Level::DelayedBug`.
/// Ensures that an error is printed. See [`Level::DelayedBug`].
///
/// Note: this function used to be called `delay_span_bug`. It was renamed
/// to match similar functions like `span_err`, `span_warn`, etc.
Expand Down
27 changes: 22 additions & 5 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2692,33 +2692,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None
}

// Check field access expressions
/// Check field access expressions, this works for both structs and tuples.
/// Returns the Ty of the field.
///
/// ```not_rust
/// base.field
/// ^^^^^^^^^^ expr
/// ^^^^ base
/// ^^^^^ field
/// ```
fn check_expr_field(
&self,
expr: &'tcx hir::Expr<'tcx>,
base: &'tcx hir::Expr<'tcx>,
field: Ident,
// The expected type hint of the field.
expected: Expectation<'tcx>,
) -> Ty<'tcx> {
debug!("check_field(expr: {:?}, base: {:?}, field: {:?})", expr, base, field);
let base_ty = self.check_expr(base);
let base_ty = self.structurally_resolve_type(base.span, base_ty);

// Whether we are trying to access a private field. Used for error reporting.
let mut private_candidate = None;

// Field expressions automatically deref
let mut autoderef = self.autoderef(expr.span, base_ty);
while let Some((deref_base_ty, _)) = autoderef.next() {
debug!("deref_base_ty: {:?}", deref_base_ty);
match deref_base_ty.kind() {
ty::Adt(base_def, args) if !base_def.is_enum() => {
debug!("struct named {:?}", deref_base_ty);
let body_hir_id = self.tcx.local_def_id_to_hir_id(self.body_id);
let (ident, def_scope) =
self.tcx.adjust_ident_and_get_scope(field, base_def.did(), body_hir_id);

// we don't care to report errors for a struct if the struct itself is tainted
if let Err(guar) = base_def.non_enum_variant().has_errors() {
return Ty::new_error(self.tcx(), guar);
}

let fn_body_hir_id = self.tcx.local_def_id_to_hir_id(self.body_id);
let (ident, def_scope) =
self.tcx.adjust_ident_and_get_scope(field, base_def.did(), fn_body_hir_id);

if let Some((idx, field)) = self.find_adt_field(*base_def, ident) {
self.write_field_index(expr.hir_id, idx);

Expand Down Expand Up @@ -2752,6 +2765,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => {}
}
}
// We failed to check the expression, report an error.

// Emits an error if we deref an infer variable, like calling `.field` on a base type of &_.
self.structurally_resolve_type(autoderef.span(), autoderef.final_ty(false));

if let Some((adjustments, did)) = private_candidate {
Expand All @@ -2776,6 +2792,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr.hir_id,
expected.only_has_type(self),
) {
// If taking a method instead of calling it
self.ban_take_value_of_method(expr, base_ty, field)
} else if !base_ty.is_primitive_ty() {
self.ban_nonexisting_field(field, base, expr, base_ty)
Expand Down

0 comments on commit c6f9444

Please sign in to comment.