From 4bb65e1c79a79fadce297a41d15003c82cabf61b Mon Sep 17 00:00:00 2001
From: Deadbeef <ent3rm4n@gmail.com>
Date: Thu, 16 Dec 2021 21:38:54 +0800
Subject: [PATCH] Fix default_method_body_is_const when used across crates

---
 compiler/rustc_metadata/src/rmeta/encoder.rs   |  5 +++--
 .../auxiliary/cross-crate.rs                   |  3 +++
 ...cross-crate-default-method-body-is-const.rs | 18 ++++++++++++++++++
 3 files changed, 24 insertions(+), 2 deletions(-)
 create mode 100644 src/test/ui/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs

diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 94e7376ddb216..75676389df719 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -869,8 +869,9 @@ fn should_encode_mir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> (bool, bool) {
             let needs_inline = (generics.requires_monomorphization(tcx)
                 || tcx.codegen_fn_attrs(def_id).requests_inline())
                 && tcx.sess.opts.output_types.should_codegen();
-            // Only check the presence of the `const` modifier.
-            let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id());
+            // The function has a `const` modifier or is annotated with `default_method_body_is_const`.
+            let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id())
+                || tcx.has_attr(def_id.to_def_id(), sym::default_method_body_is_const);
             let always_encode_mir = tcx.sess.opts.debugging_opts.always_encode_mir;
             (is_const_fn, needs_inline || always_encode_mir)
         }
diff --git a/src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
index d8fd7ef3c1f44..2d049277d7fcf 100644
--- a/src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
+++ b/src/test/ui/rfc-2632-const-trait-impl/auxiliary/cross-crate.rs
@@ -1,6 +1,9 @@
+#![feature(const_fn_trait_bound)]
 #![feature(const_trait_impl)]
 
 pub trait MyTrait {
+    #[default_method_body_is_const]
+    fn defaulted_func(&self) {}
     fn func(self);
 }
 
diff --git a/src/test/ui/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs b/src/test/ui/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs
new file mode 100644
index 0000000000000..c0f90c116e459
--- /dev/null
+++ b/src/test/ui/rfc-2632-const-trait-impl/cross-crate-default-method-body-is-const.rs
@@ -0,0 +1,18 @@
+// This tests that `default_method_body_is_const` methods can
+// be called from a const context when used across crates.
+//
+// check-pass
+
+#![feature(const_trait_impl)]
+
+// aux-build: cross-crate.rs
+extern crate cross_crate;
+
+use cross_crate::*;
+
+const _: () = {
+    Const.func();
+    Const.defaulted_func();
+};
+
+fn main() {}