diff options
| author | Oli Scherer <github333195615777966@oli-obk.de> | 2025-06-05 08:15:02 +0000 |
|---|---|---|
| committer | Oli Scherer <github333195615777966@oli-obk.de> | 2025-06-30 08:47:53 +0000 |
| commit | 422eea2863e7b60dae30eb1a348eea446ac6003a (patch) | |
| tree | 1439e1df9de5dba0c29d6551c90f60462e859673 /compiler/rustc_hir_analysis/src/check | |
| parent | 65aac24a088600c5fc81c0799e5b2de6630d7535 (diff) | |
| download | rust-422eea2863e7b60dae30eb1a348eea446ac6003a.tar.gz rust-422eea2863e7b60dae30eb1a348eea446ac6003a.zip | |
Don't run hir wfcheck if ty wfcheck handled everything
Diffstat (limited to 'compiler/rustc_hir_analysis/src/check')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/check.rs | 58 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/wfcheck.rs | 17 |
2 files changed, 58 insertions, 17 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 5285d48ab3e..f4fcb13b1a1 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -767,7 +767,12 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), DefKind::Static { .. } => { check_static_inhabited(tcx, def_id); check_static_linkage(tcx, def_id); - wfcheck::check_static_item(tcx, def_id)?; + res = res.and(wfcheck::check_static_item(tcx, def_id)); + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; } DefKind::Const => {} _ => unreachable!(), @@ -803,10 +808,17 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), tcx.ensure_ok().predicates_of(def_id); tcx.ensure_ok().associated_items(def_id); if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) { - tcx.ensure_ok() - .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)?; + res = res.and( + tcx.ensure_ok() + .coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id), + ); - check_impl_items_against_trait(tcx, def_id, impl_trait_header); + if res.is_ok() { + // Checking this only makes sense if the all trait impls satisfy basic + // requirements (see `coherent_trait` query), otherwise + // we run into infinite recursions a lot. + check_impl_items_against_trait(tcx, def_id, impl_trait_header); + } } } DefKind::Trait => { @@ -884,6 +896,11 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), tcx.ensure_ok().explicit_implied_const_bounds(def_id); tcx.ensure_ok().const_conditions(def_id); } + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; } DefKind::TyAlias => { tcx.ensure_ok().generics_of(def_id); @@ -976,6 +993,11 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), // We do not call `type_of` for closures here as that // depends on typecheck and would therefore hide // any further errors in case one typeck fails. + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; } DefKind::AssocFn => { tcx.ensure_ok().codegen_fn_attrs(def_id); @@ -990,6 +1012,11 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), res = res.and(check_trait_item(tcx, def_id)); } } + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; } DefKind::AssocConst => { tcx.ensure_ok().type_of(def_id); @@ -1002,6 +1029,11 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), res = res.and(check_trait_item(tcx, def_id)); } } + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; } DefKind::AssocTy => { tcx.ensure_ok().predicates_of(def_id); @@ -1020,10 +1052,26 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), if has_type { tcx.ensure_ok().type_of(def_id); } + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + return res; } + + // Only `Node::Item` and `Node::ForeignItem` still have HIR based + // checks. Returning early here does not miss any checks and + // avoids this query from having a direct dependency edge on the HIR + DefKind::AnonConst | DefKind::InlineConst => return res, _ => {} } - res + let node = tcx.hir_node_by_def_id(def_id); + res.and(match node { + hir::Node::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"), + hir::Node::Item(item) => wfcheck::check_item(tcx, item), + hir::Node::ForeignItem(item) => wfcheck::check_foreign_item(tcx, item), + _ => unreachable!("{node:?}"), + }) } pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, def_id: LocalDefId) { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 6f12c84139b..ed8d25e9915 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -191,16 +191,6 @@ where fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> { let mut res = crate::check::check::check_item_type(tcx, def_id); - let node = tcx.hir_node_by_def_id(def_id); - res = res.and(match node { - hir::Node::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"), - hir::Node::Item(item) => check_item(tcx, item), - hir::Node::TraitItem(..) => Ok(()), - hir::Node::ImplItem(..) => Ok(()), - hir::Node::ForeignItem(item) => check_foreign_item(tcx, item), - hir::Node::ConstBlock(_) | hir::Node::Expr(_) | hir::Node::OpaqueTy(_) => Ok(()), - _ => unreachable!("{node:?}"), - }); for param in &tcx.generics_of(def_id).own_params { res = res.and(check_param_wf(tcx, param)); @@ -223,7 +213,10 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua /// not included it frequently leads to confusing errors in fn bodies. So it's better to check /// the types first. #[instrument(skip(tcx), level = "debug")] -fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<(), ErrorGuaranteed> { +pub(super) fn check_item<'tcx>( + tcx: TyCtxt<'tcx>, + item: &'tcx hir::Item<'tcx>, +) -> Result<(), ErrorGuaranteed> { let def_id = item.owner_id.def_id; debug!( @@ -305,7 +298,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<() } } -fn check_foreign_item<'tcx>( +pub(super) fn check_foreign_item<'tcx>( tcx: TyCtxt<'tcx>, item: &'tcx hir::ForeignItem<'tcx>, ) -> Result<(), ErrorGuaranteed> { |
