Skip to content

Commit ee7a87a

Browse files
move check_naked() from check_attr.rs to codegen_attrs.rs
Signed-off-by: Richard Tjokroutomo <richard.tjokro2@gmail.com>
1 parent eca445e commit ee7a87a

9 files changed

Lines changed: 81 additions & 31 deletions

File tree

‎compiler/rustc_ast/src/ast.rs‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3790,6 +3790,25 @@ impl Extern {
37903790
Extern::Implicit(span) | Extern::Explicit(_, span) => Some(span),
37913791
}
37923792
}
3793+
3794+
/// An ABI "like Rust"
3795+
///
3796+
/// These ABIs are fully controlled by the Rust compiler, which means they
3797+
/// - support unwinding with `-Cpanic=unwind`, unlike `extern "C"`
3798+
/// - often diverge from the C ABI
3799+
/// - are subject to change between compiler versions
3800+
pub fn is_rustic_abi(self) -> bool {
3801+
match self {
3802+
Extern::None => true,
3803+
Extern::Implicit(_) => false,
3804+
Extern::Explicit(name, _) => {
3805+
matches!(
3806+
name.symbol_unescaped.as_str(),
3807+
"Rust" | "rust-call" | "rust-cold" | "rust-preserve-none" | "rust-tail"
3808+
)
3809+
}
3810+
}
3811+
}
37933812
}
37943813

37953814
/// A function header.

‎compiler/rustc_ast_lowering/src/expr.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
230230
let old_attrs =
231231
self.curr_owner.attrs.get(&ex.hir_id.local_id).copied().unwrap_or(&[]);
232232
let new_attrs = self
233-
.lower_attrs_vec(&e.attrs, e.span, ex.hir_id, Target::from_expr(e))
233+
.lower_attrs_vec(&e.attrs, e.span, ex.hir_id, Target::from_expr(e), None)
234234
.into_iter()
235235
.chain(old_attrs.iter().cloned());
236236
let new_attrs = &*self.arena.alloc_from_iter(new_attrs);

‎compiler/rustc_ast_lowering/src/item.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
215215
&i.attrs,
216216
i.span,
217217
Target::from_ast_item(i),
218+
Some(i),
218219
&extra_hir_attributes,
219220
);
220221

‎compiler/rustc_ast_lowering/src/lib.rs‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,7 +1182,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
11821182
target_span: Span,
11831183
target: Target,
11841184
) -> &'hir [hir::Attribute] {
1185-
self.lower_attrs_with_extra(id, attrs, target_span, target, &[])
1185+
self.lower_attrs_with_extra(id, attrs, target_span, target, None, &[])
11861186
}
11871187

11881188
fn lower_attrs_with_extra(
@@ -1191,13 +1191,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
11911191
attrs: &[Attribute],
11921192
target_span: Span,
11931193
target: Target,
1194+
target_item: Option<&ast::Item>,
11941195
extra_hir_attributes: &[hir::Attribute],
11951196
) -> &'hir [hir::Attribute] {
11961197
if attrs.is_empty() && extra_hir_attributes.is_empty() {
11971198
&[]
11981199
} else {
11991200
let mut lowered_attrs =
1200-
self.lower_attrs_vec(attrs, self.lower_span(target_span), id, target);
1201+
self.lower_attrs_vec(attrs, self.lower_span(target_span), id, target, target_item);
12011202
lowered_attrs.extend(extra_hir_attributes.iter().cloned());
12021203

12031204
assert_eq!(id.owner, self.curr_owner.owner_id);
@@ -1224,12 +1225,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
12241225
target_span: Span,
12251226
target_hir_id: HirId,
12261227
target: Target,
1228+
target_item: Option<&ast::Item>,
12271229
) -> Vec<hir::Attribute> {
12281230
let l = self.span_lowerer();
12291231
self.attribute_parser.parse_attribute_list(
12301232
attrs,
12311233
target_span,
12321234
target,
1235+
target_item,
12331236
|s| l.lower(s),
12341237
|lint_id, span, kind| {
12351238
self.curr_owner.delayed_lints.push(DelayedLint {

‎compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use rustc_ast::ItemKind;
12
use rustc_attr_ir::{
23
CoverageAttrKind, InstrumentFnAttr, OptimizeAttr, RtsanSetting, UsedBy, find_attr,
34
};
@@ -8,6 +9,7 @@ use rustc_structures::SanitizerSet;
89

910
use super::prelude::*;
1011
use crate::attributes::AttributeSafety;
12+
use crate::context::FinalizeCheckFn;
1113
use crate::diagnostics::{
1214
EmptyExportName, EmptySection, NakedFunctionIncompatibleAttribute, NullOnExport,
1315
NullOnObjcClass, NullOnObjcSelector, NullOnSection, ObjcClassExpectedStringLiteral,
@@ -327,6 +329,50 @@ impl AttributeParser for NakedParser {
327329

328330
Some(AttributeKind::Naked(span))
329331
}
332+
333+
fn deferred_finalize_check(&self) -> Option<(FinalizeCheckFn, Span)> {
334+
Some((
335+
|cx, _span| match cx.target {
336+
Target::Fn
337+
| Target::Method(
338+
MethodKind::Trait { body: true } | MethodKind::TraitImpl | MethodKind::Inherent,
339+
) => {
340+
let Some(item) = cx.target_item else {
341+
return;
342+
};
343+
344+
let ItemKind::Fn(fn_item) = &item.kind else {
345+
return;
346+
};
347+
348+
let fn_sig = &fn_item.sig;
349+
let abi = fn_sig.header.ext;
350+
351+
if abi.is_rustic_abi() && !cx.features().naked_functions_rustic_abi() {
352+
let abi_type = match abi {
353+
rustc_ast::ast::Extern::None => "Rust".into(),
354+
rustc_ast::ast::Extern::Explicit(name, _) => {
355+
name.symbol_unescaped.to_string()
356+
}
357+
rustc_ast::ast::Extern::Implicit(_) => unreachable!(),
358+
};
359+
feature_err(
360+
cx.sess(),
361+
sym::naked_functions_rustic_abi,
362+
fn_sig.span,
363+
format!(
364+
"`#[naked]` is currently unstable on `extern \"{}\"` functions",
365+
abi_type
366+
),
367+
)
368+
.emit();
369+
}
370+
}
371+
_ => {}
372+
},
373+
self.span?,
374+
))
375+
}
330376
}
331377

332378
pub(crate) struct TrackCallerParser;

‎compiler/rustc_attr_parsing/src/context.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,10 @@ pub(crate) struct FinalizeCheckContext<'p, 'sess> {
833833
///
834834
/// Unlike [`all_attrs`](Self::all_attrs), this contains the fully parsed attributes.
835835
pub(crate) parsed_attrs: &'p [Attribute],
836+
837+
/// The AST item these attributes were applied to, when the target is an item.
838+
/// Used by `finalize_check` to inspect item structure that is not encoded in [`Target`].
839+
pub(crate) target_item: Option<&'p rustc_ast::ast::Item>,
836840
}
837841

838842
impl<'p, 'sess: 'p> Deref for FinalizeCheckContext<'p, 'sess> {

‎compiler/rustc_attr_parsing/src/interface.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ impl<'sess> AttributeParser<'sess> {
161161
attrs,
162162
target_span,
163163
target,
164+
None,
164165
std::convert::identity,
165166
|lint_id, span, kind| {
166167
sess.psess.dyn_buffer_lint_sess(lint_id.lint, span, target_node_id, kind.0)
@@ -315,6 +316,7 @@ impl<'sess> AttributeParser<'sess> {
315316
attrs: &[ast::Attribute],
316317
target_span: Span,
317318
target: Target,
319+
target_item: Option<&ast::Item>,
318320
lower_span: impl Copy + Fn(Span) -> Span,
319321
mut emit_lint: impl FnMut(LintId, MultiSpan, EmitAttribute),
320322
) -> Vec<Attribute> {
@@ -521,6 +523,7 @@ impl<'sess> AttributeParser<'sess> {
521523
},
522524
all_attrs: &attr_paths,
523525
parsed_attrs: &attributes,
526+
target_item,
524527
},
525528
attr_span,
526529
);

‎compiler/rustc_passes/src/check_attr.rs‎

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ use rustc_middle::traits::ObligationCause;
4040
use rustc_middle::ty::error::{ExpectedFound, TypeError};
4141
use rustc_middle::ty::{self, TyCtxt, TypingMode, Unnormalized};
4242
use rustc_middle::{bug, span_bug};
43-
use rustc_session::diagnostics::feature_err;
4443
use rustc_span::edition::Edition;
4544
use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
4645
use rustc_structures::CrateType;
@@ -207,7 +206,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
207206
AttributeKind::RustcAllowConstFnUnstable(_, first_span) => {
208207
self.check_rustc_allow_const_fn_unstable(hir_id, *first_span, span, target)
209208
}
210-
AttributeKind::Naked(..) => self.check_naked(hir_id, target),
211209
AttributeKind::NonExhaustive(attr_span) => {
212210
self.check_non_exhaustive(*attr_span, span, target, item)
213211
}
@@ -284,6 +282,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
284282
AttributeKind::MoveSizeLimit { .. } => (),
285283
AttributeKind::MustNotSupend { .. } => (),
286284
AttributeKind::MustUse { .. } => (),
285+
AttributeKind::Naked(..) => (),
287286
AttributeKind::NeedsAllocator => (),
288287
AttributeKind::NeedsPanicRuntime => (),
289288
AttributeKind::NoBuiltins => (),
@@ -771,32 +770,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
771770
}
772771
}
773772

774-
/// Checks if `#[naked]` is applied to a function definition.
775-
fn check_naked(&self, hir_id: HirId, target: Target) {
776-
match target {
777-
Target::Fn
778-
| Target::Method(
779-
MethodKind::Trait { body: true } | MethodKind::TraitImpl | MethodKind::Inherent,
780-
) => {
781-
let fn_sig = self.tcx.hir_node(hir_id).fn_sig().unwrap();
782-
let abi = fn_sig.header.abi;
783-
if abi.is_rustic_abi() && !self.tcx.features().naked_functions_rustic_abi() {
784-
feature_err(
785-
&self.tcx.sess,
786-
sym::naked_functions_rustic_abi,
787-
fn_sig.span,
788-
format!(
789-
"`#[naked]` is currently unstable on `extern \"{}\"` functions",
790-
abi.as_str()
791-
),
792-
)
793-
.emit();
794-
}
795-
}
796-
_ => {}
797-
}
798-
}
799-
800773
/// Checks if the `#[non_exhaustive]` attribute on an `item` is valid.
801774
fn check_non_exhaustive(
802775
&self,

‎compiler/rustc_resolve/src/def_collector.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
188188
&i.attrs,
189189
i.span,
190190
Target::MacroDef,
191+
None,
191192
std::convert::identity,
192193
|_lint_id, _span, _kind| {
193194
// FIXME(jdonszelmann): emit lints here properly

0 commit comments

Comments
 (0)