about summary refs log tree commit diff
path: root/compiler/rustc_passes/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-05-30 09:19:03 +0000
committerbors <bors@rust-lang.org>2022-05-30 09:19:03 +0000
commit5c780b98d10f48d6255cf2deb2643194b9221c02 (patch)
treec2ff6e458787797f666a3774b05863c2a1d8333e /compiler/rustc_passes/src
parent855fc022fe879f4e3493a024f9c6b981d6317612 (diff)
parent2f96fbe2200d5928faafdf068b591170b6a127b7 (diff)
downloadrust-5c780b98d10f48d6255cf2deb2643194b9221c02.tar.gz
rust-5c780b98d10f48d6255cf2deb2643194b9221c02.zip
Auto merge of #96964 - oli-obk:const_trait_mvp, r=compiler-errors
Replace `#[default_method_body_is_const]` with `#[const_trait]`

pulled out of #96077

related issues:  #67792 and #92158

cc `@fee1-dead`

This is groundwork to only allowing `impl const Trait` for traits that are marked with `#[const_trait]`. This is necessary to prevent adding a new default method from becoming a breaking change (as it could be a non-const fn).
Diffstat (limited to 'compiler/rustc_passes/src')
-rw-r--r--compiler/rustc_passes/src/check_attr.rs23
-rw-r--r--compiler/rustc_passes/src/check_const.rs62
2 files changed, 7 insertions, 78 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 3d38ff00eab..0fe6d58b86d 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -122,9 +122,7 @@ impl CheckAttrVisitor<'_> {
                 | sym::rustc_if_this_changed
                 | sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr),
                 sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target),
-                sym::default_method_body_is_const => {
-                    self.check_default_method_body_is_const(attr, span, target)
-                }
+                sym::const_trait => self.check_const_trait(attr, span, target),
                 sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target),
                 sym::must_use => self.check_must_use(hir_id, &attr, span, target),
                 sym::rustc_pass_by_value => self.check_pass_by_value(&attr, span, target),
@@ -2097,23 +2095,14 @@ impl CheckAttrVisitor<'_> {
         }
     }
 
-    /// default_method_body_is_const should only be applied to trait methods with default bodies.
-    fn check_default_method_body_is_const(
-        &self,
-        attr: &Attribute,
-        span: Span,
-        target: Target,
-    ) -> bool {
+    /// `#[const_trait]` only applies to traits.
+    fn check_const_trait(&self, attr: &Attribute, _span: Span, target: Target) -> bool {
         match target {
-            Target::Method(MethodKind::Trait { body: true }) => true,
+            Target::Trait => true,
             _ => {
                 self.tcx
                     .sess
-                    .struct_span_err(
-                        attr.span,
-                        "attribute should be applied to a trait method with body",
-                    )
-                    .span_label(span, "not a trait method or missing a body")
+                    .struct_span_err(attr.span, "attribute should be applied to a trait")
                     .emit();
                 false
             }
@@ -2207,6 +2196,8 @@ impl CheckAttrVisitor<'_> {
                 "attribute `{}` without any lints has no effect",
                 attr.name_or_empty()
             )
+        } else if attr.name_or_empty() == sym::default_method_body_is_const {
+            format!("`default_method_body_is_const` has been replaced with `#[const_trait]` on traits")
         } else {
             return;
         };
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index 04d6e9f205a..996ca66de0e 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -13,7 +13,6 @@ use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::ty;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::parse::feature_err;
@@ -64,66 +63,6 @@ pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { check_mod_const_bodies, ..*providers };
 }
 
-fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
-    let _: Option<_> = try {
-        if let hir::ItemKind::Impl(ref imp) = item.kind && let hir::Constness::Const = imp.constness {
-            let trait_def_id = imp.of_trait.as_ref()?.trait_def_id()?;
-            let ancestors = tcx
-                .trait_def(trait_def_id)
-                .ancestors(tcx, item.def_id.to_def_id())
-                .ok()?;
-            let mut to_implement = Vec::new();
-
-            for trait_item in tcx.associated_items(trait_def_id).in_definition_order()
-            {
-                if let ty::AssocItem {
-                    kind: ty::AssocKind::Fn,
-                    defaultness,
-                    def_id: trait_item_id,
-                    ..
-                } = *trait_item
-                {
-                    // we can ignore functions that do not have default bodies:
-                    // if those are unimplemented it will be caught by typeck.
-                    if !defaultness.has_value()
-                        || tcx
-                        .has_attr(trait_item_id, sym::default_method_body_is_const)
-                    {
-                        continue;
-                    }
-
-                    let is_implemented = ancestors
-                        .leaf_def(tcx, trait_item_id)
-                        .map(|node_item| !node_item.defining_node.is_from_trait())
-                        .unwrap_or(false);
-
-                    if !is_implemented {
-                        to_implement.push(trait_item_id);
-                    }
-                }
-            }
-
-            // all nonconst trait functions (not marked with #[default_method_body_is_const])
-            // must be implemented
-            if !to_implement.is_empty() {
-                let not_implemented = to_implement
-                    .into_iter()
-                    .map(|did| tcx.item_name(did).to_string())
-                    .collect::<Vec<_>>()
-                    .join("`, `");
-                tcx
-                    .sess
-                    .struct_span_err(
-                        item.span,
-                        "const trait implementations may not use non-const default functions",
-                    )
-                    .note(&format!("`{}` not implemented", not_implemented))
-                    .emit();
-            }
-        }
-    };
-}
-
 #[derive(Copy, Clone)]
 struct CheckConstVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
@@ -254,7 +193,6 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> {
 
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
         intravisit::walk_item(self, item);
-        check_item(self.tcx, item);
     }
 
     fn visit_anon_const(&mut self, anon: &'tcx hir::AnonConst) {