1 /* General AST-related method implementations for Rust frontend.
2 Copyright (C) 2009-2024 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "rust-system.h"
21 #include "rust-ast-full.h"
22 #include "rust-diagnostics.h"
23 #include "rust-ast-visitor.h"
24 #include "rust-macro.h"
25 #include "rust-session-manager.h"
27 #include "rust-parse.h"
28 #include "rust-operators.h"
34 GenericArgs::as_string () const
39 if (!lifetime_args
.empty ())
41 auto i
= lifetime_args
.begin ();
42 auto e
= lifetime_args
.end ();
46 args
+= (*i
).as_string ();
53 if (!generic_args
.empty ())
55 auto i
= generic_args
.begin ();
56 auto e
= generic_args
.end ();
60 args
+= (*i
).as_string ();
67 if (!binding_args
.empty ())
69 auto i
= binding_args
.begin ();
70 auto e
= binding_args
.end ();
74 args
+= (*i
).as_string ();
84 GenericArg::disambiguate_to_const () const
86 rust_assert (get_kind () == Kind::Either
);
88 // FIXME: is it fine to have no outer attributes?
89 return GenericArg::create_const (
90 std::unique_ptr
<Expr
> (new IdentifierExpr (path
, {}, locus
)));
94 GenericArg::disambiguate_to_type () const
96 rust_assert (get_kind () == Kind::Either
);
98 auto segment
= std::unique_ptr
<TypePathSegment
> (
99 new TypePathSegment (path
.as_string (), false, locus
));
100 auto segments
= std::vector
<std::unique_ptr
<TypePathSegment
>> ();
101 segments
.emplace_back (std::move (segment
));
103 return GenericArg::create_type (
104 std::unique_ptr
<Type
> (new TypePath (std::move (segments
), locus
)));
108 GenericArgsBinding::as_string () const
110 // TODO: rewrite to work with non-literalisable types
111 return identifier
.as_string () + " = " + type
->as_string ();
115 ConstGenericParam::as_string () const
117 std::string
str ("ConstGenericParam: ");
118 str
+= "const " + name
.as_string () + ": " + type
->as_string ();
120 if (has_default_value ())
121 str
+= " = " + get_default_value ().as_string ();
127 PathExprSegment::as_string () const
129 // TODO: rewrite dump to work with non-literalisable types
130 std::string ident_str
= segment_name
.as_string ();
131 if (has_generic_args ())
132 ident_str
+= "::<" + generic_args
.as_string () + ">";
138 PathPattern::as_string () const
142 for (const auto &segment
: segments
)
143 str
+= segment
.as_string () + "::";
145 // basically a hack - remove last two characters of string (remove final ::)
146 str
.erase (str
.length () - 2);
152 PathPattern::convert_to_simple_path (bool with_opening_scope_resolution
) const
154 if (!has_segments ())
155 return SimplePath::create_empty ();
157 // create vector of reserved size (to minimise reallocations)
158 std::vector
<SimplePathSegment
> simple_segments
;
159 simple_segments
.reserve (segments
.size ());
161 for (const auto &segment
: segments
)
163 // return empty path if doesn't meet simple path segment requirements
164 if (segment
.is_error () || segment
.has_generic_args ()
165 || segment
.as_string () == "Self")
166 return SimplePath::create_empty ();
168 // create segment and add to vector
169 std::string segment_str
= segment
.as_string ();
170 simple_segments
.push_back (
171 SimplePathSegment (std::move (segment_str
), segment
.get_locus ()));
174 // kind of a HACK to get locus depending on opening scope resolution
175 location_t locus
= UNKNOWN_LOCATION
;
176 if (with_opening_scope_resolution
)
177 locus
= simple_segments
[0].get_locus () - 2; // minus 2 chars for ::
179 locus
= simple_segments
[0].get_locus ();
180 // FIXME: this hack probably doesn't actually work
182 return SimplePath (std::move (simple_segments
), with_opening_scope_resolution
,
187 PathInExpression::accept_vis (ASTVisitor
&vis
)
193 PathInExpression::as_string () const
197 if (has_opening_scope_resolution
)
200 return str
+ PathPattern::as_string ();
204 TypePathSegmentGeneric::as_string () const
206 // TODO: rewrite to work with non-linearisable types
207 return TypePathSegment::as_string () + "<" + generic_args
.as_string () + ">";
211 TypePathSegmentFunction::as_string () const
213 // TODO: rewrite to work with non-linearisable types
214 return TypePathSegment::as_string () + function_path
.as_string ();
218 TypePath::as_string () const
220 /* TODO: this may need to be rewritten if a segment (e.g. function) can't be
224 if (has_opening_scope_resolution
)
227 for (const auto &segment
: segments
)
228 str
+= segment
->as_string () + "::";
230 // kinda hack - remove last 2 '::' characters
231 str
.erase (str
.length () - 2);
237 TypePath::as_simple_path () const
239 if (segments
.empty ())
240 return SimplePath::create_empty ();
242 // create vector of reserved size (to minimise reallocations)
243 std::vector
<SimplePathSegment
> simple_segments
;
244 simple_segments
.reserve (segments
.size ());
246 for (const auto &segment
: segments
)
248 // return empty path if doesn't meet simple path segment requirements
249 if (segment
== nullptr || segment
->is_error ()
250 || !segment
->is_ident_only () || segment
->as_string () == "Self")
251 return SimplePath::create_empty ();
253 // create segment and add to vector
254 std::string segment_str
= segment
->as_string ();
255 simple_segments
.push_back (
256 SimplePathSegment (std::move (segment_str
), segment
->get_locus ()));
259 return SimplePath (std::move (simple_segments
), has_opening_scope_resolution
,
263 // hopefully definition here will prevent circular dependency issue
265 TypePath::to_trait_bound (bool in_parens
) const
267 return new TraitBound (TypePath (*this), get_locus (), in_parens
);
271 TypePathFunction::as_string () const
273 // TODO: rewrite to work with non-linearisable types
274 std::string
str ("(");
278 auto i
= inputs
.begin ();
279 auto e
= inputs
.end ();
283 str
+= (*i
)->as_string ();
291 if (has_return_type ())
292 str
+= " -> " + return_type
->as_string ();
298 QualifiedPathInExpression::as_string () const
300 return path_type
.as_string () + "::" + PathPattern::as_string ();
304 QualifiedPathInType::as_string () const
306 /* TODO: this may need adjusting if segments (e.g. with functions) can't be
308 std::string str
= path_type
.as_string ();
310 str
+= "::" + associated_segment
->as_string ();
311 for (const auto &segment
: segments
)
312 str
+= "::" + segment
->as_string ();
318 ConstGenericParam::accept_vis (ASTVisitor
&vis
)
324 TypePathSegment::accept_vis (ASTVisitor
&vis
)
330 TypePathSegmentGeneric::accept_vis (ASTVisitor
&vis
)
336 TypePathSegmentFunction::accept_vis (ASTVisitor
&vis
)
342 TypePath::accept_vis (ASTVisitor
&vis
)
348 QualifiedPathInExpression::accept_vis (ASTVisitor
&vis
)
354 QualifiedPathInType::accept_vis (ASTVisitor
&vis
)