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-lower.h"
20 : #include "rust-ast-lower-item.h"
21 : #include "rust-ast-lower-stmt.h"
22 : #include "rust-ast-lower-expr.h"
23 : #include "rust-ast-lower-block.h"
24 : #include "rust-ast-lower-type.h"
25 : #include "rust-ast-lower-pattern.h"
26 : #include "rust-ast-lower-struct-field-expr.h"
27 : #include "rust-expr.h"
28 : #include "rust-hir-expr.h"
29 :
30 : namespace Rust {
31 : namespace HIR {
32 : using HIR::ClosureParam;
33 :
34 : Visibility
35 36600 : translate_visibility (const AST::Visibility &vis)
36 : {
37 : // FIXME: How do we create a private visibility here? Is it always private if
38 : // the AST vis is an error?
39 : // FIXME: We need to add a `create_private()` static function to the
40 : // AST::Visibility class and use it when the vis is empty in the parser...
41 :
42 36600 : switch (vis.get_vis_type ())
43 : {
44 7921 : case AST::Visibility::PUB:
45 7921 : return Visibility (Visibility::VisType::PUBLIC);
46 28618 : case AST::Visibility::PRIV:
47 28618 : case AST::Visibility::PUB_SELF:
48 28618 : return Visibility (Visibility::VisType::PRIVATE);
49 61 : case AST::Visibility::PUB_CRATE:
50 61 : case AST::Visibility::PUB_SUPER:
51 61 : case AST::Visibility::PUB_IN_PATH:
52 61 : return Visibility (Visibility::VisType::RESTRICTED,
53 61 : ASTLoweringSimplePath::translate (vis.get_path ()),
54 61 : vis.get_locus ());
55 0 : break;
56 : }
57 :
58 0 : rust_unreachable ();
59 : }
60 :
61 4341 : ASTLowering::ASTLowering (AST::Crate &astCrate) : astCrate (astCrate) {}
62 :
63 4341 : ASTLowering::~ASTLowering () {}
64 :
65 : std::unique_ptr<HIR::Crate>
66 4341 : ASTLowering::Resolve (AST::Crate &astCrate)
67 : {
68 4341 : ASTLowering resolver (astCrate);
69 4341 : return resolver.go ();
70 4341 : }
71 :
72 : std::unique_ptr<HIR::Crate>
73 4341 : ASTLowering::go ()
74 : {
75 4341 : std::vector<std::unique_ptr<HIR::Item>> items;
76 :
77 23071 : for (auto &item : astCrate.items)
78 : {
79 18730 : auto translated = ASTLoweringItem::translate (*item);
80 18730 : if (translated != nullptr)
81 17618 : items.emplace_back (translated);
82 : }
83 :
84 4341 : auto &mappings = Analysis::Mappings::get ();
85 4341 : auto crate_num = mappings.get_current_crate ();
86 4341 : Analysis::NodeMapping mapping (crate_num, astCrate.get_node_id (),
87 : mappings.get_next_hir_id (crate_num),
88 4341 : UNKNOWN_LOCAL_DEFID);
89 :
90 4341 : return std::unique_ptr<HIR::Crate> (
91 4341 : new HIR::Crate (std::move (items), astCrate.get_inner_attrs (), mapping));
92 4341 : }
93 :
94 : // rust-ast-lower-block.h
95 : void
96 21916 : ASTLoweringBlock::visit (AST::BlockExpr &expr)
97 : {
98 21916 : tl::optional<HIR::LoopLabel> label;
99 21916 : if (expr.has_label ())
100 0 : label = lower_loop_label (expr.get_label ());
101 : else
102 : label = tl::nullopt;
103 :
104 21916 : std::vector<std::unique_ptr<HIR::Stmt>> block_stmts;
105 21916 : bool block_did_terminate = false;
106 :
107 44309 : for (auto &s : expr.get_statements ())
108 : {
109 : // FIXME: We basically need to do that check for *every* single node in
110 : // the AST. this isn't realistic and this should be turned into an
111 : // optional, debug-visitor instead, which goes through the entire AST and
112 : // checks if any of the nodes are macro invocations
113 22393 : if (s->get_stmt_kind () == AST::Stmt::Kind::MacroInvocation)
114 0 : rust_fatal_error (
115 0 : s->get_locus (),
116 : "macro invocations should not get lowered to HIR - At "
117 : "this point in "
118 : "the pipeline, they should all have been expanded");
119 :
120 22393 : if (block_did_terminate)
121 18 : rust_warning_at (s->get_locus (), 0, "unreachable statement");
122 :
123 22393 : bool terminated = false;
124 22393 : auto translated_stmt = ASTLoweringStmt::translate (s.get (), &terminated);
125 22393 : block_did_terminate |= terminated;
126 :
127 22393 : if (translated_stmt)
128 22384 : block_stmts.emplace_back (translated_stmt);
129 : }
130 :
131 21916 : if (expr.has_tail_expr () && block_did_terminate)
132 : {
133 : // warning unreachable tail expressions
134 16 : rust_warning_at (expr.get_tail_expr ().get_locus (), 0,
135 : "unreachable expression");
136 : }
137 :
138 21916 : HIR::ExprWithoutBlock *tail_expr = nullptr;
139 21916 : if (expr.has_tail_expr ())
140 : {
141 15956 : bool terminated = false;
142 15956 : tail_expr = (HIR::ExprWithoutBlock *)
143 15956 : ASTLoweringExpr::translate (expr.get_tail_expr (), &terminated);
144 15956 : block_did_terminate |= terminated;
145 : }
146 :
147 21916 : bool tail_reachable = !block_did_terminate;
148 21916 : auto crate_num = mappings.get_current_crate ();
149 43832 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
150 21916 : mappings.get_next_hir_id (crate_num),
151 21916 : UNKNOWN_LOCAL_DEFID);
152 21916 : translated
153 21916 : = new HIR::BlockExpr (mapping, std::move (block_stmts),
154 43832 : std::unique_ptr<HIR::ExprWithoutBlock> (tail_expr),
155 21916 : tail_reachable, expr.get_inner_attrs (),
156 21916 : expr.get_outer_attrs (), label,
157 43832 : expr.get_start_locus (), expr.get_end_locus ());
158 :
159 21916 : terminated = block_did_terminate;
160 21916 : }
161 :
162 : void
163 470 : ASTLoweringIfBlock::visit (AST::IfExpr &expr)
164 : {
165 470 : bool ignored_terminated = false;
166 470 : HIR::Expr *condition = ASTLoweringExpr::translate (expr.get_condition_expr (),
167 : &ignored_terminated);
168 470 : HIR::BlockExpr *block
169 470 : = ASTLoweringBlock::translate (expr.get_if_block (), &ignored_terminated);
170 :
171 470 : auto crate_num = mappings.get_current_crate ();
172 940 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
173 470 : mappings.get_next_hir_id (crate_num),
174 470 : UNKNOWN_LOCAL_DEFID);
175 :
176 470 : translated = new HIR::IfExpr (mapping, std::unique_ptr<HIR::Expr> (condition),
177 940 : std::unique_ptr<HIR::BlockExpr> (block),
178 470 : expr.get_locus ());
179 470 : }
180 :
181 : void
182 1205 : ASTLoweringIfBlock::visit (AST::IfExprConseqElse &expr)
183 : {
184 1205 : HIR::Expr *condition
185 1205 : = ASTLoweringExpr::translate (expr.get_condition_expr ());
186 :
187 1205 : bool if_block_terminated = false;
188 1205 : bool else_block_termianted = false;
189 :
190 1205 : HIR::BlockExpr *if_block
191 1205 : = ASTLoweringBlock::translate (expr.get_if_block (), &if_block_terminated);
192 1205 : HIR::ExprWithBlock *else_block
193 1205 : = ASTLoweringExprWithBlock::translate (expr.get_else_block (),
194 : &else_block_termianted);
195 :
196 1205 : terminated = if_block_terminated && else_block_termianted;
197 :
198 1205 : auto crate_num = mappings.get_current_crate ();
199 2410 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
200 1205 : mappings.get_next_hir_id (crate_num),
201 1205 : UNKNOWN_LOCAL_DEFID);
202 :
203 2410 : translated = new HIR::IfExprConseqElse (
204 1205 : mapping, std::unique_ptr<HIR::Expr> (condition),
205 2410 : std::unique_ptr<HIR::BlockExpr> (if_block),
206 2410 : std::unique_ptr<HIR::ExprWithBlock> (else_block), expr.get_locus ());
207 1205 : }
208 :
209 : /**
210 : * Lowers the common part "if let 'pattern' = 'expr' { 'if_block' }" of
211 : * IfLetExpr[ConseqElse]:
212 : * - 'expr' is lowered into *BRANCH_VALUE
213 : * - 'pattern' + 'if_block' are lowered and resulting ARM pushed in MATCH_ARMS
214 : * - 'KASE_ELSE_EXPR' is the lowered HIR to be used in the else part.
215 : *
216 : * Looks like:
217 : *
218 : * match (expr) {
219 : * pattern => {if_block}
220 : * _ => kase_else_expr
221 : * }
222 : *
223 : */
224 : void
225 29 : ASTLoweringIfLetBlock::desugar_iflet (AST::IfLetExpr &expr,
226 : HIR::Expr **branch_value,
227 : HIR::Expr *kase_else_expr,
228 : std::vector<HIR::MatchCase> &match_arms)
229 : {
230 29 : HIR::Expr *kase_expr;
231 29 : std::unique_ptr<HIR::Pattern> match_arm_pattern;
232 :
233 29 : *branch_value = ASTLoweringExpr::translate (expr.get_value_expr ());
234 29 : kase_expr = ASTLoweringExpr::translate (expr.get_if_block ());
235 :
236 : // (stable) if let only accepts a single pattern, but (unstable) if let chains
237 : // need more than one pattern.
238 : // We don't support if let chains, so only support a single pattern.
239 29 : rust_assert (expr.get_pattern () != nullptr);
240 :
241 29 : match_arm_pattern
242 29 : = ASTLoweringPattern::translate (*expr.get_pattern ())->clone_pattern ();
243 :
244 : // The match arm corresponding to the if let pattern when it matches.
245 29 : HIR::MatchArm arm (std::move (match_arm_pattern), expr.get_locus (), nullptr,
246 29 : {});
247 :
248 29 : auto crate_num = mappings.get_current_crate ();
249 58 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
250 29 : mappings.get_next_hir_id (crate_num),
251 29 : UNKNOWN_LOCAL_DEFID);
252 :
253 29 : match_arms.emplace_back (std::move (mapping), std::move (arm),
254 29 : std::unique_ptr<HIR::Expr> (kase_expr));
255 :
256 : // The default match arm when the if let pattern does not match
257 58 : Analysis::NodeMapping mapping_default (crate_num, expr.get_node_id (),
258 29 : mappings.get_next_hir_id (crate_num),
259 29 : UNKNOWN_LOCAL_DEFID);
260 :
261 29 : auto match_arm_pattern_wildcard = std::unique_ptr<HIR::WildcardPattern> (
262 29 : new HIR::WildcardPattern (mapping_default, expr.get_locus ()));
263 :
264 29 : HIR::MatchArm arm_default (std::move (match_arm_pattern_wildcard),
265 58 : expr.get_locus (), nullptr, {});
266 :
267 29 : match_arms.emplace_back (std::move (mapping_default), std::move (arm_default),
268 29 : std::unique_ptr<HIR::Expr> (kase_else_expr));
269 29 : }
270 :
271 : void
272 17 : ASTLoweringIfLetBlock::visit (AST::IfLetExpr &expr)
273 : {
274 : // Desugar:
275 : // if let Some(y) = some_value {
276 : // bar();
277 : // }
278 : //
279 : // into:
280 : //
281 : // match some_value {
282 : // Some(y) => {bar();},
283 : // _ => ()
284 : // }
285 :
286 17 : HIR::Expr *branch_value;
287 :
288 17 : std::vector<HIR::MatchCase> match_arms;
289 17 : auto crate_num = mappings.get_current_crate ();
290 34 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
291 17 : mappings.get_next_hir_id (crate_num),
292 17 : UNKNOWN_LOCAL_DEFID);
293 :
294 17 : HIR::TupleExpr *unit
295 17 : = new HIR::TupleExpr (mapping, {}, {}, {}, expr.get_locus ());
296 :
297 17 : desugar_iflet (expr, &branch_value, unit, match_arms);
298 :
299 17 : translated
300 17 : = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
301 34 : std::move (match_arms), {}, {}, expr.get_locus ());
302 17 : }
303 :
304 : void
305 12 : ASTLoweringIfLetBlock::visit (AST::IfLetExprConseqElse &expr)
306 : {
307 : // desugar:
308 : // if let Some(y) = some_value {
309 : // bar();
310 : // } else {
311 : // baz();
312 : // }
313 : //
314 : // into
315 : // match some_value {
316 : // Some(y) => {bar();},
317 : // _ => {baz();}
318 : // }
319 : //
320 :
321 12 : HIR::Expr *branch_value;
322 12 : std::vector<HIR::MatchCase> match_arms;
323 :
324 12 : HIR::Expr *kase_else_expr
325 12 : = ASTLoweringExpr::translate (expr.get_else_block ());
326 :
327 12 : desugar_iflet (expr, &branch_value, kase_else_expr, match_arms);
328 :
329 12 : auto crate_num = mappings.get_current_crate ();
330 24 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
331 12 : mappings.get_next_hir_id (crate_num),
332 12 : UNKNOWN_LOCAL_DEFID);
333 :
334 12 : translated
335 12 : = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
336 24 : std::move (match_arms), {}, {}, expr.get_locus ());
337 12 : }
338 :
339 : // rust-ast-lower-struct-field-expr.h
340 :
341 : void
342 2024 : ASTLowerStructExprField::visit (AST::StructExprFieldIdentifierValue &field)
343 : {
344 2024 : HIR::Expr *value = ASTLoweringExpr::translate (field.get_value ());
345 :
346 2024 : auto crate_num = mappings.get_current_crate ();
347 2024 : Analysis::NodeMapping mapping (crate_num, field.get_node_id (),
348 2024 : mappings.get_next_hir_id (crate_num),
349 2024 : UNKNOWN_LOCAL_DEFID);
350 :
351 2024 : translated = new HIR::StructExprFieldIdentifierValue (
352 6072 : mapping, field.get_field_name (), std::unique_ptr<HIR::Expr> (value),
353 4048 : field.get_locus ());
354 2024 : }
355 :
356 : void
357 44 : ASTLowerStructExprField::visit (AST::StructExprFieldIndexValue &field)
358 : {
359 44 : HIR::Expr *value = ASTLoweringExpr::translate (field.get_value ());
360 :
361 44 : auto crate_num = mappings.get_current_crate ();
362 44 : Analysis::NodeMapping mapping (crate_num, field.get_node_id (),
363 44 : mappings.get_next_hir_id (crate_num),
364 44 : UNKNOWN_LOCAL_DEFID);
365 :
366 44 : translated
367 44 : = new HIR::StructExprFieldIndexValue (mapping, field.get_index (),
368 44 : std::unique_ptr<HIR::Expr> (value),
369 44 : field.get_locus ());
370 44 : }
371 :
372 : void
373 216 : ASTLowerStructExprField::visit (AST::StructExprFieldIdentifier &field)
374 : {
375 216 : auto crate_num = mappings.get_current_crate ();
376 216 : Analysis::NodeMapping mapping (crate_num, field.get_node_id (),
377 216 : mappings.get_next_hir_id (crate_num),
378 216 : UNKNOWN_LOCAL_DEFID);
379 :
380 216 : translated
381 216 : = new HIR::StructExprFieldIdentifier (mapping, field.get_field_name (),
382 216 : field.get_locus ());
383 216 : }
384 :
385 : // rust-ast-lower-block.h
386 :
387 : void
388 77 : ASTLoweringExprWithBlock::visit (AST::WhileLoopExpr &expr)
389 : {
390 77 : HIR::BlockExpr *loop_block
391 77 : = ASTLoweringBlock::translate (expr.get_loop_block (), &terminated);
392 :
393 77 : tl::optional<HIR::LoopLabel> loop_label;
394 77 : if (expr.has_loop_label ())
395 2 : loop_label = lower_loop_label (expr.get_loop_label ());
396 :
397 77 : HIR::Expr *loop_condition
398 77 : = ASTLoweringExpr::translate (expr.get_predicate_expr (), &terminated);
399 :
400 77 : auto crate_num = mappings.get_current_crate ();
401 154 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
402 77 : mappings.get_next_hir_id (crate_num),
403 77 : UNKNOWN_LOCAL_DEFID);
404 :
405 77 : translated
406 77 : = new HIR::WhileLoopExpr (mapping,
407 77 : std::unique_ptr<HIR::Expr> (loop_condition),
408 154 : std::unique_ptr<HIR::BlockExpr> (loop_block),
409 : expr.get_locus (), std::move (loop_label),
410 154 : expr.get_outer_attrs ());
411 77 : }
412 :
413 : void
414 1066 : ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr)
415 : {
416 1066 : HIR::Expr *branch_value
417 1066 : = ASTLoweringExpr::translate (expr.get_scrutinee_expr ());
418 :
419 1066 : std::vector<HIR::MatchCase> match_arms;
420 3543 : for (auto &match_case : expr.get_match_cases ())
421 : {
422 2477 : HIR::Expr *kase_expr
423 2477 : = ASTLoweringExpr::translate (match_case.get_expr ());
424 :
425 2477 : HIR::Expr *kase_guard_expr = nullptr;
426 2477 : if (match_case.get_arm ().has_match_arm_guard ())
427 : {
428 1 : kase_guard_expr = ASTLoweringExpr::translate (
429 : match_case.get_arm ().get_guard_expr ());
430 : }
431 :
432 2477 : std::unique_ptr<HIR::Pattern> match_arm_pattern;
433 :
434 2477 : match_arm_pattern
435 2477 : = ASTLoweringPattern::translate (*match_case.get_arm ().get_pattern ())
436 2477 : ->clone_pattern ();
437 :
438 2477 : HIR::MatchArm arm (std::move (match_arm_pattern), expr.get_locus (),
439 2477 : std::unique_ptr<HIR::Expr> (kase_guard_expr),
440 2477 : match_case.get_arm ().get_outer_attrs ());
441 :
442 2477 : auto crate_num = mappings.get_current_crate ();
443 4954 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
444 2477 : mappings.get_next_hir_id (crate_num),
445 2477 : UNKNOWN_LOCAL_DEFID);
446 :
447 2477 : match_arms.emplace_back (std::move (mapping), std::move (arm),
448 2477 : std::unique_ptr<HIR::Expr> (kase_expr));
449 2477 : }
450 :
451 1066 : auto crate_num = mappings.get_current_crate ();
452 2132 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
453 1066 : mappings.get_next_hir_id (crate_num),
454 1066 : UNKNOWN_LOCAL_DEFID);
455 :
456 1066 : translated
457 1066 : = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
458 1066 : std::move (match_arms), expr.get_inner_attrs (),
459 2132 : expr.get_outer_attrs (), expr.get_locus ());
460 1066 : }
461 :
462 : // rust-ast-lower-expr.h
463 :
464 : void
465 24149 : ASTLowerPathInExpression::visit (AST::PathInExpression &expr)
466 : {
467 24149 : auto crate_num = mappings.get_current_crate ();
468 48298 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
469 24149 : mappings.get_next_hir_id (crate_num),
470 24149 : UNKNOWN_LOCAL_DEFID);
471 :
472 24149 : if (expr.is_lang_item ())
473 : {
474 288 : translated = new HIR::PathInExpression (mapping, expr.get_lang_item (),
475 144 : expr.get_locus (), false);
476 144 : return;
477 : }
478 :
479 24005 : auto &segments = expr.get_segments ();
480 :
481 24005 : std::vector<HIR::PathExprSegment> path_segments;
482 24005 : path_segments.reserve (segments.size ());
483 :
484 57058 : for (auto &s : segments)
485 : {
486 33053 : path_segments.push_back (lower_path_expr_seg ((s)));
487 :
488 : // insert the mappings for the segment
489 33053 : HIR::PathExprSegment *lowered_seg = &path_segments.back ();
490 33053 : mappings.insert_hir_path_expr_seg (lowered_seg);
491 : }
492 :
493 48010 : translated = new HIR::PathInExpression (mapping, std::move (path_segments),
494 : expr.get_locus (),
495 24005 : expr.opening_scope_resolution ());
496 24005 : }
497 :
498 : HIR::QualifiedPathType
499 114 : ASTLoweringBase::lower_qual_path_type (AST::QualifiedPathType &qualified_type)
500 : {
501 114 : HIR::Type *type = ASTLoweringType::translate (qualified_type.get_type ());
502 114 : HIR::TypePath *trait
503 114 : = qualified_type.has_as_clause ()
504 114 : ? ASTLowerTypePath::translate (qualified_type.get_as_type_path ())
505 : : nullptr;
506 :
507 114 : auto crate_num = mappings.get_current_crate ();
508 114 : Analysis::NodeMapping mapping (crate_num, qualified_type.get_node_id (),
509 114 : mappings.get_next_hir_id (crate_num),
510 114 : UNKNOWN_LOCAL_DEFID);
511 :
512 114 : return HIR::QualifiedPathType (mapping, std::unique_ptr<HIR::Type> (type),
513 228 : std::unique_ptr<HIR::TypePath> (trait),
514 114 : qualified_type.get_locus ());
515 : }
516 :
517 : void
518 114 : ASTLowerQualPathInExpression::visit (AST::QualifiedPathInExpression &expr)
519 : {
520 114 : HIR::QualifiedPathType qual_path_type
521 114 : = lower_qual_path_type (expr.get_qualified_path_type ());
522 :
523 114 : auto &segments = expr.get_segments ();
524 :
525 114 : std::vector<HIR::PathExprSegment> path_segments;
526 114 : path_segments.reserve (segments.size ());
527 :
528 228 : for (auto &s : segments)
529 : {
530 114 : path_segments.push_back (lower_path_expr_seg ((s)));
531 :
532 : // insert the mappings for the segment
533 114 : HIR::PathExprSegment *lowered_seg = &path_segments.back ();
534 114 : mappings.insert_hir_path_expr_seg (lowered_seg);
535 : }
536 :
537 114 : auto crate_num = mappings.get_current_crate ();
538 228 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
539 114 : mappings.get_next_hir_id (crate_num),
540 114 : UNKNOWN_LOCAL_DEFID);
541 :
542 114 : translated = new HIR::QualifiedPathInExpression (mapping, qual_path_type,
543 : std::move (path_segments),
544 : expr.get_locus (),
545 228 : expr.get_outer_attrs ());
546 114 : }
547 :
548 : ClosureParam
549 61 : ASTLoweringBase::lower_closure_param (AST::ClosureParam ¶m)
550 : {
551 61 : HIR::Pattern *param_pattern
552 61 : = ASTLoweringPattern::translate (param.get_pattern ());
553 :
554 61 : HIR::Type *param_type = param.has_type_given ()
555 61 : ? ASTLoweringType::translate (param.get_type ())
556 : : nullptr;
557 :
558 122 : return HIR::ClosureParam (std::unique_ptr<HIR::Pattern> (param_pattern),
559 : param.get_locus (),
560 61 : param.has_type_given ()
561 122 : ? std::unique_ptr<HIR::Type> (param_type)
562 : : nullptr,
563 183 : param.get_outer_attrs ());
564 : }
565 :
566 : } // namespace HIR
567 : } // namespace Rust
|