]>
Commit | Line | Data |
---|---|---|
e74abb32 XL |
1 | use crate::base::ExtCtxt; |
2 | ||
74b04a01 XL |
3 | use rustc_ast::attr; |
4 | use rustc_ast::ptr::P; | |
3dfed10e | 5 | use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, PatKind, UnOp}; |
dfeec247 | 6 | use rustc_span::source_map::{respan, Spanned}; |
f9f354fc | 7 | use rustc_span::symbol::{kw, sym, Ident, Symbol}; |
9fa01778 | 8 | |
dfeec247 | 9 | use rustc_span::Span; |
223e47cc | 10 | |
416331ca | 11 | impl<'a> ExtCtxt<'a> { |
f9f354fc | 12 | pub fn path(&self, span: Span, strs: Vec<Ident>) -> ast::Path { |
e1599b0c | 13 | self.path_all(span, false, strs, vec![]) |
223e47cc | 14 | } |
f9f354fc | 15 | pub fn path_ident(&self, span: Span, id: Ident) -> ast::Path { |
c30ab7b3 | 16 | self.path(span, vec![id]) |
970d7e83 | 17 | } |
f9f354fc | 18 | pub fn path_global(&self, span: Span, strs: Vec<Ident>) -> ast::Path { |
e1599b0c | 19 | self.path_all(span, true, strs, vec![]) |
970d7e83 | 20 | } |
dfeec247 XL |
21 | pub fn path_all( |
22 | &self, | |
23 | span: Span, | |
24 | global: bool, | |
f9f354fc | 25 | mut idents: Vec<Ident>, |
dfeec247 XL |
26 | args: Vec<ast::GenericArg>, |
27 | ) -> ast::Path { | |
0731742a XL |
28 | assert!(!idents.is_empty()); |
29 | let add_root = global && !idents[0].is_path_segment_keyword(); | |
30 | let mut segments = Vec::with_capacity(idents.len() + add_root as usize); | |
31 | if add_root { | |
32 | segments.push(ast::PathSegment::path_root(span)); | |
33 | } | |
83c7162d | 34 | let last_ident = idents.pop().unwrap(); |
dfeec247 XL |
35 | segments.extend( |
36 | idents.into_iter().map(|ident| ast::PathSegment::from_ident(ident.with_span_pos(span))), | |
37 | ); | |
e1599b0c | 38 | let args = if !args.is_empty() { |
ba9703b0 XL |
39 | let args = args.into_iter().map(ast::AngleBracketedArg::Arg).collect(); |
40 | ast::AngleBracketedArgs { args, span }.into() | |
32a655c1 | 41 | } else { |
3b2f2976 | 42 | None |
32a655c1 | 43 | }; |
13cf67c4 XL |
44 | segments.push(ast::PathSegment { |
45 | ident: last_ident.with_span_pos(span), | |
46 | id: ast::DUMMY_NODE_ID, | |
47 | args, | |
48 | }); | |
0731742a | 49 | ast::Path { span, segments } |
970d7e83 LB |
50 | } |
51 | ||
416331ca | 52 | pub fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy { |
dfeec247 | 53 | ast::MutTy { ty, mutbl } |
970d7e83 LB |
54 | } |
55 | ||
e74abb32 | 56 | pub fn ty(&self, span: Span, kind: ast::TyKind) -> P<ast::Ty> { |
dfeec247 | 57 | P(ast::Ty { id: ast::DUMMY_NODE_ID, span, kind }) |
1a4d82fc JJ |
58 | } |
59 | ||
416331ca | 60 | pub fn ty_path(&self, path: ast::Path) -> P<ast::Ty> { |
7453a54e | 61 | self.ty(path.span, ast::TyKind::Path(None, path)) |
970d7e83 LB |
62 | } |
63 | ||
970d7e83 LB |
64 | // Might need to take bounds as an argument in the future, if you ever want |
65 | // to generate a bounded existential trait type. | |
f9f354fc | 66 | pub fn ty_ident(&self, span: Span, ident: Ident) -> P<ast::Ty> { |
1a4d82fc | 67 | self.ty_path(self.path_ident(span, ident)) |
970d7e83 LB |
68 | } |
69 | ||
e74abb32 | 70 | pub fn anon_const(&self, span: Span, kind: ast::ExprKind) -> ast::AnonConst { |
9fa01778 XL |
71 | ast::AnonConst { |
72 | id: ast::DUMMY_NODE_ID, | |
f9f354fc XL |
73 | value: P(ast::Expr { |
74 | id: ast::DUMMY_NODE_ID, | |
75 | kind, | |
76 | span, | |
77 | attrs: AttrVec::new(), | |
78 | tokens: None, | |
79 | }), | |
9fa01778 XL |
80 | } |
81 | } | |
82 | ||
f9f354fc | 83 | pub fn const_ident(&self, span: Span, ident: Ident) -> ast::AnonConst { |
9fa01778 XL |
84 | self.anon_const(span, ast::ExprKind::Path(None, self.path_ident(span, ident))) |
85 | } | |
86 | ||
dfeec247 XL |
87 | pub fn ty_rptr( |
88 | &self, | |
89 | span: Span, | |
90 | ty: P<ast::Ty>, | |
91 | lifetime: Option<ast::Lifetime>, | |
92 | mutbl: ast::Mutability, | |
93 | ) -> P<ast::Ty> { | |
94 | self.ty(span, ast::TyKind::Rptr(lifetime, self.ty_mt(ty, mutbl))) | |
970d7e83 | 95 | } |
1a4d82fc | 96 | |
dfeec247 XL |
97 | pub fn ty_ptr(&self, span: Span, ty: P<ast::Ty>, mutbl: ast::Mutability) -> P<ast::Ty> { |
98 | self.ty(span, ast::TyKind::Ptr(self.ty_mt(ty, mutbl))) | |
970d7e83 LB |
99 | } |
100 | ||
dfeec247 XL |
101 | pub fn typaram( |
102 | &self, | |
103 | span: Span, | |
f9f354fc | 104 | ident: Ident, |
dfeec247 XL |
105 | attrs: Vec<ast::Attribute>, |
106 | bounds: ast::GenericBounds, | |
107 | default: Option<P<ast::Ty>>, | |
108 | ) -> ast::GenericParam { | |
8faf50e0 | 109 | ast::GenericParam { |
83c7162d | 110 | ident: ident.with_span_pos(span), |
1a4d82fc | 111 | id: ast::DUMMY_NODE_ID, |
c30ab7b3 | 112 | attrs: attrs.into(), |
3b2f2976 | 113 | bounds, |
dfeec247 XL |
114 | kind: ast::GenericParamKind::Type { default }, |
115 | is_placeholder: false, | |
970d7e83 LB |
116 | } |
117 | } | |
118 | ||
416331ca | 119 | pub fn trait_ref(&self, path: ast::Path) -> ast::TraitRef { |
dfeec247 | 120 | ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID } |
970d7e83 LB |
121 | } |
122 | ||
416331ca | 123 | pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { |
1a4d82fc | 124 | ast::PolyTraitRef { |
ff7c6d11 | 125 | bound_generic_params: Vec::new(), |
85aaf69f | 126 | trait_ref: self.trait_ref(path), |
3b2f2976 | 127 | span, |
970d7e83 LB |
128 | } |
129 | } | |
130 | ||
416331ca | 131 | pub fn trait_bound(&self, path: ast::Path) -> ast::GenericBound { |
dfeec247 XL |
132 | ast::GenericBound::Trait( |
133 | self.poly_trait_ref(path.span, path), | |
134 | ast::TraitBoundModifier::None, | |
135 | ) | |
970d7e83 LB |
136 | } |
137 | ||
f9f354fc | 138 | pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime { |
83c7162d | 139 | ast::Lifetime { id: ast::DUMMY_NODE_ID, ident: ident.with_span_pos(span) } |
970d7e83 LB |
140 | } |
141 | ||
dfeec247 XL |
142 | pub fn lifetime_def( |
143 | &self, | |
144 | span: Span, | |
f9f354fc | 145 | ident: Ident, |
dfeec247 XL |
146 | attrs: Vec<ast::Attribute>, |
147 | bounds: ast::GenericBounds, | |
148 | ) -> ast::GenericParam { | |
8faf50e0 XL |
149 | let lifetime = self.lifetime(span, ident); |
150 | ast::GenericParam { | |
151 | ident: lifetime.ident, | |
152 | id: lifetime.id, | |
c30ab7b3 | 153 | attrs: attrs.into(), |
3b2f2976 | 154 | bounds, |
8faf50e0 | 155 | kind: ast::GenericParamKind::Lifetime, |
dfeec247 | 156 | is_placeholder: false, |
1a4d82fc JJ |
157 | } |
158 | } | |
159 | ||
416331ca | 160 | pub fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt { |
dfeec247 | 161 | ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) } |
3157f602 XL |
162 | } |
163 | ||
f9f354fc | 164 | pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P<ast::Expr>) -> ast::Stmt { |
1a4d82fc | 165 | let pat = if mutbl { |
dfeec247 | 166 | let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mut); |
7453a54e | 167 | self.pat_ident_binding_mode(sp, ident, binding_mode) |
1a4d82fc JJ |
168 | } else { |
169 | self.pat_ident(sp, ident) | |
170 | }; | |
171 | let local = P(ast::Local { | |
3b2f2976 | 172 | pat, |
1a4d82fc JJ |
173 | ty: None, |
174 | init: Some(ex), | |
175 | id: ast::DUMMY_NODE_ID, | |
176 | span: sp, | |
dfeec247 | 177 | attrs: AttrVec::new(), |
1a4d82fc | 178 | }); |
dfeec247 | 179 | ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp } |
1a4d82fc JJ |
180 | } |
181 | ||
dc9dc135 | 182 | // Generates `let _: Type;`, which is usually used for type assertions. |
416331ca | 183 | pub fn stmt_let_type_only(&self, span: Span, ty: P<ast::Ty>) -> ast::Stmt { |
9e0c209e SL |
184 | let local = P(ast::Local { |
185 | pat: self.pat_wild(span), | |
186 | ty: Some(ty), | |
187 | init: None, | |
188 | id: ast::DUMMY_NODE_ID, | |
3b2f2976 | 189 | span, |
dfeec247 | 190 | attrs: AttrVec::new(), |
9e0c209e | 191 | }); |
dfeec247 | 192 | ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span } |
9e0c209e SL |
193 | } |
194 | ||
416331ca | 195 | pub fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt { |
dfeec247 | 196 | ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Item(item), span: sp } |
970d7e83 LB |
197 | } |
198 | ||
416331ca | 199 | pub fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> { |
dfeec247 XL |
200 | self.block( |
201 | expr.span, | |
202 | vec![ast::Stmt { | |
203 | id: ast::DUMMY_NODE_ID, | |
204 | span: expr.span, | |
205 | kind: ast::StmtKind::Expr(expr), | |
206 | }], | |
207 | ) | |
3157f602 | 208 | } |
416331ca | 209 | pub fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block> { |
dfeec247 | 210 | P(ast::Block { stmts, id: ast::DUMMY_NODE_ID, rules: BlockCheckMode::Default, span }) |
970d7e83 LB |
211 | } |
212 | ||
e74abb32 | 213 | pub fn expr(&self, span: Span, kind: ast::ExprKind) -> P<ast::Expr> { |
f9f354fc | 214 | P(ast::Expr { id: ast::DUMMY_NODE_ID, kind, span, attrs: AttrVec::new(), tokens: None }) |
970d7e83 LB |
215 | } |
216 | ||
416331ca | 217 | pub fn expr_path(&self, path: ast::Path) -> P<ast::Expr> { |
7453a54e | 218 | self.expr(path.span, ast::ExprKind::Path(None, path)) |
970d7e83 LB |
219 | } |
220 | ||
f9f354fc | 221 | pub fn expr_ident(&self, span: Span, id: Ident) -> P<ast::Expr> { |
970d7e83 LB |
222 | self.expr_path(self.path_ident(span, id)) |
223 | } | |
416331ca | 224 | pub fn expr_self(&self, span: Span) -> P<ast::Expr> { |
e1599b0c | 225 | self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower)) |
970d7e83 LB |
226 | } |
227 | ||
dfeec247 XL |
228 | pub fn expr_binary( |
229 | &self, | |
230 | sp: Span, | |
231 | op: ast::BinOpKind, | |
232 | lhs: P<ast::Expr>, | |
233 | rhs: P<ast::Expr>, | |
234 | ) -> P<ast::Expr> { | |
7453a54e | 235 | self.expr(sp, ast::ExprKind::Binary(Spanned { node: op, span: sp }, lhs, rhs)) |
970d7e83 LB |
236 | } |
237 | ||
416331ca | 238 | pub fn expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> { |
e1599b0c | 239 | self.expr(sp, ast::ExprKind::Unary(UnOp::Deref, e)) |
970d7e83 LB |
240 | } |
241 | ||
416331ca | 242 | pub fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> { |
dfeec247 | 243 | self.expr(sp, ast::ExprKind::AddrOf(ast::BorrowKind::Ref, ast::Mutability::Not, e)) |
970d7e83 | 244 | } |
970d7e83 | 245 | |
416331ca | 246 | pub fn expr_call( |
dfeec247 XL |
247 | &self, |
248 | span: Span, | |
249 | expr: P<ast::Expr>, | |
250 | args: Vec<P<ast::Expr>>, | |
416331ca | 251 | ) -> P<ast::Expr> { |
7453a54e | 252 | self.expr(span, ast::ExprKind::Call(expr, args)) |
970d7e83 | 253 | } |
f9f354fc | 254 | pub fn expr_call_ident(&self, span: Span, id: Ident, args: Vec<P<ast::Expr>>) -> P<ast::Expr> { |
7453a54e | 255 | self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args)) |
970d7e83 | 256 | } |
dfeec247 XL |
257 | pub fn expr_call_global( |
258 | &self, | |
259 | sp: Span, | |
f9f354fc | 260 | fn_path: Vec<Ident>, |
dfeec247 XL |
261 | args: Vec<P<ast::Expr>>, |
262 | ) -> P<ast::Expr> { | |
970d7e83 LB |
263 | let pathexpr = self.expr_path(self.path_global(sp, fn_path)); |
264 | self.expr_call(sp, pathexpr, args) | |
265 | } | |
dfeec247 XL |
266 | pub fn expr_method_call( |
267 | &self, | |
268 | span: Span, | |
269 | expr: P<ast::Expr>, | |
f9f354fc | 270 | ident: Ident, |
dfeec247 XL |
271 | mut args: Vec<P<ast::Expr>>, |
272 | ) -> P<ast::Expr> { | |
1a4d82fc | 273 | args.insert(0, expr); |
83c7162d | 274 | let segment = ast::PathSegment::from_ident(ident.with_span_pos(span)); |
f035d41b | 275 | self.expr(span, ast::ExprKind::MethodCall(segment, args, span)) |
970d7e83 | 276 | } |
416331ca | 277 | pub fn expr_block(&self, b: P<ast::Block>) -> P<ast::Expr> { |
94b46f34 | 278 | self.expr(b.span, ast::ExprKind::Block(b, None)) |
970d7e83 | 279 | } |
416331ca | 280 | pub fn field_imm(&self, span: Span, ident: Ident, e: P<ast::Expr>) -> ast::Field { |
32a655c1 | 281 | ast::Field { |
83c7162d | 282 | ident: ident.with_span_pos(span), |
32a655c1 | 283 | expr: e, |
3b2f2976 | 284 | span, |
32a655c1 | 285 | is_shorthand: false, |
dfeec247 | 286 | attrs: AttrVec::new(), |
e1599b0c XL |
287 | id: ast::DUMMY_NODE_ID, |
288 | is_placeholder: false, | |
32a655c1 | 289 | } |
970d7e83 | 290 | } |
416331ca | 291 | pub fn expr_struct( |
dfeec247 XL |
292 | &self, |
293 | span: Span, | |
294 | path: ast::Path, | |
295 | fields: Vec<ast::Field>, | |
416331ca | 296 | ) -> P<ast::Expr> { |
7453a54e | 297 | self.expr(span, ast::ExprKind::Struct(path, fields, None)) |
970d7e83 | 298 | } |
dfeec247 XL |
299 | pub fn expr_struct_ident( |
300 | &self, | |
301 | span: Span, | |
f9f354fc | 302 | id: Ident, |
dfeec247 XL |
303 | fields: Vec<ast::Field>, |
304 | ) -> P<ast::Expr> { | |
970d7e83 LB |
305 | self.expr_struct(span, self.path_ident(span, id), fields) |
306 | } | |
307 | ||
416331ca | 308 | pub fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P<ast::Expr> { |
48663c56 XL |
309 | let lit = ast::Lit::from_lit_kind(lit_kind, span); |
310 | self.expr(span, ast::ExprKind::Lit(lit)) | |
970d7e83 | 311 | } |
416331ca | 312 | pub fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr> { |
dfeec247 XL |
313 | self.expr_lit( |
314 | span, | |
315 | ast::LitKind::Int(i as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)), | |
316 | ) | |
970d7e83 | 317 | } |
416331ca | 318 | pub fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr> { |
dfeec247 | 319 | self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U32))) |
c34b1796 | 320 | } |
416331ca | 321 | pub fn expr_bool(&self, sp: Span, value: bool) -> P<ast::Expr> { |
7453a54e | 322 | self.expr_lit(sp, ast::LitKind::Bool(value)) |
970d7e83 LB |
323 | } |
324 | ||
416331ca | 325 | pub fn expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { |
32a655c1 | 326 | self.expr(sp, ast::ExprKind::Array(exprs)) |
970d7e83 | 327 | } |
416331ca | 328 | pub fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { |
1a4d82fc | 329 | self.expr_addr_of(sp, self.expr_vec(sp, exprs)) |
970d7e83 | 330 | } |
416331ca | 331 | pub fn expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr> { |
7453a54e | 332 | self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked)) |
970d7e83 | 333 | } |
1a4d82fc | 334 | |
416331ca | 335 | pub fn expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr> { |
7453a54e | 336 | self.expr(sp, ast::ExprKind::Cast(expr, ty)) |
1a4d82fc JJ |
337 | } |
338 | ||
416331ca | 339 | pub fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { |
dc9dc135 | 340 | let some = self.std_path(&[sym::option, sym::Option, sym::Some]); |
c30ab7b3 | 341 | self.expr_call_global(sp, some, vec![expr]) |
1a4d82fc JJ |
342 | } |
343 | ||
416331ca | 344 | pub fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { |
7453a54e | 345 | self.expr(sp, ast::ExprKind::Tup(exprs)) |
1a4d82fc JJ |
346 | } |
347 | ||
416331ca | 348 | pub fn expr_fail(&self, span: Span, msg: Symbol) -> P<ast::Expr> { |
970d7e83 LB |
349 | self.expr_call_global( |
350 | span, | |
416331ca | 351 | [sym::std, sym::rt, sym::begin_panic].iter().map(|s| Ident::new(*s, span)).collect(), |
dfeec247 XL |
352 | vec![self.expr_str(span, msg)], |
353 | ) | |
1a4d82fc JJ |
354 | } |
355 | ||
416331ca | 356 | pub fn expr_unreachable(&self, span: Span) -> P<ast::Expr> { |
476ff2be | 357 | self.expr_fail(span, Symbol::intern("internal error: entered unreachable code")) |
1a4d82fc JJ |
358 | } |
359 | ||
416331ca | 360 | pub fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { |
dc9dc135 | 361 | let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); |
c30ab7b3 | 362 | self.expr_call_global(sp, ok, vec![expr]) |
1a4d82fc JJ |
363 | } |
364 | ||
416331ca | 365 | pub fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> { |
dc9dc135 | 366 | let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); |
85aaf69f | 367 | let ok_path = self.path_global(sp, ok); |
dc9dc135 | 368 | let err = self.std_path(&[sym::result, sym::Result, sym::Err]); |
85aaf69f | 369 | let err_path = self.path_global(sp, err); |
1a4d82fc | 370 | |
3dfed10e | 371 | let binding_variable = Ident::new(sym::__try_var, sp); |
1a4d82fc JJ |
372 | let binding_pat = self.pat_ident(sp, binding_variable); |
373 | let binding_expr = self.expr_ident(sp, binding_variable); | |
374 | ||
dc9dc135 | 375 | // `Ok(__try_var)` pattern |
9e0c209e | 376 | let ok_pat = self.pat_tuple_struct(sp, ok_path, vec![binding_pat.clone()]); |
1a4d82fc | 377 | |
dc9dc135 | 378 | // `Err(__try_var)` (pattern and expression respectively) |
9e0c209e | 379 | let err_pat = self.pat_tuple_struct(sp, err_path.clone(), vec![binding_pat]); |
dfeec247 XL |
380 | let err_inner_expr = |
381 | self.expr_call(sp, self.expr_path(err_path), vec![binding_expr.clone()]); | |
dc9dc135 | 382 | // `return Err(__try_var)` |
7453a54e | 383 | let err_expr = self.expr(sp, ast::ExprKind::Ret(Some(err_inner_expr))); |
1a4d82fc | 384 | |
dc9dc135 | 385 | // `Ok(__try_var) => __try_var` |
e1599b0c | 386 | let ok_arm = self.arm(sp, ok_pat, binding_expr); |
dc9dc135 | 387 | // `Err(__try_var) => return Err(__try_var)` |
e1599b0c | 388 | let err_arm = self.arm(sp, err_pat, err_expr); |
1a4d82fc | 389 | |
dc9dc135 | 390 | // `match head { Ok() => ..., Err() => ... }` |
c30ab7b3 | 391 | self.expr_match(sp, head, vec![ok_arm, err_arm]) |
970d7e83 LB |
392 | } |
393 | ||
e74abb32 | 394 | pub fn pat(&self, span: Span, kind: PatKind) -> P<ast::Pat> { |
3dfed10e | 395 | P(ast::Pat { id: ast::DUMMY_NODE_ID, kind, span, tokens: None }) |
970d7e83 | 396 | } |
416331ca | 397 | pub fn pat_wild(&self, span: Span) -> P<ast::Pat> { |
7453a54e | 398 | self.pat(span, PatKind::Wild) |
970d7e83 | 399 | } |
416331ca | 400 | pub fn pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat> { |
7453a54e | 401 | self.pat(span, PatKind::Lit(expr)) |
970d7e83 | 402 | } |
f9f354fc | 403 | pub fn pat_ident(&self, span: Span, ident: Ident) -> P<ast::Pat> { |
dfeec247 | 404 | let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Not); |
7453a54e | 405 | self.pat_ident_binding_mode(span, ident, binding_mode) |
970d7e83 LB |
406 | } |
407 | ||
dfeec247 XL |
408 | pub fn pat_ident_binding_mode( |
409 | &self, | |
410 | span: Span, | |
f9f354fc | 411 | ident: Ident, |
dfeec247 XL |
412 | bm: ast::BindingMode, |
413 | ) -> P<ast::Pat> { | |
83c7162d | 414 | let pat = PatKind::Ident(bm, ident.with_span_pos(span), None); |
970d7e83 LB |
415 | self.pat(span, pat) |
416 | } | |
416331ca | 417 | pub fn pat_path(&self, span: Span, path: ast::Path) -> P<ast::Pat> { |
9e0c209e | 418 | self.pat(span, PatKind::Path(None, path)) |
970d7e83 | 419 | } |
dfeec247 XL |
420 | pub fn pat_tuple_struct( |
421 | &self, | |
422 | span: Span, | |
423 | path: ast::Path, | |
424 | subpats: Vec<P<ast::Pat>>, | |
425 | ) -> P<ast::Pat> { | |
416331ca | 426 | self.pat(span, PatKind::TupleStruct(path, subpats)) |
9e0c209e | 427 | } |
dfeec247 XL |
428 | pub fn pat_struct( |
429 | &self, | |
430 | span: Span, | |
431 | path: ast::Path, | |
432 | field_pats: Vec<ast::FieldPat>, | |
433 | ) -> P<ast::Pat> { | |
9e0c209e | 434 | self.pat(span, PatKind::Struct(path, field_pats, false)) |
970d7e83 | 435 | } |
416331ca XL |
436 | pub fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> { |
437 | self.pat(span, PatKind::Tuple(pats)) | |
1a4d82fc JJ |
438 | } |
439 | ||
416331ca | 440 | pub fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> { |
dc9dc135 | 441 | let some = self.std_path(&[sym::option, sym::Option, sym::Some]); |
1a4d82fc | 442 | let path = self.path_global(span, some); |
9e0c209e | 443 | self.pat_tuple_struct(span, path, vec![pat]) |
1a4d82fc JJ |
444 | } |
445 | ||
416331ca | 446 | pub fn pat_none(&self, span: Span) -> P<ast::Pat> { |
dc9dc135 | 447 | let some = self.std_path(&[sym::option, sym::Option, sym::None]); |
1a4d82fc | 448 | let path = self.path_global(span, some); |
9e0c209e | 449 | self.pat_path(span, path) |
1a4d82fc JJ |
450 | } |
451 | ||
416331ca | 452 | pub fn pat_ok(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> { |
dc9dc135 | 453 | let some = self.std_path(&[sym::result, sym::Result, sym::Ok]); |
1a4d82fc | 454 | let path = self.path_global(span, some); |
9e0c209e | 455 | self.pat_tuple_struct(span, path, vec![pat]) |
1a4d82fc JJ |
456 | } |
457 | ||
416331ca | 458 | pub fn pat_err(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> { |
dc9dc135 | 459 | let some = self.std_path(&[sym::result, sym::Result, sym::Err]); |
1a4d82fc | 460 | let path = self.path_global(span, some); |
9e0c209e | 461 | self.pat_tuple_struct(span, path, vec![pat]) |
1a4d82fc JJ |
462 | } |
463 | ||
e1599b0c | 464 | pub fn arm(&self, span: Span, pat: P<ast::Pat>, expr: P<ast::Expr>) -> ast::Arm { |
1a4d82fc | 465 | ast::Arm { |
c30ab7b3 | 466 | attrs: vec![], |
e1599b0c | 467 | pat, |
970d7e83 | 468 | guard: None, |
ea8adc8c | 469 | body: expr, |
dc9dc135 | 470 | span, |
e1599b0c XL |
471 | id: ast::DUMMY_NODE_ID, |
472 | is_placeholder: false, | |
970d7e83 LB |
473 | } |
474 | } | |
475 | ||
416331ca | 476 | pub fn arm_unreachable(&self, span: Span) -> ast::Arm { |
e1599b0c | 477 | self.arm(span, self.pat_wild(span), self.expr_unreachable(span)) |
1a4d82fc JJ |
478 | } |
479 | ||
416331ca | 480 | pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr> { |
7453a54e | 481 | self.expr(span, ast::ExprKind::Match(arg, arms)) |
970d7e83 LB |
482 | } |
483 | ||
dfeec247 XL |
484 | pub fn expr_if( |
485 | &self, | |
486 | span: Span, | |
487 | cond: P<ast::Expr>, | |
488 | then: P<ast::Expr>, | |
489 | els: Option<P<ast::Expr>>, | |
490 | ) -> P<ast::Expr> { | |
1a4d82fc | 491 | let els = els.map(|x| self.expr_block(self.block_expr(x))); |
7453a54e | 492 | self.expr(span, ast::ExprKind::If(cond, self.block_expr(then), els)) |
970d7e83 LB |
493 | } |
494 | ||
dfeec247 XL |
495 | pub fn lambda_fn_decl( |
496 | &self, | |
497 | span: Span, | |
498 | fn_decl: P<ast::FnDecl>, | |
499 | body: P<ast::Expr>, | |
500 | fn_decl_span: Span, | |
501 | ) -> P<ast::Expr> { | |
502 | self.expr( | |
503 | span, | |
504 | ast::ExprKind::Closure( | |
505 | ast::CaptureBy::Ref, | |
74b04a01 | 506 | ast::Async::No, |
dfeec247 XL |
507 | ast::Movability::Movable, |
508 | fn_decl, | |
509 | body, | |
510 | fn_decl_span, | |
511 | ), | |
512 | ) | |
513 | } | |
514 | ||
f9f354fc | 515 | pub fn lambda(&self, span: Span, ids: Vec<Ident>, body: P<ast::Expr>) -> P<ast::Expr> { |
970d7e83 | 516 | let fn_decl = self.fn_decl( |
e1599b0c | 517 | ids.iter().map(|id| self.param(span, *id, self.ty(span, ast::TyKind::Infer))).collect(), |
74b04a01 | 518 | ast::FnRetTy::Default(span), |
dfeec247 | 519 | ); |
970d7e83 | 520 | |
a7813a04 XL |
521 | // FIXME -- We are using `span` as the span of the `|...|` |
522 | // part of the lambda, but it probably (maybe?) corresponds to | |
523 | // the entire lambda body. Probably we should extend the API | |
524 | // here, but that's not entirely clear. | |
dfeec247 XL |
525 | self.expr( |
526 | span, | |
527 | ast::ExprKind::Closure( | |
528 | ast::CaptureBy::Ref, | |
74b04a01 | 529 | ast::Async::No, |
dfeec247 XL |
530 | ast::Movability::Movable, |
531 | fn_decl, | |
532 | body, | |
533 | span, | |
534 | ), | |
535 | ) | |
970d7e83 | 536 | } |
a7813a04 | 537 | |
416331ca | 538 | pub fn lambda0(&self, span: Span, body: P<ast::Expr>) -> P<ast::Expr> { |
476ff2be | 539 | self.lambda(span, Vec::new(), body) |
970d7e83 LB |
540 | } |
541 | ||
f9f354fc | 542 | pub fn lambda1(&self, span: Span, body: P<ast::Expr>, ident: Ident) -> P<ast::Expr> { |
476ff2be | 543 | self.lambda(span, vec![ident], body) |
970d7e83 LB |
544 | } |
545 | ||
f9f354fc | 546 | pub fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>, ident: Ident) -> P<ast::Expr> { |
476ff2be | 547 | self.lambda1(span, self.expr_block(self.block(span, stmts)), ident) |
970d7e83 LB |
548 | } |
549 | ||
f9f354fc | 550 | pub fn param(&self, span: Span, ident: Ident, ty: P<ast::Ty>) -> ast::Param { |
970d7e83 | 551 | let arg_pat = self.pat_ident(span, ident); |
e1599b0c | 552 | ast::Param { |
dfeec247 | 553 | attrs: AttrVec::default(), |
48663c56 | 554 | id: ast::DUMMY_NODE_ID, |
dc9dc135 | 555 | pat: arg_pat, |
416331ca | 556 | span, |
dc9dc135 | 557 | ty, |
e1599b0c | 558 | is_placeholder: false, |
970d7e83 LB |
559 | } |
560 | } | |
561 | ||
dc9dc135 | 562 | // FIXME: unused `self` |
74b04a01 | 563 | pub fn fn_decl(&self, inputs: Vec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl> { |
dfeec247 | 564 | P(ast::FnDecl { inputs, output }) |
970d7e83 LB |
565 | } |
566 | ||
dfeec247 XL |
567 | pub fn item( |
568 | &self, | |
569 | span: Span, | |
570 | name: Ident, | |
571 | attrs: Vec<ast::Attribute>, | |
572 | kind: ast::ItemKind, | |
573 | ) -> P<ast::Item> { | |
1a4d82fc | 574 | // FIXME: Would be nice if our generated code didn't violate |
970d7e83 | 575 | // Rust coding conventions |
1a4d82fc JJ |
576 | P(ast::Item { |
577 | ident: name, | |
3b2f2976 | 578 | attrs, |
1a4d82fc | 579 | id: ast::DUMMY_NODE_ID, |
e74abb32 | 580 | kind, |
0531ce1d | 581 | vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited), |
3b2f2976 XL |
582 | span, |
583 | tokens: None, | |
1a4d82fc | 584 | }) |
970d7e83 LB |
585 | } |
586 | ||
dfeec247 | 587 | pub fn variant(&self, span: Span, ident: Ident, tys: Vec<P<ast::Ty>>) -> ast::Variant { |
60c5eb7d | 588 | let vis_span = span.shrink_to_lo(); |
dfeec247 XL |
589 | let fields: Vec<_> = tys |
590 | .into_iter() | |
591 | .map(|ty| ast::StructField { | |
54a0048b | 592 | span: ty.span, |
3b2f2976 | 593 | ty, |
54a0048b | 594 | ident: None, |
60c5eb7d | 595 | vis: respan(vis_span, ast::VisibilityKind::Inherited), |
b039eaaf SL |
596 | attrs: Vec::new(), |
597 | id: ast::DUMMY_NODE_ID, | |
e1599b0c | 598 | is_placeholder: false, |
dfeec247 XL |
599 | }) |
600 | .collect(); | |
970d7e83 | 601 | |
b039eaaf SL |
602 | let vdata = if fields.is_empty() { |
603 | ast::VariantData::Unit(ast::DUMMY_NODE_ID) | |
604 | } else { | |
605 | ast::VariantData::Tuple(fields, ast::DUMMY_NODE_ID) | |
606 | }; | |
607 | ||
e1599b0c XL |
608 | ast::Variant { |
609 | attrs: Vec::new(), | |
610 | data: vdata, | |
611 | disr_expr: None, | |
612 | id: ast::DUMMY_NODE_ID, | |
613 | ident, | |
60c5eb7d | 614 | vis: respan(vis_span, ast::VisibilityKind::Inherited), |
970d7e83 | 615 | span, |
e1599b0c XL |
616 | is_placeholder: false, |
617 | } | |
041b39d2 XL |
618 | } |
619 | ||
dfeec247 XL |
620 | pub fn item_static( |
621 | &self, | |
622 | span: Span, | |
623 | name: Ident, | |
624 | ty: P<ast::Ty>, | |
625 | mutbl: ast::Mutability, | |
626 | expr: P<ast::Expr>, | |
627 | ) -> P<ast::Item> { | |
74b04a01 | 628 | self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr))) |
1a4d82fc JJ |
629 | } |
630 | ||
dfeec247 XL |
631 | pub fn item_const( |
632 | &self, | |
633 | span: Span, | |
634 | name: Ident, | |
635 | ty: P<ast::Ty>, | |
636 | expr: P<ast::Expr>, | |
637 | ) -> P<ast::Item> { | |
74b04a01 XL |
638 | let def = ast::Defaultness::Final; |
639 | self.item(span, name, Vec::new(), ast::ItemKind::Const(def, ty, Some(expr))) | |
1a4d82fc JJ |
640 | } |
641 | ||
416331ca XL |
642 | pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute { |
643 | attr::mk_attr_outer(mi) | |
970d7e83 LB |
644 | } |
645 | ||
f9f354fc | 646 | pub fn meta_word(&self, sp: Span, w: Symbol) -> ast::MetaItem { |
416331ca | 647 | attr::mk_word_item(Ident::new(w, sp)) |
970d7e83 | 648 | } |
970d7e83 | 649 | } |