Skip to content

Commit 1f08727

Browse files
committed
Auto merge of #157866 - JonathanBrouwer:rollup-XfF1OYf, r=JonathanBrouwer
Rollup of 3 pull requests Successful merges: - #157201 (Move logic for emitting UNSAFE_CODE for unsafe attributes to attr parsing) - #157613 (Improve invalid cfg predicate error) - #157838 (rustdoc: Don't strip hidden items in `AliasedNonLocalStripper`)
2 parents e7ef22d + 7b39994 commit 1f08727

33 files changed

Lines changed: 487 additions & 335 deletions

compiler/rustc_attr_parsing/src/attributes/cfg.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,11 @@ pub fn parse_cfg_entry(
103103
Some(sym::target) => parse_cfg_entry_target(cx, list, meta.span())?,
104104
Some(sym::version) => parse_cfg_entry_version(cx, list, meta.span())?,
105105
_ => {
106-
return Err(cx.emit_err(session_diagnostics::InvalidPredicate {
107-
span: meta.span(),
108-
predicate: meta.path().to_string(),
109-
}));
106+
let mut possibilities = vec![sym::any, sym::all, sym::not, sym::target];
107+
if cx.features().cfg_version() {
108+
possibilities.push(sym::version);
109+
}
110+
return Err(cx.adcx().expected_specific_argument(meta.span(), &possibilities));
110111
}
111112
},
112113
a @ (ArgParser::NoArgs | ArgParser::NameValue(_)) => {

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,10 @@ pub(crate) struct ExportNameParser;
108108
impl SingleAttributeParser for ExportNameParser {
109109
const PATH: &[rustc_span::Symbol] = &[sym::export_name];
110110
const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
111-
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: Some(Edition2024) };
111+
const SAFETY: AttributeSafety = AttributeSafety::Unsafe {
112+
note: "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them",
113+
unsafe_since: Some(Edition2024),
114+
};
112115
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
113116
Allow(Target::Static),
114117
Allow(Target::Fn),
@@ -217,7 +220,10 @@ impl AttributeParser for NakedParser {
217220
this.span = Some(cx.attr_span);
218221
}
219222
})];
220-
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: None };
223+
const SAFETY: AttributeSafety = AttributeSafety::Unsafe {
224+
note: "the `#[naked]` attribute adds the safety obligation that the function's body must respect the function’s calling convention, uphold its signature, and either return or diverge (i.e., not fall through past the end of the assembly code).",
225+
unsafe_since: None,
226+
};
221227
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
222228
Allow(Target::Fn),
223229
Allow(Target::Method(MethodKind::Inherent)),
@@ -347,7 +353,10 @@ pub(crate) struct NoMangleParser;
347353
impl NoArgsAttributeParser for NoMangleParser {
348354
const PATH: &[Symbol] = &[sym::no_mangle];
349355
const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn;
350-
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: Some(Edition2024) };
356+
const SAFETY: AttributeSafety = AttributeSafety::Unsafe {
357+
note: "the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them",
358+
unsafe_since: Some(Edition2024),
359+
};
351360
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
352361
Allow(Target::Fn),
353362
Allow(Target::Static),
@@ -540,7 +549,10 @@ pub(crate) struct ForceTargetFeatureParser;
540549
impl CombineAttributeParser for ForceTargetFeatureParser {
541550
type Item = (Symbol, Span);
542551
const PATH: &[Symbol] = &[sym::force_target_feature];
543-
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: None };
552+
const SAFETY: AttributeSafety = AttributeSafety::Unsafe {
553+
note: "a function with the signature of the function the attribute is applied to must only be callable if the force-enabled features are guaranteed to be present",
554+
unsafe_since: None,
555+
};
544556
const CONVERT: ConvertFn<Self::Item> = |items, span| AttributeKind::TargetFeature {
545557
features: items,
546558
attr_span: span,

compiler/rustc_attr_parsing/src/attributes/link_attrs.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,10 @@ fn check_link_section_macho(name: Symbol) -> Result<(), InvalidMachoSectionReaso
489489
impl SingleAttributeParser for LinkSectionParser {
490490
const PATH: &[Symbol] = &[sym::link_section];
491491
const ON_DUPLICATE: OnDuplicate = OnDuplicate::WarnButFutureError;
492-
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: Some(Edition2024) };
492+
const SAFETY: AttributeSafety = AttributeSafety::Unsafe {
493+
note: "the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them",
494+
unsafe_since: Some(Edition2024),
495+
};
493496
const STABILITY: AttributeStability = AttributeStability::Stable;
494497
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
495498
Allow(Target::Static),
@@ -540,7 +543,10 @@ impl NoArgsAttributeParser for ExportStableParser {
540543
pub(crate) struct FfiConstParser;
541544
impl NoArgsAttributeParser for FfiConstParser {
542545
const PATH: &[Symbol] = &[sym::ffi_const];
543-
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: None };
546+
const SAFETY: AttributeSafety = AttributeSafety::Unsafe {
547+
note: "`#[ffi_const]` functions shall have no effects except for its return value, which can only depend on the values of the function parameters, and is not affected by changes to the observable state of the program.",
548+
unsafe_since: None,
549+
};
544550
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
545551
const STABILITY: AttributeStability = unstable!(ffi_const);
546552
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::FfiConst;
@@ -549,7 +555,10 @@ impl NoArgsAttributeParser for FfiConstParser {
549555
pub(crate) struct FfiPureParser;
550556
impl NoArgsAttributeParser for FfiPureParser {
551557
const PATH: &[Symbol] = &[sym::ffi_pure];
552-
const SAFETY: AttributeSafety = AttributeSafety::Unsafe { unsafe_since: None };
558+
const SAFETY: AttributeSafety = AttributeSafety::Unsafe {
559+
note: "`#[ffi_pure]` functions shall have no effects except for its return value, which shall not change across two consecutive function calls with the same parameters.",
560+
unsafe_since: None,
561+
};
553562
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::ForeignFn)]);
554563
const STABILITY: AttributeStability = unstable!(ffi_pure);
555564
const CREATE: fn(Span) -> AttributeKind = AttributeKind::FfiPure;

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,11 @@ pub enum AttributeSafety {
236236
/// An error is emitted when `#[unsafe(...)]` is omitted, except when the attribute's edition
237237
/// is less than the one stored in `unsafe_since`. This handles attributes that were safe in
238238
/// earlier editions, but become unsafe in later ones.
239-
Unsafe { unsafe_since: Option<Edition> },
239+
Unsafe {
240+
/// The `note` is emitted during the `unsafe_code`, and explains to the user why this attribute is unsafe.
241+
note: &'static str,
242+
unsafe_since: Option<Edition>,
243+
},
240244
}
241245

242246
/// An even simpler version of [`SingleAttributeParser`]:

compiler/rustc_attr_parsing/src/diagnostics.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,3 +826,11 @@ pub(crate) enum InvalidOnClause {
826826
"using multiple `rustc_on_unimplemented` (or mixing it with `diagnostic::on_unimplemented`) is not supported"
827827
)]
828828
pub(crate) struct DupesNotAllowed;
829+
830+
#[derive(Diagnostic)]
831+
#[diag("usage of the unsafe `#[{$attr_path}]` attribute")]
832+
#[note("{$note}")]
833+
pub(crate) struct UnsafeAttribute {
834+
pub attr_path: AttrPath,
835+
pub note: &'static str,
836+
}

compiler/rustc_attr_parsing/src/safety.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use rustc_ast::Safety;
22
use rustc_errors::{Diagnostic, MultiSpan};
33
use rustc_hir::AttrPath;
4+
use rustc_lint_defs::builtin::UNSAFE_CODE;
45
use rustc_session::lint::LintId;
56
use rustc_session::lint::builtin::UNSAFE_ATTR_OUTSIDE_UNSAFE;
67
use rustc_span::Span;
@@ -21,6 +22,7 @@ impl<'sess> AttributeParser<'sess> {
2122
return;
2223
}
2324

25+
// Check if expected & actual safety match
2426
match (expected_safety, attr_safety) {
2527
// - Unsafe builtin attribute
2628
// - User wrote `#[unsafe(..)]`, which is permitted on any edition
@@ -30,7 +32,7 @@ impl<'sess> AttributeParser<'sess> {
3032

3133
// - Unsafe builtin attribute
3234
// - User did not write `#[unsafe(..)]`
33-
(AttributeSafety::Unsafe { unsafe_since }, Safety::Default) => {
35+
(AttributeSafety::Unsafe { unsafe_since, note: _ }, Safety::Default) => {
3436
let path_span = attr_path.span;
3537

3638
// If the `attr_item`'s span is not from a macro, then just suggest
@@ -112,5 +114,17 @@ impl<'sess> AttributeParser<'sess> {
112114
);
113115
}
114116
}
117+
118+
// Emit `unsafe_code` lint
119+
if let AttributeSafety::Unsafe { note, .. } = expected_safety {
120+
let attr_path = attr_path.clone();
121+
emit_lint(
122+
LintId::of(UNSAFE_CODE),
123+
attr_span.into(),
124+
EmitAttribute(Box::new(move |dcx, level, _| {
125+
diagnostics::UnsafeAttribute { attr_path, note }.into_diag(dcx, level)
126+
})),
127+
)
128+
}
115129
}
116130
}

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,6 @@ use rustc_target::spec::TargetTuple;
1313
use crate::AttributeTemplate;
1414
use crate::context::Suggestion;
1515

16-
#[derive(Diagnostic)]
17-
#[diag("invalid predicate `{$predicate}`", code = E0537)]
18-
pub(crate) struct InvalidPredicate {
19-
#[primary_span]
20-
pub span: Span,
21-
22-
pub predicate: String,
23-
}
24-
2516
#[derive(Diagnostic)]
2617
#[diag("{$attr_str} attribute cannot have empty value")]
2718
pub(crate) struct DocAliasEmpty<'a> {

compiler/rustc_error_codes/src/error_codes/E0537.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
#### Note: this error code is no longer emitted by the compiler
12
An unknown predicate was used inside the `cfg` attribute.
23

34
Erroneous code example:
45

5-
```compile_fail,E0537
6+
```compile_fail,E0539
67
#[cfg(unknown())] // error: invalid predicate `unknown`
78
pub fn something() {}
89

compiler/rustc_lint/src/builtin.rs

Lines changed: 0 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -189,46 +189,6 @@ impl<'tcx> LateLintPass<'tcx> for NonShorthandFieldPatterns {
189189
}
190190
}
191191

192-
declare_lint! {
193-
/// The `unsafe_code` lint catches usage of `unsafe` code and other
194-
/// potentially unsound constructs like `no_mangle`, `export_name`,
195-
/// and `link_section`.
196-
///
197-
/// ### Example
198-
///
199-
/// ```rust,compile_fail
200-
/// #![deny(unsafe_code)]
201-
/// fn main() {
202-
/// unsafe {
203-
///
204-
/// }
205-
/// }
206-
///
207-
/// #[no_mangle]
208-
/// fn func_0() { }
209-
///
210-
/// #[export_name = "exported_symbol_name"]
211-
/// pub fn name_in_rust() { }
212-
///
213-
/// #[no_mangle]
214-
/// #[link_section = ".example_section"]
215-
/// pub static VAR1: u32 = 1;
216-
/// ```
217-
///
218-
/// {{produces}}
219-
///
220-
/// ### Explanation
221-
///
222-
/// This lint is intended to restrict the usage of `unsafe` blocks and other
223-
/// constructs (including, but not limited to `no_mangle`, `link_section`
224-
/// and `export_name` attributes) wrong usage of which causes undefined
225-
/// behavior.
226-
UNSAFE_CODE,
227-
Allow,
228-
"usage of `unsafe` code and other potentially unsound constructs",
229-
@eval_always = true
230-
}
231-
232192
declare_lint_pass!(UnsafeCode => [UNSAFE_CODE]);
233193

234194
impl UnsafeCode {
@@ -271,34 +231,6 @@ impl EarlyLintPass for UnsafeCode {
271231
self.report_unsafe(cx, it.span, BuiltinUnsafe::UnsafeImpl);
272232
}
273233

274-
ast::ItemKind::Fn(..) => {
275-
if let Some(attr) = attr::find_by_name(&it.attrs, sym::no_mangle) {
276-
self.report_unsafe(cx, attr.span, BuiltinUnsafe::NoMangleFn);
277-
}
278-
279-
if let Some(attr) = attr::find_by_name(&it.attrs, sym::export_name) {
280-
self.report_unsafe(cx, attr.span, BuiltinUnsafe::ExportNameFn);
281-
}
282-
283-
if let Some(attr) = attr::find_by_name(&it.attrs, sym::link_section) {
284-
self.report_unsafe(cx, attr.span, BuiltinUnsafe::LinkSectionFn);
285-
}
286-
}
287-
288-
ast::ItemKind::Static(..) => {
289-
if let Some(attr) = attr::find_by_name(&it.attrs, sym::no_mangle) {
290-
self.report_unsafe(cx, attr.span, BuiltinUnsafe::NoMangleStatic);
291-
}
292-
293-
if let Some(attr) = attr::find_by_name(&it.attrs, sym::export_name) {
294-
self.report_unsafe(cx, attr.span, BuiltinUnsafe::ExportNameStatic);
295-
}
296-
297-
if let Some(attr) = attr::find_by_name(&it.attrs, sym::link_section) {
298-
self.report_unsafe(cx, attr.span, BuiltinUnsafe::LinkSectionStatic);
299-
}
300-
}
301-
302234
ast::ItemKind::GlobalAsm(..) => {
303235
self.report_unsafe(cx, it.span, BuiltinUnsafe::GlobalAsm);
304236
}
@@ -325,17 +257,6 @@ impl EarlyLintPass for UnsafeCode {
325257
}
326258
}
327259

328-
fn check_impl_item(&mut self, cx: &EarlyContext<'_>, it: &ast::AssocItem) {
329-
if let ast::AssocItemKind::Fn(..) = it.kind {
330-
if let Some(attr) = attr::find_by_name(&it.attrs, sym::no_mangle) {
331-
self.report_unsafe(cx, attr.span, BuiltinUnsafe::NoMangleMethod);
332-
}
333-
if let Some(attr) = attr::find_by_name(&it.attrs, sym::export_name) {
334-
self.report_unsafe(cx, attr.span, BuiltinUnsafe::ExportNameMethod);
335-
}
336-
}
337-
}
338-
339260
fn check_fn(&mut self, cx: &EarlyContext<'_>, fk: FnKind<'_>, span: Span, _: ast::NodeId) {
340261
if let FnKind::Fn(
341262
ctxt,

compiler/rustc_lint/src/lints.rs

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -160,46 +160,6 @@ pub(crate) enum BuiltinUnsafe {
160160
UnsafeTrait,
161161
#[diag("implementation of an `unsafe` trait")]
162162
UnsafeImpl,
163-
#[diag("declaration of a `no_mangle` function")]
164-
#[note(
165-
"the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them"
166-
)]
167-
NoMangleFn,
168-
#[diag("declaration of a function with `export_name`")]
169-
#[note(
170-
"the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them"
171-
)]
172-
ExportNameFn,
173-
#[diag("declaration of a function with `link_section`")]
174-
#[note(
175-
"the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them"
176-
)]
177-
LinkSectionFn,
178-
#[diag("declaration of a `no_mangle` static")]
179-
#[note(
180-
"the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them"
181-
)]
182-
NoMangleStatic,
183-
#[diag("declaration of a static with `export_name`")]
184-
#[note(
185-
"the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them"
186-
)]
187-
ExportNameStatic,
188-
#[diag("declaration of a static with `link_section`")]
189-
#[note(
190-
"the program's behavior with overridden link sections on items is unpredictable and Rust cannot provide guarantees when you manually override them"
191-
)]
192-
LinkSectionStatic,
193-
#[diag("declaration of a `no_mangle` method")]
194-
#[note(
195-
"the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them"
196-
)]
197-
NoMangleMethod,
198-
#[diag("declaration of a method with `export_name`")]
199-
#[note(
200-
"the linker's behavior with multiple libraries exporting duplicate symbol names is undefined and Rust cannot provide guarantees when you manually override them"
201-
)]
202-
ExportNameMethod,
203163
#[diag("declaration of an `unsafe` function")]
204164
DeclUnsafeFn,
205165
#[diag("declaration of an `unsafe` method")]

0 commit comments

Comments
 (0)