Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit bb6d372

Browse files
committedJun 24, 2024
Auto merge of rust-lang#126886 - workingjubilee:rollup-e6ar0vq, r=workingjubilee
Rollup of 9 pull requests Successful merges: - rust-lang#126177 (Add hard error and migration lint for unsafe attrs) - rust-lang#126298 (Promote loongarch64-unknown-linux-musl to Tier 2 with host tools) - rust-lang#126455 (For [E0308]: mismatched types, when expr is in an arm's body, not add semicolon ';' at the end of it.) - rust-lang#126754 (Implement `use<>` formatting in rustfmt) - rust-lang#126807 (std::unix::fs: copy simplification for apple.) - rust-lang#126845 (Weekly `cargo update`) - rust-lang#126849 (Fix 32-bit Arm reg classes by hierarchically sorting them) - rust-lang#126854 (std::unix::os::home_dir: fallback's optimisation.) - rust-lang#126861 (Migrate `run-make/invalid-library` to `rmake.rs`) r? `@ghost` `@rustbot` modify labels: rollup
2 parents d49994b + 969bbc6 commit bb6d372

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+1003
-286
lines changed
 

‎compiler/rustc_parse/src/errors.rs

+31
Original file line numberDiff line numberDiff line change
@@ -2997,3 +2997,34 @@ pub(crate) struct DotDotRangeAttribute {
29972997
#[primary_span]
29982998
pub span: Span,
29992999
}
3000+
3001+
#[derive(Diagnostic)]
3002+
#[diag(parse_invalid_attr_unsafe)]
3003+
#[note]
3004+
pub struct InvalidAttrUnsafe {
3005+
#[primary_span]
3006+
pub span: Span,
3007+
pub name: Path,
3008+
}
3009+
3010+
#[derive(Diagnostic)]
3011+
#[diag(parse_unsafe_attr_outside_unsafe)]
3012+
pub struct UnsafeAttrOutsideUnsafe {
3013+
#[primary_span]
3014+
#[label]
3015+
pub span: Span,
3016+
#[subdiagnostic]
3017+
pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
3018+
}
3019+
3020+
#[derive(Subdiagnostic)]
3021+
#[multipart_suggestion(
3022+
parse_unsafe_attr_outside_unsafe_suggestion,
3023+
applicability = "machine-applicable"
3024+
)]
3025+
pub struct UnsafeAttrOutsideUnsafeSuggestion {
3026+
#[suggestion_part(code = "unsafe(")]
3027+
pub left: Span,
3028+
#[suggestion_part(code = ")")]
3029+
pub right: Span,
3030+
}

‎compiler/rustc_parse/src/validate_attr.rs

+58-6
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,73 @@ use crate::{errors, parse_in};
55
use rustc_ast::token::Delimiter;
66
use rustc_ast::tokenstream::DelimSpan;
77
use rustc_ast::MetaItemKind;
8-
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem};
8+
use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, Safety};
99
use rustc_errors::{Applicability, FatalError, PResult};
10-
use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
10+
use rustc_feature::{
11+
AttributeSafety, AttributeTemplate, BuiltinAttribute, Features, BUILTIN_ATTRIBUTE_MAP,
12+
};
1113
use rustc_session::errors::report_lit_error;
12-
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
14+
use rustc_session::lint::builtin::{ILL_FORMED_ATTRIBUTE_INPUT, UNSAFE_ATTR_OUTSIDE_UNSAFE};
1315
use rustc_session::lint::BuiltinLintDiag;
1416
use rustc_session::parse::ParseSess;
15-
use rustc_span::{sym, Span, Symbol};
17+
use rustc_span::{sym, BytePos, Span, Symbol};
1618

17-
pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
19+
pub fn check_attr(features: &Features, psess: &ParseSess, attr: &Attribute) {
1820
if attr.is_doc_comment() {
1921
return;
2022
}
2123

2224
let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
25+
let attr_item = attr.get_normal_item();
26+
27+
let is_unsafe_attr = attr_info.is_some_and(|attr| attr.safety == AttributeSafety::Unsafe);
28+
29+
if features.unsafe_attributes {
30+
if is_unsafe_attr {
31+
if let ast::Safety::Default = attr_item.unsafety {
32+
let path_span = attr_item.path.span;
33+
34+
// If the `attr_item`'s span is not from a macro, then just suggest
35+
// wrapping it in `unsafe(...)`. Otherwise, we suggest putting the
36+
// `unsafe(`, `)` right after and right before the opening and closing
37+
// square bracket respectively.
38+
let diag_span = if attr_item.span().can_be_used_for_suggestions() {
39+
attr_item.span()
40+
} else {
41+
attr.span
42+
.with_lo(attr.span.lo() + BytePos(2))
43+
.with_hi(attr.span.hi() - BytePos(1))
44+
};
45+
46+
if attr.span.at_least_rust_2024() {
47+
psess.dcx().emit_err(errors::UnsafeAttrOutsideUnsafe {
48+
span: path_span,
49+
suggestion: errors::UnsafeAttrOutsideUnsafeSuggestion {
50+
left: diag_span.shrink_to_lo(),
51+
right: diag_span.shrink_to_hi(),
52+
},
53+
});
54+
} else {
55+
psess.buffer_lint(
56+
UNSAFE_ATTR_OUTSIDE_UNSAFE,
57+
path_span,
58+
ast::CRATE_NODE_ID,
59+
BuiltinLintDiag::UnsafeAttrOutsideUnsafe {
60+
attribute_name_span: path_span,
61+
sugg_spans: (diag_span.shrink_to_lo(), diag_span.shrink_to_hi()),
62+
},
63+
);
64+
}
65+
}
66+
} else {
67+
if let Safety::Unsafe(unsafe_span) = attr_item.unsafety {
68+
psess.dcx().emit_err(errors::InvalidAttrUnsafe {
69+
span: unsafe_span,
70+
name: attr_item.path.clone(),
71+
});
72+
}
73+
}
74+
}
2375

2476
// Check input tokens for built-in and key-value attributes.
2577
match attr_info {
@@ -32,7 +84,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
3284
}
3385
}
3486
}
35-
_ if let AttrArgs::Eq(..) = attr.get_normal_item().args => {
87+
_ if let AttrArgs::Eq(..) = attr_item.args => {
3688
// All key-value attributes are restricted to meta-item syntax.
3789
match parse_meta(psess, attr) {
3890
Ok(_) => {}

‎compiler/rustc_passes/messages.ftl

-4
Original file line numberDiff line numberDiff line change
@@ -384,10 +384,6 @@ passes_invalid_attr_at_crate_level =
384384
passes_invalid_attr_at_crate_level_item =
385385
the inner attribute doesn't annotate this {$kind}
386386
387-
passes_invalid_attr_unsafe = `{$name}` is not an unsafe attribute
388-
.suggestion = remove the `unsafe(...)`
389-
.note = extraneous unsafe is not allowed in attributes
390-
391387
passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument
392388
393389
passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.