Line data Source code
1 : // Copyright (C) 2020-2026 Free Software Foundation, Inc.
2 :
3 : // This file is part of GCC.
4 :
5 : // GCC is free software; you can redistribute it and/or modify it under
6 : // the terms of the GNU General Public License as published by the Free
7 : // Software Foundation; either version 3, or (at your option) any later
8 : // version.
9 :
10 : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : // for more details.
14 :
15 : // You should have received a copy of the GNU General Public License
16 : // along with GCC; see the file COPYING3. If not see
17 : // <http://www.gnu.org/licenses/>.
18 :
19 : #include "rust-ast-visitor.h"
20 : #include "rust-system.h"
21 : #include "rust-session-manager.h"
22 : #include "rust-attributes.h"
23 : #include "rust-ast.h"
24 : #include "rust-ast-full.h"
25 : #include "rust-diagnostics.h"
26 : #include "rust-unicode.h"
27 : #include "rust-attribute-values.h"
28 :
29 : namespace Rust {
30 : namespace Analysis {
31 :
32 : bool
33 28990 : Attributes::is_known (const std::string &attribute_path)
34 : {
35 28990 : const auto &lookup
36 28990 : = BuiltinAttributeMappings::get ()->lookup_builtin (attribute_path);
37 :
38 28990 : return !lookup.is_error ();
39 : }
40 :
41 : tl::optional<std::string>
42 6460 : Attributes::extract_string_literal (const AST::Attribute &attr)
43 : {
44 6460 : if (!attr.has_attr_input ())
45 0 : return tl::nullopt;
46 :
47 6460 : auto &attr_input = attr.get_attr_input ();
48 :
49 6460 : if (attr_input.get_attr_input_type ()
50 : != AST::AttrInput::AttrInputType::LITERAL)
51 2 : return tl::nullopt;
52 :
53 6458 : auto &literal_expr
54 6458 : = static_cast<AST::AttrInputLiteral &> (attr_input).get_literal ();
55 :
56 6458 : auto lit_type = literal_expr.get_lit_type ();
57 :
58 : // TODO: bring escape sequence handling out of lexing?
59 6458 : if (lit_type != AST::Literal::LitType::STRING
60 6458 : && lit_type != AST::Literal::LitType::RAW_STRING)
61 2 : return tl::nullopt;
62 :
63 6456 : return literal_expr.as_string ();
64 : }
65 :
66 : using Attrs = Values::Attributes;
67 :
68 : // https://doc.rust-lang.org/stable/nightly-rustc/src/rustc_feature/builtin_attrs.rs.html#248
69 : static const BuiltinAttrDefinition __definitions[]
70 : = {{Attrs::INLINE, CODE_GENERATION},
71 : {Attrs::COLD, CODE_GENERATION},
72 : {Attrs::CFG, EXPANSION},
73 : {Attrs::CFG_ATTR, EXPANSION},
74 : {Attrs::DERIVE_ATTR, EXPANSION},
75 : {Attrs::DEPRECATED, STATIC_ANALYSIS},
76 : {Attrs::ALLOW, STATIC_ANALYSIS},
77 : {Attrs::ALLOW_INTERNAL_UNSTABLE, STATIC_ANALYSIS},
78 : {Attrs::DOC, HIR_LOWERING},
79 : {Attrs::MUST_USE, STATIC_ANALYSIS},
80 : {Attrs::LANG, HIR_LOWERING},
81 : {Attrs::LINK_NAME, CODE_GENERATION},
82 : {Attrs::LINK_SECTION, CODE_GENERATION},
83 : {Attrs::NO_MANGLE, CODE_GENERATION},
84 : {Attrs::EXPORT_NAME, CODE_GENERATION},
85 : {Attrs::REPR, CODE_GENERATION},
86 : {Attrs::RUSTC_BUILTIN_MACRO, EXPANSION},
87 : {Attrs::RUSTC_MACRO_TRANSPARENCY, EXPANSION},
88 : {Attrs::PATH, EXPANSION},
89 : {Attrs::MACRO_USE, NAME_RESOLUTION},
90 : {Attrs::MACRO_EXPORT, NAME_RESOLUTION},
91 : {Attrs::PROC_MACRO, EXPANSION},
92 : {Attrs::PROC_MACRO_DERIVE, EXPANSION},
93 : {Attrs::PROC_MACRO_ATTRIBUTE, EXPANSION},
94 : // FIXME: This is not implemented yet, see
95 : // https://github.com/Rust-GCC/gccrs/issues/1475
96 : {Attrs::TARGET_FEATURE, CODE_GENERATION},
97 : // From now on, these are reserved by the compiler and gated through
98 : // #![feature(rustc_attrs)]
99 : {Attrs::RUSTC_DEPRECATED, STATIC_ANALYSIS},
100 : {Attrs::RUSTC_INHERIT_OVERFLOW_CHECKS, CODE_GENERATION},
101 : {Attrs::STABLE, STATIC_ANALYSIS},
102 : {Attrs::UNSTABLE, STATIC_ANALYSIS},
103 : // assuming we keep these for static analysis
104 : {Attrs::RUSTC_PROMOTABLE, CODE_GENERATION},
105 : {Attrs::RUSTC_CONST_STABLE, STATIC_ANALYSIS},
106 : {Attrs::RUSTC_CONST_UNSTABLE, STATIC_ANALYSIS},
107 : {Attrs::RUSTC_ALLOW_CONST_FN_UNSTABLE, STATIC_ANALYSIS},
108 : {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
109 : {Attrs::TRACK_CALLER, CODE_GENERATION},
110 : {Attrs::RUSTC_SPECIALIZATION_TRAIT, TYPE_CHECK},
111 : {Attrs::RUSTC_UNSAFE_SPECIALIZATION_MARKER, TYPE_CHECK},
112 : {Attrs::RUSTC_RESERVATION_IMPL, TYPE_CHECK},
113 : {Attrs::RUSTC_PAREN_SUGAR, TYPE_CHECK},
114 : {Attrs::RUSTC_NONNULL_OPTIMIZATION_GUARANTEED, TYPE_CHECK},
115 : {Attrs::RUSTC_LAYOUT_SCALAR_VALID_RANGE_START, CODE_GENERATION},
116 : // TODO: be careful about calling functions marked with this?
117 : {Attrs::RUSTC_ARGS_REQUIRED_CONST, CODE_GENERATION},
118 : {Attrs::PRELUDE_IMPORT, NAME_RESOLUTION},
119 : {Attrs::RUSTC_DIAGNOSTIC_ITEM, STATIC_ANALYSIS},
120 : {Attrs::RUSTC_ON_UNIMPLEMENTED, STATIC_ANALYSIS},
121 : {Attrs::FUNDAMENTAL, TYPE_CHECK},
122 : {Attrs::NON_EXHAUSTIVE, TYPE_CHECK},
123 : {Attrs::RUSTFMT, EXTERNAL},
124 : {Attrs::TEST, CODE_GENERATION}};
125 :
126 : static const std::set<std::string> __outer_attributes
127 : = {Attrs::INLINE,
128 : Attrs::DERIVE_ATTR,
129 : Attrs::ALLOW_INTERNAL_UNSTABLE,
130 : Attrs::LANG,
131 : Attrs::REPR,
132 : Attrs::PATH,
133 : Attrs::TARGET_FEATURE,
134 : Attrs::TEST,
135 : Attrs::COLD,
136 : Attrs::MACRO_USE,
137 : Attrs::MACRO_EXPORT,
138 : Attrs::PROC_MACRO_ATTRIBUTE,
139 : Attrs::PROC_MACRO_DERIVE,
140 : Attrs::DEPRECATED,
141 : Attrs::MUST_USE,
142 : Attrs::LINK_NAME,
143 : Attrs::LINK_SECTION};
144 :
145 : BuiltinAttributeMappings *
146 487782 : BuiltinAttributeMappings::get ()
147 : {
148 487782 : static BuiltinAttributeMappings *instance = nullptr;
149 487782 : if (instance == nullptr)
150 4510 : instance = new BuiltinAttributeMappings ();
151 :
152 487782 : return instance;
153 : }
154 :
155 : const BuiltinAttrDefinition &
156 107073 : BuiltinAttributeMappings::lookup_builtin (const std::string &attr_name) const
157 : {
158 107073 : auto it = mappings.find (attr_name);
159 107073 : if (it == mappings.end ())
160 22228 : return BuiltinAttrDefinition::error_node ();
161 :
162 84845 : return it->second;
163 : }
164 :
165 4510 : BuiltinAttributeMappings::BuiltinAttributeMappings ()
166 : {
167 4510 : size_t ndefinitions = sizeof (__definitions) / sizeof (BuiltinAttrDefinition);
168 225500 : for (size_t i = 0; i < ndefinitions; i++)
169 : {
170 220990 : const BuiltinAttrDefinition &def = __definitions[i];
171 441980 : mappings.insert ({def.name, def});
172 : }
173 4510 : }
174 :
175 4510 : AttributeChecker::AttributeChecker () {}
176 :
177 : void
178 4510 : AttributeChecker::go (AST::Crate &crate)
179 : {
180 4510 : visit (crate);
181 4510 : }
182 :
183 : void
184 4510 : AttributeChecker::visit (AST::Crate &crate)
185 : {
186 15737 : for (auto &attr : crate.get_inner_attrs ())
187 : {
188 11227 : check_inner_attribute (attr);
189 11227 : check_attribute (attr);
190 : }
191 :
192 22786 : for (auto &item : crate.items)
193 18276 : item->accept_vis (*this);
194 4510 : }
195 :
196 : static bool
197 33899 : is_builtin (const AST::Attribute &attribute, BuiltinAttrDefinition &builtin)
198 : {
199 33899 : auto &segments = attribute.get_path ().get_segments ();
200 :
201 : // Builtin attributes always have a single segment. This avoids us creating
202 : // strings all over the place and performing a linear search in the builtins
203 : // map
204 33899 : if (segments.size () != 1)
205 : return false;
206 :
207 33899 : builtin = BuiltinAttributeMappings::get ()->lookup_builtin (
208 33899 : segments.at (0).get_segment_name ());
209 :
210 33899 : return !builtin.is_error ();
211 : }
212 :
213 : /**
214 : * Check that the string given to #[doc(alias = ...)] or #[doc(alias(...))] is
215 : * valid.
216 : *
217 : * This means no whitespace characters other than spaces and no quoting
218 : * characters.
219 : */
220 : static void
221 700 : check_doc_alias (const std::string &alias_input, const location_t locus)
222 : {
223 : // FIXME: The locus here is for the whole attribute. Can we get the locus
224 : // of the alias input instead?
225 1872 : for (auto c : alias_input)
226 1172 : if ((ISSPACE (c) && c != ' ') || c == '\'' || c == '\"')
227 : {
228 7 : auto to_print = std::string (1, c);
229 7 : switch (c)
230 : {
231 7 : case '\n':
232 7 : to_print = "\\n";
233 7 : break;
234 0 : case '\t':
235 0 : to_print = "\\t";
236 0 : break;
237 : default:
238 : break;
239 : }
240 7 : rust_error_at (locus,
241 : "invalid character used in %<#[doc(alias)]%> input: %qs",
242 : to_print.c_str ());
243 7 : }
244 :
245 700 : if (alias_input.empty ())
246 : return;
247 :
248 1400 : if (alias_input.front () == ' ' || alias_input.back () == ' ')
249 0 : rust_error_at (locus,
250 : "%<#[doc(alias)]%> input cannot start or end with a space");
251 : }
252 :
253 : static void
254 877 : check_doc_attribute (const AST::Attribute &attribute)
255 : {
256 877 : if (!attribute.has_attr_input ())
257 : {
258 1 : rust_error_at (
259 : attribute.get_locus (),
260 : "valid forms for the attribute are "
261 : "%<#[doc(hidden|inline|...)]%> and %<#[doc = \" string \"]%>");
262 1 : return;
263 : }
264 :
265 876 : switch (attribute.get_attr_input ().get_attr_input_type ())
266 : {
267 : case AST::AttrInput::LITERAL:
268 : case AST::AttrInput::MACRO:
269 : case AST::AttrInput::META_ITEM:
270 : break;
271 : // FIXME: Handle them as well
272 :
273 742 : case AST::AttrInput::TOKEN_TREE:
274 742 : {
275 : // FIXME: This doesn't check for #[doc(alias(...))]
276 742 : const auto &option = static_cast<const AST::DelimTokenTree &> (
277 742 : attribute.get_attr_input ());
278 742 : auto *meta_item = option.parse_to_meta_item ();
279 :
280 1491 : for (auto &item : meta_item->get_items ())
281 : {
282 749 : if (item->is_key_value_pair ())
283 : {
284 707 : auto name_value
285 707 : = static_cast<AST::MetaNameValueStr *> (item.get ())
286 707 : ->get_name_value_pair ();
287 :
288 : // FIXME: Check for other stuff than #[doc(alias = ...)]
289 707 : if (name_value.first.as_string () == "alias")
290 700 : check_doc_alias (name_value.second, attribute.get_locus ());
291 707 : }
292 : }
293 : break;
294 : }
295 : }
296 : }
297 :
298 : static void
299 1 : check_deprecated_attribute (const AST::Attribute &attribute)
300 : {
301 1 : if (!attribute.has_attr_input ())
302 : return;
303 :
304 0 : const auto &input = attribute.get_attr_input ();
305 :
306 0 : if (input.get_attr_input_type () != AST::AttrInput::META_ITEM)
307 : return;
308 :
309 0 : auto &meta = static_cast<const AST::AttrInputMetaItemContainer &> (input);
310 :
311 0 : for (auto ¤t : meta.get_items ())
312 : {
313 0 : switch (current->get_kind ())
314 : {
315 0 : case AST::MetaItemInner::Kind::MetaItem:
316 0 : {
317 0 : auto *meta_item = static_cast<AST::MetaItem *> (current.get ());
318 :
319 0 : switch (meta_item->get_item_kind ())
320 : {
321 0 : case AST::MetaItem::ItemKind::NameValueStr:
322 0 : {
323 0 : auto *nv = static_cast<AST::MetaNameValueStr *> (meta_item);
324 :
325 0 : const std::string key = nv->get_name ().as_string ();
326 :
327 0 : if (key != "since" && key != "note")
328 : {
329 0 : rust_error_at (nv->get_locus (), "unknown meta item %qs",
330 : key.c_str ());
331 0 : rust_inform (nv->get_locus (),
332 : "expected one of %<since%>, %<note%>");
333 : }
334 0 : }
335 0 : break;
336 :
337 0 : case AST::MetaItem::ItemKind::Path:
338 0 : {
339 : // #[deprecated(a,a)]
340 0 : auto *p = static_cast<AST::MetaItemPath *> (meta_item);
341 :
342 0 : std::string ident = p->get_path ().as_string ();
343 :
344 0 : rust_error_at (p->get_locus (), "unknown meta item %qs",
345 : ident.c_str ());
346 0 : rust_inform (p->get_locus (),
347 : "expected one of %<since%>, %<note%>");
348 0 : }
349 0 : break;
350 :
351 0 : case AST::MetaItem::ItemKind::Word:
352 0 : {
353 : // #[deprecated("a")]
354 0 : auto *w = static_cast<AST::MetaWord *> (meta_item);
355 :
356 0 : rust_error_at (
357 0 : w->get_locus (),
358 : "item in %<deprecated%> must be a key/value pair");
359 : }
360 0 : break;
361 :
362 0 : case AST::MetaItem::ItemKind::PathExpr:
363 0 : {
364 : // #[deprecated(since=a)]
365 0 : auto *px = static_cast<AST::MetaItemPathExpr *> (meta_item);
366 :
367 0 : rust_error_at (
368 0 : px->get_locus (),
369 : "expected unsuffixed literal or identifier, found %qs",
370 0 : px->get_expr ().as_string ().c_str ());
371 : }
372 0 : break;
373 :
374 0 : case AST::MetaItem::ItemKind::Seq:
375 0 : case AST::MetaItem::ItemKind::ListPaths:
376 0 : case AST::MetaItem::ItemKind::ListNameValueStr:
377 0 : default:
378 0 : gcc_unreachable ();
379 0 : break;
380 : }
381 : }
382 0 : break;
383 :
384 0 : case AST::MetaItemInner::Kind::LitExpr:
385 0 : default:
386 0 : gcc_unreachable ();
387 0 : break;
388 : }
389 : }
390 : }
391 :
392 : /**
393 : * Emit an error when an attribute is attached
394 : * to an incompatable item type. e.g.:
395 : *
396 : * #[cold]
397 : * struct A(u8, u8);
398 : *
399 : * Note that "#[derive]" is handled
400 : * explicitly in rust-derive.cc
401 : */
402 : static void
403 5064 : check_valid_attribute_for_item (const AST::Attribute &attr,
404 : const AST::Item &item)
405 : {
406 10128 : if (item.get_item_kind () != AST::Item::Kind::Function
407 14870 : && (attr.get_path () == Values::Attributes::TARGET_FEATURE
408 14546 : || attr.get_path () == Values::Attributes::COLD
409 9805 : || attr.get_path () == Values::Attributes::INLINE))
410 : {
411 1 : rust_error_at (attr.get_locus (),
412 : "the %<#[%s]%> attribute may only be applied to functions",
413 2 : attr.get_path ().as_string ().c_str ());
414 : }
415 10126 : else if (attr.get_path () == Values::Attributes::REPR
416 39 : && item.get_item_kind () != AST::Item::Kind::Enum
417 37 : && item.get_item_kind () != AST::Item::Kind::Union
418 5092 : && item.get_item_kind () != AST::Item::Kind::Struct)
419 : {
420 1 : rust_error_at (attr.get_locus (),
421 : "the %<#[%s]%> attribute may only be applied "
422 : "to structs, enums and unions",
423 2 : attr.get_path ().as_string ().c_str ());
424 : }
425 5064 : }
426 :
427 : static bool
428 6750 : is_proc_macro_type (const AST::Attribute &attribute)
429 : {
430 6750 : BuiltinAttrDefinition result;
431 6750 : if (!is_builtin (attribute, result))
432 : return false;
433 :
434 6750 : auto name = result.name;
435 6732 : return name == Attrs::PROC_MACRO || name == Attrs::PROC_MACRO_DERIVE
436 13482 : || name == Attrs::PROC_MACRO_ATTRIBUTE;
437 6750 : }
438 :
439 : // Emit an error when one encountered attribute is either #[proc_macro],
440 : // #[proc_macro_attribute] or #[proc_macro_derive]
441 : static void
442 4742 : check_proc_macro_non_function (const AST::Attribute &attr)
443 : {
444 4742 : if (is_proc_macro_type (attr))
445 45 : rust_error_at (attr.get_locus (),
446 : "the %<#[%s]%> attribute may only be used on bare functions",
447 90 : attr.get_path ().get_segments ()[0].as_string ().c_str ());
448 4742 : }
449 :
450 : // Emit an error when one attribute is either proc_macro, proc_macro_attribute
451 : // or proc_macro_derive
452 : static void
453 2008 : check_proc_macro_non_root (const AST::Attribute &attr, location_t loc)
454 : {
455 2008 : if (is_proc_macro_type (attr))
456 : {
457 9 : rust_error_at (
458 : loc,
459 : "functions tagged with %<#[%s]%> must currently "
460 : "reside in the root of the crate",
461 18 : attr.get_path ().get_segments ().at (0).as_string ().c_str ());
462 : }
463 2008 : }
464 :
465 : void
466 11227 : AttributeChecker::check_inner_attribute (const AST::Attribute &attribute)
467 : {
468 11227 : BuiltinAttrDefinition result;
469 :
470 11227 : if (!is_builtin (attribute, result))
471 11113 : return;
472 :
473 114 : if (__outer_attributes.find (result.name) != __outer_attributes.end ())
474 3 : rust_error_at (attribute.get_locus (),
475 : "attribute cannot be used at crate level");
476 11227 : }
477 :
478 : static void
479 2 : check_link_section_attribute (const AST::Attribute &attribute)
480 : {
481 2 : if (!attribute.has_attr_input ())
482 : {
483 1 : rust_error_at (attribute.get_locus (),
484 : "malformed %<link_section%> attribute input");
485 1 : rust_inform (attribute.get_locus (),
486 : "must be of the form: %<#[link_section = \"name\"]%>");
487 : }
488 2 : }
489 :
490 : static void
491 9 : check_export_name_attribute (const AST::Attribute &attribute)
492 : {
493 9 : if (!attribute.has_attr_input ())
494 : {
495 2 : rust_error_at (attribute.get_locus (),
496 : "malformed %<export_name%> attribute input");
497 2 : rust_inform (attribute.get_locus (),
498 : "must be of the form: %<#[export_name = \"name\"]%>");
499 2 : return;
500 : }
501 :
502 10 : if (!Attributes::extract_string_literal (attribute))
503 : {
504 4 : rust_error_at (attribute.get_locus (),
505 : "attribute must be a string literal");
506 : }
507 : }
508 :
509 : static void
510 10 : check_lint_attribute (const AST::Attribute &attribute, const char *name)
511 : {
512 10 : if (!attribute.has_attr_input ())
513 : {
514 1 : rust_error_at (attribute.get_locus (), "malformed %qs attribute input",
515 : name);
516 1 : rust_inform (attribute.get_locus (),
517 : "must be of the form: %<#[%s(lint1, lint2, ...)]%>", name);
518 : }
519 10 : }
520 :
521 : void
522 15592 : AttributeChecker::check_attribute (const AST::Attribute &attribute)
523 : {
524 15592 : if (!attribute.empty_input ())
525 : {
526 11043 : const auto &attr_input = attribute.get_attr_input ();
527 11043 : auto type = attr_input.get_attr_input_type ();
528 11043 : if (type == AST::AttrInput::AttrInputType::TOKEN_TREE)
529 : {
530 8036 : const auto &option = static_cast<const AST::DelimTokenTree &> (
531 8036 : attribute.get_attr_input ());
532 8036 : std::unique_ptr<AST::AttrInputMetaItemContainer> meta_item (
533 8036 : option.parse_to_meta_item ());
534 8036 : AST::DefaultASTVisitor::visit (meta_item);
535 8036 : }
536 : }
537 :
538 15592 : BuiltinAttrDefinition result;
539 :
540 : // This checker does not check non-builtin attributes
541 15592 : if (!is_builtin (attribute, result))
542 11113 : return;
543 :
544 : // TODO: Add checks here for each builtin attribute
545 : // TODO: Have an enum of builtins as well, switching on strings is annoying
546 : // and costly
547 4479 : if (result.name == Attrs::DOC)
548 877 : check_doc_attribute (attribute);
549 3602 : else if (result.name == Attrs::DEPRECATED)
550 1 : check_deprecated_attribute (attribute);
551 15592 : }
552 :
553 : void
554 0 : AttributeChecker::visit (AST::Token &)
555 0 : {}
556 :
557 : void
558 0 : AttributeChecker::visit (AST::DelimTokenTree &)
559 0 : {}
560 :
561 : void
562 519 : AttributeChecker::visit (AST::IdentifierExpr &)
563 519 : {}
564 :
565 : void
566 0 : AttributeChecker::visit (AST::Lifetime &)
567 0 : {}
568 :
569 : void
570 33 : AttributeChecker::visit (AST::LifetimeParam &)
571 33 : {}
572 :
573 : void
574 23 : AttributeChecker::visit (AST::ConstGenericParam &)
575 23 : {}
576 :
577 : // rust-path.h
578 : void
579 38 : AttributeChecker::visit (AST::PathInExpression &)
580 38 : {}
581 :
582 : void
583 0 : AttributeChecker::visit (AST::TypePathSegment &)
584 0 : {}
585 :
586 : void
587 0 : AttributeChecker::visit (AST::TypePathSegmentGeneric &)
588 0 : {}
589 :
590 : void
591 0 : AttributeChecker::visit (AST::TypePathSegmentFunction &)
592 0 : {}
593 :
594 : void
595 4366 : AttributeChecker::visit (AST::TypePath &)
596 4366 : {}
597 :
598 : void
599 0 : AttributeChecker::visit (AST::QualifiedPathInExpression &)
600 0 : {}
601 :
602 : void
603 0 : AttributeChecker::visit (AST::QualifiedPathInType &)
604 0 : {}
605 :
606 : // rust-expr.h
607 : void
608 1418 : AttributeChecker::visit (AST::LiteralExpr &)
609 1418 : {}
610 :
611 : void
612 0 : AttributeChecker::visit (AST::AttrInputLiteral &)
613 0 : {}
614 :
615 : void
616 0 : AttributeChecker::visit (AST::AttrInputMacro &)
617 0 : {}
618 :
619 : void
620 26 : AttributeChecker::visit (AST::MetaItemLitExpr &)
621 26 : {}
622 :
623 : void
624 2 : AttributeChecker::visit (AST::MetaItemPathExpr &attribute)
625 : {
626 2 : if (!attribute.get_expr ().is_literal ())
627 : {
628 1 : rust_error_at (attribute.get_expr ().get_locus (),
629 : "malformed %<path%> attribute input");
630 1 : rust_inform (attribute.get_expr ().get_locus (),
631 : "must be of the form: %<#[path = \"file\"]%>");
632 : }
633 2 : }
634 :
635 : void
636 143 : AttributeChecker::visit (AST::BorrowExpr &)
637 143 : {}
638 :
639 : void
640 228 : AttributeChecker::visit (AST::DereferenceExpr &)
641 228 : {}
642 :
643 : void
644 0 : AttributeChecker::visit (AST::ErrorPropagationExpr &)
645 0 : {}
646 :
647 : void
648 15 : AttributeChecker::visit (AST::NegationExpr &)
649 15 : {}
650 :
651 : void
652 776 : AttributeChecker::visit (AST::ArithmeticOrLogicalExpr &)
653 776 : {}
654 :
655 : void
656 743 : AttributeChecker::visit (AST::ComparisonExpr &)
657 743 : {}
658 :
659 : void
660 28 : AttributeChecker::visit (AST::LazyBooleanExpr &)
661 28 : {}
662 :
663 : void
664 158 : AttributeChecker::visit (AST::TypeCastExpr &)
665 158 : {}
666 :
667 : void
668 1 : AttributeChecker::visit (AST::AssignmentExpr &)
669 1 : {}
670 :
671 : void
672 7 : AttributeChecker::visit (AST::CompoundAssignmentExpr &)
673 7 : {}
674 :
675 : void
676 12 : AttributeChecker::visit (AST::GroupedExpr &)
677 12 : {}
678 :
679 : void
680 0 : AttributeChecker::visit (AST::ArrayElemsValues &)
681 0 : {}
682 :
683 : void
684 0 : AttributeChecker::visit (AST::ArrayElemsCopied &)
685 0 : {}
686 :
687 : void
688 15 : AttributeChecker::visit (AST::ArrayExpr &)
689 15 : {}
690 :
691 : void
692 0 : AttributeChecker::visit (AST::ArrayIndexExpr &)
693 0 : {}
694 :
695 : void
696 53 : AttributeChecker::visit (AST::TupleExpr &)
697 53 : {}
698 :
699 : void
700 187 : AttributeChecker::visit (AST::TupleIndexExpr &)
701 187 : {}
702 :
703 : void
704 7 : AttributeChecker::visit (AST::StructExprStruct &)
705 7 : {}
706 :
707 : void
708 0 : AttributeChecker::visit (AST::StructExprFieldIdentifier &)
709 0 : {}
710 :
711 : void
712 0 : AttributeChecker::visit (AST::StructExprFieldIdentifierValue &)
713 0 : {}
714 :
715 : void
716 0 : AttributeChecker::visit (AST::StructExprFieldIndexValue &)
717 0 : {}
718 :
719 : void
720 155 : AttributeChecker::visit (AST::StructExprStructFields &)
721 155 : {}
722 :
723 : void
724 0 : AttributeChecker::visit (AST::StructExprStructBase &)
725 0 : {}
726 :
727 : void
728 646 : AttributeChecker::visit (AST::CallExpr &)
729 646 : {}
730 :
731 : void
732 276 : AttributeChecker::visit (AST::MethodCallExpr &)
733 276 : {}
734 :
735 : void
736 171 : AttributeChecker::visit (AST::FieldAccessExpr &)
737 171 : {}
738 :
739 : void
740 1 : AttributeChecker::visit (AST::ClosureExprInner &)
741 1 : {}
742 :
743 : void
744 11152 : AttributeChecker::visit (AST::BlockExpr &expr)
745 : {
746 26812 : for (auto &stmt : expr.get_statements ())
747 : {
748 15660 : if (stmt->get_stmt_kind () == AST::Stmt::Kind::Item)
749 : {
750 : // Non owning pointer, let it go out of scope
751 718 : auto item = static_cast<AST::Item *> (stmt.get ());
752 728 : for (auto &attr : item->get_outer_attrs ())
753 10 : check_proc_macro_non_root (attr, item->get_locus ());
754 : }
755 : }
756 11152 : AST::DefaultASTVisitor::visit (expr);
757 11152 : }
758 :
759 : void
760 0 : AttributeChecker::visit (AST::ClosureExprInnerTyped &)
761 0 : {}
762 :
763 : void
764 0 : AttributeChecker::visit (AST::ContinueExpr &)
765 0 : {}
766 :
767 : void
768 0 : AttributeChecker::visit (AST::BreakExpr &)
769 0 : {}
770 :
771 : void
772 0 : AttributeChecker::visit (AST::RangeFromToExpr &)
773 0 : {}
774 :
775 : void
776 0 : AttributeChecker::visit (AST::RangeFromExpr &)
777 0 : {}
778 :
779 : void
780 0 : AttributeChecker::visit (AST::RangeToExpr &)
781 0 : {}
782 :
783 : void
784 0 : AttributeChecker::visit (AST::RangeFullExpr &)
785 0 : {}
786 :
787 : void
788 0 : AttributeChecker::visit (AST::RangeFromToInclExpr &)
789 0 : {}
790 :
791 : void
792 0 : AttributeChecker::visit (AST::RangeToInclExpr &)
793 0 : {}
794 :
795 : void
796 3 : AttributeChecker::visit (AST::ReturnExpr &)
797 3 : {}
798 :
799 : void
800 52 : AttributeChecker::visit (AST::LoopExpr &)
801 52 : {}
802 :
803 : void
804 18 : AttributeChecker::visit (AST::WhileLoopExpr &)
805 18 : {}
806 :
807 : void
808 2 : AttributeChecker::visit (AST::WhileLetLoopExpr &)
809 2 : {}
810 :
811 : void
812 1 : AttributeChecker::visit (AST::ForLoopExpr &)
813 1 : {}
814 :
815 : void
816 66 : AttributeChecker::visit (AST::IfExpr &)
817 66 : {}
818 :
819 : void
820 460 : AttributeChecker::visit (AST::IfExprConseqElse &)
821 460 : {}
822 :
823 : void
824 0 : AttributeChecker::visit (AST::IfLetExpr &)
825 0 : {}
826 :
827 : void
828 9 : AttributeChecker::visit (AST::IfLetExprConseqElse &)
829 9 : {}
830 :
831 : void
832 225 : AttributeChecker::visit (AST::MatchExpr &)
833 225 : {}
834 :
835 : void
836 0 : AttributeChecker::visit (AST::AwaitExpr &)
837 0 : {}
838 :
839 : void
840 0 : AttributeChecker::visit (AST::AsyncBlockExpr &)
841 0 : {}
842 :
843 : // rust-item.h
844 : void
845 965 : AttributeChecker::visit (AST::TypeParam &)
846 965 : {}
847 :
848 : void
849 0 : AttributeChecker::visit (AST::LifetimeWhereClauseItem &)
850 0 : {}
851 :
852 : void
853 85 : AttributeChecker::visit (AST::TypeBoundWhereClauseItem &)
854 85 : {}
855 :
856 : void
857 1303 : AttributeChecker::visit (AST::Module &module)
858 : {
859 1470 : for (auto &attr : module.get_outer_attrs ())
860 : {
861 167 : check_valid_attribute_for_item (attr, module);
862 167 : check_attribute (attr);
863 167 : check_proc_macro_non_function (attr);
864 : }
865 :
866 4135 : for (auto &item : module.get_items ())
867 4830 : for (auto &attr : item->get_outer_attrs ())
868 1998 : check_proc_macro_non_root (attr, item->get_locus ());
869 :
870 1303 : AST::DefaultASTVisitor::visit (module);
871 1303 : }
872 :
873 : void
874 27 : AttributeChecker::visit (AST::ExternCrate &crate)
875 : {
876 30 : for (auto &attr : crate.get_outer_attrs ())
877 : {
878 3 : check_valid_attribute_for_item (attr, crate);
879 3 : check_proc_macro_non_function (attr);
880 : }
881 27 : }
882 :
883 : void
884 0 : AttributeChecker::visit (AST::UseTreeGlob &)
885 0 : {}
886 :
887 : void
888 0 : AttributeChecker::visit (AST::UseTreeList &)
889 0 : {}
890 :
891 : void
892 0 : AttributeChecker::visit (AST::UseTreeRebind &)
893 0 : {}
894 :
895 : void
896 676 : AttributeChecker::visit (AST::UseDeclaration &declaration)
897 : {
898 680 : for (auto &attr : declaration.get_outer_attrs ())
899 : {
900 4 : check_valid_attribute_for_item (attr, declaration);
901 4 : check_proc_macro_non_function (attr);
902 : }
903 676 : }
904 :
905 : static void
906 1 : check_no_mangle_function (const AST::Attribute &attribute,
907 : const AST::Function &fun)
908 : {
909 1 : if (attribute.has_attr_input ())
910 : {
911 0 : rust_error_at (attribute.get_locus (), ErrorCode::E0754,
912 : "malformed %<no_mangle%> attribute input");
913 0 : rust_inform (attribute.get_locus (),
914 : "must be of the form: %<#[no_mangle]%>");
915 : }
916 1 : if (!is_ascii_only (fun.get_function_name ().as_string ()))
917 0 : rust_error_at (fun.get_function_name ().get_locus (),
918 : "the %<#[no_mangle]%> attribute requires ASCII identifier");
919 1 : }
920 :
921 : void
922 10032 : AttributeChecker::visit (AST::Function &fun)
923 : {
924 10354 : for (auto &attr : fun.get_outer_attrs ())
925 322 : check_valid_attribute_for_item (attr, fun);
926 :
927 10048 : auto check_crate_type = [] (const char *name, AST::Attribute &attribute) {
928 16 : if (!Session::get_instance ().options.is_proc_macro ())
929 3 : rust_error_at (attribute.get_locus (),
930 : "the %<#[%s]%> attribute is only usable with crates of "
931 : "the %<proc-macro%> crate type",
932 : name);
933 16 : };
934 :
935 10032 : BuiltinAttrDefinition result;
936 10354 : for (auto &attribute : fun.get_outer_attrs ())
937 : {
938 322 : if (!is_builtin (attribute, result))
939 0 : return;
940 :
941 322 : auto name = result.name.c_str ();
942 :
943 322 : if (result.name == Attrs::PROC_MACRO_DERIVE)
944 : {
945 6 : if (!attribute.has_attr_input ())
946 : {
947 1 : rust_error_at (attribute.get_locus (),
948 : "malformed %qs attribute input", name);
949 1 : rust_inform (
950 : attribute.get_locus (),
951 : "must be of the form: %<#[proc_macro_derive(TraitName, "
952 : "/*opt*/ attributes(name1, name2, ...))]%>");
953 : }
954 6 : check_crate_type (name, attribute);
955 : }
956 316 : else if (result.name == Attrs::PROC_MACRO
957 316 : || result.name == Attrs::PROC_MACRO_ATTRIBUTE)
958 : {
959 10 : check_crate_type (name, attribute);
960 : }
961 306 : else if (result.name == Attrs::TARGET_FEATURE)
962 : {
963 3 : if (!attribute.has_attr_input ())
964 : {
965 1 : rust_error_at (attribute.get_locus (),
966 : "malformed %<target_feature%> attribute input");
967 1 : rust_inform (attribute.get_locus (),
968 : "must be of the form: %<#[target_feature(enable = "
969 : "\"name\")]%>");
970 : }
971 2 : else if (!fun.get_qualifiers ().is_unsafe ())
972 : {
973 1 : rust_error_at (
974 : attribute.get_locus (),
975 : "the %<#[target_feature]%> attribute can only be applied "
976 : "to %<unsafe%> functions");
977 : }
978 : }
979 303 : else if (result.name == Attrs::NO_MANGLE)
980 : {
981 2 : if (attribute.has_attr_input ())
982 : {
983 1 : rust_error_at (attribute.get_locus (),
984 : "malformed %<no_mangle%> attribute input");
985 1 : rust_inform (attribute.get_locus (),
986 : "must be of the form: %<#[no_mangle]%>");
987 : }
988 : else
989 1 : check_no_mangle_function (attribute, fun);
990 : }
991 301 : else if (result.name == Attrs::EXPORT_NAME)
992 : {
993 5 : check_export_name_attribute (attribute);
994 : }
995 286 : else if (result.name == Attrs::ALLOW || result.name == "deny"
996 582 : || result.name == "warn" || result.name == "forbid")
997 : {
998 10 : check_lint_attribute (attribute, name);
999 : }
1000 286 : else if (result.name == Attrs::LINK_NAME)
1001 : {
1002 1 : if (!attribute.has_attr_input ())
1003 : {
1004 1 : rust_error_at (attribute.get_locus (),
1005 : "malformed %<link_name%> attribute input");
1006 1 : rust_inform (attribute.get_locus (),
1007 : "must be of the form: %<#[link_name = \"name\"]%>");
1008 : }
1009 : }
1010 285 : else if (result.name == Attrs::LINK_SECTION)
1011 : {
1012 1 : check_link_section_attribute (attribute);
1013 : }
1014 : }
1015 :
1016 10032 : if (fun.has_body ())
1017 10025 : fun.get_definition ().value ()->accept_vis (*this);
1018 10032 : }
1019 :
1020 : void
1021 736 : AttributeChecker::visit (AST::TypeAlias &alias)
1022 : {
1023 739 : for (auto &attr : alias.get_outer_attrs ())
1024 : {
1025 3 : check_valid_attribute_for_item (attr, alias);
1026 3 : check_proc_macro_non_function (attr);
1027 : }
1028 736 : }
1029 :
1030 : void
1031 1492 : AttributeChecker::visit (AST::StructStruct &struct_item)
1032 : {
1033 1961 : for (auto &attr : struct_item.get_outer_attrs ())
1034 : {
1035 469 : check_valid_attribute_for_item (attr, struct_item);
1036 469 : check_attribute (attr);
1037 469 : check_proc_macro_non_function (attr);
1038 : }
1039 1492 : }
1040 :
1041 : void
1042 963 : AttributeChecker::visit (AST::TupleStruct &tuplestruct)
1043 : {
1044 995 : for (auto &attr : tuplestruct.get_outer_attrs ())
1045 : {
1046 32 : check_valid_attribute_for_item (attr, tuplestruct);
1047 32 : check_proc_macro_non_function (attr);
1048 : }
1049 963 : }
1050 :
1051 : void
1052 0 : AttributeChecker::visit (AST::EnumItem &)
1053 0 : {}
1054 :
1055 : void
1056 0 : AttributeChecker::visit (AST::EnumItemTuple &)
1057 0 : {}
1058 :
1059 : void
1060 0 : AttributeChecker::visit (AST::EnumItemStruct &)
1061 0 : {}
1062 :
1063 : void
1064 0 : AttributeChecker::visit (AST::EnumItemDiscriminant &)
1065 0 : {}
1066 :
1067 : void
1068 544 : AttributeChecker::visit (AST::Enum &enumeration)
1069 : {
1070 697 : for (auto &attr : enumeration.get_outer_attrs ())
1071 : {
1072 153 : check_valid_attribute_for_item (attr, enumeration);
1073 153 : check_proc_macro_non_function (attr);
1074 : }
1075 544 : }
1076 :
1077 : void
1078 107 : AttributeChecker::visit (AST::Union &u)
1079 : {
1080 120 : for (auto &attr : u.get_outer_attrs ())
1081 : {
1082 13 : check_valid_attribute_for_item (attr, u);
1083 13 : check_proc_macro_non_function (attr);
1084 : }
1085 107 : }
1086 :
1087 : void
1088 524 : AttributeChecker::visit (AST::ConstantItem &item)
1089 : {
1090 527 : for (auto &attr : item.get_outer_attrs ())
1091 : {
1092 3 : check_valid_attribute_for_item (attr, item);
1093 3 : check_proc_macro_non_function (attr);
1094 : }
1095 524 : }
1096 :
1097 : void
1098 64 : AttributeChecker::visit (AST::StaticItem &item)
1099 : {
1100 64 : BuiltinAttrDefinition result;
1101 72 : for (auto &attr : item.get_outer_attrs ())
1102 : {
1103 8 : check_valid_attribute_for_item (attr, item);
1104 8 : check_proc_macro_non_function (attr);
1105 8 : if (is_builtin (attr, result))
1106 : {
1107 8 : if (result.name == Attrs::LINK_SECTION)
1108 : {
1109 1 : check_link_section_attribute (attr);
1110 : }
1111 7 : else if (result.name == Attrs::EXPORT_NAME)
1112 : {
1113 4 : check_export_name_attribute (attr);
1114 : }
1115 : }
1116 : }
1117 64 : }
1118 :
1119 : void
1120 0 : AttributeChecker::visit (AST::TraitItemType &)
1121 0 : {}
1122 :
1123 : void
1124 3737 : AttributeChecker::visit (AST::Trait &trait)
1125 : {
1126 7466 : for (auto &attr : trait.get_outer_attrs ())
1127 : {
1128 3729 : check_valid_attribute_for_item (attr, trait);
1129 3729 : check_proc_macro_non_function (attr);
1130 3729 : check_attribute (attr);
1131 : }
1132 3737 : }
1133 :
1134 : void
1135 760 : AttributeChecker::visit (AST::InherentImpl &impl)
1136 : {
1137 906 : for (auto &attr : impl.get_outer_attrs ())
1138 : {
1139 146 : check_valid_attribute_for_item (attr, impl);
1140 146 : check_proc_macro_non_function (attr);
1141 : }
1142 :
1143 760 : AST::DefaultASTVisitor::visit (impl);
1144 760 : }
1145 :
1146 : void
1147 2010 : AttributeChecker::visit (AST::TraitImpl &impl)
1148 : {
1149 2018 : for (auto &attr : impl.get_outer_attrs ())
1150 : {
1151 8 : check_valid_attribute_for_item (attr, impl);
1152 8 : check_proc_macro_non_function (attr);
1153 : }
1154 2010 : AST::DefaultASTVisitor::visit (impl);
1155 2010 : }
1156 :
1157 : void
1158 0 : AttributeChecker::visit (AST::ExternalTypeItem &)
1159 0 : {}
1160 :
1161 : void
1162 0 : AttributeChecker::visit (AST::ExternalStaticItem &)
1163 0 : {}
1164 :
1165 : void
1166 1464 : AttributeChecker::visit (AST::ExternBlock &block)
1167 : {
1168 1468 : for (auto &attr : block.get_outer_attrs ())
1169 : {
1170 4 : check_valid_attribute_for_item (attr, block);
1171 4 : check_proc_macro_non_function (attr);
1172 : }
1173 1464 : }
1174 :
1175 : // rust-macro.h
1176 : void
1177 0 : AttributeChecker::visit (AST::MacroMatchFragment &)
1178 0 : {}
1179 :
1180 : void
1181 0 : AttributeChecker::visit (AST::MacroMatchRepetition &)
1182 0 : {}
1183 :
1184 : void
1185 0 : AttributeChecker::visit (AST::MacroMatcher &)
1186 0 : {}
1187 :
1188 : void
1189 962 : AttributeChecker::visit (AST::MacroRulesDefinition &)
1190 962 : {}
1191 :
1192 : void
1193 710 : AttributeChecker::visit (AST::MacroInvocation &)
1194 710 : {}
1195 :
1196 : void
1197 0 : AttributeChecker::visit (AST::MetaItemPath &)
1198 0 : {}
1199 :
1200 : void
1201 7094 : AttributeChecker::visit (AST::MetaWord &)
1202 7094 : {}
1203 :
1204 : void
1205 1699 : AttributeChecker::visit (AST::MetaNameValueStr &)
1206 1699 : {}
1207 :
1208 : void
1209 0 : AttributeChecker::visit (AST::MetaListPaths &)
1210 0 : {}
1211 :
1212 : void
1213 0 : AttributeChecker::visit (AST::MetaListNameValueStr &)
1214 0 : {}
1215 :
1216 : // rust-pattern.h
1217 : void
1218 0 : AttributeChecker::visit (AST::LiteralPattern &)
1219 0 : {}
1220 :
1221 : void
1222 0 : AttributeChecker::visit (AST::IdentifierPattern &)
1223 0 : {}
1224 :
1225 : void
1226 0 : AttributeChecker::visit (AST::WildcardPattern &)
1227 0 : {}
1228 :
1229 : void
1230 0 : AttributeChecker::visit (AST::RestPattern &)
1231 0 : {}
1232 :
1233 : // void AttributeChecker::visit(RangePatternBound& ){}
1234 :
1235 : void
1236 0 : AttributeChecker::visit (AST::RangePatternBoundLiteral &)
1237 0 : {}
1238 :
1239 : void
1240 0 : AttributeChecker::visit (AST::RangePatternBoundPath &)
1241 0 : {}
1242 :
1243 : void
1244 0 : AttributeChecker::visit (AST::RangePatternBoundQualPath &)
1245 0 : {}
1246 :
1247 : void
1248 0 : AttributeChecker::visit (AST::RangePattern &)
1249 0 : {}
1250 :
1251 : void
1252 0 : AttributeChecker::visit (AST::ReferencePattern &)
1253 0 : {}
1254 :
1255 : // void AttributeChecker::visit(StructPatternField& ){}
1256 :
1257 : void
1258 0 : AttributeChecker::visit (AST::StructPatternFieldTuplePat &)
1259 0 : {}
1260 :
1261 : void
1262 0 : AttributeChecker::visit (AST::StructPatternFieldIdentPat &)
1263 0 : {}
1264 :
1265 : void
1266 0 : AttributeChecker::visit (AST::StructPatternFieldIdent &)
1267 0 : {}
1268 :
1269 : void
1270 0 : AttributeChecker::visit (AST::StructPattern &)
1271 0 : {}
1272 :
1273 : // void AttributeChecker::visit(TupleStructItems& ){}
1274 :
1275 : void
1276 0 : AttributeChecker::visit (AST::TupleStructItemsNoRest &)
1277 0 : {}
1278 :
1279 : void
1280 0 : AttributeChecker::visit (AST::TupleStructItemsHasRest &)
1281 0 : {}
1282 :
1283 : void
1284 0 : AttributeChecker::visit (AST::TupleStructPattern &)
1285 0 : {}
1286 :
1287 : // void AttributeChecker::visit(TuplePatternItems& ){}
1288 :
1289 : void
1290 0 : AttributeChecker::visit (AST::TuplePatternItemsNoRest &)
1291 0 : {}
1292 :
1293 : void
1294 0 : AttributeChecker::visit (AST::TuplePatternItemsHasRest &)
1295 0 : {}
1296 :
1297 : void
1298 0 : AttributeChecker::visit (AST::TuplePattern &)
1299 0 : {}
1300 :
1301 : void
1302 0 : AttributeChecker::visit (AST::GroupedPattern &)
1303 0 : {}
1304 :
1305 : void
1306 0 : AttributeChecker::visit (AST::SlicePattern &)
1307 0 : {}
1308 :
1309 : void
1310 0 : AttributeChecker::visit (AST::AltPattern &)
1311 0 : {}
1312 :
1313 : // rust-stmt.h
1314 : void
1315 18 : AttributeChecker::visit (AST::EmptyStmt &)
1316 18 : {}
1317 :
1318 : void
1319 9571 : AttributeChecker::visit (AST::LetStmt &)
1320 9571 : {}
1321 :
1322 : void
1323 5353 : AttributeChecker::visit (AST::ExprStmt &)
1324 5353 : {}
1325 :
1326 : // rust-type.h
1327 : void
1328 0 : AttributeChecker::visit (AST::TraitBound &)
1329 0 : {}
1330 :
1331 : void
1332 0 : AttributeChecker::visit (AST::ImplTraitType &)
1333 0 : {}
1334 :
1335 : void
1336 4 : AttributeChecker::visit (AST::TraitObjectType &)
1337 4 : {}
1338 :
1339 : void
1340 2 : AttributeChecker::visit (AST::ParenthesisedType &)
1341 2 : {}
1342 :
1343 : void
1344 0 : AttributeChecker::visit (AST::ImplTraitTypeOneBound &)
1345 0 : {}
1346 :
1347 : void
1348 7 : AttributeChecker::visit (AST::TraitObjectTypeOneBound &)
1349 7 : {}
1350 :
1351 : void
1352 2 : AttributeChecker::visit (AST::TupleType &)
1353 2 : {}
1354 :
1355 : void
1356 2 : AttributeChecker::visit (AST::NeverType &)
1357 2 : {}
1358 :
1359 : void
1360 164 : AttributeChecker::visit (AST::RawPointerType &)
1361 164 : {}
1362 :
1363 : void
1364 166 : AttributeChecker::visit (AST::ReferenceType &)
1365 166 : {}
1366 :
1367 : void
1368 0 : AttributeChecker::visit (AST::ArrayType &)
1369 0 : {}
1370 :
1371 : void
1372 66 : AttributeChecker::visit (AST::SliceType &)
1373 66 : {}
1374 :
1375 : void
1376 0 : AttributeChecker::visit (AST::InferredType &)
1377 0 : {}
1378 :
1379 : void
1380 1 : AttributeChecker::visit (AST::BareFunctionType &)
1381 1 : {}
1382 :
1383 : void
1384 0 : AttributeChecker::visit (AST::SelfParam &)
1385 0 : {}
1386 :
1387 : void
1388 0 : AttributeChecker::visit (AST::VariadicParam &)
1389 0 : {}
1390 :
1391 : void
1392 0 : AttributeChecker::visit (AST::FunctionParam &)
1393 0 : {}
1394 :
1395 : } // namespace Analysis
1396 : } // namespace Rust
|