diff options
| author | Deadbeef <ent3rm4n@gmail.com> | 2021-07-04 12:24:20 +0800 |
|---|---|---|
| committer | Deadbeef <ent3rm4n@gmail.com> | 2021-07-10 20:54:44 +0800 |
| commit | 2db927d8d82260759e4aaa183dbebd0adbb00177 (patch) | |
| tree | 04bbc46ca5e71ad46526c929b471e00aeb431321 /compiler | |
| parent | a84d1b21aea9863f0fc5f436b4982d145dade646 (diff) | |
| download | rust-2db927d8d82260759e4aaa183dbebd0adbb00177.tar.gz rust-2db927d8d82260759e4aaa183dbebd0adbb00177.zip | |
Add #[default_method_body_is_const]
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_feature/src/builtin_attrs.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_const.rs | 49 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 1 |
3 files changed, 37 insertions, 18 deletions
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 259a6328a22..dbdc14dced8 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -470,6 +470,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ rustc_attr!(rustc_promotable, AssumedUsed, template!(Word), IMPL_DETAIL), rustc_attr!(rustc_legacy_const_generics, AssumedUsed, template!(List: "N"), INTERNAL_UNSTABLE), + gated!( + default_method_body_is_const, AssumedUsed, template!(Word), const_trait_impl, + "the `#[default_method_body_is_const]` attribute marks a default method of a trait \ + as const, so it does not need to be duplicated by a const impl." + ), // ========================================================================== // Internal attributes, Layout related: diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs index d783852aaca..eaeec19eb31 100644 --- a/compiler/rustc_passes/src/check_const.rs +++ b/compiler/rustc_passes/src/check_const.rs @@ -8,6 +8,7 @@ //! through, but errors for structured control flow in a `const` should be emitted here. use rustc_attr as attr; +use rustc_data_structures::stable_set::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; @@ -85,34 +86,46 @@ impl<'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for CheckConstTraitVisitor< if let hir::ItemKind::Impl(ref imp) = item.kind { if let hir::Constness::Const = imp.constness { let did = imp.of_trait.as_ref()?.trait_def_id()?; - let trait_fn_cnt = self - .tcx - .associated_item_def_ids(did) - .iter() - .filter(|did| { - matches!( - self.tcx.associated_item(**did), - ty::AssocItem { kind: ty::AssocKind::Fn, .. } - ) - }) - .count(); + let mut to_implement = FxHashSet::default(); + + for did in self.tcx.associated_item_def_ids(did) { + if let ty::AssocItem { + kind: ty::AssocKind::Fn, ident, defaultness, .. + } = self.tcx.associated_item(*did) + { + match ( + self.tcx.has_attr(*did, sym::default_method_body_is_const), + defaultness.has_value(), + ) { + (false, true) => { + to_implement.insert(ident); + } + // ignore functions that do not have default bodies + // if those are unimplemented it will be catched by + // typeck. + _ => {} + } + } + } - let impl_fn_cnt = imp + for it in imp .items .iter() .filter(|it| matches!(it.kind, hir::AssocItemKind::Fn { .. })) - .count(); + { + to_implement.remove(&it.ident); + } - // number of trait functions unequal to functions in impl, - // meaning that one or more provided/default functions of the - // trait are used. - if trait_fn_cnt != impl_fn_cnt { + // all nonconst trait functions (not marked with #[default_method_body_is_const]) + // must be implemented + if !to_implement.is_empty() { self.tcx .sess .struct_span_err( item.span, - "const trait implementations may not use default functions", + "const trait implementations may not use non-const default functions", ) + .note(&format!("`{}` not implemented", to_implement.into_iter().map(|id| id.to_string()).collect::<Vec<_>>().join("`, `"))) .emit(); } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 9051c9d69b5..f7a11876f7d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -462,6 +462,7 @@ symbols! { decode, default_alloc_error_handler, default_lib_allocator, + default_method_body_is_const, default_type_parameter_fallback, default_type_params, delay_span_bug_from_inside_query, |
