From 4b82bbeac009c09c55e4a5458ee7338bddb14a44 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Mon, 19 Jul 2021 18:50:47 +0800 Subject: [PATCH] Recognize bounds on impls as const bounds --- compiler/rustc_hir/src/hir.rs | 21 +++++++++++++++++++ .../rustc_typeck/src/check/fn_ctxt/mod.rs | 9 +------- compiler/rustc_typeck/src/collect.rs | 7 +------ .../call-generic-in-impl.rs | 15 +++++++++++++ 4 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 4b2679e164aac..213887e26179c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3064,6 +3064,27 @@ impl<'hir> Node<'hir> { Node::Crate(_) | Node::Visibility(_) => None, } } + + /// Returns `Constness::Const` when this node is a const fn/impl. + pub fn constness(&self) -> Constness { + match self { + Node::Item(Item { + kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..), + .. + }) + | Node::TraitItem(TraitItem { + kind: TraitItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..), + .. + }) + | Node::ImplItem(ImplItem { + kind: ImplItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..), + .. + }) + | Node::Item(Item { kind: ItemKind::Impl(Impl { constness, .. }), .. }) => *constness, + + _ => Constness::NotConst, + } + } } // Some nodes are used a lot. Make sure they don't unintentionally get bigger. diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 4da4835f7cfbb..13686cfec809a 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -15,7 +15,6 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::hir::map::blocks::FnLikeNode; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; @@ -175,13 +174,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { } fn default_constness_for_trait_bounds(&self) -> hir::Constness { - // FIXME: refactor this into a method - let node = self.tcx.hir().get(self.body_id); - if let Some(fn_like) = FnLikeNode::from_node(node) { - fn_like.constness() - } else { - hir::Constness::NotConst - } + self.tcx.hir().get(self.body_id).constness() } fn get_type_parameter_bounds( diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 506ca98b96026..1a4c2eb515584 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -35,7 +35,6 @@ use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::weak_lang_items; use rustc_hir::{GenericParamKind, HirId, Node}; -use rustc_middle::hir::map::blocks::FnLikeNode; use rustc_middle::hir::map::Map; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::mono::Linkage; @@ -358,11 +357,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { } fn default_constness_for_trait_bounds(&self) -> hir::Constness { - if let Some(fn_like) = FnLikeNode::from_node(self.node()) { - fn_like.constness() - } else { - hir::Constness::NotConst - } + self.node().constness() } fn get_type_parameter_bounds( diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs new file mode 100644 index 0000000000000..536c1d7374023 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs @@ -0,0 +1,15 @@ +// check-pass +#![feature(const_fn_trait_bound)] +#![feature(const_trait_impl)] + +trait MyPartialEq { + fn eq(&self, other: &Self) -> bool; +} + +impl const MyPartialEq for T { + fn eq(&self, other: &Self) -> bool { + PartialEq::eq(self, other) + } +} + +fn main() {}