about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDeadbeef <ent3rm4n@gmail.com>2021-11-29 22:21:38 +0800
committerDeadbeef <ent3rm4n@gmail.com>2021-11-29 22:21:38 +0800
commit87cd1ce6c149c002e158e29cee9ff863073c5412 (patch)
tree054ead12baa9fb12db3be76128e301fafa81d3c1
parent8710a2e169a6b008734b75f3f86f79d93319fbfd (diff)
downloadrust-87cd1ce6c149c002e158e29cee9ff863073c5412.tar.gz
rust-87cd1ce6c149c002e158e29cee9ff863073c5412.zip
`ParamEnv` should be const when `ImplItem` is within a const impl.
-rw-r--r--compiler/rustc_hir/src/hir.rs27
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs38
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs3
-rw-r--r--src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr20
4 files changed, 58 insertions, 30 deletions
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 1446c84a397..ca60b91fae0 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3228,33 +3228,6 @@ impl<'hir> Node<'hir> {
         }
     }
 
-    /// Returns `Constness::Const` when this node is a const fn/impl/item.
-    pub fn constness_for_typeck(&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,
-
-            Node::Item(Item { kind: ItemKind::Const(..), .. })
-            | Node::Item(Item { kind: ItemKind::Static(..), .. })
-            | Node::TraitItem(TraitItem { kind: TraitItemKind::Const(..), .. })
-            | Node::AnonConst(_)
-            | Node::ImplItem(ImplItem { kind: ImplItemKind::Const(..), .. }) => Constness::Const,
-
-            _ => Constness::NotConst,
-        }
-    }
-
     pub fn as_owner(self) -> Option<OwnerNode<'hir>> {
         match self {
             Node::Item(i) => Some(OwnerNode::Item(i)),
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 9a4639b0886..f47f8a562dd 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -287,7 +287,43 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
     let hir_id = local_did.map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id));
 
     let constness = match hir_id {
-        Some(hir_id) => tcx.hir().get(hir_id).constness_for_typeck(),
+        Some(hir_id) => match tcx.hir().get(hir_id) {
+            hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. })
+            | hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. })
+            | hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Const(..), .. })
+            | hir::Node::AnonConst(_)
+            | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
+            | hir::Node::ImplItem(hir::ImplItem {
+                kind: hir::ImplItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness: hir::Constness::Const, .. }, .. }, ..),
+                ..
+            }) => hir::Constness::Const,
+
+            hir::Node::ImplItem(hir::ImplItem {
+                kind: hir::ImplItemKind::TyAlias(..) | hir::ImplItemKind::Fn(..),
+                ..
+            }) => {
+                let parent_hir_id = tcx.hir().get_parent_node(hir_id);
+                match tcx.hir().get(parent_hir_id) {
+                    hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), .. }) => *constness,
+                    _ => span_bug!(
+                        tcx.def_span(parent_hir_id.owner),
+                        "impl item's parent node is not an impl",
+                    ),
+                }
+            }
+
+            hir::Node::Item(hir::Item {
+                kind: hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
+                ..
+            })
+            | hir::Node::TraitItem(hir::TraitItem {
+                kind: hir::TraitItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
+                ..
+            })
+            | hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { constness, .. }), .. }) => *constness,
+
+            _ => hir::Constness::NotConst,
+        },
         None => hir::Constness::NotConst,
     };
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs
index 11334c10775..7b012083c5a 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.rs
@@ -1,6 +1,5 @@
 // FIXME(fee1-dead): this should have a better error message
 #![feature(const_trait_impl)]
-// check-pass
 struct NonConstAdd(i32);
 
 impl std::ops::Add for NonConstAdd {
@@ -17,7 +16,7 @@ trait Foo {
 
 impl const Foo for NonConstAdd {
     type Bar = NonConstAdd;
-    //TODO: ~^ ERROR
+    //~^ ERROR
 }
 
 trait Baz {
diff --git a/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
new file mode 100644
index 00000000000..d1e55e12d6f
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/assoc-type.stderr
@@ -0,0 +1,20 @@
+error[E0277]: cannot add `NonConstAdd` to `NonConstAdd`
+  --> $DIR/assoc-type.rs:18:5
+   |
+LL |     type Bar = NonConstAdd;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `NonConstAdd + NonConstAdd`
+   |
+   = help: the trait `Add` is not implemented for `NonConstAdd`
+note: required by a bound in `Foo::Bar`
+  --> $DIR/assoc-type.rs:14:15
+   |
+LL |     type Bar: ~const std::ops::Add;
+   |               ^^^^^^^^^^^^^^^^^^^^ required by this bound in `Foo::Bar`
+help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
+   |
+LL | impl const Foo for NonConstAdd where NonConstAdd: Add {
+   |                                ++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.