diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-12-11 20:00:15 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-11 20:00:15 +0100 |
| commit | 90a42c2519c97775b2b9cd55fb2b6d9100b8db3b (patch) | |
| tree | 63b33a6d42eef86d380aa949ef2878698ef0ae52 | |
| parent | 2e60288ce0b317134779d95daf80df601a4c17c5 (diff) | |
| parent | 55806e565503f8d9e519f3c958f3c51836304cd2 (diff) | |
| download | rust-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.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/expr.rs | 27 |
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) |
