From 5f24dd38778af6c4c856f926be1e83b399a4c80c Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 5 Mar 2024 12:16:22 +0000 Subject: [PATCH] Use `hir::Node` helper methods instead of repeat the same impl multiple times There already were inconsistencies, so this ensures we don't introduce subtle surprising bugs --- .../src/collect/generics_of.rs | 26 +----- .../src/collect/predicates_of.rs | 83 ++++--------------- compiler/rustc_hir_typeck/src/lib.rs | 24 +----- compiler/rustc_passes/src/check_attr.rs | 8 +- 4 files changed, 22 insertions(+), 119 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs index 9cc6c16c12639..fda3739e183b1 100644 --- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs @@ -471,29 +471,9 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option match &item.kind { - hir::TraitItemKind::Fn(sig, _) => has_late_bound_regions(tcx, item.generics, sig.decl), - _ => None, - }, - Node::ImplItem(item) => match &item.kind { - hir::ImplItemKind::Fn(sig, _) => has_late_bound_regions(tcx, item.generics, sig.decl), - _ => None, - }, - Node::ForeignItem(item) => match item.kind { - hir::ForeignItemKind::Fn(fn_decl, _, generics) => { - has_late_bound_regions(tcx, generics, fn_decl) - } - _ => None, - }, - Node::Item(item) => match &item.kind { - hir::ItemKind::Fn(sig, .., generics, _) => { - has_late_bound_regions(tcx, generics, sig.decl) - } - _ => None, - }, - _ => None, - } + let decl = node.fn_decl()?; + let generics = node.generics()?; + has_late_bound_regions(tcx, generics, decl) } struct AnonConstInParamTyDetector { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index f70bb8c4289f6..d1a50bfbac87d 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -123,43 +123,22 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen // Preserving the order of insertion is important here so as not to break UI tests. let mut predicates: FxIndexSet<(ty::Clause<'_>, Span)> = FxIndexSet::default(); - let ast_generics = match node { - Node::TraitItem(item) => item.generics, - - Node::ImplItem(item) => item.generics, - - Node::Item(item) => match item.kind { + let ast_generics = node.generics().unwrap_or(NO_GENERICS); + if let Node::Item(item) = node { + match item.kind { ItemKind::Impl(impl_) => { if impl_.defaultness.is_default() { is_default_impl_trait = tcx .impl_trait_ref(def_id) .map(|t| ty::Binder::dummy(t.instantiate_identity())); } - impl_.generics } - ItemKind::Fn(.., generics, _) - | ItemKind::TyAlias(_, generics) - | ItemKind::Const(_, generics, _) - | ItemKind::Enum(_, generics) - | ItemKind::Struct(_, generics) - | ItemKind::Union(_, generics) => generics, - - ItemKind::Trait(_, _, generics, self_bounds, ..) - | ItemKind::TraitAlias(generics, self_bounds) => { + + ItemKind::Trait(_, _, _, self_bounds, ..) | ItemKind::TraitAlias(_, self_bounds) => { is_trait = Some(self_bounds); - generics } - ItemKind::OpaqueTy(OpaqueTy { generics, .. }) => generics, - _ => NO_GENERICS, - }, - - Node::ForeignItem(item) => match item.kind { - ForeignItemKind::Static(..) => NO_GENERICS, - ForeignItemKind::Fn(_, _, generics) => generics, - ForeignItemKind::Type => NO_GENERICS, - }, - - _ => NO_GENERICS, + _ => {} + } }; let generics = tcx.generics_of(def_id); @@ -705,45 +684,17 @@ pub(super) fn type_param_predicates( let mut extend = None; let item_hir_id = tcx.local_def_id_to_hir_id(item_def_id); - let ast_generics = match tcx.hir_node(item_hir_id) { - Node::TraitItem(item) => item.generics, - - Node::ImplItem(item) => item.generics, - - Node::Item(item) => { - match item.kind { - ItemKind::Fn(.., generics, _) - | ItemKind::Impl(&hir::Impl { generics, .. }) - | ItemKind::TyAlias(_, generics) - | ItemKind::Const(_, generics, _) - | ItemKind::OpaqueTy(&OpaqueTy { - generics, - origin: hir::OpaqueTyOrigin::TyAlias { .. }, - .. - }) - | ItemKind::Enum(_, generics) - | ItemKind::Struct(_, generics) - | ItemKind::Union(_, generics) => generics, - ItemKind::Trait(_, _, generics, ..) => { - // Implied `Self: Trait` and supertrait bounds. - if param_id == item_hir_id { - let identity_trait_ref = - ty::TraitRef::identity(tcx, item_def_id.to_def_id()); - extend = Some((identity_trait_ref.to_predicate(tcx), item.span)); - } - generics - } - _ => return result, - } - } - - Node::ForeignItem(item) => match item.kind { - ForeignItemKind::Fn(_, _, generics) => generics, - _ => return result, - }, - _ => return result, - }; + let hir_node = tcx.hir_node(item_hir_id); + let Some(ast_generics) = hir_node.generics() else { return result }; + if let Node::Item(item) = hir_node + && let ItemKind::Trait(..) = item.kind + // Implied `Self: Trait` and supertrait bounds. + && param_id == item_hir_id + { + let identity_trait_ref = ty::TraitRef::identity(tcx, item_def_id.to_def_id()); + extend = Some((identity_trait_ref.to_predicate(tcx), item.span)); + } let icx = ItemCtxt::new(tcx, item_def_id); let extra_predicates = extend.into_iter().chain( diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 70ddd6b2f4cf5..9b6cd50d4db3c 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -95,29 +95,7 @@ macro_rules! type_error_struct { fn primary_body_of( node: Node<'_>, ) -> Option<(hir::BodyId, Option<&hir::Ty<'_>>, Option<&hir::FnSig<'_>>)> { - match node { - Node::Item(item) => match item.kind { - hir::ItemKind::Const(ty, _, body) | hir::ItemKind::Static(ty, _, body) => { - Some((body, Some(ty), None)) - } - hir::ItemKind::Fn(ref sig, .., body) => Some((body, None, Some(sig))), - _ => None, - }, - Node::TraitItem(item) => match item.kind { - hir::TraitItemKind::Const(ty, Some(body)) => Some((body, Some(ty), None)), - hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { - Some((body, None, Some(sig))) - } - _ => None, - }, - Node::ImplItem(item) => match item.kind { - hir::ImplItemKind::Const(ty, body) => Some((body, Some(ty), None)), - hir::ImplItemKind::Fn(ref sig, body) => Some((body, None, Some(sig))), - _ => None, - }, - Node::AnonConst(constant) => Some((constant.body, None, None)), - _ => None, - } + Some((node.body_id()?, node.ty(), node.fn_sig())) } fn has_typeck_results(tcx: TyCtxt<'_>, def_id: DefId) -> bool { diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 04c0cf7436e2b..486de9e2233d1 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -609,13 +609,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { && !self.tcx.sess.target.is_like_wasm && !self.tcx.sess.opts.actually_rustdoc { - let hir::Node::Item(item) = self.tcx.hir_node(hir_id) else { - unreachable!(); - }; - let hir::ItemKind::Fn(sig, _, _) = item.kind else { - // target is `Fn` - unreachable!(); - }; + let sig = self.tcx.hir_node(hir_id).fn_sig().unwrap(); self.dcx().emit_err(errors::LangItemWithTargetFeature { attr_span: attr.span,