diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-02-09 23:29:56 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-09 23:29:56 +0100 |
| commit | 3f4aaf4f2e9fd49736e660475f446619e8734e09 (patch) | |
| tree | ee6ff4aed191d3baab16454560fe605299af423c /compiler/rustc_passes | |
| parent | 9634559599537e334cbfa854446d048e6ebe5ee9 (diff) | |
| parent | 170593313a6ac2206107ec52a0d3bb9cc873a97c (diff) | |
| download | rust-3f4aaf4f2e9fd49736e660475f446619e8734e09.tar.gz rust-3f4aaf4f2e9fd49736e660475f446619e8734e09.zip | |
Rollup merge of #91504 - cynecx:used_retain, r=nikic
`#[used(linker)]` attribute See https://github.com/dtolnay/linkme/issues/41#issuecomment-927255631.
Diffstat (limited to 'compiler/rustc_passes')
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 34 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/dead.rs | 5 |
2 files changed, 38 insertions, 1 deletions
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ca511f7b814..479a08e43c0 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1741,12 +1741,46 @@ impl CheckAttrVisitor<'_> { } fn check_used(&self, attrs: &[Attribute], target: Target) { + let mut used_linker_span = None; + let mut used_compiler_span = None; for attr in attrs { if attr.has_name(sym::used) && target != Target::Static { self.tcx .sess .span_err(attr.span, "attribute must be applied to a `static` variable"); } + let inner = attr.meta_item_list(); + match inner.as_deref() { + Some([item]) if item.has_name(sym::linker) => { + if used_linker_span.is_none() { + used_linker_span = Some(attr.span); + } + } + Some([item]) if item.has_name(sym::compiler) => { + if used_compiler_span.is_none() { + used_compiler_span = Some(attr.span); + } + } + Some(_) => { + // This error case is handled in rustc_typeck::collect. + } + None => { + // Default case (compiler) when arg isn't defined. + if used_compiler_span.is_none() { + used_compiler_span = Some(attr.span); + } + } + } + } + if let (Some(linker_span), Some(compiler_span)) = (used_linker_span, used_compiler_span) { + let spans = vec![linker_span, compiler_span]; + self.tcx + .sess + .struct_span_err( + spans, + "`used(compiler)` and `used(linker)` can't be used together", + ) + .emit(); } } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index e7e56711b33..dc3ce1afa33 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -466,7 +466,10 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool { // #[used], #[no_mangle], #[export_name], etc also keeps the item alive // forcefully, e.g., for placing it in a specific section. - if cg_attrs.contains_extern_indicator() || cg_attrs.flags.contains(CodegenFnAttrFlags::USED) { + if cg_attrs.contains_extern_indicator() + || cg_attrs.flags.contains(CodegenFnAttrFlags::USED) + || cg_attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) + { return true; } |
