|
1 | 1 | //! Checks validity of naked functions.
|
2 | 2 |
|
3 | 3 | use rustc_hir as hir;
|
4 |
| -use rustc_hir::def::DefKind; |
5 |
| -use rustc_hir::def_id::{LocalDefId, LocalModDefId}; |
| 4 | +use rustc_hir::def_id::LocalDefId; |
6 | 5 | use rustc_hir::intravisit::Visitor;
|
7 | 6 | use rustc_hir::{ExprKind, HirIdSet, StmtKind};
|
8 |
| -use rustc_middle::hir::nested_filter::OnlyBodies; |
9 |
| -use rustc_middle::query::Providers; |
10 | 7 | use rustc_middle::span_bug;
|
11 | 8 | use rustc_middle::ty::TyCtxt;
|
12 | 9 | use rustc_span::{Span, sym};
|
13 | 10 |
|
14 | 11 | use crate::errors::{
|
15 |
| - NakedAsmOutsideNakedFn, NakedFunctionsAsmBlock, NakedFunctionsMustNakedAsm, NoPatterns, |
16 |
| - ParamsNotAllowed, |
| 12 | + NakedFunctionsAsmBlock, NakedFunctionsMustNakedAsm, NoPatterns, ParamsNotAllowed, |
17 | 13 | };
|
18 | 14 |
|
19 |
| -pub(crate) fn provide(providers: &mut Providers) { |
20 |
| - *providers = Providers { check_mod_naked_functions, ..*providers }; |
21 |
| -} |
22 |
| - |
23 |
| -fn check_mod_naked_functions(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { |
24 |
| - let items = tcx.hir_module_items(module_def_id); |
25 |
| - for def_id in items.definitions() { |
26 |
| - if !matches!(tcx.def_kind(def_id), DefKind::Fn | DefKind::AssocFn) { |
27 |
| - continue; |
28 |
| - } |
29 |
| - |
30 |
| - let body = match tcx.hir_node_by_def_id(def_id) { |
31 |
| - hir::Node::Item(hir::Item { |
32 |
| - kind: hir::ItemKind::Fn { body: body_id, .. }, .. |
33 |
| - }) |
34 |
| - | hir::Node::TraitItem(hir::TraitItem { |
35 |
| - kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body_id)), |
36 |
| - .. |
37 |
| - }) |
38 |
| - | hir::Node::ImplItem(hir::ImplItem { |
39 |
| - kind: hir::ImplItemKind::Fn(_, body_id), .. |
40 |
| - }) => tcx.hir_body(*body_id), |
41 |
| - _ => continue, |
42 |
| - }; |
43 |
| - |
44 |
| - if tcx.has_attr(def_id, sym::naked) { |
45 |
| - check_no_patterns(tcx, body.params); |
46 |
| - check_no_parameters_use(tcx, body); |
47 |
| - check_asm(tcx, def_id, body); |
48 |
| - } else { |
49 |
| - // `naked_asm!` is not allowed outside of functions marked as `#[naked]` |
50 |
| - let mut visitor = CheckNakedAsmInNakedFn { tcx }; |
51 |
| - visitor.visit_body(body); |
52 |
| - } |
53 |
| - } |
| 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 | +) { |
| 23 | + debug_assert!(tcx.has_attr(def_id, sym::naked)); |
| 24 | + check_no_patterns(tcx, body.params); |
| 25 | + check_no_parameters_use(tcx, body); |
| 26 | + check_asm(tcx, def_id, body); |
54 | 27 | }
|
55 | 28 |
|
56 | 29 | /// Checks that parameters don't use patterns. Mirrors the checks for function declarations.
|
@@ -231,25 +204,3 @@ impl<'tcx> Visitor<'tcx> for CheckInlineAssembly {
|
231 | 204 | self.check_expr(expr, expr.span);
|
232 | 205 | }
|
233 | 206 | }
|
234 |
| - |
235 |
| -struct CheckNakedAsmInNakedFn<'tcx> { |
236 |
| - tcx: TyCtxt<'tcx>, |
237 |
| -} |
238 |
| - |
239 |
| -impl<'tcx> Visitor<'tcx> for CheckNakedAsmInNakedFn<'tcx> { |
240 |
| - type NestedFilter = OnlyBodies; |
241 |
| - |
242 |
| - fn maybe_tcx(&mut self) -> Self::MaybeTyCtxt { |
243 |
| - self.tcx |
244 |
| - } |
245 |
| - |
246 |
| - fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { |
247 |
| - if let ExprKind::InlineAsm(inline_asm) = expr.kind { |
248 |
| - if let rustc_ast::AsmMacro::NakedAsm = inline_asm.asm_macro { |
249 |
| - self.tcx.dcx().emit_err(NakedAsmOutsideNakedFn { span: expr.span }); |
250 |
| - } |
251 |
| - } |
252 |
| - |
253 |
| - hir::intravisit::walk_expr(self, expr); |
254 |
| - } |
255 |
| -} |
0 commit comments