]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/rust/hir/rust-ast-lower-type.h
gccrs: Add AST to HIR lowering pass
[thirdparty/gcc.git] / gcc / rust / hir / rust-ast-lower-type.h
CommitLineData
7999cf32
PH
1// Copyright (C) 2020-2022 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#ifndef RUST_AST_LOWER_TYPE
20#define RUST_AST_LOWER_TYPE
21
22#include "rust-ast-lower-base.h"
23#include "rust-diagnostics.h"
24#include "rust-ast-lower-expr.h"
25
26namespace Rust {
27namespace HIR {
28
29class ASTLowerTypePath : public ASTLoweringBase
30{
31protected:
32 using Rust::HIR::ASTLoweringBase::visit;
33
34public:
35 static HIR::TypePath *translate (AST::TypePath &type)
36 {
37 ASTLowerTypePath resolver;
38 type.accept_vis (resolver);
39 rust_assert (resolver.translated != nullptr);
40 return resolver.translated;
41 }
42
43 void visit (AST::TypePathSegmentFunction &) override { gcc_unreachable (); }
44
45 void visit (AST::TypePathSegment &segment) override
46 {
47 auto crate_num = mappings->get_current_crate ();
48 auto hirid = mappings->get_next_hir_id (crate_num);
49 Analysis::NodeMapping mapping (crate_num, segment.get_node_id (), hirid,
50 UNKNOWN_LOCAL_DEFID);
51
52 HIR::PathIdentSegment ident (segment.get_ident_segment ().as_string ());
53 translated_segment
54 = new HIR::TypePathSegment (std::move (mapping), ident,
55 segment.get_separating_scope_resolution (),
56 segment.get_locus ());
57 }
58
59 void visit (AST::TypePathSegmentGeneric &segment) override;
60
61 void visit (AST::TypePath &path) override
62 {
63 std::vector<std::unique_ptr<HIR::TypePathSegment>> translated_segments;
64
65 for (auto &seg : path.get_segments ())
66 {
67 translated_segment = nullptr;
68 seg->accept_vis (*this);
69 if (translated_segment == nullptr)
70 {
71 rust_fatal_error (seg->get_locus (),
72 "failed to translate AST TypePathSegment");
73 }
74 translated_segments.push_back (
75 std::unique_ptr<HIR::TypePathSegment> (translated_segment));
76 }
77
78 auto crate_num = mappings->get_current_crate ();
79 auto hirid = mappings->get_next_hir_id (crate_num);
80 Analysis::NodeMapping mapping (crate_num, path.get_node_id (), hirid,
81 mappings->get_next_localdef_id (crate_num));
82
83 translated
84 = new HIR::TypePath (std::move (mapping), std::move (translated_segments),
85 path.get_locus (),
86 path.has_opening_scope_resolution_op ());
87 }
88
89protected:
90 HIR::TypePathSegment *translated_segment;
91
92private:
93 HIR::TypePath *translated;
94};
95
96class ASTLowerQualifiedPathInType : public ASTLowerTypePath
97{
98 using ASTLowerTypePath::visit;
99
100public:
101 static HIR::QualifiedPathInType *translate (AST::QualifiedPathInType &type)
102 {
103 ASTLowerQualifiedPathInType resolver;
104 type.accept_vis (resolver);
105 rust_assert (resolver.translated != nullptr);
106 return resolver.translated;
107 }
108
109 void visit (AST::QualifiedPathInType &path) override;
110
111private:
112 HIR::QualifiedPathInType *translated;
113};
114
115class ASTLoweringType : public ASTLoweringBase
116{
117 using Rust::HIR::ASTLoweringBase::visit;
118
119public:
120 static HIR::Type *translate (AST::Type *type)
121 {
122 ASTLoweringType resolver;
123 type->accept_vis (resolver);
124
125 rust_assert (resolver.translated != nullptr);
126 resolver.mappings->insert_hir_type (resolver.translated);
127 resolver.mappings->insert_location (
128 resolver.translated->get_mappings ().get_hirid (),
129 resolver.translated->get_locus ());
130
131 return resolver.translated;
132 }
133
134 void visit (AST::BareFunctionType &fntype) override
135 {
136 bool is_variadic = false;
137 std::vector<HIR::LifetimeParam> lifetime_params;
138 HIR::FunctionQualifiers qualifiers
139 = lower_qualifiers (fntype.get_function_qualifiers ());
140
141 std::vector<HIR::MaybeNamedParam> named_params;
142 for (auto &param : fntype.get_function_params ())
143 {
144 HIR::MaybeNamedParam::ParamKind kind;
145 switch (param.get_param_kind ())
146 {
147 case AST::MaybeNamedParam::ParamKind::UNNAMED:
148 kind = HIR::MaybeNamedParam::ParamKind::UNNAMED;
149 break;
150 case AST::MaybeNamedParam::ParamKind::IDENTIFIER:
151 kind = HIR::MaybeNamedParam::ParamKind::IDENTIFIER;
152 break;
153 case AST::MaybeNamedParam::ParamKind::WILDCARD:
154 kind = HIR::MaybeNamedParam::ParamKind::WILDCARD;
155 break;
156 default:
157 gcc_unreachable ();
158 }
159
160 HIR::Type *param_type
161 = ASTLoweringType::translate (param.get_type ().get ());
162
163 HIR::MaybeNamedParam p (param.get_name (), kind,
164 std::unique_ptr<HIR::Type> (param_type),
165 param.get_locus ());
166 named_params.push_back (std::move (p));
167 }
168
169 HIR::Type *return_type = nullptr;
170 if (fntype.has_return_type ())
171 {
172 return_type
173 = ASTLoweringType::translate (fntype.get_return_type ().get ());
174 }
175
176 auto crate_num = mappings->get_current_crate ();
177 Analysis::NodeMapping mapping (crate_num, fntype.get_node_id (),
178 mappings->get_next_hir_id (crate_num),
179 mappings->get_next_localdef_id (crate_num));
180
181 translated = new HIR::BareFunctionType (
182 std::move (mapping), std::move (lifetime_params), std::move (qualifiers),
183 std::move (named_params), is_variadic,
184 std::unique_ptr<HIR::Type> (return_type), fntype.get_locus ());
185 }
186
187 void visit (AST::TupleType &tuple) override
188 {
189 std::vector<std::unique_ptr<HIR::Type>> elems;
190 for (auto &e : tuple.get_elems ())
191 {
192 HIR::Type *t = ASTLoweringType::translate (e.get ());
193 elems.push_back (std::unique_ptr<HIR::Type> (t));
194 }
195
196 auto crate_num = mappings->get_current_crate ();
197 Analysis::NodeMapping mapping (crate_num, tuple.get_node_id (),
198 mappings->get_next_hir_id (crate_num),
199 mappings->get_next_localdef_id (crate_num));
200
201 translated = new HIR::TupleType (std::move (mapping), std::move (elems),
202 tuple.get_locus ());
203 }
204
205 void visit (AST::TypePath &path) override
206 {
207 translated = ASTLowerTypePath::translate (path);
208 }
209
210 void visit (AST::QualifiedPathInType &path) override
211 {
212 translated = ASTLowerQualifiedPathInType::translate (path);
213 }
214
215 void visit (AST::ArrayType &type) override
216 {
217 HIR::Type *translated_type
218 = ASTLoweringType::translate (type.get_elem_type ().get ());
219 HIR::Expr *array_size
220 = ASTLoweringExpr::translate (type.get_size_expr ().get ());
221
222 auto crate_num = mappings->get_current_crate ();
223 Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
224 mappings->get_next_hir_id (crate_num),
225 mappings->get_next_localdef_id (crate_num));
226
227 translated
228 = new HIR::ArrayType (mapping,
229 std::unique_ptr<HIR::Type> (translated_type),
230 std::unique_ptr<HIR::Expr> (array_size),
231 type.get_locus ());
232 }
233
234 void visit (AST::ReferenceType &type) override
235 {
236 HIR::Lifetime lifetime = lower_lifetime (type.get_lifetime ());
237
238 HIR::Type *base_type
239 = ASTLoweringType::translate (type.get_base_type ().get ());
240
241 auto crate_num = mappings->get_current_crate ();
242 Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
243 mappings->get_next_hir_id (crate_num),
244 mappings->get_next_localdef_id (crate_num));
245
246 translated = new HIR::ReferenceType (mapping,
247 type.get_has_mut () ? Mutability::Mut
248 : Mutability::Imm,
249 std::unique_ptr<HIR::Type> (base_type),
250 type.get_locus (), lifetime);
251 }
252
253 void visit (AST::RawPointerType &type) override
254 {
255 HIR::Type *base_type
256 = ASTLoweringType::translate (type.get_type_pointed_to ().get ());
257
258 auto crate_num = mappings->get_current_crate ();
259 Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
260 mappings->get_next_hir_id (crate_num),
261 mappings->get_next_localdef_id (crate_num));
262
263 translated
264 = new HIR::RawPointerType (mapping,
265 type.get_pointer_type ()
266 == AST::RawPointerType::PointerType::MUT
267 ? Mutability::Mut
268 : Mutability::Imm,
269 std::unique_ptr<HIR::Type> (base_type),
270 type.get_locus ());
271 }
272
273 void visit (AST::SliceType &type) override
274 {
275 HIR::Type *base_type
276 = ASTLoweringType::translate (type.get_elem_type ().get ());
277
278 auto crate_num = mappings->get_current_crate ();
279 Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
280 mappings->get_next_hir_id (crate_num),
281 mappings->get_next_localdef_id (crate_num));
282
283 translated
284 = new HIR::SliceType (mapping, std::unique_ptr<HIR::Type> (base_type),
285 type.get_locus ());
286 }
287
288 void visit (AST::InferredType &type) override
289 {
290 auto crate_num = mappings->get_current_crate ();
291 Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
292 mappings->get_next_hir_id (crate_num),
293 mappings->get_next_localdef_id (crate_num));
294
295 translated = new HIR::InferredType (mapping, type.get_locus ());
296 }
297
298 void visit (AST::NeverType &type) override
299 {
300 auto crate_num = mappings->get_current_crate ();
301 Analysis::NodeMapping mapping (crate_num, type.get_node_id (),
302 mappings->get_next_hir_id (crate_num),
303 mappings->get_next_localdef_id (crate_num));
304
305 translated = new HIR::NeverType (mapping, type.get_locus ());
306 }
307
308 void visit (AST::TraitObjectTypeOneBound &type) override;
309
310 void visit (AST::TraitObjectType &type) override;
311
312private:
313 ASTLoweringType () : ASTLoweringBase (), translated (nullptr) {}
314
315 HIR::Type *translated;
316};
317
318class ASTLowerGenericParam : public ASTLoweringBase
319{
320 using Rust::HIR::ASTLoweringBase::visit;
321
322public:
323 static HIR::GenericParam *translate (AST::GenericParam *param)
324 {
325 ASTLowerGenericParam resolver;
326 param->accept_vis (resolver);
327
328 rust_assert (resolver.translated != nullptr);
329 resolver.mappings->insert_location (
330 resolver.translated->get_mappings ().get_hirid (), param->get_locus ());
331 resolver.mappings->insert_hir_generic_param (resolver.translated);
332
333 return resolver.translated;
334 }
335
336 void visit (AST::LifetimeParam &param) override
337 {
338 auto crate_num = mappings->get_current_crate ();
339 Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
340 mappings->get_next_hir_id (crate_num),
341 mappings->get_next_localdef_id (crate_num));
342
343 HIR::Lifetime lt (mapping, param.get_lifetime ().get_lifetime_type (),
344 param.get_lifetime ().get_lifetime_name (),
345 param.get_lifetime ().get_locus ());
346
347 translated = new HIR::LifetimeParam (mapping, lt, param.get_locus (),
348 std::vector<Lifetime> ());
349 }
350
351 void visit (AST::ConstGenericParam &param) override
352 {
353 auto crate_num = mappings->get_current_crate ();
354 Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
355 mappings->get_next_hir_id (crate_num),
356 mappings->get_next_localdef_id (crate_num));
357
358 auto type = ASTLoweringType::translate (param.get_type ().get ());
359
360 HIR::Expr *default_expr = nullptr;
361 if (param.has_default_value ())
362 default_expr = ASTLoweringExpr::translate (
363 param.get_default_value ().get_expression ().get ());
364
365 translated
366 = new HIR::ConstGenericParam (param.get_name (),
367 std::unique_ptr<Type> (type),
368 std::unique_ptr<Expr> (default_expr),
369 mapping, param.get_locus ());
370 }
371
372 void visit (AST::TypeParam &param) override
373 {
374 AST::Attribute outer_attr = AST::Attribute::create_empty ();
375 std::vector<std::unique_ptr<HIR::TypeParamBound>> type_param_bounds;
376 if (param.has_type_param_bounds ())
377 {
378 for (auto &bound : param.get_type_param_bounds ())
379 {
380 HIR::TypeParamBound *lowered_bound = lower_bound (bound.get ());
381 type_param_bounds.push_back (
382 std::unique_ptr<HIR::TypeParamBound> (lowered_bound));
383 }
384 }
385
386 HIR::Type *type = param.has_type ()
387 ? ASTLoweringType::translate (param.get_type ().get ())
388 : nullptr;
389
390 auto crate_num = mappings->get_current_crate ();
391 Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
392 mappings->get_next_hir_id (crate_num),
393 mappings->get_next_localdef_id (crate_num));
394
395 translated
396 = new HIR::TypeParam (mapping, param.get_type_representation (),
397 param.get_locus (), std::move (type_param_bounds),
398 std::unique_ptr<Type> (type),
399 std::move (outer_attr));
400 }
401
402private:
403 ASTLowerGenericParam () : ASTLoweringBase (), translated (nullptr) {}
404
405 HIR::GenericParam *translated;
406};
407
408class ASTLoweringTypeBounds : public ASTLoweringBase
409{
410 using Rust::HIR::ASTLoweringBase::visit;
411
412public:
413 static HIR::TypeParamBound *translate (AST::TypeParamBound *type)
414 {
415 ASTLoweringTypeBounds resolver;
416 type->accept_vis (resolver);
417
418 rust_assert (resolver.translated != nullptr);
419 resolver.mappings->insert_location (
420 resolver.translated->get_mappings ().get_hirid (),
421 resolver.translated->get_locus ());
422
423 return resolver.translated;
424 }
425
426 void visit (AST::TraitBound &bound) override
427 {
428 // FIXME
429 std::vector<HIR::LifetimeParam> lifetimes;
430
431 AST::TypePath &ast_trait_path = bound.get_type_path ();
432 HIR::TypePath *trait_path = ASTLowerTypePath::translate (ast_trait_path);
433
434 auto crate_num = mappings->get_current_crate ();
435 Analysis::NodeMapping mapping (crate_num, bound.get_node_id (),
436 mappings->get_next_hir_id (crate_num),
437 UNKNOWN_LOCAL_DEFID);
438
439 translated = new HIR::TraitBound (mapping, *trait_path, bound.get_locus (),
440 bound.is_in_parens (),
441 bound.has_opening_question_mark ());
442 }
443
444 void visit (AST::Lifetime &bound) override
445 {
446 HIR::Lifetime lifetime = lower_lifetime (bound);
447 translated = new HIR::Lifetime (lifetime);
448 }
449
450private:
451 ASTLoweringTypeBounds () : ASTLoweringBase (), translated (nullptr) {}
452
453 HIR::TypeParamBound *translated;
454};
455
456class ASTLowerWhereClauseItem : public ASTLoweringBase
457{
458 using Rust::HIR::ASTLoweringBase::visit;
459
460public:
461 static HIR::WhereClauseItem *translate (AST::WhereClauseItem &item)
462 {
463 ASTLowerWhereClauseItem compiler;
464 item.accept_vis (compiler);
465
466 rust_assert (compiler.translated != nullptr);
467 // FIXME
468 // compiler.mappings->insert_location (
469 // compiler.translated->get_mappings ().get_hirid (),
470 // compiler.translated->get_locus ());
471
472 return compiler.translated;
473 }
474
475 void visit (AST::LifetimeWhereClauseItem &item) override
476 {
477 HIR::Lifetime l = lower_lifetime (item.get_lifetime ());
478 std::vector<HIR::Lifetime> lifetime_bounds;
479 for (auto &lifetime_bound : item.get_lifetime_bounds ())
480 {
481 HIR::Lifetime ll = lower_lifetime (lifetime_bound);
482 lifetime_bounds.push_back (std::move (ll));
483 }
484
485 auto crate_num = mappings->get_current_crate ();
486 Analysis::NodeMapping mapping (crate_num, item.get_node_id (),
487 mappings->get_next_hir_id (crate_num),
488 UNKNOWN_LOCAL_DEFID);
489
490 translated = new HIR::LifetimeWhereClauseItem (mapping, std::move (l),
491 std::move (lifetime_bounds),
492 item.get_locus ());
493 }
494
495 void visit (AST::TypeBoundWhereClauseItem &item) override
496 {
497 // FIXME
498 std::vector<HIR::LifetimeParam> for_lifetimes;
499
500 std::unique_ptr<HIR::Type> bound_type = std::unique_ptr<HIR::Type> (
501 ASTLoweringType::translate (item.get_type ().get ()));
502
503 std::vector<std::unique_ptr<HIR::TypeParamBound>> type_param_bounds;
504 for (auto &bound : item.get_type_param_bounds ())
505 {
506 HIR::TypeParamBound *b
507 = ASTLoweringTypeBounds::translate (bound.get ());
508 type_param_bounds.push_back (std::unique_ptr<HIR::TypeParamBound> (b));
509 }
510
511 auto crate_num = mappings->get_current_crate ();
512 Analysis::NodeMapping mapping (crate_num, item.get_node_id (),
513 mappings->get_next_hir_id (crate_num),
514 UNKNOWN_LOCAL_DEFID);
515
516 translated
517 = new HIR::TypeBoundWhereClauseItem (mapping, std::move (for_lifetimes),
518 std::move (bound_type),
519 std::move (type_param_bounds),
520 item.get_locus ());
521 }
522
523private:
524 ASTLowerWhereClauseItem () : ASTLoweringBase (), translated (nullptr) {}
525
526 HIR::WhereClauseItem *translated;
527};
528
529} // namespace HIR
530} // namespace Rust
531
532#endif // RUST_AST_LOWER_TYPE