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