about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-12-11 20:00:15 +0100
committerGitHub <noreply@github.com>2024-12-11 20:00:15 +0100
commit90a42c2519c97775b2b9cd55fb2b6d9100b8db3b (patch)
tree63b33a6d42eef86d380aa949ef2878698ef0ae52
parent2e60288ce0b317134779d95daf80df601a4c17c5 (diff)
parent55806e565503f8d9e519f3c958f3c51836304cd2 (diff)
downloadrust-90a42c2519c97775b2b9cd55fb2b6d9100b8db3b.tar.gz
rust-90a42c2519c97775b2b9cd55fb2b6d9100b8db3b.zip
Rollup merge of #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.
-rw-r--r--compiler/rustc_errors/src/lib.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs27
2 files changed, 23 insertions, 6 deletions
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 6232c875ee8..fc44340851c 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -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.
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 30f02b80ea6..b3ce1df3def 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -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);
 
@@ -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 {
@@ -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)