diff options
| author | bors <bors@rust-lang.org> | 2022-05-30 09:19:03 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-05-30 09:19:03 +0000 |
| commit | 5c780b98d10f48d6255cf2deb2643194b9221c02 (patch) | |
| tree | c2ff6e458787797f666a3774b05863c2a1d8333e /compiler/rustc_passes/src | |
| parent | 855fc022fe879f4e3493a024f9c6b981d6317612 (diff) | |
| parent | 2f96fbe2200d5928faafdf068b591170b6a127b7 (diff) | |
| download | rust-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.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_const.rs | 62 |
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) { |
