Skip to content

Commit

Permalink
Emit an error for invalid use of the linkage attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
s7tya committed Aug 11, 2024
1 parent 730d5d4 commit 01a580b
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 1 deletion.
4 changes: 4 additions & 0 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,10 @@ passes_link_section =
.warn = {-passes_previously_accepted}
.label = not a function or static
passes_linkage =
attribute should be applied to a free function, impl method or static, foreign static
.label = not a free function, impl method or static, foreign static
passes_macro_export =
`#[macro_export]` only has an effect on macro definitions
Expand Down
11 changes: 10 additions & 1 deletion compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
[sym::coroutine, ..] => {
self.check_coroutine(attr, target);
}
[sym::linkage, ..] => self.check_linkage(attr, span, target),
[
// ok
sym::allow
Expand All @@ -256,7 +257,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::cfi_encoding // FIXME(cfi_encoding)
| sym::may_dangle // FIXME(dropck_eyepatch)
| sym::pointee // FIXME(derive_smart_pointer)
| sym::linkage // FIXME(linkage)
| sym::omit_gdb_pretty_printer_section // FIXME(omit_gdb_pretty_printer_section)
| sym::used // handled elsewhere to restrict to static items
| sym::repr // handled elsewhere to restrict to type decls items
Expand Down Expand Up @@ -2349,6 +2349,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
}

fn check_linkage(&self, attr: &Attribute, span: Span, target: Target) {
match target {
Target::Fn | Target::Method(..) | Target::Static | Target::ForeignStatic => {}
_ => {
self.dcx().emit_err(errors::Linkage { attr_span: attr.span, span });
}
}
}
}

impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,15 @@ pub struct CoroutineOnNonClosure {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(passes_linkage)]
pub struct Linkage {
#[primary_span]
pub attr_span: Span,
#[label]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(passes_empty_confusables)]
pub(crate) struct EmptyConfusables {
Expand Down
38 changes: 38 additions & 0 deletions tests/ui/attributes/linkage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#![feature(linkage)]
#![feature(stmt_expr_attributes)]
#![deny(unused_attributes)]
#![allow(dead_code)]

#[linkage = "weak"] //~ ERROR attribute should be applied to a free function, impl method or static, foreign static
type InvalidTy = ();

#[linkage = "weak"] //~ ERROR attribute should be applied to a free function, impl method or static, foreign static
mod invalid_module {}

#[linkage = "weak"] //~ ERROR attribute should be applied to a free function, impl method or static, foreign static
struct F;

#[linkage = "weak"] //~ ERROR attribute should be applied to a free function, impl method or static, foreign static
impl F {
#[linkage = "weak"]
fn valid(&self) {}
}

#[linkage = "weak"]
fn f() {
#[linkage = "weak"]
{
1
};
//~^^^^ ERROR attribute should be applied to a free function, impl method or static, foreign static
}

extern "C" {
#[linkage = "weak"]
static A: *const ();
}

fn main() {
let _ = #[linkage = "weak"] //~ ERROR attribute should be applied to a free function, impl method or static, foreign static
(|| 1);
}
55 changes: 55 additions & 0 deletions tests/ui/attributes/linkage.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
error: attribute should be applied to a free function, impl method or static, foreign static
--> $DIR/linkage.rs:6:1
|
LL | #[linkage = "weak"]
| ^^^^^^^^^^^^^^^^^^^
LL | type InvalidTy = ();
| -------------------- not a free function, impl method or static, foreign static

error: attribute should be applied to a free function, impl method or static, foreign static
--> $DIR/linkage.rs:9:1
|
LL | #[linkage = "weak"]
| ^^^^^^^^^^^^^^^^^^^
LL | mod invalid_module {}
| --------------------- not a free function, impl method or static, foreign static

error: attribute should be applied to a free function, impl method or static, foreign static
--> $DIR/linkage.rs:12:1
|
LL | #[linkage = "weak"]
| ^^^^^^^^^^^^^^^^^^^
LL | struct F;
| --------- not a free function, impl method or static, foreign static

error: attribute should be applied to a free function, impl method or static, foreign static
--> $DIR/linkage.rs:15:1
|
LL | #[linkage = "weak"]
| ^^^^^^^^^^^^^^^^^^^
LL | / impl F {
LL | | #[linkage = "weak"]
LL | | fn valid(&self) {}
LL | | }
| |_- not a free function, impl method or static, foreign static

error: attribute should be applied to a free function, impl method or static, foreign static
--> $DIR/linkage.rs:23:5
|
LL | #[linkage = "weak"]
| ^^^^^^^^^^^^^^^^^^^
LL | / {
LL | | 1
LL | | };
| |_____- not a free function, impl method or static, foreign static

error: attribute should be applied to a free function, impl method or static, foreign static
--> $DIR/linkage.rs:36:13
|
LL | let _ = #[linkage = "weak"]
| ^^^^^^^^^^^^^^^^^^^
LL | (|| 1);
| ------ not a free function, impl method or static, foreign static

error: aborting due to 6 previous errors

0 comments on commit 01a580b

Please sign in to comment.