]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rust/checks/errors/rust-ast-validation.cc
Update copyright years.
[thirdparty/gcc.git] / gcc / rust / checks / errors / rust-ast-validation.cc
CommitLineData
767698ff 1// Copyright (C) 2020-2024 Free Software Foundation, Inc.
f24d4083
PEP
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-validation.h"
5959f32d 20#include "rust-common.h"
cb9ecb55 21#include "rust-diagnostics.h"
72792563 22#include "rust-item.h"
8f41baaa 23#include "rust-keyword-values.h"
f24d4083
PEP
24
25namespace Rust {
26
ea4cd645
PEP
27void
28ASTValidation::visit (AST::Lifetime &lifetime)
29{
30 auto name = lifetime.get_lifetime_name ();
31 auto valid = std::set<std::string>{"static", "_"};
8f41baaa
PEP
32 auto &keywords = Values::Keywords::keywords;
33
ea4cd645
PEP
34 if (valid.find (name) == valid.end ()
35 && keywords.find (name) != keywords.end ())
36 rust_error_at (lifetime.get_locus (), "lifetimes cannot use keyword names");
37
38 AST::ContextualASTVisitor::visit (lifetime);
39}
40
93ca83c5
PEP
41void
42ASTValidation::visit (AST::LoopLabel &label)
43{
44 auto name = label.get_lifetime ().get_lifetime_name ();
45 auto lifetime_name = '\'' + name;
46 auto &keywords = Values::Keywords::keywords;
47 if (keywords.find (name) != keywords.end ())
66fc33f6 48 rust_error_at (label.get_lifetime ().get_locus (), "invalid label name %qs",
93ca83c5
PEP
49 lifetime_name.c_str ());
50
51 // WARNING: Do not call ContextualASTVisitor, we don't want to visit the
52 // lifetime
53 // Maybe we should refactor LoopLabel instead ?
54}
55
cb9ecb55
PEP
56void
57ASTValidation::visit (AST::ConstantItem &const_item)
58{
59 if (!const_item.has_expr () && context.back () != Context::TRAIT_IMPL)
60 {
61 rust_error_at (const_item.get_locus (),
62 "associated constant in %<impl%> without body");
63 }
222f27d3 64 AST::ContextualASTVisitor::visit (const_item);
cb9ecb55 65}
f24d4083 66
e92ae55f
PEP
67void
68ASTValidation::visit (AST::ExternalFunctionItem &item)
69{
70 auto &params = item.get_function_params ();
71
72 if (params.size () == 1 && params[0].is_variadic ())
73 rust_error_at (
74 params[0].get_locus (),
75 "C-variadic function must be declared with at least one named argument");
76
77 for (auto it = params.begin (); it != params.end (); it++)
78 if (it->is_variadic () && it + 1 != params.end ())
79 rust_error_at (
80 it->get_locus (),
81 "%<...%> must be the last argument of a C-variadic function");
82
83 AST::ContextualASTVisitor::visit (item);
84}
85
72792563
PEP
86void
87ASTValidation::visit (AST::Union &item)
88{
89 if (item.get_variants ().empty ())
90 rust_error_at (item.get_locus (), "unions cannot have zero fields");
91
92 AST::ContextualASTVisitor::visit (item);
93}
94
513b0154
PEP
95void
96ASTValidation::visit (AST::Function &function)
97{
04b3089a
PEP
98 const auto &qualifiers = function.get_qualifiers ();
99 if (qualifiers.is_async () && qualifiers.is_const ())
100 rust_error_at (function.get_locus (),
101 "functions cannot be both %<const%> and %<async%>");
102
4be51abd
KP
103 if (qualifiers.is_const ()
104 && (context.back () == Context::TRAIT_IMPL
105 || context.back () == Context::TRAIT))
f48f9a9a 106 rust_error_at (function.get_locus (), ErrorCode::E0379,
4be51abd 107 "functions in traits cannot be declared %<const%>");
f48f9a9a 108
81fcf108 109 // may change soon
4be51abd
KP
110 if (qualifiers.is_async ()
111 && (context.back () == Context::TRAIT_IMPL
112 || context.back () == Context::TRAIT))
81fcf108
KP
113 rust_error_at (function.get_locus (), ErrorCode::E0706,
114 "functions in traits cannot be declared %<async%>");
115
4be51abd
KP
116 // if not an associated function but has a self parameter
117 if (context.back () != Context::TRAIT
118 && context.back () != Context::TRAIT_IMPL
119 && context.back () != Context::INHERENT_IMPL
513b0154
PEP
120 && function.has_self_param ())
121 rust_error_at (
122 function.get_self_param ()->get_locus (),
123 "%<self%> parameter is only allowed in associated functions");
124
04fd5a04
PEP
125 if (!function.has_body ())
126 {
127 if (context.back () == Context::INHERENT_IMPL
128 || context.back () == Context::TRAIT_IMPL)
129 rust_error_at (function.get_locus (),
130 "associated function in %<impl%> without body");
131 else if (context.back () != Context::TRAIT)
132 rust_error_at (function.get_locus (), "free function without a body");
133 }
134
e7c1948f 135 auto &function_params = function.get_function_params ();
136 for (auto it = function_params.begin (); it != function_params.end (); it++)
137 {
138 if (it->get ()->is_variadic ())
139 rust_error_at (it->get ()->get_locus (),
140 "only foreign or %<unsafe extern \"C\"%> functions may "
141 "be C-variadic");
142 }
162137fd 143
513b0154
PEP
144 AST::ContextualASTVisitor::visit (function);
145}
146
b1b744fc
PEP
147void
148ASTValidation::visit (AST::Trait &trait)
149{
150 if (trait.is_auto ())
151 {
152 if (trait.has_generics ())
153 rust_error_at (trait.get_generic_params ()[0]->get_locus (),
154 ErrorCode::E0567,
155 "auto traits cannot have generic parameters");
d8c1a756
PEP
156 if (trait.has_type_param_bounds ())
157 rust_error_at (trait.get_type_param_bounds ()[0]->get_locus (),
158 ErrorCode::E0568,
159 "auto traits cannot have super traits");
685491f2
PEP
160 if (trait.has_trait_items ())
161 {
162 rust_error_at (trait.get_identifier ().get_locus (), ErrorCode::E0380,
163 "auto traits cannot have methods or associated items");
164 for (const auto &item : trait.get_trait_items ())
165 Error::Hint (item->get_locus (), "remove this item").emit ();
166 }
b1b744fc
PEP
167 }
168
169 AST::ContextualASTVisitor::visit (trait);
170}
171
5959f32d
PEP
172void
173ASTValidation::visit (AST::Module &module)
174{
175 if (module.get_unsafety () == Unsafety::Unsafe)
176 rust_error_at (module.get_locus (), "module cannot be declared unsafe");
177
178 AST::ContextualASTVisitor::visit (module);
179}
180
f24d4083 181} // namespace Rust