Skip to content

Commit 02e2766

Browse files
committed
Move naked fn checks to hir_typeck
1 parent 685d1c9 commit 02e2766

File tree

8 files changed

+73
-77
lines changed

8 files changed

+73
-77
lines changed

compiler/rustc_hir_typeck/messages.ftl

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,15 @@ hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on
140140
hir_typeck_naked_asm_outside_naked_fn =
141141
the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
142142
143+
hir_typeck_naked_functions_asm_block =
144+
naked functions must contain a single `naked_asm!` invocation
145+
.label_multiple_asm = multiple `naked_asm!` invocations are not allowed in naked functions
146+
.label_non_asm = not allowed in naked functions
147+
148+
hir_typeck_naked_functions_must_naked_asm =
149+
the `asm!` macro is not allowed in naked functions
150+
.label = consider using the `naked_asm!` macro instead
151+
143152
hir_typeck_never_type_fallback_flowing_into_unsafe_call = never type fallback affects this call to an `unsafe` function
144153
.help = specify the type explicitly
145154
hir_typeck_never_type_fallback_flowing_into_unsafe_deref = never type fallback affects this raw pointer dereference
@@ -162,6 +171,9 @@ hir_typeck_no_field_on_variant = no field named `{$field}` on enum variant `{$co
162171
hir_typeck_no_field_on_variant_enum = this enum variant...
163172
hir_typeck_no_field_on_variant_field = ...does not have this field
164173
174+
hir_typeck_no_patterns =
175+
patterns not allowed in naked function parameters
176+
165177
hir_typeck_note_caller_chooses_ty_for_ty_param = the caller chooses a type for `{$ty_param_name}` which can be different from `{$found_ty}`
166178
167179
hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
@@ -170,6 +182,10 @@ hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expecte
170182
hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}`
171183
hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}`
172184
185+
hir_typeck_params_not_allowed =
186+
referencing function parameters is not allowed in naked functions
187+
.help = follow the calling convention in asm block to use parameters
188+
173189
hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function
174190
.suggestion = cast the value to `{$cast_ty}`
175191
.teach_help = certain types, like `{$ty}`, must be cast before passing them to a variadic function to match the implicit cast that a C compiler would perform as part of C's numeric promotion rules

compiler/rustc_hir_typeck/src/errors.rs

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::borrow::Cow;
44

55
use rustc_errors::codes::*;
66
use rustc_errors::{
7-
Applicability, Diag, DiagArgValue, DiagSymbolList, EmissionGuarantee, IntoDiagArg, MultiSpan,
8-
Subdiagnostic,
7+
Applicability, Diag, DiagArgValue, DiagCtxtHandle, DiagSymbolList, Diagnostic,
8+
EmissionGuarantee, IntoDiagArg, Level, MultiSpan, Subdiagnostic,
99
};
1010
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
1111
use rustc_middle::ty::{self, Ty};
@@ -990,3 +990,48 @@ pub(crate) struct NakedAsmOutsideNakedFn {
990990
#[primary_span]
991991
pub span: Span,
992992
}
993+
994+
#[derive(Diagnostic)]
995+
#[diag(hir_typeck_no_patterns)]
996+
pub(crate) struct NoPatterns {
997+
#[primary_span]
998+
pub span: Span,
999+
}
1000+
1001+
#[derive(Diagnostic)]
1002+
#[diag(hir_typeck_params_not_allowed)]
1003+
#[help]
1004+
pub(crate) struct ParamsNotAllowed {
1005+
#[primary_span]
1006+
pub span: Span,
1007+
}
1008+
1009+
pub(crate) struct NakedFunctionsAsmBlock {
1010+
pub span: Span,
1011+
pub multiple_asms: Vec<Span>,
1012+
pub non_asms: Vec<Span>,
1013+
}
1014+
1015+
impl<G: EmissionGuarantee> Diagnostic<'_, G> for NakedFunctionsAsmBlock {
1016+
#[track_caller]
1017+
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
1018+
let mut diag = Diag::new(dcx, level, fluent::hir_typeck_naked_functions_asm_block);
1019+
diag.span(self.span);
1020+
diag.code(E0787);
1021+
for span in self.multiple_asms.iter() {
1022+
diag.span_label(*span, fluent::hir_typeck_label_multiple_asm);
1023+
}
1024+
for span in self.non_asms.iter() {
1025+
diag.span_label(*span, fluent::hir_typeck_label_non_asm);
1026+
}
1027+
diag
1028+
}
1029+
}
1030+
1031+
#[derive(Diagnostic)]
1032+
#[diag(hir_typeck_naked_functions_must_naked_asm, code = E0787)]
1033+
pub(crate) struct NakedFunctionsMustNakedAsm {
1034+
#[primary_span]
1035+
#[label]
1036+
pub span: Span,
1037+
}

compiler/rustc_hir_typeck/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ mod fn_ctxt;
3131
mod gather_locals;
3232
mod intrinsicck;
3333
mod method;
34+
mod naked_functions;
3435
mod op;
3536
mod opaque_types;
3637
mod pat;
@@ -171,7 +172,7 @@ fn typeck_with_inspect<'tcx>(
171172
);
172173

173174
if tcx.has_attr(def_id, sym::naked) {
174-
tcx.typeck_naked_fn(def_id, body);
175+
naked_functions::typeck_naked_fn(tcx, def_id, body);
175176
}
176177

177178
check_fn(&mut fcx, fn_sig, None, decl, def_id, body, tcx.features().unsized_fn_params());

compiler/rustc_passes/src/naked_functions.rs renamed to compiler/rustc_hir_typeck/src/naked_functions.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,20 @@ use rustc_hir::intravisit::Visitor;
66
use rustc_hir::{ExprKind, HirIdSet, StmtKind};
77
use rustc_middle::span_bug;
88
use rustc_middle::ty::TyCtxt;
9-
use rustc_middle::util::Providers;
109
use rustc_span::{Span, sym};
1110

1211
use crate::errors::{
1312
NakedFunctionsAsmBlock, NakedFunctionsMustNakedAsm, NoPatterns, ParamsNotAllowed,
1413
};
1514

16-
pub(crate) fn provide(providers: &mut Providers) {
17-
providers.hooks.typeck_naked_fn = typeck_naked_fn;
18-
}
19-
20-
fn typeck_naked_fn<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId, body: &'tcx hir::Body<'tcx>) {
15+
/// Naked fns can only have trivial binding patterns in arguments,
16+
/// may not actually use those arguments, and the body must consist of just
17+
/// a single asm statement.
18+
pub(crate) fn typeck_naked_fn<'tcx>(
19+
tcx: TyCtxt<'tcx>,
20+
def_id: LocalDefId,
21+
body: &'tcx hir::Body<'tcx>,
22+
) {
2123
debug_assert!(tcx.has_attr(def_id, sym::naked));
2224
check_no_patterns(tcx, body.params);
2325
check_no_parameters_use(tcx, body);

compiler/rustc_middle/src/hooks/mod.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,6 @@ declare_hooks! {
102102
/// Ensure the given scalar is valid for the given type.
103103
/// This checks non-recursive runtime validity.
104104
hook validate_scalar_in_layout(scalar: crate::ty::ScalarInt, ty: Ty<'tcx>) -> bool;
105-
106-
/// Naked fns can only have trivial binding patterns in arguments,
107-
/// may not actually use those arguments, and the body must consist of just
108-
/// a single asm statement.
109-
hook typeck_naked_fn(def_id: LocalDefId, body: &'tcx rustc_hir::Body<'tcx>) -> ();
110105
}
111106

112107
#[cold]

compiler/rustc_passes/messages.ftl

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -509,20 +509,11 @@ passes_must_not_suspend =
509509
passes_must_use_no_effect =
510510
`#[must_use]` has no effect when applied to {$article} {$target}
511511
512-
passes_naked_functions_asm_block =
513-
naked functions must contain a single `naked_asm!` invocation
514-
.label_multiple_asm = multiple `naked_asm!` invocations are not allowed in naked functions
515-
.label_non_asm = not allowed in naked functions
516-
517512
passes_naked_functions_incompatible_attribute =
518513
attribute incompatible with `#[unsafe(naked)]`
519514
.label = the `{$attr}` attribute is incompatible with `#[unsafe(naked)]`
520515
.naked_attribute = function marked with `#[unsafe(naked)]` here
521516
522-
passes_naked_functions_must_naked_asm =
523-
the `asm!` macro is not allowed in naked functions
524-
.label = consider using the `naked_asm!` macro instead
525-
526517
passes_no_link =
527518
attribute should be applied to an `extern crate` item
528519
.label = not an `extern crate` item
@@ -553,9 +544,6 @@ passes_no_mangle_foreign =
553544
.note = symbol names in extern blocks are not mangled
554545
.suggestion = remove this attribute
555546
556-
passes_no_patterns =
557-
patterns not allowed in naked function parameters
558-
559547
passes_no_sanitize =
560548
`#[no_sanitize({$attr_str})]` should be applied to {$accepted_kind}
561549
.label = not {$accepted_kind}
@@ -603,10 +591,6 @@ passes_panic_unwind_without_std =
603591
.note = since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
604592
.help = using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding
605593
606-
passes_params_not_allowed =
607-
referencing function parameters is not allowed in naked functions
608-
.help = follow the calling convention in asm block to use parameters
609-
610594
passes_parent_info =
611595
{$num ->
612596
[one] {$descr}

compiler/rustc_passes/src/errors.rs

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,51 +1196,6 @@ pub(crate) struct UnlabeledCfInWhileCondition<'a> {
11961196
pub cf_type: &'a str,
11971197
}
11981198

1199-
#[derive(Diagnostic)]
1200-
#[diag(passes_no_patterns)]
1201-
pub(crate) struct NoPatterns {
1202-
#[primary_span]
1203-
pub span: Span,
1204-
}
1205-
1206-
#[derive(Diagnostic)]
1207-
#[diag(passes_params_not_allowed)]
1208-
#[help]
1209-
pub(crate) struct ParamsNotAllowed {
1210-
#[primary_span]
1211-
pub span: Span,
1212-
}
1213-
1214-
pub(crate) struct NakedFunctionsAsmBlock {
1215-
pub span: Span,
1216-
pub multiple_asms: Vec<Span>,
1217-
pub non_asms: Vec<Span>,
1218-
}
1219-
1220-
impl<G: EmissionGuarantee> Diagnostic<'_, G> for NakedFunctionsAsmBlock {
1221-
#[track_caller]
1222-
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
1223-
let mut diag = Diag::new(dcx, level, fluent::passes_naked_functions_asm_block);
1224-
diag.span(self.span);
1225-
diag.code(E0787);
1226-
for span in self.multiple_asms.iter() {
1227-
diag.span_label(*span, fluent::passes_label_multiple_asm);
1228-
}
1229-
for span in self.non_asms.iter() {
1230-
diag.span_label(*span, fluent::passes_label_non_asm);
1231-
}
1232-
diag
1233-
}
1234-
}
1235-
1236-
#[derive(Diagnostic)]
1237-
#[diag(passes_naked_functions_must_naked_asm, code = E0787)]
1238-
pub(crate) struct NakedFunctionsMustNakedAsm {
1239-
#[primary_span]
1240-
#[label]
1241-
pub span: Span,
1242-
}
1243-
12441199
#[derive(Diagnostic)]
12451200
#[diag(passes_naked_functions_incompatible_attribute, code = E0736)]
12461201
pub(crate) struct NakedFunctionIncompatibleAttribute {

compiler/rustc_passes/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ pub mod layout_test;
3232
mod lib_features;
3333
mod liveness;
3434
pub mod loops;
35-
mod naked_functions;
3635
mod reachable;
3736
pub mod stability;
3837
mod upvars;
@@ -49,7 +48,6 @@ pub fn provide(providers: &mut Providers) {
4948
lang_items::provide(providers);
5049
lib_features::provide(providers);
5150
loops::provide(providers);
52-
naked_functions::provide(providers);
5351
liveness::provide(providers);
5452
reachable::provide(providers);
5553
stability::provide(providers);

0 commit comments

Comments
 (0)