diff options
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_feature/src/builtin_attrs.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_hir_analysis/src/collect.rs | 46 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/trait_def.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_passes/messages.ftl | 3 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 43 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/errors.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_span/src/symbol.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/project.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs | 4 |
9 files changed, 70 insertions, 60 deletions
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 0e7deef0cff..3c5bff3812a 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -705,15 +705,14 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ "#[rustc_allow_incoherent_impl] has to be added to all impl items of an incoherent inherent impl." ), rustc_attr!( - rustc_deny_explicit_impl, AttributeType::Normal, template!(Word), ErrorFollowing, @only_local: true, + rustc_deny_explicit_impl, + AttributeType::Normal, + template!(List: "implement_via_object = (true|false)"), + ErrorFollowing, + @only_local: true, "#[rustc_deny_explicit_impl] enforces that a trait can have no user-provided impls" ), rustc_attr!( - rustc_do_not_implement_via_object, AttributeType::Normal, template!(Word), ErrorFollowing, @only_local: true, - "#[rustc_do_not_implement_via_object] marks a trait so that `dyn Trait` does not \ - implement `Trait` (without requiring `Sized` as a supertrait)" - ), - rustc_attr!( rustc_has_incoherent_inherent_impls, AttributeType::Normal, template!(Word), ErrorFollowing, "#[rustc_has_incoherent_inherent_impls] allows the addition of incoherent inherent impls for \ the given type by annotating all impl items with #[rustc_allow_incoherent_impl]." diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 17a180a7eb2..ec378c0984f 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -985,8 +985,50 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef { no_dups.then_some(list) }); - let do_not_implement_via_object = tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object); - let deny_explicit_impl = tcx.has_attr(def_id, sym::rustc_deny_explicit_impl); + + let mut deny_explicit_impl = false; + let mut implement_via_object = true; + if let Some(attr) = tcx.get_attr(def_id, sym::rustc_deny_explicit_impl) { + deny_explicit_impl = true; + let mut seen_attr = false; + for meta in attr.meta_item_list().iter().flatten() { + if let Some(meta) = meta.meta_item() + && meta.name_or_empty() == sym::implement_via_object + && let Some(lit) = meta.name_value_literal() + { + if seen_attr { + tcx.sess.span_err( + meta.span, + "duplicated `implement_via_object` meta item", + ); + } + seen_attr = true; + + match lit.symbol { + kw::True => { + implement_via_object = true; + } + kw::False => { + implement_via_object = false; + } + _ => { + tcx.sess.span_err( + meta.span, + format!("unknown literal passed to `implement_via_object` attribute: {}", lit.symbol), + ); + } + } + } else { + tcx.sess.span_err( + meta.span(), + format!("unknown meta item passed to `rustc_deny_explicit_impl` {:?}", meta), + ); + } + } + if !seen_attr { + tcx.sess.span_err(attr.span, "missing `implement_via_object` meta item"); + } + } ty::TraitDef { def_id: def_id.to_def_id(), diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 325e156fba5..98c70e330f1 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -53,12 +53,14 @@ pub struct TraitDef { /// must be implemented. pub must_implement_one_of: Option<Box<[Ident]>>, - /// Whether a type's built-in `dyn Trait: Trait` implementation is explicitly - /// denied. This only applies to built-in trait, and is marked via - /// `#[rustc_do_not_implement_via_object]`. - pub do_not_implement_via_object: bool, + /// Whether to add a builtin `dyn Trait: Trait` implementation. + /// This is enabled for all traits except ones marked with + /// `#[rustc_deny_explicit_impl(implement_via_object = false)]`. + pub implement_via_object: bool, /// Whether a trait is fully built-in, and any implementation is disallowed. + /// This only applies to built-in traits, and is marked via + /// `#[rustc_deny_explicit_impl(implement_via_object = ...)]`. pub deny_explicit_impl: bool, } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index e76f1614b93..a607e483c97 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -102,9 +102,6 @@ passes_const_impl_const_trait = const `impl`s must be for traits marked with `#[const_trait]` .note = this trait must be annotated with `#[const_trait]` -passes_const_trait = - attribute should be applied to a trait - passes_continue_labeled_block = `continue` pointing to a labeled block .label = labeled blocks cannot be `continue`'d diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c35c7da2664..073760f394e 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -110,9 +110,6 @@ impl CheckAttrVisitor<'_> { sym::no_coverage => self.check_no_coverage(hir_id, attr, span, target), sym::non_exhaustive => self.check_non_exhaustive(hir_id, attr, span, target), sym::marker => self.check_marker(hir_id, attr, span, target), - sym::rustc_must_implement_one_of => { - self.check_rustc_must_implement_one_of(attr, span, target) - } sym::target_feature => self.check_target_feature(hir_id, attr, span, target), sym::thread_local => self.check_thread_local(attr, span, target), sym::track_caller => { @@ -159,12 +156,14 @@ impl CheckAttrVisitor<'_> { | sym::rustc_dirty | sym::rustc_if_this_changed | sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr), - sym::rustc_coinductive => self.check_rustc_coinductive(&attr, span, target), + sym::rustc_coinductive + | sym::rustc_must_implement_one_of + | sym::rustc_deny_explicit_impl + | sym::const_trait => self.check_must_be_applied_to_trait(&attr, span, target), sym::cmse_nonsecure_entry => { self.check_cmse_nonsecure_entry(hir_id, attr, span, target) } sym::collapse_debuginfo => self.check_collapse_debuginfo(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, target), sym::rustc_pass_by_value => self.check_pass_by_value(&attr, span, target), @@ -567,25 +566,6 @@ impl CheckAttrVisitor<'_> { } } - /// Checks if the `#[rustc_must_implement_one_of]` attribute on a `target` is valid. Returns `true` if valid. - fn check_rustc_must_implement_one_of( - &self, - attr: &Attribute, - span: Span, - target: Target, - ) -> bool { - match target { - Target::Trait => true, - _ => { - self.tcx.sess.emit_err(errors::AttrShouldBeAppliedToTrait { - attr_span: attr.span, - defn_span: span, - }); - false - } - } - } - /// Checks if the `#[target_feature]` attribute on `item` is valid. Returns `true` if valid. fn check_target_feature( &self, @@ -1591,8 +1571,8 @@ impl CheckAttrVisitor<'_> { } } - /// Checks if the `#[rustc_coinductive]` attribute is applied to a trait. - fn check_rustc_coinductive(&self, attr: &Attribute, span: Span, target: Target) -> bool { + /// Checks if the attribute is applied to a trait. + fn check_must_be_applied_to_trait(&self, attr: &Attribute, span: Span, target: Target) -> bool { match target { Target::Trait => true, _ => { @@ -1986,17 +1966,6 @@ impl CheckAttrVisitor<'_> { } } - /// `#[const_trait]` only applies to traits. - fn check_const_trait(&self, attr: &Attribute, _span: Span, target: Target) -> bool { - match target { - Target::Trait => true, - _ => { - self.tcx.sess.emit_err(errors::ConstTrait { attr_span: attr.span }); - false - } - } - } - fn check_stability_promotable(&self, attr: &Attribute, _span: Span, target: Target) -> bool { match target { Target::Expression => { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index ae624dbc9c9..7890c93d5ff 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -611,13 +611,6 @@ pub struct RustcStdInternalSymbol { } #[derive(Diagnostic)] -#[diag(passes_const_trait)] -pub struct ConstTrait { - #[primary_span] - pub attr_span: Span, -} - -#[derive(Diagnostic)] #[diag(passes_link_ordinal)] pub struct LinkOrdinal { #[primary_span] diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index f476f891631..cd1a16a1b89 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -817,6 +817,7 @@ symbols! { impl_trait_in_bindings, impl_trait_in_fn_trait_return, impl_trait_projections, + implement_via_object, implied_by, import, import_name_type, @@ -1270,7 +1271,6 @@ symbols! { rustc_diagnostic_macros, rustc_dirty, rustc_do_not_const_check, - rustc_do_not_implement_via_object, rustc_doc_primitive, rustc_dummy, rustc_dump_env_program_clauses, diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 563cc257e03..5554c8a0cc4 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1586,6 +1586,10 @@ fn assemble_candidates_from_object_ty<'cx, 'tcx>( let tcx = selcx.tcx(); + if !tcx.trait_def(obligation.predicate.trait_def_id(tcx)).implement_via_object { + return; + } + let self_ty = obligation.predicate.self_ty(); let object_ty = selcx.infcx.shallow_resolve(self_ty); let data = match object_ty.kind() { diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 3c223db5a0b..9fb9385eefc 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -554,6 +554,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { "assemble_candidates_from_object_ty", ); + if !self.tcx().trait_def(obligation.predicate.def_id()).implement_via_object { + return; + } + self.infcx.probe(|_snapshot| { if obligation.has_non_region_late_bound() { return; |
