Auto merge of #138499 - lcnr:borrowck-typeck_root, r=oli-obk

borrowck typeck children together with their root

This introduces new cycle errors, even with `feature(inline_const_pat)` removed, see the `non-structural-match-types-cycle-err.rs` test.

The new cycle error happens as the layout of `async`-blocks relies on their `optimized_mir`. As that now depends on `mir_borrowck` of its typeck parent, computing the layout of an `async`-block during MIR building, e.g. when evaluating a named `const` pattern. I think there's currently no way to have a named const pattern whose type references an async block while being allowed? cc `@oli-obk` `@RalfJung`

I cannot think of other cases where we currently rely on the MIR of a typeck children while borrowchecking their parent. The crater run came back without any breakage. My work here will prevent any future features which rely on this as we'll get locked into borrowchecking them together as I continue to work on https://github.com/rust-lang/types-team/issues/129, cc `@rust-lang/types.`

r? compiler-errors
This commit is contained in:
bors 2025-04-08 16:01:37 +00:00
commit d4f880f8ce
22 changed files with 491 additions and 369 deletions

View file

@ -397,8 +397,11 @@ fn best_definition_site_of_opaque<'tcx>(
return ControlFlow::Continue(());
}
if let Some(hidden_ty) =
self.tcx.mir_borrowck(item_def_id).concrete_opaque_types.get(&self.opaque_def_id)
if let Some(hidden_ty) = self
.tcx
.mir_borrowck(item_def_id)
.ok()
.and_then(|opaque_types| opaque_types.0.get(&self.opaque_def_id))
{
ControlFlow::Break((hidden_ty.span, item_def_id))
} else {
@ -413,9 +416,6 @@ fn best_definition_site_of_opaque<'tcx>(
self.tcx
}
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) -> Self::Result {
if let hir::ExprKind::Closure(closure) = ex.kind {
self.check(closure.def_id)?;
}
intravisit::walk_expr(self, ex)
}
fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) -> Self::Result {

View file

@ -183,25 +183,23 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
self.non_defining_use_in_defining_scope(item_def_id);
}
}
DefiningScopeKind::MirBorrowck => {
let borrowck_result = tcx.mir_borrowck(item_def_id);
if let Some(guar) = borrowck_result.tainted_by_errors {
self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
} else if let Some(&hidden_type) =
borrowck_result.concrete_opaque_types.get(&self.def_id)
{
debug!(?hidden_type, "found constraint");
self.insert_found(hidden_type);
} else if let Err(guar) = tcx
.type_of_opaque_hir_typeck(self.def_id)
.instantiate_identity()
.error_reported()
{
self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
} else {
self.non_defining_use_in_defining_scope(item_def_id);
DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(item_def_id) {
Err(guar) => self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)),
Ok(concrete_opaque_types) => {
if let Some(&hidden_type) = concrete_opaque_types.0.get(&self.def_id) {
debug!(?hidden_type, "found constraint");
self.insert_found(hidden_type);
} else if let Err(guar) = tcx
.type_of_opaque_hir_typeck(self.def_id)
.instantiate_identity()
.error_reported()
{
self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
} else {
self.non_defining_use_in_defining_scope(item_def_id);
}
}
}
},
}
}
}
@ -264,20 +262,20 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
Ty::new_diverging_default(tcx)
}
}
DefiningScopeKind::MirBorrowck => {
let borrowck_result = tcx.mir_borrowck(owner_def_id);
if let Some(guar) = borrowck_result.tainted_by_errors {
Ty::new_error(tcx, guar)
} else if let Some(hidden_ty) = borrowck_result.concrete_opaque_types.get(&def_id) {
hidden_ty.ty
} else {
let hir_ty = tcx.type_of_opaque_hir_typeck(def_id).instantiate_identity();
if let Err(guar) = hir_ty.error_reported() {
Ty::new_error(tcx, guar)
DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(owner_def_id) {
Ok(concrete_opaque_types) => {
if let Some(hidden_ty) = concrete_opaque_types.0.get(&def_id) {
hidden_ty.ty
} else {
hir_ty
let hir_ty = tcx.type_of_opaque_hir_typeck(def_id).instantiate_identity();
if let Err(guar) = hir_ty.error_reported() {
Ty::new_error(tcx, guar)
} else {
hir_ty
}
}
}
}
Err(guar) => Ty::new_error(tcx, guar),
},
}
}