@@ -1741,12 +1741,46 @@ impl CheckAttrVisitor<'_> {
1741
1741
}
1742
1742
1743
1743
fn check_used ( & self , attrs : & [ Attribute ] , target : Target ) {
1744
+ let mut used_linker_span = None ;
1745
+ let mut used_compiler_span = None ;
1744
1746
for attr in attrs {
1745
1747
if attr. has_name ( sym:: used) && target != Target :: Static {
1746
1748
self . tcx
1747
1749
. sess
1748
1750
. span_err ( attr. span , "attribute must be applied to a `static` variable" ) ;
1749
1751
}
1752
+ let inner = attr. meta_item_list ( ) ;
1753
+ match inner. as_deref ( ) {
1754
+ Some ( [ item] ) if item. has_name ( sym:: linker) => {
1755
+ if used_linker_span. is_none ( ) {
1756
+ used_linker_span = Some ( attr. span ) ;
1757
+ }
1758
+ }
1759
+ Some ( [ item] ) if item. has_name ( sym:: compiler) => {
1760
+ if used_compiler_span. is_none ( ) {
1761
+ used_compiler_span = Some ( attr. span ) ;
1762
+ }
1763
+ }
1764
+ Some ( _) => {
1765
+ // This error case is handled in rustc_typeck::collect.
1766
+ }
1767
+ None => {
1768
+ // Default case (compiler) when arg isn't defined.
1769
+ if used_compiler_span. is_none ( ) {
1770
+ used_compiler_span = Some ( attr. span ) ;
1771
+ }
1772
+ }
1773
+ }
1774
+ }
1775
+ if let ( Some ( linker_span) , Some ( compiler_span) ) = ( used_linker_span, used_compiler_span) {
1776
+ let spans = vec ! [ linker_span, compiler_span] ;
1777
+ self . tcx
1778
+ . sess
1779
+ . struct_span_err (
1780
+ spans,
1781
+ "`used(compiler)` and `used(linker)` can't be used together" ,
1782
+ )
1783
+ . emit ( ) ;
1750
1784
}
1751
1785
}
1752
1786
0 commit comments