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 37391 : 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 37391 : switch (vis.get_vis_type ())
43 : {
44 8360 : case AST::Visibility::PUB:
45 8360 : return Visibility (Visibility::VisType::PUBLIC);
46 28970 : case AST::Visibility::PRIV:
47 28970 : case AST::Visibility::PUB_SELF:
48 28970 : 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 4504 : ASTLowering::ASTLowering (AST::Crate &astCrate) : astCrate (astCrate) {}
62 :
63 4504 : ASTLowering::~ASTLowering () {}
64 :
65 : std::unique_ptr<HIR::Crate>
66 4504 : ASTLowering::Resolve (AST::Crate &astCrate)
67 : {
68 4504 : ASTLowering resolver (astCrate);
69 4504 : return resolver.go ();
70 4504 : }
71 :
72 : std::unique_ptr<HIR::Crate>
73 4504 : ASTLowering::go ()
74 : {
75 4504 : std::vector<std::unique_ptr<HIR::Item>> items;
76 :
77 23721 : for (auto &item : astCrate.items)
78 : {
79 19217 : auto translated = ASTLoweringItem::translate (*item);
80 19217 : if (translated != nullptr)
81 18102 : items.emplace_back (translated);
82 : }
83 :
84 4504 : auto &mappings = Analysis::Mappings::get ();
85 4504 : auto crate_num = mappings.get_current_crate ();
86 4504 : Analysis::NodeMapping mapping (crate_num, astCrate.get_node_id (),
87 : mappings.get_next_hir_id (crate_num),
88 4504 : UNKNOWN_LOCAL_DEFID);
89 :
90 4504 : return std::unique_ptr<HIR::Crate> (
91 4504 : new HIR::Crate (std::move (items), astCrate.get_inner_attrs (), mapping));
92 4504 : }
93 :
94 : // rust-ast-lower-block.h
95 : void
96 22922 : ASTLoweringBlock::visit (AST::BlockExpr &expr)
97 : {
98 22922 : tl::optional<HIR::LoopLabel> label;
99 22922 : if (expr.has_label ())
100 0 : label = lower_loop_label (expr.get_label ());
101 : else
102 : label = tl::nullopt;
103 :
104 22922 : std::vector<std::unique_ptr<HIR::Stmt>> block_stmts;
105 22922 : bool block_did_terminate = false;
106 :
107 46869 : 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 23947 : 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 23947 : if (block_did_terminate)
121 18 : rust_warning_at (s->get_locus (), 0, "unreachable statement");
122 :
123 23947 : bool terminated = false;
124 23947 : auto translated_stmt = ASTLoweringStmt::translate (s.get (), &terminated);
125 23947 : block_did_terminate |= terminated;
126 :
127 23947 : if (translated_stmt)
128 23936 : block_stmts.emplace_back (translated_stmt);
129 : }
130 :
131 22922 : 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 22922 : HIR::ExprWithoutBlock *tail_expr = nullptr;
139 22922 : if (expr.has_tail_expr ())
140 : {
141 16188 : bool terminated = false;
142 16188 : tail_expr = (HIR::ExprWithoutBlock *)
143 16188 : ASTLoweringExpr::translate (expr.get_tail_expr (), &terminated);
144 16188 : block_did_terminate |= terminated;
145 : }
146 :
147 22922 : bool tail_reachable = !block_did_terminate;
148 22922 : auto crate_num = mappings.get_current_crate ();
149 45844 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
150 22922 : mappings.get_next_hir_id (crate_num),
151 22922 : UNKNOWN_LOCAL_DEFID);
152 22922 : translated
153 22922 : = new HIR::BlockExpr (mapping, std::move (block_stmts),
154 45844 : std::unique_ptr<HIR::ExprWithoutBlock> (tail_expr),
155 22922 : tail_reachable, expr.get_inner_attrs (),
156 22922 : expr.get_outer_attrs (), label,
157 45844 : expr.get_start_locus (), expr.get_end_locus ());
158 :
159 22922 : terminated = block_did_terminate;
160 22922 : }
161 :
162 : void
163 1227 : ASTLoweringIfBlock::visit (AST::IfExpr &expr)
164 : {
165 1227 : bool ignored_terminated = false;
166 1227 : HIR::Expr *condition = ASTLoweringExpr::translate (expr.get_condition_expr (),
167 : &ignored_terminated);
168 1227 : HIR::BlockExpr *block
169 1227 : = ASTLoweringBlock::translate (expr.get_if_block (), &ignored_terminated);
170 :
171 1227 : auto crate_num = mappings.get_current_crate ();
172 2454 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
173 1227 : mappings.get_next_hir_id (crate_num),
174 1227 : UNKNOWN_LOCAL_DEFID);
175 :
176 1227 : translated = new HIR::IfExpr (mapping, std::unique_ptr<HIR::Expr> (condition),
177 2454 : std::unique_ptr<HIR::BlockExpr> (block),
178 1227 : expr.get_locus ());
179 1227 : }
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 2032 : ASTLowerStructExprField::visit (AST::StructExprFieldIdentifierValue &field)
343 : {
344 2032 : HIR::Expr *value = ASTLoweringExpr::translate (field.get_value ());
345 :
346 2032 : auto crate_num = mappings.get_current_crate ();
347 2032 : Analysis::NodeMapping mapping (crate_num, field.get_node_id (),
348 2032 : mappings.get_next_hir_id (crate_num),
349 2032 : UNKNOWN_LOCAL_DEFID);
350 :
351 2032 : translated = new HIR::StructExprFieldIdentifierValue (
352 6096 : mapping, field.get_field_name (), std::unique_ptr<HIR::Expr> (value),
353 4064 : field.get_locus ());
354 2032 : }
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 1073 : ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr)
415 : {
416 1073 : HIR::Expr *branch_value
417 1073 : = ASTLoweringExpr::translate (expr.get_scrutinee_expr ());
418 :
419 1073 : std::vector<HIR::MatchCase> match_arms;
420 3563 : for (auto &match_case : expr.get_match_cases ())
421 : {
422 2490 : HIR::Expr *kase_expr
423 2490 : = ASTLoweringExpr::translate (match_case.get_expr ());
424 :
425 2490 : HIR::Expr *kase_guard_expr = nullptr;
426 2490 : 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 2490 : std::unique_ptr<HIR::Pattern> match_arm_pattern;
433 :
434 2490 : match_arm_pattern
435 2490 : = ASTLoweringPattern::translate (*match_case.get_arm ().get_pattern ())
436 2490 : ->clone_pattern ();
437 :
438 2490 : HIR::MatchArm arm (std::move (match_arm_pattern), expr.get_locus (),
439 2490 : std::unique_ptr<HIR::Expr> (kase_guard_expr),
440 2490 : match_case.get_arm ().get_outer_attrs ());
441 :
442 2490 : auto crate_num = mappings.get_current_crate ();
443 4980 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
444 2490 : mappings.get_next_hir_id (crate_num),
445 2490 : UNKNOWN_LOCAL_DEFID);
446 :
447 2490 : match_arms.emplace_back (std::move (mapping), std::move (arm),
448 2490 : std::unique_ptr<HIR::Expr> (kase_expr));
449 2490 : }
450 :
451 1073 : auto crate_num = mappings.get_current_crate ();
452 2146 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
453 1073 : mappings.get_next_hir_id (crate_num),
454 1073 : UNKNOWN_LOCAL_DEFID);
455 :
456 1073 : translated
457 1073 : = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
458 1073 : std::move (match_arms), expr.get_inner_attrs (),
459 2146 : expr.get_outer_attrs (), expr.get_locus ());
460 1073 : }
461 :
462 : // rust-ast-lower-expr.h
463 :
464 : void
465 25663 : ASTLowerPathInExpression::visit (AST::PathInExpression &expr)
466 : {
467 25663 : auto crate_num = mappings.get_current_crate ();
468 51326 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
469 25663 : mappings.get_next_hir_id (crate_num),
470 25663 : UNKNOWN_LOCAL_DEFID);
471 :
472 25663 : 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 25519 : auto &segments = expr.get_segments ();
480 :
481 25519 : std::vector<HIR::PathExprSegment> path_segments;
482 25519 : path_segments.reserve (segments.size ());
483 :
484 60092 : for (auto &s : segments)
485 : {
486 34573 : path_segments.push_back (lower_path_expr_seg ((s)));
487 :
488 : // insert the mappings for the segment
489 34573 : HIR::PathExprSegment *lowered_seg = &path_segments.back ();
490 34573 : mappings.insert_hir_path_expr_seg (lowered_seg);
491 : }
492 :
493 51038 : translated = new HIR::PathInExpression (mapping, std::move (path_segments),
494 : expr.get_locus (),
495 25519 : expr.opening_scope_resolution ());
496 25519 : }
497 :
498 : HIR::QualifiedPathType
499 116 : ASTLoweringBase::lower_qual_path_type (AST::QualifiedPathType &qualified_type)
500 : {
501 116 : HIR::Type *type = ASTLoweringType::translate (qualified_type.get_type ());
502 116 : HIR::TypePath *trait
503 116 : = qualified_type.has_as_clause ()
504 116 : ? ASTLowerTypePath::translate (qualified_type.get_as_type_path ())
505 : : nullptr;
506 :
507 116 : auto crate_num = mappings.get_current_crate ();
508 116 : Analysis::NodeMapping mapping (crate_num, qualified_type.get_node_id (),
509 116 : mappings.get_next_hir_id (crate_num),
510 116 : UNKNOWN_LOCAL_DEFID);
511 :
512 116 : return HIR::QualifiedPathType (mapping, std::unique_ptr<HIR::Type> (type),
513 232 : std::unique_ptr<HIR::TypePath> (trait),
514 116 : qualified_type.get_locus ());
515 : }
516 :
517 : void
518 116 : ASTLowerQualPathInExpression::visit (AST::QualifiedPathInExpression &expr)
519 : {
520 116 : HIR::QualifiedPathType qual_path_type
521 116 : = lower_qual_path_type (expr.get_qualified_path_type ());
522 :
523 116 : auto &segments = expr.get_segments ();
524 :
525 116 : std::vector<HIR::PathExprSegment> path_segments;
526 116 : path_segments.reserve (segments.size ());
527 :
528 232 : for (auto &s : segments)
529 : {
530 116 : path_segments.push_back (lower_path_expr_seg ((s)));
531 :
532 : // insert the mappings for the segment
533 116 : HIR::PathExprSegment *lowered_seg = &path_segments.back ();
534 116 : mappings.insert_hir_path_expr_seg (lowered_seg);
535 : }
536 :
537 116 : auto crate_num = mappings.get_current_crate ();
538 232 : Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
539 116 : mappings.get_next_hir_id (crate_num),
540 116 : UNKNOWN_LOCAL_DEFID);
541 :
542 116 : translated = new HIR::QualifiedPathInExpression (mapping, qual_path_type,
543 : std::move (path_segments),
544 : expr.get_locus (),
545 232 : expr.get_outer_attrs ());
546 116 : }
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
|