1use rustc_ast::ptr::P;
2use rustc_ast::token::Delimiter;
3use rustc_ast::tokenstream::TokenStream;
4use rustc_ast::util::literal;
5use rustc_ast::{
6 self as ast, AnonConst, AttrVec, BlockCheckMode, Expr, LocalKind, MatchKind, PatKind, UnOp,
7 attr, token, tokenstream,
8};
9use rustc_span::source_map::Spanned;
10use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
11use thin_vec::{ThinVec, thin_vec};
12
13use crate::base::ExtCtxt;
14
15impl<'a> ExtCtxt<'a> {
16 pub fn path(&self, span: Span, strs: Vec<Ident>) -> ast::Path {
17 self.path_all(span, false, strs, vec![])
18 }
19 pub fn path_ident(&self, span: Span, id: Ident) -> ast::Path {
20 self.path(span, vec![id])
21 }
22 pub fn path_global(&self, span: Span, strs: Vec<Ident>) -> ast::Path {
23 self.path_all(span, true, strs, vec![])
24 }
25 pub fn path_all(
26 &self,
27 span: Span,
28 global: bool,
29 mut idents: Vec<Ident>,
30 args: Vec<ast::GenericArg>,
31 ) -> ast::Path {
32 assert!(!idents.is_empty());
33 let add_root = global && !idents[0].is_path_segment_keyword();
34 let mut segments = ThinVec::with_capacity(idents.len() + add_root as usize);
35 if add_root {
36 segments.push(ast::PathSegment::path_root(span));
37 }
38 let last_ident = idents.pop().unwrap();
39 segments.extend(
40 idents.into_iter().map(|ident| ast::PathSegment::from_ident(ident.with_span_pos(span))),
41 );
42 let args = if !args.is_empty() {
43 let args = args.into_iter().map(ast::AngleBracketedArg::Arg).collect();
44 Some(ast::AngleBracketedArgs { args, span }.into())
45 } else {
46 None
47 };
48 segments.push(ast::PathSegment {
49 ident: last_ident.with_span_pos(span),
50 id: ast::DUMMY_NODE_ID,
51 args,
52 });
53 ast::Path { span, segments, tokens: None }
54 }
55
56 pub fn macro_call(
57 &self,
58 span: Span,
59 path: ast::Path,
60 delim: Delimiter,
61 tokens: TokenStream,
62 ) -> P<ast::MacCall> {
63 P(ast::MacCall {
64 path,
65 args: P(ast::DelimArgs {
66 dspan: tokenstream::DelimSpan { open: span, close: span },
67 delim,
68 tokens,
69 }),
70 })
71 }
72
73 pub fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy {
74 ast::MutTy { ty, mutbl }
75 }
76
77 pub fn ty(&self, span: Span, kind: ast::TyKind) -> P<ast::Ty> {
78 P(ast::Ty { id: ast::DUMMY_NODE_ID, span, kind, tokens: None })
79 }
80
81 pub fn ty_infer(&self, span: Span) -> P<ast::Ty> {
82 self.ty(span, ast::TyKind::Infer)
83 }
84
85 pub fn ty_path(&self, path: ast::Path) -> P<ast::Ty> {
86 self.ty(path.span, ast::TyKind::Path(None, path))
87 }
88
89 pub fn ty_ident(&self, span: Span, ident: Ident) -> P<ast::Ty> {
92 self.ty_path(self.path_ident(span, ident))
93 }
94
95 pub fn anon_const(&self, span: Span, kind: ast::ExprKind) -> ast::AnonConst {
96 ast::AnonConst {
97 id: ast::DUMMY_NODE_ID,
98 value: P(ast::Expr {
99 id: ast::DUMMY_NODE_ID,
100 kind,
101 span,
102 attrs: AttrVec::new(),
103 tokens: None,
104 }),
105 }
106 }
107
108 pub fn const_ident(&self, span: Span, ident: Ident) -> ast::AnonConst {
109 self.anon_const(span, ast::ExprKind::Path(None, self.path_ident(span, ident)))
110 }
111
112 pub fn ty_ref(
113 &self,
114 span: Span,
115 ty: P<ast::Ty>,
116 lifetime: Option<ast::Lifetime>,
117 mutbl: ast::Mutability,
118 ) -> P<ast::Ty> {
119 self.ty(span, ast::TyKind::Ref(lifetime, self.ty_mt(ty, mutbl)))
120 }
121
122 pub fn ty_ptr(&self, span: Span, ty: P<ast::Ty>, mutbl: ast::Mutability) -> P<ast::Ty> {
123 self.ty(span, ast::TyKind::Ptr(self.ty_mt(ty, mutbl)))
124 }
125
126 pub fn typaram(
127 &self,
128 span: Span,
129 ident: Ident,
130 bounds: ast::GenericBounds,
131 default: Option<P<ast::Ty>>,
132 ) -> ast::GenericParam {
133 ast::GenericParam {
134 ident: ident.with_span_pos(span),
135 id: ast::DUMMY_NODE_ID,
136 attrs: AttrVec::new(),
137 bounds,
138 kind: ast::GenericParamKind::Type { default },
139 is_placeholder: false,
140 colon_span: None,
141 }
142 }
143
144 pub fn lifetime_param(
145 &self,
146 span: Span,
147 ident: Ident,
148 bounds: ast::GenericBounds,
149 ) -> ast::GenericParam {
150 ast::GenericParam {
151 id: ast::DUMMY_NODE_ID,
152 ident: ident.with_span_pos(span),
153 attrs: AttrVec::new(),
154 bounds,
155 is_placeholder: false,
156 kind: ast::GenericParamKind::Lifetime,
157 colon_span: None,
158 }
159 }
160
161 pub fn const_param(
162 &self,
163 span: Span,
164 ident: Ident,
165 bounds: ast::GenericBounds,
166 ty: P<ast::Ty>,
167 default: Option<AnonConst>,
168 ) -> ast::GenericParam {
169 ast::GenericParam {
170 id: ast::DUMMY_NODE_ID,
171 ident: ident.with_span_pos(span),
172 attrs: AttrVec::new(),
173 bounds,
174 is_placeholder: false,
175 kind: ast::GenericParamKind::Const { ty, kw_span: DUMMY_SP, default },
176 colon_span: None,
177 }
178 }
179
180 pub fn trait_ref(&self, path: ast::Path) -> ast::TraitRef {
181 ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID }
182 }
183
184 pub fn poly_trait_ref(&self, span: Span, path: ast::Path, is_const: bool) -> ast::PolyTraitRef {
185 ast::PolyTraitRef {
186 bound_generic_params: ThinVec::new(),
187 modifiers: ast::TraitBoundModifiers {
188 polarity: ast::BoundPolarity::Positive,
189 constness: if is_const {
190 ast::BoundConstness::Maybe(DUMMY_SP)
191 } else {
192 ast::BoundConstness::Never
193 },
194 asyncness: ast::BoundAsyncness::Normal,
195 },
196 trait_ref: self.trait_ref(path),
197 span,
198 }
199 }
200
201 pub fn trait_bound(&self, path: ast::Path, is_const: bool) -> ast::GenericBound {
202 ast::GenericBound::Trait(self.poly_trait_ref(path.span, path, is_const))
203 }
204
205 pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime {
206 ast::Lifetime { id: ast::DUMMY_NODE_ID, ident: ident.with_span_pos(span) }
207 }
208
209 pub fn lifetime_static(&self, span: Span) -> ast::Lifetime {
210 self.lifetime(span, Ident::new(kw::StaticLifetime, span))
211 }
212
213 pub fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt {
214 ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) }
215 }
216
217 pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P<ast::Expr>) -> ast::Stmt {
218 self.stmt_let_ty(sp, mutbl, ident, None, ex)
219 }
220
221 pub fn stmt_let_ty(
222 &self,
223 sp: Span,
224 mutbl: bool,
225 ident: Ident,
226 ty: Option<P<ast::Ty>>,
227 ex: P<ast::Expr>,
228 ) -> ast::Stmt {
229 let pat = if mutbl {
230 self.pat_ident_binding_mode(sp, ident, ast::BindingMode::MUT)
231 } else {
232 self.pat_ident(sp, ident)
233 };
234 let local = P(ast::Local {
235 super_: None,
236 pat,
237 ty,
238 id: ast::DUMMY_NODE_ID,
239 kind: LocalKind::Init(ex),
240 span: sp,
241 colon_sp: None,
242 attrs: AttrVec::new(),
243 tokens: None,
244 });
245 self.stmt_local(local, sp)
246 }
247
248 pub fn stmt_let_type_only(&self, span: Span, ty: P<ast::Ty>) -> ast::Stmt {
250 let local = P(ast::Local {
251 super_: None,
252 pat: self.pat_wild(span),
253 ty: Some(ty),
254 id: ast::DUMMY_NODE_ID,
255 kind: LocalKind::Decl,
256 span,
257 colon_sp: None,
258 attrs: AttrVec::new(),
259 tokens: None,
260 });
261 self.stmt_local(local, span)
262 }
263
264 pub fn stmt_semi(&self, expr: P<ast::Expr>) -> ast::Stmt {
265 ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Semi(expr) }
266 }
267
268 pub fn stmt_local(&self, local: P<ast::Local>, span: Span) -> ast::Stmt {
269 ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Let(local), span }
270 }
271
272 pub fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt {
273 ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Item(item), span: sp }
274 }
275
276 pub fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
277 self.block(
278 expr.span,
279 thin_vec![ast::Stmt {
280 id: ast::DUMMY_NODE_ID,
281 span: expr.span,
282 kind: ast::StmtKind::Expr(expr),
283 }],
284 )
285 }
286 pub fn block(&self, span: Span, stmts: ThinVec<ast::Stmt>) -> P<ast::Block> {
287 P(ast::Block {
288 stmts,
289 id: ast::DUMMY_NODE_ID,
290 rules: BlockCheckMode::Default,
291 span,
292 tokens: None,
293 })
294 }
295
296 pub fn expr(&self, span: Span, kind: ast::ExprKind) -> P<ast::Expr> {
297 P(ast::Expr { id: ast::DUMMY_NODE_ID, kind, span, attrs: AttrVec::new(), tokens: None })
298 }
299
300 pub fn expr_path(&self, path: ast::Path) -> P<ast::Expr> {
301 self.expr(path.span, ast::ExprKind::Path(None, path))
302 }
303
304 pub fn expr_ident(&self, span: Span, id: Ident) -> P<ast::Expr> {
305 self.expr_path(self.path_ident(span, id))
306 }
307 pub fn expr_self(&self, span: Span) -> P<ast::Expr> {
308 self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower))
309 }
310
311 pub fn expr_macro_call(&self, span: Span, call: P<ast::MacCall>) -> P<ast::Expr> {
312 self.expr(span, ast::ExprKind::MacCall(call))
313 }
314
315 pub fn expr_binary(
316 &self,
317 sp: Span,
318 op: ast::BinOpKind,
319 lhs: P<ast::Expr>,
320 rhs: P<ast::Expr>,
321 ) -> P<ast::Expr> {
322 self.expr(sp, ast::ExprKind::Binary(Spanned { node: op, span: sp }, lhs, rhs))
323 }
324
325 pub fn expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
326 self.expr(sp, ast::ExprKind::Unary(UnOp::Deref, e))
327 }
328
329 pub fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
330 self.expr(sp, ast::ExprKind::AddrOf(ast::BorrowKind::Ref, ast::Mutability::Not, e))
331 }
332
333 pub fn expr_paren(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {
334 self.expr(sp, ast::ExprKind::Paren(e))
335 }
336
337 pub fn expr_method_call(
338 &self,
339 span: Span,
340 expr: P<ast::Expr>,
341 ident: Ident,
342 args: ThinVec<P<ast::Expr>>,
343 ) -> P<ast::Expr> {
344 let seg = ast::PathSegment::from_ident(ident);
345 self.expr(
346 span,
347 ast::ExprKind::MethodCall(Box::new(ast::MethodCall {
348 seg,
349 receiver: expr,
350 args,
351 span,
352 })),
353 )
354 }
355
356 pub fn expr_call(
357 &self,
358 span: Span,
359 expr: P<ast::Expr>,
360 args: ThinVec<P<ast::Expr>>,
361 ) -> P<ast::Expr> {
362 self.expr(span, ast::ExprKind::Call(expr, args))
363 }
364 pub fn expr_loop(&self, sp: Span, block: P<ast::Block>) -> P<ast::Expr> {
365 self.expr(sp, ast::ExprKind::Loop(block, None, sp))
366 }
367 pub fn expr_asm(&self, sp: Span, expr: P<ast::InlineAsm>) -> P<ast::Expr> {
368 self.expr(sp, ast::ExprKind::InlineAsm(expr))
369 }
370 pub fn expr_call_ident(
371 &self,
372 span: Span,
373 id: Ident,
374 args: ThinVec<P<ast::Expr>>,
375 ) -> P<ast::Expr> {
376 self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args))
377 }
378 pub fn expr_call_global(
379 &self,
380 sp: Span,
381 fn_path: Vec<Ident>,
382 args: ThinVec<P<ast::Expr>>,
383 ) -> P<ast::Expr> {
384 let pathexpr = self.expr_path(self.path_global(sp, fn_path));
385 self.expr_call(sp, pathexpr, args)
386 }
387 pub fn expr_block(&self, b: P<ast::Block>) -> P<ast::Expr> {
388 self.expr(b.span, ast::ExprKind::Block(b, None))
389 }
390 pub fn field_imm(&self, span: Span, ident: Ident, e: P<ast::Expr>) -> ast::ExprField {
391 ast::ExprField {
392 ident: ident.with_span_pos(span),
393 expr: e,
394 span,
395 is_shorthand: false,
396 attrs: AttrVec::new(),
397 id: ast::DUMMY_NODE_ID,
398 is_placeholder: false,
399 }
400 }
401 pub fn expr_struct(
402 &self,
403 span: Span,
404 path: ast::Path,
405 fields: ThinVec<ast::ExprField>,
406 ) -> P<ast::Expr> {
407 self.expr(
408 span,
409 ast::ExprKind::Struct(P(ast::StructExpr {
410 qself: None,
411 path,
412 fields,
413 rest: ast::StructRest::None,
414 })),
415 )
416 }
417 pub fn expr_struct_ident(
418 &self,
419 span: Span,
420 id: Ident,
421 fields: ThinVec<ast::ExprField>,
422 ) -> P<ast::Expr> {
423 self.expr_struct(span, self.path_ident(span, id), fields)
424 }
425
426 pub fn expr_usize(&self, span: Span, n: usize) -> P<ast::Expr> {
427 let suffix = Some(ast::UintTy::Usize.name());
428 let lit = token::Lit::new(token::Integer, sym::integer(n), suffix);
429 self.expr(span, ast::ExprKind::Lit(lit))
430 }
431
432 pub fn expr_u32(&self, span: Span, n: u32) -> P<ast::Expr> {
433 let suffix = Some(ast::UintTy::U32.name());
434 let lit = token::Lit::new(token::Integer, sym::integer(n), suffix);
435 self.expr(span, ast::ExprKind::Lit(lit))
436 }
437
438 pub fn expr_bool(&self, span: Span, value: bool) -> P<ast::Expr> {
439 let lit = token::Lit::new(token::Bool, if value { kw::True } else { kw::False }, None);
440 self.expr(span, ast::ExprKind::Lit(lit))
441 }
442
443 pub fn expr_str(&self, span: Span, s: Symbol) -> P<ast::Expr> {
444 let lit = token::Lit::new(token::Str, literal::escape_string_symbol(s), None);
445 self.expr(span, ast::ExprKind::Lit(lit))
446 }
447
448 pub fn expr_byte_str(&self, span: Span, bytes: Vec<u8>) -> P<ast::Expr> {
449 let lit = token::Lit::new(token::ByteStr, literal::escape_byte_str_symbol(&bytes), None);
450 self.expr(span, ast::ExprKind::Lit(lit))
451 }
452
453 pub fn expr_array(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> {
455 self.expr(sp, ast::ExprKind::Array(exprs))
456 }
457
458 pub fn expr_array_ref(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> {
460 self.expr_addr_of(sp, self.expr_array(sp, exprs))
461 }
462
463 pub fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
464 let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
465 self.expr_call_global(sp, some, thin_vec![expr])
466 }
467
468 pub fn expr_none(&self, sp: Span) -> P<ast::Expr> {
469 let none = self.std_path(&[sym::option, sym::Option, sym::None]);
470 self.expr_path(self.path_global(sp, none))
471 }
472 pub fn expr_tuple(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> {
473 self.expr(sp, ast::ExprKind::Tup(exprs))
474 }
475
476 pub fn expr_unreachable(&self, span: Span) -> P<ast::Expr> {
477 self.expr_macro_call(
478 span,
479 self.macro_call(
480 span,
481 self.path_global(
482 span,
483 [sym::std, sym::unreachable].map(|s| Ident::new(s, span)).to_vec(),
484 ),
485 Delimiter::Parenthesis,
486 TokenStream::default(),
487 ),
488 )
489 }
490
491 pub fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
492 let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]);
493 self.expr_call_global(sp, ok, thin_vec![expr])
494 }
495
496 pub fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> {
497 let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]);
498 let ok_path = self.path_global(sp, ok);
499 let err = self.std_path(&[sym::result, sym::Result, sym::Err]);
500 let err_path = self.path_global(sp, err);
501
502 let binding_variable = Ident::new(sym::__try_var, sp);
503 let binding_pat = self.pat_ident(sp, binding_variable);
504 let binding_expr = self.expr_ident(sp, binding_variable);
505
506 let ok_pat = self.pat_tuple_struct(sp, ok_path, thin_vec![binding_pat.clone()]);
508
509 let err_pat = self.pat_tuple_struct(sp, err_path.clone(), thin_vec![binding_pat]);
511 let err_inner_expr =
512 self.expr_call(sp, self.expr_path(err_path), thin_vec![binding_expr.clone()]);
513 let err_expr = self.expr(sp, ast::ExprKind::Ret(Some(err_inner_expr)));
515
516 let ok_arm = self.arm(sp, ok_pat, binding_expr);
518 let err_arm = self.arm(sp, err_pat, err_expr);
520
521 self.expr_match(sp, head, thin_vec![ok_arm, err_arm])
523 }
524
525 pub fn pat(&self, span: Span, kind: PatKind) -> P<ast::Pat> {
526 P(ast::Pat { id: ast::DUMMY_NODE_ID, kind, span, tokens: None })
527 }
528 pub fn pat_wild(&self, span: Span) -> P<ast::Pat> {
529 self.pat(span, PatKind::Wild)
530 }
531 pub fn pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat> {
532 self.pat(span, PatKind::Expr(expr))
533 }
534 pub fn pat_ident(&self, span: Span, ident: Ident) -> P<ast::Pat> {
535 self.pat_ident_binding_mode(span, ident, ast::BindingMode::NONE)
536 }
537
538 pub fn pat_ident_binding_mode(
539 &self,
540 span: Span,
541 ident: Ident,
542 ann: ast::BindingMode,
543 ) -> P<ast::Pat> {
544 let pat = PatKind::Ident(ann, ident.with_span_pos(span), None);
545 self.pat(span, pat)
546 }
547 pub fn pat_path(&self, span: Span, path: ast::Path) -> P<ast::Pat> {
548 self.pat(span, PatKind::Path(None, path))
549 }
550 pub fn pat_tuple_struct(
551 &self,
552 span: Span,
553 path: ast::Path,
554 subpats: ThinVec<P<ast::Pat>>,
555 ) -> P<ast::Pat> {
556 self.pat(span, PatKind::TupleStruct(None, path, subpats))
557 }
558 pub fn pat_struct(
559 &self,
560 span: Span,
561 path: ast::Path,
562 field_pats: ThinVec<ast::PatField>,
563 ) -> P<ast::Pat> {
564 self.pat(span, PatKind::Struct(None, path, field_pats, ast::PatFieldsRest::None))
565 }
566 pub fn pat_tuple(&self, span: Span, pats: ThinVec<P<ast::Pat>>) -> P<ast::Pat> {
567 self.pat(span, PatKind::Tuple(pats))
568 }
569
570 pub fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
571 let some = self.std_path(&[sym::option, sym::Option, sym::Some]);
572 let path = self.path_global(span, some);
573 self.pat_tuple_struct(span, path, thin_vec![pat])
574 }
575
576 pub fn arm(&self, span: Span, pat: P<ast::Pat>, expr: P<ast::Expr>) -> ast::Arm {
577 ast::Arm {
578 attrs: AttrVec::new(),
579 pat,
580 guard: None,
581 body: Some(expr),
582 span,
583 id: ast::DUMMY_NODE_ID,
584 is_placeholder: false,
585 }
586 }
587
588 pub fn arm_unreachable(&self, span: Span) -> ast::Arm {
589 self.arm(span, self.pat_wild(span), self.expr_unreachable(span))
590 }
591
592 pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: ThinVec<ast::Arm>) -> P<Expr> {
593 self.expr(span, ast::ExprKind::Match(arg, arms, MatchKind::Prefix))
594 }
595
596 pub fn expr_if(
597 &self,
598 span: Span,
599 cond: P<ast::Expr>,
600 then: P<ast::Expr>,
601 els: Option<P<ast::Expr>>,
602 ) -> P<ast::Expr> {
603 let els = els.map(|x| self.expr_block(self.block_expr(x)));
604 self.expr(span, ast::ExprKind::If(cond, self.block_expr(then), els))
605 }
606
607 pub fn lambda(&self, span: Span, ids: Vec<Ident>, body: P<ast::Expr>) -> P<ast::Expr> {
608 let fn_decl = self.fn_decl(
609 ids.iter().map(|id| self.param(span, *id, self.ty(span, ast::TyKind::Infer))).collect(),
610 ast::FnRetTy::Default(span),
611 );
612
613 self.expr(
618 span,
619 ast::ExprKind::Closure(Box::new(ast::Closure {
620 binder: ast::ClosureBinder::NotPresent,
621 capture_clause: ast::CaptureBy::Ref,
622 constness: ast::Const::No,
623 coroutine_kind: None,
624 movability: ast::Movability::Movable,
625 fn_decl,
626 body,
627 fn_decl_span: span,
628 fn_arg_span: span,
631 })),
632 )
633 }
634
635 pub fn lambda0(&self, span: Span, body: P<ast::Expr>) -> P<ast::Expr> {
636 self.lambda(span, Vec::new(), body)
637 }
638
639 pub fn lambda1(&self, span: Span, body: P<ast::Expr>, ident: Ident) -> P<ast::Expr> {
640 self.lambda(span, vec![ident], body)
641 }
642
643 pub fn lambda_stmts_1(
644 &self,
645 span: Span,
646 stmts: ThinVec<ast::Stmt>,
647 ident: Ident,
648 ) -> P<ast::Expr> {
649 self.lambda1(span, self.expr_block(self.block(span, stmts)), ident)
650 }
651
652 pub fn param(&self, span: Span, ident: Ident, ty: P<ast::Ty>) -> ast::Param {
653 let arg_pat = self.pat_ident(span, ident);
654 ast::Param {
655 attrs: AttrVec::default(),
656 id: ast::DUMMY_NODE_ID,
657 pat: arg_pat,
658 span,
659 ty,
660 is_placeholder: false,
661 }
662 }
663
664 pub fn fn_decl(&self, inputs: ThinVec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl> {
666 P(ast::FnDecl { inputs, output })
667 }
668
669 pub fn item(&self, span: Span, attrs: ast::AttrVec, kind: ast::ItemKind) -> P<ast::Item> {
670 P(ast::Item {
671 attrs,
672 id: ast::DUMMY_NODE_ID,
673 kind,
674 vis: ast::Visibility {
675 span: span.shrink_to_lo(),
676 kind: ast::VisibilityKind::Inherited,
677 tokens: None,
678 },
679 span,
680 tokens: None,
681 })
682 }
683
684 pub fn item_static(
685 &self,
686 span: Span,
687 ident: Ident,
688 ty: P<ast::Ty>,
689 mutability: ast::Mutability,
690 expr: P<ast::Expr>,
691 ) -> P<ast::Item> {
692 self.item(
693 span,
694 AttrVec::new(),
695 ast::ItemKind::Static(
696 ast::StaticItem {
697 ident,
698 ty,
699 safety: ast::Safety::Default,
700 mutability,
701 expr: Some(expr),
702 define_opaque: None,
703 }
704 .into(),
705 ),
706 )
707 }
708
709 pub fn item_const(
710 &self,
711 span: Span,
712 ident: Ident,
713 ty: P<ast::Ty>,
714 expr: P<ast::Expr>,
715 ) -> P<ast::Item> {
716 let defaultness = ast::Defaultness::Final;
717 self.item(
718 span,
719 AttrVec::new(),
720 ast::ItemKind::Const(
721 ast::ConstItem {
722 defaultness,
723 ident,
724 generics: ast::Generics::default(),
726 ty,
727 expr: Some(expr),
728 define_opaque: None,
729 }
730 .into(),
731 ),
732 )
733 }
734
735 pub fn attr_word(&self, name: Symbol, span: Span) -> ast::Attribute {
737 let g = &self.sess.psess.attr_id_generator;
738 attr::mk_attr_word(g, ast::AttrStyle::Outer, ast::Safety::Default, name, span)
739 }
740
741 pub fn attr_name_value_str(&self, name: Symbol, val: Symbol, span: Span) -> ast::Attribute {
745 let g = &self.sess.psess.attr_id_generator;
746 attr::mk_attr_name_value_str(
747 g,
748 ast::AttrStyle::Outer,
749 ast::Safety::Default,
750 name,
751 val,
752 span,
753 )
754 }
755
756 pub fn attr_nested_word(&self, outer: Symbol, inner: Symbol, span: Span) -> ast::Attribute {
758 let g = &self.sess.psess.attr_id_generator;
759 attr::mk_attr_nested_word(
760 g,
761 ast::AttrStyle::Outer,
762 ast::Safety::Default,
763 outer,
764 inner,
765 span,
766 )
767 }
768}