Skip to content

Commit

Permalink
Implement #[proc_macro_warning] to generate LintId for macro-generate…
Browse files Browse the repository at this point in the history
…d warnings
  • Loading branch information
dtolnay committed Jan 13, 2025
1 parent a2016aa commit e76936f
Show file tree
Hide file tree
Showing 53 changed files with 736 additions and 121 deletions.
47 changes: 40 additions & 7 deletions compiler/rustc_ast/src/attr/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Functions dealing with attributes and meta items.
use std::fmt::Debug;
use std::fmt::{self, Debug, Display};
use std::sync::atomic::{AtomicU32, Ordering};

use rustc_index::bit_set::GrowableBitSet;
Expand Down Expand Up @@ -720,6 +720,31 @@ impl MetaItemLit {
}
}

/// An attribute relevant to the expansion of the proc macro harness performed
/// by `rustc_builtin_macros`.
#[derive(PartialEq, Debug)]
pub enum ProcMacroAttr {
/// `#[proc_macro_derive]`
Derive,
/// `#[proc_macro_attribute]`
Attribute,
/// `#[proc_macro]`
Bang,
/// `#[proc_macro_warning]`
Warning,
}

impl Display for ProcMacroAttr {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str(match self {
ProcMacroAttr::Derive => "proc_macro_derive",
ProcMacroAttr::Attribute => "proc_macro_attribute",
ProcMacroAttr::Bang => "proc_macro",
ProcMacroAttr::Warning => "proc_macro_warning",
})
}
}

pub trait AttributeExt: Debug {
fn id(&self) -> AttrId;

Expand Down Expand Up @@ -774,10 +799,18 @@ pub trait AttributeExt: Debug {
/// * `#[doc(...)]` returns `None`.
fn doc_str(&self) -> Option<Symbol>;

fn is_proc_macro_attr(&self) -> bool {
[sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive]
.iter()
.any(|kind| self.has_name(*kind))
fn proc_macro_attr(&self) -> Option<ProcMacroAttr> {
if self.has_name(sym::proc_macro_derive) {
Some(ProcMacroAttr::Derive)
} else if self.has_name(sym::proc_macro_attribute) {
Some(ProcMacroAttr::Attribute)
} else if self.has_name(sym::proc_macro) {
Some(ProcMacroAttr::Bang)
} else if self.has_name(sym::proc_macro_warning) {
Some(ProcMacroAttr::Warning)
} else {
None
}
}

/// Returns the documentation and its kind if this is a doc comment or a sugared doc comment.
Expand Down Expand Up @@ -850,8 +883,8 @@ impl Attribute {
AttributeExt::doc_str(self)
}

pub fn is_proc_macro_attr(&self) -> bool {
AttributeExt::is_proc_macro_attr(self)
pub fn proc_macro_attr(&self) -> Option<ProcMacroAttr> {
AttributeExt::proc_macro_attr(self)
}

pub fn doc_str_and_comment_kind(&self) -> Option<(Symbol, CommentKind)> {
Expand Down
10 changes: 8 additions & 2 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::mem;
use std::ops::{Deref, DerefMut};

use itertools::{Either, Itertools};
use rustc_ast::attr::ProcMacroAttr;
use rustc_ast::ptr::P;
use rustc_ast::visit::{AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor, walk_list};
use rustc_ast::*;
Expand Down Expand Up @@ -813,7 +814,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
}

fn visit_item(&mut self, item: &'a Item) {
if item.attrs.iter().any(|attr| attr.is_proc_macro_attr()) {
if item.attrs.iter().any(|attr| attr.proc_macro_attr().is_some()) {
self.has_proc_macro_decls = true;
}

Expand Down Expand Up @@ -1080,7 +1081,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.dcx().emit_err(errors::UnsafeStatic { span: item.span });
}

if expr.is_none() {
if expr.is_none()
&& !item
.attrs
.iter()
.any(|attr| attr.proc_macro_attr() == Some(ProcMacroAttr::Warning))
{
self.dcx().emit_err(errors::StaticWithoutBody {
span: item.span,
replace_span: self.ending_semi_or_hi(item.span),
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_builtin_macros/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ builtin_macros_proc_macro = `proc-macro` crate types currently cannot export any
builtin_macros_proc_macro_attribute_only_be_used_on_bare_functions = the `#[{$path}]` attribute may only be used on bare functions
builtin_macros_proc_macro_attribute_only_be_used_on_statics = the `#[{$path}]` attribute may only be used on a `static`
builtin_macros_proc_macro_lint_id_is_filled_in_by_attribute = a unique LintId value is automatically filled in by `#[proc_macro_warning]`
.suggestion = remove this value
builtin_macros_proc_macro_attribute_only_usable_with_crate_type = the `#[{$path}]` attribute is only usable with crates of the `proc-macro` crate type
builtin_macros_requires_cfg_pattern =
Expand Down
16 changes: 16 additions & 0 deletions compiler/rustc_builtin_macros/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,22 @@ pub(crate) struct AttributeOnlyBeUsedOnBareFunctions<'a> {
pub path: &'a str,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_proc_macro_attribute_only_be_used_on_statics)]
pub(crate) struct AttributeOnlyBeUsedOnStatics<'a> {
#[primary_span]
pub span: Span,
pub path: &'a str,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_proc_macro_lint_id_is_filled_in_by_attribute)]
pub(crate) struct LintIdIsFilledInByAttribute {
#[primary_span]
#[suggestion(code = "", applicability = "machine-applicable")]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(builtin_macros_proc_macro_attribute_only_usable_with_crate_type)]
pub(crate) struct AttributeOnlyUsableWithCrateType<'a> {
Expand Down
Loading

0 comments on commit e76936f

Please sign in to comment.