From db03a2deb090d5c24f15ef30cf4e5ccb13690b9d Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 29 Mar 2022 23:50:01 +0200 Subject: [PATCH] Avoid accessing HIR from MIR queries. --- compiler/rustc_borrowck/src/lib.rs | 21 ++++++++++--------- .../rustc_borrowck/src/universal_regions.rs | 8 +++---- .../src/transform/check_consts/check.rs | 8 ++----- .../src/transform/check_consts/mod.rs | 10 ++------- compiler/rustc_hir/src/def.rs | 8 +++++++ .../rustc_mir_transform/src/const_prop.rs | 5 +++-- .../src/const_prop_lint.rs | 2 +- compiler/rustc_mir_transform/src/lib.rs | 2 +- compiler/rustc_mir_transform/src/shim.rs | 5 ++--- compiler/rustc_ty_utils/src/ty.rs | 7 +------ 10 files changed, 35 insertions(+), 41 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 0007d8026e6..0a1eae39d75 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -23,7 +23,6 @@ use rustc_data_structures::graph::dominators::Dominators; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; -use rustc_hir::Node; use rustc_index::bit_set::ChunkedBitSet; use rustc_index::vec::IndexVec; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; @@ -288,14 +287,16 @@ fn do_mir_borrowck<'a, 'tcx>( .pass_name("borrowck") .iterate_to_fixpoint(); - let def_hir_id = tcx.hir().local_def_id_to_hir_id(def.did); - let movable_generator = !matches!( - tcx.hir().get(def_hir_id), - Node::Expr(&hir::Expr { - kind: hir::ExprKind::Closure(.., Some(hir::Movability::Static)), - .. - }) - ); + let movable_generator = + // The first argument is the generator type passed by value + if let Some(local) = body.local_decls.raw.get(1) + // Get the interior types and substs which typeck computed + && let ty::Generator(_, _, hir::Movability::Static) = local.ty.kind() + { + false + } else { + true + }; for (idx, move_data_results) in promoted_errors { let promoted_body = &promoted[idx]; @@ -385,7 +386,7 @@ fn do_mir_borrowck<'a, 'tcx>( let scope = mbcx.body.source_info(location).scope; let lint_root = match &mbcx.body.source_scopes[scope].local_data { ClearCrossCrate::Set(data) => data.lint_root, - _ => def_hir_id, + _ => tcx.hir().local_def_id_to_hir_id(def.did), }; // Span and message don't matter; we overwrite them below anyway diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index 0bf2eb17d1b..28a566ca408 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -829,12 +829,12 @@ fn for_each_late_bound_region_defined_on<'tcx>( ) { if let Some((owner, late_bounds)) = tcx.is_late_bound_map(fn_def_id.expect_local()) { for &late_bound in late_bounds.iter() { - let hir_id = HirId { owner, local_id: late_bound }; - let name = tcx.hir().name(hir_id); - let region_def_id = tcx.hir().local_def_id(hir_id); + let region_def_id = + tcx.hir().local_def_id(HirId { owner, local_id: late_bound }).to_def_id(); + let name = tcx.item_name(region_def_id); let liberated_region = tcx.mk_region(ty::ReFree(ty::FreeRegion { scope: owner.to_def_id(), - bound_region: ty::BoundRegionKind::BrNamed(region_def_id.to_def_id(), name), + bound_region: ty::BoundRegionKind::BrNamed(region_def_id, name), })); f(liberated_region); } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index e203c79030d..625f57b872b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -222,7 +222,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { // `async` functions cannot be `const fn`. This is checked during AST lowering, so there's // no need to emit duplicate errors here. - if is_async_fn(self.ccx) || body.generator.is_some() { + if self.ccx.is_async() || body.generator.is_some() { tcx.sess.delay_span_bug(body.span, "`async` functions cannot be `const fn`"); return; } @@ -1056,12 +1056,8 @@ fn is_int_bool_or_char(ty: Ty<'_>) -> bool { ty.is_bool() || ty.is_integral() || ty.is_char() } -fn is_async_fn(ccx: &ConstCx<'_, '_>) -> bool { - ccx.fn_sig().map_or(false, |sig| sig.header.asyncness == hir::IsAsync::Async) -} - fn emit_unstable_in_stable_error(ccx: &ConstCx<'_, '_>, span: Span, gate: Symbol) { - let attr_span = ccx.fn_sig().map_or(ccx.body.span, |sig| sig.span.shrink_to_lo()); + let attr_span = ccx.tcx.def_span(ccx.def_id()).shrink_to_lo(); ccx.tcx .sess diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index b026bb2bad6..25ba97ee605 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -61,14 +61,8 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> { && is_const_stable_const_fn(self.tcx, self.def_id().to_def_id()) } - /// Returns the function signature of the item being const-checked if it is a `fn` or `const fn`. - pub fn fn_sig(&self) -> Option<&'tcx hir::FnSig<'tcx>> { - // Get this from the HIR map instead of a query to avoid cycle errors. - // - // FIXME: Is this still an issue? - let hir_map = self.tcx.hir(); - let hir_id = hir_map.local_def_id_to_hir_id(self.def_id()); - hir_map.fn_sig_by_hir_id(hir_id) + fn is_async(&self) -> bool { + self.tcx.asyncness(self.def_id()) == hir::IsAsync::Async } } diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 352f369f0d4..53d60d280c0 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -223,6 +223,14 @@ impl DefKind { | DefKind::Impl => None, } } + + #[inline] + pub fn is_fn_like(self) -> bool { + match self { + DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Generator => true, + _ => false, + } + } } /// The resolution of a path or export. diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index a342aeed905..aa47630a26a 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -71,8 +71,9 @@ impl<'tcx> MirPass<'tcx> for ConstProp { } let def_id = body.source.def_id().expect_local(); - let is_fn_like = tcx.hir().get_by_def_id(def_id).fn_kind().is_some(); - let is_assoc_const = tcx.def_kind(def_id) == DefKind::AssocConst; + let def_kind = tcx.def_kind(def_id); + let is_fn_like = def_kind.is_fn_like(); + let is_assoc_const = def_kind == DefKind::AssocConst; // Only run const prop on functions, methods, closures and associated constants if !is_fn_like && !is_assoc_const { diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 159503ad2d3..50400cdeac9 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -67,7 +67,7 @@ impl<'tcx> MirLint<'tcx> for ConstProp { } let def_id = body.source.def_id().expect_local(); - let is_fn_like = tcx.hir().get_by_def_id(def_id).fn_kind().is_some(); + let is_fn_like = tcx.def_kind(def_id).is_fn_like(); let is_assoc_const = tcx.def_kind(def_id) == DefKind::AssocConst; // Only run const prop on functions, methods, closures and associated constants diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 059ee09dfd7..d395ccd3819 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -366,7 +366,7 @@ fn mir_drops_elaborated_and_const_checked<'tcx>( let mir_borrowck = tcx.mir_borrowck_opt_const_arg(def); - let is_fn_like = tcx.hir().get_by_def_id(def.did).fn_kind().is_some(); + let is_fn_like = tcx.def_kind(def.did).is_fn_like(); if is_fn_like { let did = def.did.to_def_id(); let def = ty::WithOptConstParam::unknown(did); diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index bf031b423c2..d10cac2ac76 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -725,9 +725,6 @@ fn build_call_shim<'tcx>( pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { debug_assert!(tcx.is_constructor(ctor_id)); - let span = - tcx.hir().span_if_local(ctor_id).unwrap_or_else(|| bug!("no span for ctor {:?}", ctor_id)); - let param_env = tcx.param_env(ctor_id); // Normalize the sig. @@ -740,6 +737,8 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { debug!("build_ctor: ctor_id={:?} sig={:?}", ctor_id, sig); + let span = tcx.def_span(ctor_id); + let local_decls = local_decls_for_sig(&sig, span); let source_info = SourceInfo::outermost(span); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 64145bbf189..6ad71bdb481 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -414,12 +414,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { /// Check if a function is async. fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { let node = tcx.hir().get_by_def_id(def_id.expect_local()); - - let fn_kind = node.fn_kind().unwrap_or_else(|| { - bug!("asyncness: expected fn-like node but got `{:?}`", def_id); - }); - - fn_kind.asyncness() + if let Some(fn_kind) = node.fn_kind() { fn_kind.asyncness() } else { hir::IsAsync::NotAsync } } /// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead.