1
Fork 0

Check that #[may_dangle] is properly applied

It's only valid when applied to a type or lifetime parameter
in `Drop` trait implementation.
This commit is contained in:
Goldstein 2024-08-18 17:11:47 +03:00
parent 7521bdaf5b
commit 3a9bf45513
No known key found for this signature in database
GPG key ID: DE6031ABA0BB269A
5 changed files with 135 additions and 1 deletions

View file

@ -189,6 +189,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
[sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(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::may_dangle, ..] => self.check_may_dangle(hir_id, attr),
[sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target),
[sym::rustc_allow_incoherent_impl, ..] => {
self.check_allow_incoherent_impl(attr, span, target)
@ -255,7 +256,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::cfg_attr
// need to be fixed
| sym::cfi_encoding // FIXME(cfi_encoding)
| sym::may_dangle // FIXME(dropck_eyepatch)
| sym::pointee // FIXME(derive_smart_pointer)
| sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
| sym::used // handled elsewhere to restrict to static items
@ -1373,6 +1373,27 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
/// Checks if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl.
fn check_may_dangle(&self, hir_id: HirId, attr: &Attribute) {
if let hir::Node::GenericParam(param) = self.tcx.hir_node(hir_id)
&& matches!(
param.kind,
hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. }
)
&& matches!(param.source, hir::GenericParamSource::Generics)
&& let parent_hir_id = self.tcx.parent_hir_id(hir_id)
&& let hir::Node::Item(item) = self.tcx.hir_node(parent_hir_id)
&& let hir::ItemKind::Impl(impl_) = item.kind
&& let Some(trait_) = impl_.of_trait
&& let Some(def_id) = trait_.trait_def_id()
&& self.tcx.is_lang_item(def_id, hir::LangItem::Drop)
{
return;
}
self.dcx().emit_err(errors::InvalidMayDangle { attr_span: attr.span });
}
/// Checks if `#[cold]` is applied to a non-function.
fn check_cold(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
match target {

View file

@ -737,6 +737,13 @@ pub struct NonExportedMacroInvalidAttrs {
pub attr_span: Span,
}
#[derive(Diagnostic)]
#[diag(passes_may_dangle)]
pub struct InvalidMayDangle {
#[primary_span]
pub attr_span: Span,
}
#[derive(LintDiagnostic)]
#[diag(passes_unused_duplicate)]
pub struct UnusedDuplicate {