Change:
<!-- [31mICE[0m: Rustc '-Zincremental-verify-ich=yes -Cincremental=<dir-Cdebuginfo=2' 'thread 'rustc' panicked at 'forcing query with already existing '', 'thread 'rustc' panicked at 'forcing query with already existing '' File: --auto-reduced (treereduce-rust): &lt;details&lt;summary&lt;strongoriginal code&lt;/strong&lt;/summary&lt;poriginal: </p</detailsVersion information ` Command: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summary<strongProgram output</strong</summary<p</p</details<!-- query stack: note: compiler flags: -Z incremental-verify-ich=yes -C incremental=[REDACTED] -C debuginfo=2 [findfield] find the index of maybe nested field in [typeck] type-checking [analysis] running analysis passes on this crate --
This bisects to :thinking:
WG-prioritization assigning priority (). cc: + for label -I-prioritize +P-medium
I'm going to fix it in (still WIP), where the query will be removed.
Testing out on this issue:
I seems like does not have proper or impls, possibly due to the differing . Are you familiar with that part of spans?

Discussion:
use rustc_middle::{bug, span_bug}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; <del> use rustc_target::abi::FieldIdx; </del> use rustc_target::spec::abi; use rustc_trait_selection::error_reporting::traits::suggestions::NextTypeParamName; use rustc_trait_selection::infer::InferCtxtExt;

coroutine_kind, coroutine_for_closure, is_type_alias_impl_trait, <del> find_field, </del> ..*providers }; }

} } <del> fn find_field(tcx: TyCtxt<'_>, (def_id, ident): (DefId, Ident)) -> Option<FieldIdx> { let adt = tcx.adt_def(def_id); if adt.is_enum() { return None; } adt.non_enum_variant().fields.iter_enumerated().find_map(|(idx, field)| { if field.is_unnamed() { let field_ty = tcx.type_of(field.did).instantiate_identity(); let adt_def = field_ty.ty_adt_def().expect("expect Adt for unnamed field"); tcx.find_field((adt_def.did(), ident)).map(|_| idx) } else { (field.ident(tcx).normalize_to_macros_2_0() == ident).then_some(idx) } }) } </del> #[derive(Clone, Copy)] struct NestedSpan { span: Span,

use rustc_trait_selection::traits::ObligationCtxt; use rustc_trait_selection::traits::{self, ObligationCauseCode}; <ins> use smallvec::SmallVec; </ins> impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn check_expr_has_type_or_error( &self,

display } <ins> /// Find the position of a field named `ident` in `base_def`, accounting for unnammed fields. /// Return whether such a field has been found. The path to it is stored in `nested_fields`. /// `ident` must have been adjusted beforehand. fn find_adt_field( &self, base_def: ty::AdtDef<'tcx>, ident: Ident, nested_fields: &mut SmallVec<[(FieldIdx, &'tcx ty::FieldDef); 1]>, ) -> bool { // No way to find a field in an enum. if base_def.is_enum() { return false; } for (field_idx, field) in base_def.non_enum_variant().fields.iter_enumerated() { if field.is_unnamed() { // We have an unnamed field, recurse into the nested ADT to find `ident`. // If we find it there, return immediately, and `nested_fields` will contain the // correct path. nested_fields.push((field_idx, field)); let field_ty = self.tcx.type_of(field.did).instantiate_identity(); let adt_def = field_ty.ty_adt_def().expect("expect Adt for unnamed field"); if self.find_adt_field(adt_def, ident, &mut *nested_fields) { return true; } nested_fields.pop(); } else if field.ident(self.tcx).normalize_to_macros_2_0() == ident { // We found the field we wanted. nested_fields.push((field_idx, field)); return true; } } false } </ins> // Check field access expressions fn check_field( &self,

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); <del> let mut adt_def = *base_def; let mut last_ty = None; let mut nested_fields = Vec::new(); let mut index = None; </del> // we don't care to report errors for a struct if the struct itself is tainted <del> if let Err(guar) = adt_def.non_enum_variant().has_errors() { </del> <ins> if let Err(guar) = base_def.non_enum_variant().has_errors() { </ins> return Ty::new_error(self.tcx(), guar); } <del> while let Some(idx) = self.tcx.find_field((adt_def.did(), ident)) { let &mut first_idx = index.get_or_insert(idx); let field = &adt_def.non_enum_variant().fields[idx]; let field_ty = self.field_ty(expr.span, field, args); if let Some(ty) = last_ty { nested_fields.push((ty, idx)); } if field.ident(self.tcx).normalize_to_macros_2_0() == ident { // Save the index of all fields regardless of their visibility in case // of error recovery. self.write_field_index(expr.hir_id, first_idx, nested_fields); let adjustments = self.adjust_steps(&autoderef); if field.vis.is_accessible_from(def_scope, self.tcx) { 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((adjustments, base_def.did())); break; </del> <ins> let mut field_path = SmallVec::new(); if self.find_adt_field(*base_def, ident, &mut field_path) { let (first_idx, _) = field_path[0]; let (_, last_field) = field_path.last().unwrap(); // Save the index of all fields regardless of their visibility in case // of error recovery. let nested_fields = field_path[..] .array_windows() .map(|[(_, outer), (inner_idx, _)]| { let outer_ty = self.field_ty(expr.span, outer, args); (outer_ty, *inner_idx) }) .collect(); self.write_field_index(expr.hir_id, first_idx, nested_fields); let adjustments = self.adjust_steps(&autoderef); if last_field.vis.is_accessible_from(def_scope, self.tcx) { self.apply_adjustments(base, adjustments); self.register_predicates(autoderef.into_obligations()); self.tcx.check_stability( last_field.did, Some(expr.hir_id), expr.span, None, ); return self.field_ty(expr.span, last_field, args); </ins> } <del> last_ty = Some(field_ty); adt_def = field_ty.ty_adt_def().expect("expect Adt for unnamed field"); </del> <ins> // The field is not accessible, fall through to error reporting. private_candidate = Some((adjustments, base_def.did())); </ins> } } ty::Tuple(tys) => {

// tidy-alphabetical-start #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] <ins> #![feature(array_windows)] </ins> #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(if_let_guard)]

desc { "whether the item should be made inlinable across crates" } separate_provide_extern } <del> query find_field((def_id, ident): (DefId, rustc_span::symbol::Ident)) -> Option<rustc_target::abi::FieldIdx> { desc { |tcx| "find the index of maybe nested field `{ident}` in `{}`", tcx.def_path_str(def_id) } } </del> } rustc_query_append! { define_callbacks! }