about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2021-07-21 15:52:47 +0200
committerGitHub <noreply@github.com>2021-07-21 15:52:47 +0200
commit1008ace95c825bd48ad9dffdb27fd63be45bb3c2 (patch)
tree5786084682e91ed2798eeec904ae056d429dfc91
parente6380a699b150b88e4e0b43ed5e7c3eff438ec58 (diff)
parent4b82bbeac009c09c55e4a5458ee7338bddb14a44 (diff)
downloadrust-1008ace95c825bd48ad9dffdb27fd63be45bb3c2.tar.gz
rust-1008ace95c825bd48ad9dffdb27fd63be45bb3c2.zip
Rollup merge of #87273 - fee1-dead:impl-const-impl-bounds, r=oli-obk
Recognize bounds on impls as const bounds

r? ```@oli-obk```
-rw-r--r--compiler/rustc_hir/src/hir.rs21
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/validation.rs19
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/mod.rs9
-rw-r--r--compiler/rustc_typeck/src/collect.rs7
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs15
5 files changed, 49 insertions, 22 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 5c7d10560ca..6aff2fdbd1f 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3060,6 +3060,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_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index 646ae8ced7e..cfc538ef500 100644
--- a/compiler/rustc_mir/src/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
@@ -897,16 +897,19 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
                                 permitted = true;
                             }
                         }
-                        let mut const_impls = true;
-                        tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| {
-                            if const_impls {
-                                if let hir::Constness::NotConst = tcx.impl_constness(imp) {
-                                    const_impls = false;
+                        if !permitted {
+                            // if trait's impls are all const, permit the call.
+                            let mut const_impls = true;
+                            tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| {
+                                if const_impls {
+                                    if let hir::Constness::NotConst = tcx.impl_constness(imp) {
+                                        const_impls = false;
+                                    }
                                 }
+                            });
+                            if const_impls {
+                                permitted = true;
                             }
-                        });
-                        if const_impls {
-                            permitted = true;
                         }
                     }
 
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs
index 4da4835f7cf..13686cfec80 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 506ca98b960..1a4c2eb5155 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 00000000000..536c1d73740
--- /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<T: PartialEq> const MyPartialEq for T {
+    fn eq(&self, other: &Self) -> bool {
+        PartialEq::eq(self, other)
+    }
+}
+
+fn main() {}