Skip to content

Commit 90a42c2

Browse files
authored
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.
2 parents 2e60288 + 55806e5 commit 90a42c2

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

compiler/rustc_errors/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,7 @@ impl<'a> DiagCtxtHandle<'a> {
12911291
Diag::<ErrorGuaranteed>::new(self, DelayedBug, msg.into()).emit()
12921292
}
12931293

1294-
/// Ensures that an error is printed. See `Level::DelayedBug`.
1294+
/// Ensures that an error is printed. See [`Level::DelayedBug`].
12951295
///
12961296
/// Note: this function used to be called `delay_span_bug`. It was renamed
12971297
/// to match similar functions like `span_err`, `span_warn`, etc.

compiler/rustc_hir_typeck/src/expr.rs

+22-5
Original file line numberDiff line numberDiff line change
@@ -2692,33 +2692,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26922692
None
26932693
}
26942694

2695-
// Check field access expressions
2695+
/// Check field access expressions, this works for both structs and tuples.
2696+
/// Returns the Ty of the field.
2697+
///
2698+
/// ```not_rust
2699+
/// base.field
2700+
/// ^^^^^^^^^^ expr
2701+
/// ^^^^ base
2702+
/// ^^^^^ field
2703+
/// ```
26962704
fn check_expr_field(
26972705
&self,
26982706
expr: &'tcx hir::Expr<'tcx>,
26992707
base: &'tcx hir::Expr<'tcx>,
27002708
field: Ident,
2709+
// The expected type hint of the field.
27012710
expected: Expectation<'tcx>,
27022711
) -> Ty<'tcx> {
27032712
debug!("check_field(expr: {:?}, base: {:?}, field: {:?})", expr, base, field);
27042713
let base_ty = self.check_expr(base);
27052714
let base_ty = self.structurally_resolve_type(base.span, base_ty);
2715+
2716+
// Whether we are trying to access a private field. Used for error reporting.
27062717
let mut private_candidate = None;
2718+
2719+
// Field expressions automatically deref
27072720
let mut autoderef = self.autoderef(expr.span, base_ty);
27082721
while let Some((deref_base_ty, _)) = autoderef.next() {
27092722
debug!("deref_base_ty: {:?}", deref_base_ty);
27102723
match deref_base_ty.kind() {
27112724
ty::Adt(base_def, args) if !base_def.is_enum() => {
27122725
debug!("struct named {:?}", deref_base_ty);
2713-
let body_hir_id = self.tcx.local_def_id_to_hir_id(self.body_id);
2714-
let (ident, def_scope) =
2715-
self.tcx.adjust_ident_and_get_scope(field, base_def.did(), body_hir_id);
2716-
27172726
// we don't care to report errors for a struct if the struct itself is tainted
27182727
if let Err(guar) = base_def.non_enum_variant().has_errors() {
27192728
return Ty::new_error(self.tcx(), guar);
27202729
}
27212730

2731+
let fn_body_hir_id = self.tcx.local_def_id_to_hir_id(self.body_id);
2732+
let (ident, def_scope) =
2733+
self.tcx.adjust_ident_and_get_scope(field, base_def.did(), fn_body_hir_id);
2734+
27222735
if let Some((idx, field)) = self.find_adt_field(*base_def, ident) {
27232736
self.write_field_index(expr.hir_id, idx);
27242737

@@ -2752,6 +2765,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
27522765
_ => {}
27532766
}
27542767
}
2768+
// We failed to check the expression, report an error.
2769+
2770+
// Emits an error if we deref an infer variable, like calling `.field` on a base type of &_.
27552771
self.structurally_resolve_type(autoderef.span(), autoderef.final_ty(false));
27562772

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

0 commit comments

Comments
 (0)