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