1 use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs}
;
4 use rustc_data_structures
::thin_vec
::ThinVec
;
5 use rustc_errors
::struct_span_err
;
7 use rustc_hir
::def
::Res
;
8 use rustc_span
::source_map
::{respan, DesugaringKind, Span, Spanned}
;
9 use rustc_span
::symbol
::{sym, Symbol}
;
12 use syntax
::ptr
::P
as AstP
;
14 impl<'hir
> LoweringContext
<'_
, 'hir
> {
15 fn lower_exprs(&mut self, exprs
: &[AstP
<Expr
>]) -> &'hir
[hir
::Expr
<'hir
>] {
16 self.arena
.alloc_from_iter(exprs
.iter().map(|x
| self.lower_expr_mut(x
)))
19 pub(super) fn lower_expr(&mut self, e
: &Expr
) -> &'hir hir
::Expr
<'hir
> {
20 self.arena
.alloc(self.lower_expr_mut(e
))
23 pub(super) fn lower_expr_mut(&mut self, e
: &Expr
) -> hir
::Expr
<'hir
> {
24 let kind
= match e
.kind
{
25 ExprKind
::Box(ref inner
) => hir
::ExprKind
::Box(self.lower_expr(inner
)),
26 ExprKind
::Array(ref exprs
) => hir
::ExprKind
::Array(self.lower_exprs(exprs
)),
27 ExprKind
::Repeat(ref expr
, ref count
) => {
28 let expr
= self.lower_expr(expr
);
29 let count
= self.lower_anon_const(count
);
30 hir
::ExprKind
::Repeat(expr
, count
)
32 ExprKind
::Tup(ref elts
) => hir
::ExprKind
::Tup(self.lower_exprs(elts
)),
33 ExprKind
::Call(ref f
, ref args
) => {
34 let f
= self.lower_expr(f
);
35 hir
::ExprKind
::Call(f
, self.lower_exprs(args
))
37 ExprKind
::MethodCall(ref seg
, ref args
) => {
38 let hir_seg
= self.arena
.alloc(self.lower_path_segment(
43 ParenthesizedGenericArgs
::Err
,
44 ImplTraitContext
::disallowed(),
47 let args
= self.lower_exprs(args
);
48 hir
::ExprKind
::MethodCall(hir_seg
, seg
.ident
.span
, args
)
50 ExprKind
::Binary(binop
, ref lhs
, ref rhs
) => {
51 let binop
= self.lower_binop(binop
);
52 let lhs
= self.lower_expr(lhs
);
53 let rhs
= self.lower_expr(rhs
);
54 hir
::ExprKind
::Binary(binop
, lhs
, rhs
)
56 ExprKind
::Unary(op
, ref ohs
) => {
57 let op
= self.lower_unop(op
);
58 let ohs
= self.lower_expr(ohs
);
59 hir
::ExprKind
::Unary(op
, ohs
)
61 ExprKind
::Lit(ref l
) => hir
::ExprKind
::Lit(respan(l
.span
, l
.kind
.clone())),
62 ExprKind
::Cast(ref expr
, ref ty
) => {
63 let expr
= self.lower_expr(expr
);
64 let ty
= self.lower_ty(ty
, ImplTraitContext
::disallowed());
65 hir
::ExprKind
::Cast(expr
, ty
)
67 ExprKind
::Type(ref expr
, ref ty
) => {
68 let expr
= self.lower_expr(expr
);
69 let ty
= self.lower_ty(ty
, ImplTraitContext
::disallowed());
70 hir
::ExprKind
::Type(expr
, ty
)
72 ExprKind
::AddrOf(k
, m
, ref ohs
) => {
73 let ohs
= self.lower_expr(ohs
);
74 hir
::ExprKind
::AddrOf(k
, m
, ohs
)
76 ExprKind
::Let(ref pat
, ref scrutinee
) => self.lower_expr_let(e
.span
, pat
, scrutinee
),
77 ExprKind
::If(ref cond
, ref then
, ref else_opt
) => {
78 self.lower_expr_if(e
.span
, cond
, then
, else_opt
.as_deref())
80 ExprKind
::While(ref cond
, ref body
, opt_label
) => self.with_loop_scope(e
.id
, |this
| {
81 this
.lower_expr_while_in_loop_scope(e
.span
, cond
, body
, opt_label
)
83 ExprKind
::Loop(ref body
, opt_label
) => self.with_loop_scope(e
.id
, |this
| {
84 hir
::ExprKind
::Loop(this
.lower_block(body
, false), opt_label
, hir
::LoopSource
::Loop
)
86 ExprKind
::TryBlock(ref body
) => self.lower_expr_try_block(body
),
87 ExprKind
::Match(ref expr
, ref arms
) => hir
::ExprKind
::Match(
88 self.lower_expr(expr
),
89 self.arena
.alloc_from_iter(arms
.iter().map(|x
| self.lower_arm(x
))),
90 hir
::MatchSource
::Normal
,
92 ExprKind
::Async(capture_clause
, closure_node_id
, ref block
) => self.make_async_expr(
97 hir
::AsyncGeneratorKind
::Block
,
98 |this
| this
.with_new_scopes(|this
| this
.lower_block_expr(block
)),
100 ExprKind
::Await(ref expr
) => self.lower_expr_await(e
.span
, expr
),
109 if let IsAsync
::Async { closure_id, .. }
= asyncness
{
110 self.lower_expr_async_closure(
118 self.lower_expr_closure(capture_clause
, movability
, decl
, body
, fn_decl_span
)
121 ExprKind
::Block(ref blk
, opt_label
) => {
122 hir
::ExprKind
::Block(self.lower_block(blk
, opt_label
.is_some()), opt_label
)
124 ExprKind
::Assign(ref el
, ref er
, span
) => {
125 hir
::ExprKind
::Assign(self.lower_expr(el
), self.lower_expr(er
), span
)
127 ExprKind
::AssignOp(op
, ref el
, ref er
) => hir
::ExprKind
::AssignOp(
128 self.lower_binop(op
),
132 ExprKind
::Field(ref el
, ident
) => hir
::ExprKind
::Field(self.lower_expr(el
), ident
),
133 ExprKind
::Index(ref el
, ref er
) => {
134 hir
::ExprKind
::Index(self.lower_expr(el
), self.lower_expr(er
))
136 ExprKind
::Range(Some(ref e1
), Some(ref e2
), RangeLimits
::Closed
) => {
137 self.lower_expr_range_closed(e
.span
, e1
, e2
)
139 ExprKind
::Range(ref e1
, ref e2
, lims
) => {
140 self.lower_expr_range(e
.span
, e1
.as_deref(), e2
.as_deref(), lims
)
142 ExprKind
::Path(ref qself
, ref path
) => {
143 let qpath
= self.lower_qpath(
148 ImplTraitContext
::disallowed(),
150 hir
::ExprKind
::Path(qpath
)
152 ExprKind
::Break(opt_label
, ref opt_expr
) => {
153 let opt_expr
= opt_expr
.as_ref().map(|x
| self.lower_expr(x
));
154 hir
::ExprKind
::Break(self.lower_jump_destination(e
.id
, opt_label
), opt_expr
)
156 ExprKind
::Continue(opt_label
) => {
157 hir
::ExprKind
::Continue(self.lower_jump_destination(e
.id
, opt_label
))
159 ExprKind
::Ret(ref e
) => {
160 let e
= e
.as_ref().map(|x
| self.lower_expr(x
));
161 hir
::ExprKind
::Ret(e
)
163 ExprKind
::InlineAsm(ref asm
) => self.lower_expr_asm(asm
),
164 ExprKind
::Struct(ref path
, ref fields
, ref maybe_expr
) => {
165 let maybe_expr
= maybe_expr
.as_ref().map(|x
| self.lower_expr(x
));
166 hir
::ExprKind
::Struct(
167 self.arena
.alloc(self.lower_qpath(
172 ImplTraitContext
::disallowed(),
174 self.arena
.alloc_from_iter(fields
.iter().map(|x
| self.lower_field(x
))),
178 ExprKind
::Paren(ref ex
) => {
179 let mut ex
= self.lower_expr_mut(ex
);
180 // Include parens in span, but only if it is a super-span.
181 if e
.span
.contains(ex
.span
) {
184 // Merge attributes into the inner expression.
185 let mut attrs
= e
.attrs
.clone();
186 attrs
.extend
::<Vec
<_
>>(ex
.attrs
.into());
191 ExprKind
::Yield(ref opt_expr
) => self.lower_expr_yield(e
.span
, opt_expr
.as_deref()),
193 ExprKind
::Err
=> hir
::ExprKind
::Err
,
195 // Desugar `ExprForLoop`
196 // from: `[opt_ident]: for <pat> in <head> <body>`
197 ExprKind
::ForLoop(ref pat
, ref head
, ref body
, opt_label
) => {
198 return self.lower_expr_for(e
, pat
, head
, body
, opt_label
);
200 ExprKind
::Try(ref sub_expr
) => self.lower_expr_try(e
.span
, sub_expr
),
201 ExprKind
::Mac(_
) => panic
!("Shouldn't exist here"),
205 hir_id
: self.lower_node_id(e
.id
),
208 attrs
: e
.attrs
.iter().map(|a
| self.lower_attr(a
)).collect
::<Vec
<_
>>().into(),
212 fn lower_unop(&mut self, u
: UnOp
) -> hir
::UnOp
{
214 UnOp
::Deref
=> hir
::UnOp
::UnDeref
,
215 UnOp
::Not
=> hir
::UnOp
::UnNot
,
216 UnOp
::Neg
=> hir
::UnOp
::UnNeg
,
220 fn lower_binop(&mut self, b
: BinOp
) -> hir
::BinOp
{
223 BinOpKind
::Add
=> hir
::BinOpKind
::Add
,
224 BinOpKind
::Sub
=> hir
::BinOpKind
::Sub
,
225 BinOpKind
::Mul
=> hir
::BinOpKind
::Mul
,
226 BinOpKind
::Div
=> hir
::BinOpKind
::Div
,
227 BinOpKind
::Rem
=> hir
::BinOpKind
::Rem
,
228 BinOpKind
::And
=> hir
::BinOpKind
::And
,
229 BinOpKind
::Or
=> hir
::BinOpKind
::Or
,
230 BinOpKind
::BitXor
=> hir
::BinOpKind
::BitXor
,
231 BinOpKind
::BitAnd
=> hir
::BinOpKind
::BitAnd
,
232 BinOpKind
::BitOr
=> hir
::BinOpKind
::BitOr
,
233 BinOpKind
::Shl
=> hir
::BinOpKind
::Shl
,
234 BinOpKind
::Shr
=> hir
::BinOpKind
::Shr
,
235 BinOpKind
::Eq
=> hir
::BinOpKind
::Eq
,
236 BinOpKind
::Lt
=> hir
::BinOpKind
::Lt
,
237 BinOpKind
::Le
=> hir
::BinOpKind
::Le
,
238 BinOpKind
::Ne
=> hir
::BinOpKind
::Ne
,
239 BinOpKind
::Ge
=> hir
::BinOpKind
::Ge
,
240 BinOpKind
::Gt
=> hir
::BinOpKind
::Gt
,
246 /// Emit an error and lower `ast::ExprKind::Let(pat, scrutinee)` into:
248 /// match scrutinee { pats => true, _ => false }
250 fn lower_expr_let(&mut self, span
: Span
, pat
: &Pat
, scrutinee
: &Expr
) -> hir
::ExprKind
<'hir
> {
251 // If we got here, the `let` expression is not allowed.
253 if self.sess
.opts
.unstable_features
.is_nightly_build() {
255 .struct_span_err(span
, "`let` expressions are not supported here")
256 .note("only supported directly in conditions of `if`- and `while`-expressions")
257 .note("as well as when nested within `&&` and parenthesis in those conditions")
261 .struct_span_err(span
, "expected expression, found statement (`let`)")
262 .note("variable declaration using `let` is a statement")
266 // For better recovery, we emit:
268 // match scrutinee { pat => true, _ => false }
270 // While this doesn't fully match the user's intent, it has key advantages:
271 // 1. We can avoid using `abort_if_errors`.
272 // 2. We can typeck both `pat` and `scrutinee`.
273 // 3. `pat` is allowed to be refutable.
274 // 4. The return type of the block is `bool` which seems like what the user wanted.
275 let scrutinee
= self.lower_expr(scrutinee
);
277 let pat
= self.lower_pat(pat
);
278 let expr
= self.expr_bool(span
, true);
282 let pat
= self.pat_wild(span
);
283 let expr
= self.expr_bool(span
, false);
286 hir
::ExprKind
::Match(
288 arena_vec
![self; then_arm
, else_arm
],
289 hir
::MatchSource
::Normal
,
298 else_opt
: Option
<&Expr
>,
299 ) -> hir
::ExprKind
<'hir
> {
300 // FIXME(#53667): handle lowering of && and parens.
302 // `_ => else_block` where `else_block` is `{}` if there's `None`:
303 let else_pat
= self.pat_wild(span
);
304 let (else_expr
, contains_else_clause
) = match else_opt
{
305 None
=> (self.expr_block_empty(span
), false),
306 Some(els
) => (self.lower_expr(els
), true),
308 let else_arm
= self.arm(else_pat
, else_expr
);
310 // Handle then + scrutinee:
311 let then_expr
= self.lower_block_expr(then
);
312 let (then_pat
, scrutinee
, desugar
) = match cond
.kind
{
313 // `<pat> => <then>`:
314 ExprKind
::Let(ref pat
, ref scrutinee
) => {
315 let scrutinee
= self.lower_expr(scrutinee
);
316 let pat
= self.lower_pat(pat
);
317 (pat
, scrutinee
, hir
::MatchSource
::IfLetDesugar { contains_else_clause }
)
322 let cond
= self.lower_expr(cond
);
324 self.mark_span_with_reason(DesugaringKind
::CondTemporary
, cond
.span
, None
);
325 // Wrap in a construct equivalent to `{ let _t = $cond; _t }`
326 // to preserve drop semantics since `if cond { ... }` does not
327 // let temporaries live outside of `cond`.
328 let cond
= self.expr_drop_temps(span_block
, cond
, ThinVec
::new());
329 let pat
= self.pat_bool(span
, true);
330 (pat
, cond
, hir
::MatchSource
::IfDesugar { contains_else_clause }
)
333 let then_arm
= self.arm(then_pat
, self.arena
.alloc(then_expr
));
335 hir
::ExprKind
::Match(scrutinee
, arena_vec
![self; then_arm
, else_arm
], desugar
)
338 fn lower_expr_while_in_loop_scope(
343 opt_label
: Option
<Label
>,
344 ) -> hir
::ExprKind
<'hir
> {
345 // FIXME(#53667): handle lowering of && and parens.
347 // Note that the block AND the condition are evaluated in the loop scope.
348 // This is done to allow `break` from inside the condition of the loop.
352 let else_pat
= self.pat_wild(span
);
353 let else_expr
= self.expr_break(span
, ThinVec
::new());
354 self.arm(else_pat
, else_expr
)
357 // Handle then + scrutinee:
358 let then_expr
= self.lower_block_expr(body
);
359 let (then_pat
, scrutinee
, desugar
, source
) = match cond
.kind
{
360 ExprKind
::Let(ref pat
, ref scrutinee
) => {
363 // [opt_ident]: loop {
364 // match <sub_expr> {
369 let scrutinee
= self.with_loop_condition_scope(|t
| t
.lower_expr(scrutinee
));
370 let pat
= self.lower_pat(pat
);
371 (pat
, scrutinee
, hir
::MatchSource
::WhileLetDesugar
, hir
::LoopSource
::WhileLet
)
374 // We desugar: `'label: while $cond $body` into:
378 // match drop-temps { $cond } {
386 let cond
= self.with_loop_condition_scope(|this
| this
.lower_expr(cond
));
388 self.mark_span_with_reason(DesugaringKind
::CondTemporary
, cond
.span
, None
);
389 // Wrap in a construct equivalent to `{ let _t = $cond; _t }`
390 // to preserve drop semantics since `while cond { ... }` does not
391 // let temporaries live outside of `cond`.
392 let cond
= self.expr_drop_temps(span_block
, cond
, ThinVec
::new());
394 let pat
= self.pat_bool(span
, true);
395 (pat
, cond
, hir
::MatchSource
::WhileDesugar
, hir
::LoopSource
::While
)
398 let then_arm
= self.arm(then_pat
, self.arena
.alloc(then_expr
));
400 // `match <scrutinee> { ... }`
401 let match_expr
= self.expr_match(
404 arena_vec
![self; then_arm
, else_arm
],
408 // `[opt_ident]: loop { ... }`
409 hir
::ExprKind
::Loop(self.block_expr(self.arena
.alloc(match_expr
)), opt_label
, source
)
412 /// Desugar `try { <stmts>; <expr> }` into `{ <stmts>; ::std::ops::Try::from_ok(<expr>) }`,
413 /// `try { <stmts>; }` into `{ <stmts>; ::std::ops::Try::from_ok(()) }`
414 /// and save the block id to use it as a break target for desugaring of the `?` operator.
415 fn lower_expr_try_block(&mut self, body
: &Block
) -> hir
::ExprKind
<'hir
> {
416 self.with_catch_scope(body
.id
, |this
| {
417 let mut block
= this
.lower_block_noalloc(body
, true);
419 let try_span
= this
.mark_span_with_reason(
420 DesugaringKind
::TryBlock
,
422 this
.allow_try_trait
.clone(),
425 // Final expression of the block (if present) or `()` with span at the end of block
426 let tail_expr
= block
429 .unwrap_or_else(|| this
.expr_unit(this
.sess
.source_map().end_point(try_span
)));
431 let ok_wrapped_span
=
432 this
.mark_span_with_reason(DesugaringKind
::TryBlock
, tail_expr
.span
, None
);
434 // `::std::ops::Try::from_ok($tail_expr)`
435 block
.expr
= Some(this
.wrap_in_try_constructor(
442 hir
::ExprKind
::Block(this
.arena
.alloc(block
), None
)
446 fn wrap_in_try_constructor(
450 expr
: &'hir hir
::Expr
<'hir
>,
452 ) -> &'hir hir
::Expr
<'hir
> {
453 let path
= &[sym
::ops
, sym
::Try
, method
];
455 self.arena
.alloc(self.expr_std_path(method_span
, path
, None
, ThinVec
::new()));
456 self.expr_call(overall_span
, constructor
, std
::slice
::from_ref(expr
))
459 fn lower_arm(&mut self, arm
: &Arm
) -> hir
::Arm
<'hir
> {
461 hir_id
: self.next_id(),
462 attrs
: self.lower_attrs(&arm
.attrs
),
463 pat
: self.lower_pat(&arm
.pat
),
464 guard
: match arm
.guard
{
465 Some(ref x
) => Some(hir
::Guard
::If(self.lower_expr(x
))),
468 body
: self.lower_expr(&arm
.body
),
473 pub(super) fn make_async_expr(
475 capture_clause
: CaptureBy
,
476 closure_node_id
: NodeId
,
477 ret_ty
: Option
<AstP
<Ty
>>,
479 async_gen_kind
: hir
::AsyncGeneratorKind
,
480 body
: impl FnOnce(&mut Self) -> hir
::Expr
<'hir
>,
481 ) -> hir
::ExprKind
<'hir
> {
482 let output
= match ret_ty
{
483 Some(ty
) => FunctionRetTy
::Ty(ty
),
484 None
=> FunctionRetTy
::Default(span
),
486 let ast_decl
= FnDecl { inputs: vec![], output }
;
487 let decl
= self.lower_fn_decl(&ast_decl
, None
, /* impl trait allowed */ false, None
);
488 let body_id
= self.lower_fn_body(&ast_decl
, |this
| {
489 this
.generator_kind
= Some(hir
::GeneratorKind
::Async(async_gen_kind
));
493 // `static || -> <ret_ty> { body }`:
494 let generator_kind
= hir
::ExprKind
::Closure(
499 Some(hir
::Movability
::Static
),
501 let generator
= hir
::Expr
{
502 hir_id
: self.lower_node_id(closure_node_id
),
503 kind
: generator_kind
,
505 attrs
: ThinVec
::new(),
508 // `future::from_generator`:
510 self.mark_span_with_reason(DesugaringKind
::Async
, span
, self.allow_gen_future
.clone());
511 let gen_future
= self.expr_std_path(
513 &[sym
::future
, sym
::from_generator
],
518 // `future::from_generator(generator)`:
519 hir
::ExprKind
::Call(self.arena
.alloc(gen_future
), arena_vec
![self; generator
])
522 /// Desugar `<expr>.await` into:
525 /// mut pinned => loop {
526 /// match ::std::future::poll_with_tls_context(unsafe {
527 /// <::std::pin::Pin>::new_unchecked(&mut pinned)
529 /// ::std::task::Poll::Ready(result) => break result,
530 /// ::std::task::Poll::Pending => {}
536 fn lower_expr_await(&mut self, await_span
: Span
, expr
: &Expr
) -> hir
::ExprKind
<'hir
> {
537 match self.generator_kind
{
538 Some(hir
::GeneratorKind
::Async(_
)) => {}
539 Some(hir
::GeneratorKind
::Gen
) | None
=> {
540 let mut err
= struct_span_err
!(
544 "`await` is only allowed inside `async` functions and blocks"
546 err
.span_label(await_span
, "only allowed inside `async` functions and blocks");
547 if let Some(item_sp
) = self.current_item
{
548 err
.span_label(item_sp
, "this is not `async`");
553 let span
= self.mark_span_with_reason(DesugaringKind
::Await
, await_span
, None
);
554 let gen_future_span
= self.mark_span_with_reason(
555 DesugaringKind
::Await
,
557 self.allow_gen_future
.clone(),
560 let pinned_ident
= Ident
::with_dummy_span(sym
::pinned
);
561 let (pinned_pat
, pinned_pat_hid
) =
562 self.pat_ident_binding_mode(span
, pinned_ident
, hir
::BindingAnnotation
::Mutable
);
564 // ::std::future::poll_with_tls_context(unsafe {
565 // ::std::pin::Pin::new_unchecked(&mut pinned)
568 let pinned
= self.expr_ident(span
, pinned_ident
, pinned_pat_hid
);
569 let ref_mut_pinned
= self.expr_mut_addr_of(span
, pinned
);
570 let pin_ty_id
= self.next_id();
571 let new_unchecked_expr_kind
= self.expr_call_std_assoc_fn(
574 &[sym
::pin
, sym
::Pin
],
576 arena_vec
![self; ref_mut_pinned
],
579 self.arena
.alloc(self.expr(span
, new_unchecked_expr_kind
, ThinVec
::new()));
580 let unsafe_expr
= self.expr_unsafe(new_unchecked
);
581 self.expr_call_std_path(
583 &[sym
::future
, sym
::poll_with_tls_context
],
584 arena_vec
![self; unsafe_expr
],
588 // `::std::task::Poll::Ready(result) => break result`
589 let loop_node_id
= self.resolver
.next_node_id();
590 let loop_hir_id
= self.lower_node_id(loop_node_id
);
592 let x_ident
= Ident
::with_dummy_span(sym
::result
);
593 let (x_pat
, x_pat_hid
) = self.pat_ident(span
, x_ident
);
594 let x_expr
= self.expr_ident(span
, x_ident
, x_pat_hid
);
595 let ready_pat
= self.pat_std_enum(
597 &[sym
::task
, sym
::Poll
, sym
::Ready
],
598 arena_vec
![self; x_pat
],
600 let break_x
= self.with_loop_scope(loop_node_id
, move |this
| {
602 hir
::ExprKind
::Break(this
.lower_loop_destination(None
), Some(x_expr
));
603 this
.arena
.alloc(this
.expr(await_span
, expr_break
, ThinVec
::new()))
605 self.arm(ready_pat
, break_x
)
608 // `::std::task::Poll::Pending => {}`
610 let pending_pat
= self.pat_std_enum(span
, &[sym
::task
, sym
::Poll
, sym
::Pending
], &[]);
611 let empty_block
= self.expr_block_empty(span
);
612 self.arm(pending_pat
, empty_block
)
615 let inner_match_stmt
= {
616 let match_expr
= self.expr_match(
619 arena_vec
![self; ready_arm
, pending_arm
],
620 hir
::MatchSource
::AwaitDesugar
,
622 self.stmt_expr(span
, match_expr
)
626 let unit
= self.expr_unit(span
);
627 let yield_expr
= self.expr(
629 hir
::ExprKind
::Yield(unit
, hir
::YieldSource
::Await
),
632 self.stmt_expr(span
, yield_expr
)
635 let loop_block
= self.block_all(span
, arena_vec
![self; inner_match_stmt
, yield_stmt
], None
);
638 let loop_expr
= self.arena
.alloc(hir
::Expr
{
640 kind
: hir
::ExprKind
::Loop(loop_block
, None
, hir
::LoopSource
::Loop
),
642 attrs
: ThinVec
::new(),
645 // mut pinned => loop { ... }
646 let pinned_arm
= self.arm(pinned_pat
, loop_expr
);
649 // mut pinned => loop { .. }
651 let expr
= self.lower_expr(expr
);
652 hir
::ExprKind
::Match(expr
, arena_vec
![self; pinned_arm
], hir
::MatchSource
::AwaitDesugar
)
655 fn lower_expr_closure(
657 capture_clause
: CaptureBy
,
658 movability
: Movability
,
662 ) -> hir
::ExprKind
<'hir
> {
663 // Lower outside new scope to preserve `is_in_loop_condition`.
664 let fn_decl
= self.lower_fn_decl(decl
, None
, false, None
);
666 self.with_new_scopes(move |this
| {
667 let prev
= this
.current_item
;
668 this
.current_item
= Some(fn_decl_span
);
669 let mut generator_kind
= None
;
670 let body_id
= this
.lower_fn_body(decl
, |this
| {
671 let e
= this
.lower_expr_mut(body
);
672 generator_kind
= this
.generator_kind
;
675 let generator_option
=
676 this
.generator_movability_for_fn(&decl
, fn_decl_span
, generator_kind
, movability
);
677 this
.current_item
= prev
;
678 hir
::ExprKind
::Closure(capture_clause
, fn_decl
, body_id
, fn_decl_span
, generator_option
)
682 fn generator_movability_for_fn(
686 generator_kind
: Option
<hir
::GeneratorKind
>,
687 movability
: Movability
,
688 ) -> Option
<hir
::Movability
> {
689 match generator_kind
{
690 Some(hir
::GeneratorKind
::Gen
) => {
691 if !decl
.inputs
.is_empty() {
696 "generators cannot have explicit parameters"
702 Some(hir
::GeneratorKind
::Async(_
)) => {
703 bug
!("non-`async` closure body turned `async` during lowering");
706 if movability
== Movability
::Static
{
707 struct_span_err
!(self.sess
, fn_decl_span
, E0697
, "closures cannot be static")
715 fn lower_expr_async_closure(
717 capture_clause
: CaptureBy
,
722 ) -> hir
::ExprKind
<'hir
> {
724 FnDecl { inputs: decl.inputs.clone(), output: FunctionRetTy::Default(fn_decl_span) }
;
725 // We need to lower the declaration outside the new scope, because we
726 // have to conserve the state of being inside a loop condition for the
727 // closure argument types.
728 let fn_decl
= self.lower_fn_decl(&outer_decl
, None
, false, None
);
730 self.with_new_scopes(move |this
| {
731 // FIXME(cramertj): allow `async` non-`move` closures with arguments.
732 if capture_clause
== CaptureBy
::Ref
&& !decl
.inputs
.is_empty() {
737 "`async` non-`move` closures with parameters are not currently supported",
740 "consider using `let` statements to manually capture \
741 variables by reference before entering an `async move` closure",
746 // Transform `async |x: u8| -> X { ... }` into
747 // `|x: u8| future_from_generator(|| -> X { ... })`.
748 let body_id
= this
.lower_fn_body(&outer_decl
, |this
| {
750 if let FunctionRetTy
::Ty(ty
) = &decl
.output { Some(ty.clone()) }
else { None }
;
751 let async_body
= this
.make_async_expr(
756 hir
::AsyncGeneratorKind
::Closure
,
757 |this
| this
.with_new_scopes(|this
| this
.lower_expr_mut(body
)),
759 this
.expr(fn_decl_span
, async_body
, ThinVec
::new())
761 hir
::ExprKind
::Closure(capture_clause
, fn_decl
, body_id
, fn_decl_span
, None
)
765 /// Desugar `<start>..=<end>` into `std::ops::RangeInclusive::new(<start>, <end>)`.
766 fn lower_expr_range_closed(&mut self, span
: Span
, e1
: &Expr
, e2
: &Expr
) -> hir
::ExprKind
<'hir
> {
767 let id
= self.next_id();
768 let e1
= self.lower_expr_mut(e1
);
769 let e2
= self.lower_expr_mut(e2
);
770 self.expr_call_std_assoc_fn(
773 &[sym
::ops
, sym
::RangeInclusive
],
775 arena_vec
![self; e1
, e2
],
785 ) -> hir
::ExprKind
<'hir
> {
786 use syntax
::ast
::RangeLimits
::*;
788 let path
= match (e1
, e2
, lims
) {
789 (None
, None
, HalfOpen
) => sym
::RangeFull
,
790 (Some(..), None
, HalfOpen
) => sym
::RangeFrom
,
791 (None
, Some(..), HalfOpen
) => sym
::RangeTo
,
792 (Some(..), Some(..), HalfOpen
) => sym
::Range
,
793 (None
, Some(..), Closed
) => sym
::RangeToInclusive
,
794 (Some(..), Some(..), Closed
) => unreachable
!(),
795 (_
, None
, Closed
) => {
796 self.diagnostic().span_fatal(span
, "inclusive range with no end").raise()
800 let fields
= self.arena
.alloc_from_iter(
801 e1
.iter().map(|e
| ("start", e
)).chain(e2
.iter().map(|e
| ("end", e
))).map(|(s
, e
)| {
802 let expr
= self.lower_expr(&e
);
803 let ident
= Ident
::new(Symbol
::intern(s
), e
.span
);
804 self.field(ident
, expr
, e
.span
)
808 let is_unit
= fields
.is_empty();
809 let struct_path
= [sym
::ops
, path
];
810 let struct_path
= self.std_path(span
, &struct_path
, None
, is_unit
);
811 let struct_path
= hir
::QPath
::Resolved(None
, struct_path
);
814 hir
::ExprKind
::Path(struct_path
)
816 hir
::ExprKind
::Struct(self.arena
.alloc(struct_path
), fields
, None
)
820 fn lower_loop_destination(&mut self, destination
: Option
<(NodeId
, Label
)>) -> hir
::Destination
{
821 let target_id
= match destination
{
823 if let Some(loop_id
) = self.resolver
.get_label_res(id
) {
824 Ok(self.lower_node_id(loop_id
))
826 Err(hir
::LoopIdError
::UnresolvedLabel
)
833 .map(|id
| Ok(self.lower_node_id(id
)))
834 .unwrap_or(Err(hir
::LoopIdError
::OutsideLoopScope
))
837 hir
::Destination { label: destination.map(|(_, label)| label), target_id }
840 fn lower_jump_destination(&mut self, id
: NodeId
, opt_label
: Option
<Label
>) -> hir
::Destination
{
841 if self.is_in_loop_condition
&& opt_label
.is_none() {
844 target_id
: Err(hir
::LoopIdError
::UnlabeledCfInWhileCondition
).into(),
847 self.lower_loop_destination(opt_label
.map(|label
| (id
, label
)))
851 fn with_catch_scope
<T
>(&mut self, catch_id
: NodeId
, f
: impl FnOnce(&mut Self) -> T
) -> T
{
852 let len
= self.catch_scopes
.len();
853 self.catch_scopes
.push(catch_id
);
855 let result
= f(self);
858 self.catch_scopes
.len(),
859 "catch scopes should be added and removed in stack order"
862 self.catch_scopes
.pop().unwrap();
867 fn with_loop_scope
<T
>(&mut self, loop_id
: NodeId
, f
: impl FnOnce(&mut Self) -> T
) -> T
{
868 // We're no longer in the base loop's condition; we're in another loop.
869 let was_in_loop_condition
= self.is_in_loop_condition
;
870 self.is_in_loop_condition
= false;
872 let len
= self.loop_scopes
.len();
873 self.loop_scopes
.push(loop_id
);
875 let result
= f(self);
878 self.loop_scopes
.len(),
879 "loop scopes should be added and removed in stack order"
882 self.loop_scopes
.pop().unwrap();
884 self.is_in_loop_condition
= was_in_loop_condition
;
889 fn with_loop_condition_scope
<T
>(&mut self, f
: impl FnOnce(&mut Self) -> T
) -> T
{
890 let was_in_loop_condition
= self.is_in_loop_condition
;
891 self.is_in_loop_condition
= true;
893 let result
= f(self);
895 self.is_in_loop_condition
= was_in_loop_condition
;
900 fn lower_expr_asm(&mut self, asm
: &InlineAsm
) -> hir
::ExprKind
<'hir
> {
901 let inner
= hir
::InlineAsmInner
{
902 inputs
: asm
.inputs
.iter().map(|&(c
, _
)| c
).collect(),
906 .map(|out
| hir
::InlineAsmOutput
{
907 constraint
: out
.constraint
,
909 is_indirect
: out
.is_indirect
,
914 asm_str_style
: asm
.asm_str_style
,
915 clobbers
: asm
.clobbers
.clone().into(),
916 volatile
: asm
.volatile
,
917 alignstack
: asm
.alignstack
,
918 dialect
: asm
.dialect
,
920 let hir_asm
= hir
::InlineAsm
{
922 inputs_exprs
: self.arena
.alloc_from_iter(
923 asm
.inputs
.iter().map(|&(_
, ref input
)| self.lower_expr_mut(input
)),
927 .alloc_from_iter(asm
.outputs
.iter().map(|out
| self.lower_expr_mut(&out
.expr
))),
929 hir
::ExprKind
::InlineAsm(self.arena
.alloc(hir_asm
))
932 fn lower_field(&mut self, f
: &Field
) -> hir
::Field
<'hir
> {
934 hir_id
: self.next_id(),
936 expr
: self.lower_expr(&f
.expr
),
938 is_shorthand
: f
.is_shorthand
,
942 fn lower_expr_yield(&mut self, span
: Span
, opt_expr
: Option
<&Expr
>) -> hir
::ExprKind
<'hir
> {
943 match self.generator_kind
{
944 Some(hir
::GeneratorKind
::Gen
) => {}
945 Some(hir
::GeneratorKind
::Async(_
)) => {
950 "`async` generators are not yet supported"
953 return hir
::ExprKind
::Err
;
955 None
=> self.generator_kind
= Some(hir
::GeneratorKind
::Gen
),
959 opt_expr
.as_ref().map(|x
| self.lower_expr(x
)).unwrap_or_else(|| self.expr_unit(span
));
961 hir
::ExprKind
::Yield(expr
, hir
::YieldSource
::Yield
)
964 /// Desugar `ExprForLoop` from: `[opt_ident]: for <pat> in <head> <body>` into:
967 /// let result = match ::std::iter::IntoIterator::into_iter(<head>) {
969 /// [opt_ident]: loop {
971 /// match ::std::iter::Iterator::next(&mut iter) {
972 /// ::std::option::Option::Some(val) => __next = val,
973 /// ::std::option::Option::None => break
975 /// let <pat> = __next;
976 /// StmtKind::Expr(<body>);
989 opt_label
: Option
<Label
>,
990 ) -> hir
::Expr
<'hir
> {
992 let mut head
= self.lower_expr_mut(head
);
993 let desugared_span
= self.mark_span_with_reason(DesugaringKind
::ForLoop
, head
.span
, None
);
994 head
.span
= desugared_span
;
996 let iter
= Ident
::with_dummy_span(sym
::iter
);
998 let next_ident
= Ident
::with_dummy_span(sym
::__next
);
999 let (next_pat
, next_pat_hid
) = self.pat_ident_binding_mode(
1002 hir
::BindingAnnotation
::Mutable
,
1005 // `::std::option::Option::Some(val) => __next = val`
1007 let val_ident
= Ident
::with_dummy_span(sym
::val
);
1008 let (val_pat
, val_pat_hid
) = self.pat_ident(pat
.span
, val_ident
);
1009 let val_expr
= self.expr_ident(pat
.span
, val_ident
, val_pat_hid
);
1010 let next_expr
= self.expr_ident(pat
.span
, next_ident
, next_pat_hid
);
1011 let assign
= self.arena
.alloc(self.expr(
1013 hir
::ExprKind
::Assign(next_expr
, val_expr
, pat
.span
),
1016 let some_pat
= self.pat_some(pat
.span
, val_pat
);
1017 self.arm(some_pat
, assign
)
1020 // `::std::option::Option::None => break`
1023 self.with_loop_scope(e
.id
, |this
| this
.expr_break(e
.span
, ThinVec
::new()));
1024 let pat
= self.pat_none(e
.span
);
1025 self.arm(pat
, break_expr
)
1029 let (iter_pat
, iter_pat_nid
) =
1030 self.pat_ident_binding_mode(desugared_span
, iter
, hir
::BindingAnnotation
::Mutable
);
1032 // `match ::std::iter::Iterator::next(&mut iter) { ... }`
1034 let iter
= self.expr_ident(desugared_span
, iter
, iter_pat_nid
);
1035 let ref_mut_iter
= self.expr_mut_addr_of(desugared_span
, iter
);
1036 let next_path
= &[sym
::iter
, sym
::Iterator
, sym
::next
];
1038 self.expr_call_std_path(desugared_span
, next_path
, arena_vec
![self; ref_mut_iter
]);
1039 let arms
= arena_vec
![self; pat_arm
, break_arm
];
1041 self.expr_match(desugared_span
, next_expr
, arms
, hir
::MatchSource
::ForLoopDesugar
)
1043 let match_stmt
= self.stmt_expr(desugared_span
, match_expr
);
1045 let next_expr
= self.expr_ident(desugared_span
, next_ident
, next_pat_hid
);
1048 let next_let
= self.stmt_let_pat(
1053 hir
::LocalSource
::ForLoopDesugar
,
1056 // `let <pat> = __next`
1057 let pat
= self.lower_pat(pat
);
1058 let pat_let
= self.stmt_let_pat(
1063 hir
::LocalSource
::ForLoopDesugar
,
1066 let body_block
= self.with_loop_scope(e
.id
, |this
| this
.lower_block(body
, false));
1067 let body_expr
= self.expr_block(body_block
, ThinVec
::new());
1068 let body_stmt
= self.stmt_expr(body
.span
, body_expr
);
1070 let loop_block
= self.block_all(
1072 arena_vec
![self; next_let
, match_stmt
, pat_let
, body_stmt
],
1076 // `[opt_ident]: loop { ... }`
1077 let kind
= hir
::ExprKind
::Loop(loop_block
, opt_label
, hir
::LoopSource
::ForLoop
);
1078 let loop_expr
= self.arena
.alloc(hir
::Expr
{
1079 hir_id
: self.lower_node_id(e
.id
),
1082 attrs
: ThinVec
::new(),
1085 // `mut iter => { ... }`
1086 let iter_arm
= self.arm(iter_pat
, loop_expr
);
1088 // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
1089 let into_iter_expr
= {
1090 let into_iter_path
= &[sym
::iter
, sym
::IntoIterator
, sym
::into_iter
];
1091 self.expr_call_std_path(desugared_span
, into_iter_path
, arena_vec
![self; head
])
1094 let match_expr
= self.arena
.alloc(self.expr_match(
1097 arena_vec
![self; iter_arm
],
1098 hir
::MatchSource
::ForLoopDesugar
,
1101 // This is effectively `{ let _result = ...; _result }`.
1102 // The construct was introduced in #21984 and is necessary to make sure that
1103 // temporaries in the `head` expression are dropped and do not leak to the
1104 // surrounding scope of the `match` since the `match` is not a terminating scope.
1106 // Also, add the attributes to the outer returned expr node.
1107 self.expr_drop_temps_mut(desugared_span
, match_expr
, e
.attrs
.clone())
1110 /// Desugar `ExprKind::Try` from: `<expr>?` into:
1112 /// match Try::into_result(<expr>) {
1113 /// Ok(val) => #[allow(unreachable_code)] val,
1114 /// Err(err) => #[allow(unreachable_code)]
1115 /// // If there is an enclosing `try {...}`:
1116 /// break 'catch_target Try::from_error(From::from(err)),
1118 /// return Try::from_error(From::from(err)),
1121 fn lower_expr_try(&mut self, span
: Span
, sub_expr
: &Expr
) -> hir
::ExprKind
<'hir
> {
1122 let unstable_span
= self.mark_span_with_reason(
1123 DesugaringKind
::QuestionMark
,
1125 self.allow_try_trait
.clone(),
1127 let try_span
= self.sess
.source_map().end_point(span
);
1128 let try_span
= self.mark_span_with_reason(
1129 DesugaringKind
::QuestionMark
,
1131 self.allow_try_trait
.clone(),
1134 // `Try::into_result(<expr>)`
1137 let sub_expr
= self.lower_expr_mut(sub_expr
);
1139 let path
= &[sym
::ops
, sym
::Try
, sym
::into_result
];
1140 self.expr_call_std_path(unstable_span
, path
, arena_vec
![self; sub_expr
])
1143 // `#[allow(unreachable_code)]`
1145 // `allow(unreachable_code)`
1147 let allow_ident
= Ident
::new(sym
::allow
, span
);
1148 let uc_ident
= Ident
::new(sym
::unreachable_code
, span
);
1149 let uc_nested
= attr
::mk_nested_word_item(uc_ident
);
1150 attr
::mk_list_item(allow_ident
, vec
![uc_nested
])
1152 attr
::mk_attr_outer(allow
)
1154 let attrs
= vec
![attr
];
1156 // `Ok(val) => #[allow(unreachable_code)] val,`
1158 let val_ident
= Ident
::with_dummy_span(sym
::val
);
1159 let (val_pat
, val_pat_nid
) = self.pat_ident(span
, val_ident
);
1160 let val_expr
= self.arena
.alloc(self.expr_ident_with_attrs(
1164 ThinVec
::from(attrs
.clone()),
1166 let ok_pat
= self.pat_ok(span
, val_pat
);
1167 self.arm(ok_pat
, val_expr
)
1170 // `Err(err) => #[allow(unreachable_code)]
1171 // return Try::from_error(From::from(err)),`
1173 let err_ident
= Ident
::with_dummy_span(sym
::err
);
1174 let (err_local
, err_local_nid
) = self.pat_ident(try_span
, err_ident
);
1176 let from_path
= &[sym
::convert
, sym
::From
, sym
::from
];
1177 let err_expr
= self.expr_ident_mut(try_span
, err_ident
, err_local_nid
);
1178 self.expr_call_std_path(try_span
, from_path
, arena_vec
![self; err_expr
])
1181 self.wrap_in_try_constructor(sym
::from_error
, unstable_span
, from_expr
, try_span
);
1182 let thin_attrs
= ThinVec
::from(attrs
);
1183 let catch_scope
= self.catch_scopes
.last().map(|x
| *x
);
1184 let ret_expr
= if let Some(catch_node
) = catch_scope
{
1185 let target_id
= Ok(self.lower_node_id(catch_node
));
1186 self.arena
.alloc(self.expr(
1188 hir
::ExprKind
::Break(
1189 hir
::Destination { label: None, target_id }
,
1190 Some(from_err_expr
),
1195 self.arena
.alloc(self.expr(
1197 hir
::ExprKind
::Ret(Some(from_err_expr
)),
1202 let err_pat
= self.pat_err(try_span
, err_local
);
1203 self.arm(err_pat
, ret_expr
)
1206 hir
::ExprKind
::Match(
1208 arena_vec
![self; err_arm
, ok_arm
],
1209 hir
::MatchSource
::TryDesugar
,
1213 // =========================================================================
1214 // Helper methods for building HIR.
1215 // =========================================================================
1217 /// Constructs a `true` or `false` literal expression.
1218 pub(super) fn expr_bool(&mut self, span
: Span
, val
: bool
) -> &'hir hir
::Expr
<'hir
> {
1219 let lit
= Spanned { span, node: LitKind::Bool(val) }
;
1220 self.arena
.alloc(self.expr(span
, hir
::ExprKind
::Lit(lit
), ThinVec
::new()))
1223 /// Wrap the given `expr` in a terminating scope using `hir::ExprKind::DropTemps`.
1225 /// In terms of drop order, it has the same effect as wrapping `expr` in
1226 /// `{ let _t = $expr; _t }` but should provide better compile-time performance.
1228 /// The drop order can be important in e.g. `if expr { .. }`.
1229 pub(super) fn expr_drop_temps(
1232 expr
: &'hir hir
::Expr
<'hir
>,
1234 ) -> &'hir hir
::Expr
<'hir
> {
1235 self.arena
.alloc(self.expr_drop_temps_mut(span
, expr
, attrs
))
1238 pub(super) fn expr_drop_temps_mut(
1241 expr
: &'hir hir
::Expr
<'hir
>,
1243 ) -> hir
::Expr
<'hir
> {
1244 self.expr(span
, hir
::ExprKind
::DropTemps(expr
), attrs
)
1250 arg
: &'hir hir
::Expr
<'hir
>,
1251 arms
: &'hir
[hir
::Arm
<'hir
>],
1252 source
: hir
::MatchSource
,
1253 ) -> hir
::Expr
<'hir
> {
1254 self.expr(span
, hir
::ExprKind
::Match(arg
, arms
, source
), ThinVec
::new())
1257 fn expr_break(&mut self, span
: Span
, attrs
: AttrVec
) -> &'hir hir
::Expr
<'hir
> {
1258 let expr_break
= hir
::ExprKind
::Break(self.lower_loop_destination(None
), None
);
1259 self.arena
.alloc(self.expr(span
, expr_break
, attrs
))
1262 fn expr_mut_addr_of(&mut self, span
: Span
, e
: &'hir hir
::Expr
<'hir
>) -> hir
::Expr
<'hir
> {
1265 hir
::ExprKind
::AddrOf(hir
::BorrowKind
::Ref
, hir
::Mutability
::Mut
, e
),
1270 fn expr_unit(&mut self, sp
: Span
) -> &'hir hir
::Expr
<'hir
> {
1271 self.arena
.alloc(self.expr(sp
, hir
::ExprKind
::Tup(&[]), ThinVec
::new()))
1277 e
: &'hir hir
::Expr
<'hir
>,
1278 args
: &'hir
[hir
::Expr
<'hir
>],
1279 ) -> &'hir hir
::Expr
<'hir
> {
1280 self.arena
.alloc(self.expr(span
, hir
::ExprKind
::Call(e
, args
), ThinVec
::new()))
1283 // Note: associated functions must use `expr_call_std_path`.
1284 fn expr_call_std_path(
1287 path_components
: &[Symbol
],
1288 args
: &'hir
[hir
::Expr
<'hir
>],
1289 ) -> &'hir hir
::Expr
<'hir
> {
1291 self.arena
.alloc(self.expr_std_path(span
, path_components
, None
, ThinVec
::new()));
1292 self.expr_call(span
, path
, args
)
1295 // Create an expression calling an associated function of an std type.
1297 // Associated functions cannot be resolved through the normal `std_path` function,
1298 // as they are resolved differently and so cannot use `expr_call_std_path`.
1300 // This function accepts the path component (`ty_path_components`) separately from
1301 // the name of the associated function (`assoc_fn_name`) in order to facilitate
1302 // separate resolution of the type and creation of a path referring to its associated
1304 fn expr_call_std_assoc_fn(
1306 ty_path_id
: hir
::HirId
,
1308 ty_path_components
: &[Symbol
],
1309 assoc_fn_name
: &str,
1310 args
: &'hir
[hir
::Expr
<'hir
>],
1311 ) -> hir
::ExprKind
<'hir
> {
1312 let ty_path
= self.std_path(span
, ty_path_components
, None
, false);
1314 self.arena
.alloc(self.ty_path(ty_path_id
, span
, hir
::QPath
::Resolved(None
, ty_path
)));
1315 let fn_seg
= self.arena
.alloc(hir
::PathSegment
::from_ident(Ident
::from_str(assoc_fn_name
)));
1316 let fn_path
= hir
::QPath
::TypeRelative(ty
, fn_seg
);
1318 self.arena
.alloc(self.expr(span
, hir
::ExprKind
::Path(fn_path
), ThinVec
::new()));
1319 hir
::ExprKind
::Call(fn_expr
, args
)
1325 components
: &[Symbol
],
1326 params
: Option
<&'hir hir
::GenericArgs
<'hir
>>,
1328 ) -> hir
::Expr
<'hir
> {
1329 let path
= self.std_path(span
, components
, params
, true);
1330 self.expr(span
, hir
::ExprKind
::Path(hir
::QPath
::Resolved(None
, path
)), attrs
)
1333 pub(super) fn expr_ident(
1337 binding
: hir
::HirId
,
1338 ) -> &'hir hir
::Expr
<'hir
> {
1339 self.arena
.alloc(self.expr_ident_mut(sp
, ident
, binding
))
1342 pub(super) fn expr_ident_mut(
1346 binding
: hir
::HirId
,
1347 ) -> hir
::Expr
<'hir
> {
1348 self.expr_ident_with_attrs(sp
, ident
, binding
, ThinVec
::new())
1351 fn expr_ident_with_attrs(
1355 binding
: hir
::HirId
,
1357 ) -> hir
::Expr
<'hir
> {
1358 let expr_path
= hir
::ExprKind
::Path(hir
::QPath
::Resolved(
1360 self.arena
.alloc(hir
::Path
{
1362 res
: Res
::Local(binding
),
1363 segments
: arena_vec
![self; hir
::PathSegment
::from_ident(ident
)],
1367 self.expr(span
, expr_path
, attrs
)
1370 fn expr_unsafe(&mut self, expr
: &'hir hir
::Expr
<'hir
>) -> hir
::Expr
<'hir
> {
1371 let hir_id
= self.next_id();
1372 let span
= expr
.span
;
1375 hir
::ExprKind
::Block(
1376 self.arena
.alloc(hir
::Block
{
1380 rules
: hir
::BlockCheckMode
::UnsafeBlock(hir
::UnsafeSource
::CompilerGenerated
),
1382 targeted_by_break
: false,
1390 fn expr_block_empty(&mut self, span
: Span
) -> &'hir hir
::Expr
<'hir
> {
1391 let blk
= self.block_all(span
, &[], None
);
1392 let expr
= self.expr_block(blk
, ThinVec
::new());
1393 self.arena
.alloc(expr
)
1396 pub(super) fn expr_block(
1398 b
: &'hir hir
::Block
<'hir
>,
1400 ) -> hir
::Expr
<'hir
> {
1401 self.expr(b
.span
, hir
::ExprKind
::Block(b
, None
), attrs
)
1407 kind
: hir
::ExprKind
<'hir
>,
1409 ) -> hir
::Expr
<'hir
> {
1410 hir
::Expr { hir_id: self.next_id(), kind, span, attrs }
1413 fn field(&mut self, ident
: Ident
, expr
: &'hir hir
::Expr
<'hir
>, span
: Span
) -> hir
::Field
<'hir
> {
1414 hir
::Field { hir_id: self.next_id(), ident, span, expr, is_shorthand: false }
1417 fn arm(&mut self, pat
: &'hir hir
::Pat
<'hir
>, expr
: &'hir hir
::Expr
<'hir
>) -> hir
::Arm
<'hir
> {
1419 hir_id
: self.next_id(),