From 81b1810cd7b5f1cb74d498f20fa0ef5887420d33 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Sat, 30 Jul 2022 18:01:03 +0000 Subject: [PATCH] Require `#[const_trait]` for `const` `impl`s --- compiler/rustc_passes/src/check_const.rs | 22 ++++++++++++++++++++++ library/core/src/convert/mod.rs | 1 + library/core/src/default.rs | 1 + library/core/src/ops/index.rs | 2 ++ library/core/src/slice/index.rs | 1 + 5 files changed, 27 insertions(+) diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index 70518284cf9..4062862ad74 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -192,6 +192,28 @@ impl<'tcx> Visitor<'tcx> for CheckConstVisitor<'tcx> { } fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { + let tcx = self.tcx; + if let hir::ItemKind::Impl(hir::Impl { + constness: hir::Constness::Const, + of_trait: Some(trait_ref), + .. + }) = item.kind + { + let def_id = trait_ref.trait_def_id().unwrap(); + let source_map = tcx.sess.source_map(); + if !tcx.has_attr(def_id, sym::const_trait) { + tcx.sess + .struct_span_err( + source_map.guess_head_span(item.span), + "const `impl`s must be for traits marked with `#[const_trait]`", + ) + .span_note( + source_map.guess_head_span(tcx.def_span(def_id)), + "this trait must be annotated with `#[const_trait]`", + ) + .emit(); + } + } intravisit::walk_item(self, item); } diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 05637c16622..95900828451 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -368,6 +368,7 @@ pub trait Into: Sized { all(_Self = "&str", T = "std::string::String"), note = "to coerce a `{T}` into a `{Self}`, use `&*` as a prefix", ))] +#[const_trait] pub trait From: Sized { /// Converts to this type from the input type. #[lang = "from"] diff --git a/library/core/src/default.rs b/library/core/src/default.rs index b53cd6074b5..d96b53de0a3 100644 --- a/library/core/src/default.rs +++ b/library/core/src/default.rs @@ -99,6 +99,7 @@ /// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "Default")] #[stable(feature = "rust1", since = "1.0.0")] +#[const_trait] pub trait Default: Sized { /// Returns the "default value" for a type. /// diff --git a/library/core/src/ops/index.rs b/library/core/src/ops/index.rs index e2e569cb7ea..5e3dc48b6ca 100644 --- a/library/core/src/ops/index.rs +++ b/library/core/src/ops/index.rs @@ -55,6 +55,7 @@ #[doc(alias = "]")] #[doc(alias = "[")] #[doc(alias = "[]")] +#[const_trait] pub trait Index { /// The returned type after indexing. #[stable(feature = "rust1", since = "1.0.0")] @@ -163,6 +164,7 @@ see chapter in The Book : Index { /// Performs the mutable indexing (`container[index]`) operation. /// diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 3403a5a86f7..3d99bb7f9a0 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -158,6 +158,7 @@ mod private_slice_index { message = "the type `{T}` cannot be indexed by `{Self}`", label = "slice indices are of type `usize` or ranges of `usize`" )] +#[const_trait] pub unsafe trait SliceIndex: private_slice_index::Sealed { /// The output type returned by methods. #[stable(feature = "slice_get_slice", since = "1.28.0")]