Unrolled build for #150141
Rollup merge of #150141 - BoxyUwU:borrowck_cleanup_1, r=lcnr
Misc cleanups from reading some borrowck code
title
r? lcnr
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 71ce6b7..91defba 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -1,4 +1,4 @@
-//! This query borrow-checks the MIR to (further) ensure it is not broken.
+//! This crate implemens MIR typeck and MIR borrowck.
// tidy-alphabetical-start
#![allow(internal_features)]
@@ -111,9 +111,9 @@ pub fn provide(providers: &mut Providers) {
*providers = Providers { mir_borrowck, ..*providers };
}
-/// Provider for `query mir_borrowck`. Similar to `typeck`, this must
-/// only be called for typeck roots which will then borrowck all
-/// nested bodies as well.
+/// Provider for `query mir_borrowck`. Unlike `typeck`, this must
+/// only be called for typeck roots which *similar* to `typeck` will
+/// then borrowck all nested bodies as well.
fn mir_borrowck(
tcx: TyCtxt<'_>,
def: LocalDefId,
diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs
index c3ff8cb..4d42055 100644
--- a/compiler/rustc_borrowck/src/root_cx.rs
+++ b/compiler/rustc_borrowck/src/root_cx.rs
@@ -255,7 +255,7 @@ pub(super) fn do_mir_borrowck(&mut self) {
}
// We now apply the closure requirements of nested bodies modulo
- // regions. In case a body does not depend on opaque types, we
+ // opaques. In case a body does not depend on opaque types, we
// eagerly check its region constraints and use the final closure
// requirements.
//
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index aee1eb9..a0d5e1c 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -1,13 +1,12 @@
//! Code to extract the universally quantified regions declared on a
-//! function and the relationships between them. For example:
+//! function. For example:
//!
//! ```
//! fn foo<'a, 'b, 'c: 'b>() { }
//! ```
//!
//! here we would return a map assigning each of `{'a, 'b, 'c}`
-//! to an index, as well as the `FreeRegionMap` which can compute
-//! relationships between them.
+//! to an index.
//!
//! The code in this file doesn't *do anything* with those results; it
//! just returns them for other code to use.
@@ -271,8 +270,7 @@ impl<'tcx> UniversalRegions<'tcx> {
/// Creates a new and fully initialized `UniversalRegions` that
/// contains indices for all the free regions found in the given
/// MIR -- that is, all the regions that appear in the function's
- /// signature. This will also compute the relationships that are
- /// known between those regions.
+ /// signature.
pub(crate) fn new(infcx: &BorrowckInferCtxt<'tcx>, mir_def: LocalDefId) -> Self {
UniversalRegionsBuilder { infcx, mir_def }.build()
}
@@ -648,17 +646,14 @@ fn defining_ty(&self) -> DefiningTy<'tcx> {
BodyOwnerKind::Const { .. } | BodyOwnerKind::Static(..) => {
let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
- if self.mir_def.to_def_id() == typeck_root_def_id
- // Do not ICE when checking default_field_values consts with lifetimes (#135649)
- && DefKind::Field != tcx.def_kind(tcx.parent(typeck_root_def_id))
- {
+ if self.mir_def.to_def_id() == typeck_root_def_id {
let args = self.infcx.replace_free_regions_with_nll_infer_vars(
NllRegionVariableOrigin::FreeRegion,
identity_args,
);
DefiningTy::Const(self.mir_def.to_def_id(), args)
} else {
- // FIXME this line creates a dependency between borrowck and typeck.
+ // FIXME: this line creates a query dependency between borrowck and typeck.
//
// This is required for `AscribeUserType` canonical query, which will call
// `type_of(inline_const_def_id)`. That `type_of` would inject erased lifetimes
@@ -699,30 +694,14 @@ fn compute_indices(
let tcx = self.infcx.tcx;
let typeck_root_def_id = tcx.typeck_root_def_id(self.mir_def.to_def_id());
let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
- let fr_args = match defining_ty {
- DefiningTy::Closure(_, args)
- | DefiningTy::CoroutineClosure(_, args)
- | DefiningTy::Coroutine(_, args)
- | DefiningTy::InlineConst(_, args) => {
- // In the case of closures, we rely on the fact that
- // the first N elements in the ClosureArgs are
- // inherited from the `typeck_root_def_id`.
- // Therefore, when we zip together (below) with
- // `identity_args`, we will get only those regions
- // that correspond to early-bound regions declared on
- // the `typeck_root_def_id`.
- assert!(args.len() >= identity_args.len());
- assert_eq!(args.regions().count(), identity_args.regions().count());
- args
- }
-
- DefiningTy::FnDef(_, args) | DefiningTy::Const(_, args) => args,
-
- DefiningTy::GlobalAsm(_) => ty::List::empty(),
- };
+ let renumbered_args = defining_ty.args();
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
- let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
+ // This relies on typeck roots being generics_of parents with their
+ // parameters at the start of nested bodies' generics.
+ assert!(renumbered_args.len() >= identity_args.len());
+ let arg_mapping =
+ iter::zip(identity_args.regions(), renumbered_args.regions().map(|r| r.as_var()));
UniversalRegionIndices {
indices: global_mapping.chain(arg_mapping).collect(),
@@ -862,8 +841,8 @@ fn compute_inputs_and_output(
};
// FIXME(#129952): We probably want a more principled approach here.
- if let Err(terr) = inputs_and_output.skip_binder().error_reported() {
- self.infcx.set_tainted_by_errors(terr);
+ if let Err(e) = inputs_and_output.error_reported() {
+ self.infcx.set_tainted_by_errors(e);
}
inputs_and_output
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 1805893..aa0e5c7 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -10,6 +10,7 @@
use rustc_middle::ty::{self, DefiningScopeKind, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::{bug, span_bug};
use rustc_span::{DUMMY_SP, Ident, Span};
+use tracing::instrument;
use super::{HirPlaceholderCollector, ItemCtxt, bad_placeholder};
use crate::check::wfcheck::check_static_item;
@@ -17,85 +18,7 @@
mod opaque;
-fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
- use hir::*;
- use rustc_middle::ty::Ty;
- let tcx = icx.tcx;
- let hir_id = tcx.local_def_id_to_hir_id(def_id);
-
- let node = tcx.hir_node(hir_id);
- let Node::AnonConst(&AnonConst { span, .. }) = node else {
- span_bug!(
- tcx.def_span(def_id),
- "expected anon const in `anon_const_type_of`, got {node:?}"
- );
- };
-
- let parent_node_id = tcx.parent_hir_id(hir_id);
- let parent_node = tcx.hir_node(parent_node_id);
-
- match parent_node {
- // Anon consts "inside" the type system.
- Node::ConstArg(&ConstArg {
- hir_id: arg_hir_id,
- kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }),
- ..
- }) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span),
-
- Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => {
- tcx.adt_def(tcx.hir_get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
- }
-
- Node::Field(&hir::FieldDef { default: Some(c), def_id: field_def_id, .. })
- if c.hir_id == hir_id =>
- {
- tcx.type_of(field_def_id).instantiate_identity()
- }
-
- _ => Ty::new_error_with_message(
- tcx,
- span,
- format!("unexpected anon const parent in type_of(): {parent_node:?}"),
- ),
- }
-}
-
-fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
- use hir::*;
- use rustc_middle::ty::Ty;
-
- let tcx = icx.tcx;
-
- match tcx.parent_hir_node(arg_hir_id) {
- // Array length const arguments do not have `type_of` fed as there is never a corresponding
- // generic parameter definition.
- Node::Ty(&hir::Ty { kind: TyKind::Array(_, ref constant), .. })
- | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
- if constant.hir_id == arg_hir_id =>
- {
- tcx.types.usize
- }
-
- Node::TyPat(pat) => {
- let node = match tcx.parent_hir_node(pat.hir_id) {
- // Or patterns can be nested one level deep
- Node::TyPat(p) => tcx.parent_hir_node(p.hir_id),
- other => other,
- };
- let hir::TyKind::Pat(ty, _) = node.expect_ty().kind else { bug!() };
- icx.lower_ty(ty)
- }
-
- // This is not a `bug!` as const arguments in path segments that did not resolve to anything
- // will result in `type_of` never being fed.
- _ => Ty::new_error_with_message(
- tcx,
- span,
- "`type_of` called on const argument's anon const before the const argument was lowered",
- ),
- }
-}
-
+#[instrument(level = "debug", skip(tcx), ret)]
pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, Ty<'_>> {
use rustc_hir::*;
use rustc_middle::ty::Ty;
@@ -408,6 +331,85 @@ pub(super) fn type_of_opaque_hir_typeck(
}
}
+fn anon_const_type_of<'tcx>(icx: &ItemCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
+ use hir::*;
+ use rustc_middle::ty::Ty;
+ let tcx = icx.tcx;
+ let hir_id = tcx.local_def_id_to_hir_id(def_id);
+
+ let node = tcx.hir_node(hir_id);
+ let Node::AnonConst(&AnonConst { span, .. }) = node else {
+ span_bug!(
+ tcx.def_span(def_id),
+ "expected anon const in `anon_const_type_of`, got {node:?}"
+ );
+ };
+
+ let parent_node_id = tcx.parent_hir_id(hir_id);
+ let parent_node = tcx.hir_node(parent_node_id);
+
+ match parent_node {
+ // Anon consts "inside" the type system.
+ Node::ConstArg(&ConstArg {
+ hir_id: arg_hir_id,
+ kind: ConstArgKind::Anon(&AnonConst { hir_id: anon_hir_id, .. }),
+ ..
+ }) if anon_hir_id == hir_id => const_arg_anon_type_of(icx, arg_hir_id, span),
+
+ Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => {
+ tcx.adt_def(tcx.hir_get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
+ }
+
+ Node::Field(&hir::FieldDef { default: Some(c), def_id: field_def_id, .. })
+ if c.hir_id == hir_id =>
+ {
+ tcx.type_of(field_def_id).instantiate_identity()
+ }
+
+ _ => Ty::new_error_with_message(
+ tcx,
+ span,
+ format!("unexpected anon const parent in type_of(): {parent_node:?}"),
+ ),
+ }
+}
+
+fn const_arg_anon_type_of<'tcx>(icx: &ItemCtxt<'tcx>, arg_hir_id: HirId, span: Span) -> Ty<'tcx> {
+ use hir::*;
+ use rustc_middle::ty::Ty;
+
+ let tcx = icx.tcx;
+
+ match tcx.parent_hir_node(arg_hir_id) {
+ // Array length const arguments do not have `type_of` fed as there is never a corresponding
+ // generic parameter definition.
+ Node::Ty(&hir::Ty { kind: TyKind::Array(_, ref constant), .. })
+ | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
+ if constant.hir_id == arg_hir_id =>
+ {
+ tcx.types.usize
+ }
+
+ Node::TyPat(pat) => {
+ let node = match tcx.parent_hir_node(pat.hir_id) {
+ // Or patterns can be nested one level deep
+ Node::TyPat(p) => tcx.parent_hir_node(p.hir_id),
+ other => other,
+ };
+ let hir::TyKind::Pat(ty, _) = node.expect_ty().kind else { bug!() };
+ icx.lower_ty(ty)
+ }
+
+ // This is not a `bug!` as const arguments in path segments that did not resolve to anything
+ // will result in `type_of` never being fed.
+ _ => Ty::new_error_with_message(
+ tcx,
+ span,
+ "`type_of` called on const argument's anon const before the const argument was lowered",
+ ),
+ }
+}
+
fn infer_placeholder_type<'tcx>(
cx: &dyn HirTyLowerer<'tcx>,
def_id: LocalDefId,