split up #[rustc_deny_explicit_impl]
attribute
This commit splits the `#[rustc_deny_explicit_impl(implement_via_object = ...)]` attribute into two attributes `#[rustc_deny_explicit_impl]` and `#[rustc_do_not_implement_via_object]`. This allows us to have special traits that can have user-defined impls but do not have the automatic trait impl for trait objects (`impl Trait for dyn Trait`).
This commit is contained in:
parent
8a1f8039a7
commit
42c00cb647
13 changed files with 152 additions and 91 deletions
|
@ -206,7 +206,9 @@ fn check_object_overlap<'tcx>(
|
|||
// so this is valid.
|
||||
} else {
|
||||
let mut supertrait_def_ids = tcx.supertrait_def_ids(component_def_id);
|
||||
if supertrait_def_ids.any(|d| d == trait_def_id) {
|
||||
if supertrait_def_ids
|
||||
.any(|d| d == trait_def_id && tcx.trait_def(d).implement_via_object)
|
||||
{
|
||||
let span = tcx.def_span(impl_def_id);
|
||||
return Err(struct_span_code_err!(
|
||||
tcx.dcx(),
|
||||
|
|
|
@ -1261,49 +1261,8 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
|
|||
no_dups.then_some(list)
|
||||
});
|
||||
|
||||
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.dcx().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.dcx().span_err(
|
||||
meta.span,
|
||||
format!(
|
||||
"unknown literal passed to `implement_via_object` attribute: {}",
|
||||
lit.symbol
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tcx.dcx().span_err(
|
||||
meta.span(),
|
||||
format!("unknown meta item passed to `rustc_deny_explicit_impl` {meta:?}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
if !seen_attr {
|
||||
tcx.dcx().span_err(attr.span, "missing `implement_via_object` meta item");
|
||||
}
|
||||
}
|
||||
let deny_explicit_impl = tcx.has_attr(def_id, sym::rustc_deny_explicit_impl);
|
||||
let implement_via_object = !tcx.has_attr(def_id, sym::rustc_do_not_implement_via_object);
|
||||
|
||||
ty::TraitDef {
|
||||
def_id: def_id.to_def_id(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue