]>
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}; |
1b1a35ee | 6 | use rustc_span::source_map::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 | }); | |
1b1a35ee | 49 | ast::Path { span, segments, tokens: None } |
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> { |
1b1a35ee | 57 | P(ast::Ty { id: ast::DUMMY_NODE_ID, span, kind, tokens: None }) |
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 | ||
416331ca | 142 | pub fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt { |
fc512014 | 143 | ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) } |
3157f602 XL |
144 | } |
145 | ||
f9f354fc | 146 | pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P<ast::Expr>) -> ast::Stmt { |
1a4d82fc | 147 | let pat = if mutbl { |
dfeec247 | 148 | let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mut); |
7453a54e | 149 | self.pat_ident_binding_mode(sp, ident, binding_mode) |
1a4d82fc JJ |
150 | } else { |
151 | self.pat_ident(sp, ident) | |
152 | }; | |
153 | let local = P(ast::Local { | |
3b2f2976 | 154 | pat, |
1a4d82fc JJ |
155 | ty: None, |
156 | init: Some(ex), | |
157 | id: ast::DUMMY_NODE_ID, | |
158 | span: sp, | |
dfeec247 | 159 | attrs: AttrVec::new(), |
1b1a35ee | 160 | tokens: None, |
fc512014 XL |
161 | }); |
162 | ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp } | |
1a4d82fc JJ |
163 | } |
164 | ||
dc9dc135 | 165 | // Generates `let _: Type;`, which is usually used for type assertions. |
416331ca | 166 | pub fn stmt_let_type_only(&self, span: Span, ty: P<ast::Ty>) -> ast::Stmt { |
9e0c209e SL |
167 | let local = P(ast::Local { |
168 | pat: self.pat_wild(span), | |
169 | ty: Some(ty), | |
170 | init: None, | |
171 | id: ast::DUMMY_NODE_ID, | |
3b2f2976 | 172 | span, |
dfeec247 | 173 | attrs: AttrVec::new(), |
fc512014 | 174 | tokens: None, |
9e0c209e | 175 | }); |
fc512014 | 176 | ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span } |
9e0c209e SL |
177 | } |
178 | ||
416331ca | 179 | pub fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt { |
fc512014 | 180 | ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Item(item), span: sp } |
970d7e83 LB |
181 | } |
182 | ||
416331ca | 183 | pub fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> { |
dfeec247 XL |
184 | self.block( |
185 | expr.span, | |
186 | vec![ast::Stmt { | |
187 | id: ast::DUMMY_NODE_ID, | |
188 | span: expr.span, | |
189 | kind: ast::StmtKind::Expr(expr), | |
190 | }], | |
191 | ) | |
3157f602 | 192 | } |
416331ca | 193 | pub fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block> { |
1b1a35ee XL |
194 | P(ast::Block { |
195 | stmts, | |
196 | id: ast::DUMMY_NODE_ID, | |
197 | rules: BlockCheckMode::Default, | |
198 | span, | |
199 | tokens: None, | |
200 | }) | |
970d7e83 LB |
201 | } |
202 | ||
e74abb32 | 203 | pub fn expr(&self, span: Span, kind: ast::ExprKind) -> P<ast::Expr> { |
f9f354fc | 204 | P(ast::Expr { id: ast::DUMMY_NODE_ID, kind, span, attrs: AttrVec::new(), tokens: None }) |
970d7e83 LB |
205 | } |
206 | ||
416331ca | 207 | pub fn expr_path(&self, path: ast::Path) -> P<ast::Expr> { |
7453a54e | 208 | self.expr(path.span, ast::ExprKind::Path(None, path)) |
970d7e83 LB |
209 | } |
210 | ||
f9f354fc | 211 | pub fn expr_ident(&self, span: Span, id: Ident) -> P<ast::Expr> { |
970d7e83 LB |
212 | self.expr_path(self.path_ident(span, id)) |
213 | } | |
416331ca | 214 | pub fn expr_self(&self, span: Span) -> P<ast::Expr> { |
e1599b0c | 215 | self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower)) |
970d7e83 LB |
216 | } |
217 | ||
dfeec247 XL |
218 | pub fn expr_binary( |
219 | &self, | |
220 | sp: Span, | |
221 | op: ast::BinOpKind, | |
222 | lhs: P<ast::Expr>, | |
223 | rhs: P<ast::Expr>, | |
224 | ) -> P<ast::Expr> { | |
7453a54e | 225 | self.expr(sp, ast::ExprKind::Binary(Spanned { node: op, span: sp }, lhs, rhs)) |
970d7e83 LB |
226 | } |
227 | ||
416331ca | 228 | pub fn expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> { |
e1599b0c | 229 | self.expr(sp, ast::ExprKind::Unary(UnOp::Deref, e)) |
970d7e83 LB |
230 | } |
231 | ||
416331ca | 232 | pub fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> { |
dfeec247 | 233 | self.expr(sp, ast::ExprKind::AddrOf(ast::BorrowKind::Ref, ast::Mutability::Not, e)) |
970d7e83 | 234 | } |
970d7e83 | 235 | |
416331ca | 236 | pub fn expr_call( |
dfeec247 XL |
237 | &self, |
238 | span: Span, | |
239 | expr: P<ast::Expr>, | |
240 | args: Vec<P<ast::Expr>>, | |
416331ca | 241 | ) -> P<ast::Expr> { |
7453a54e | 242 | self.expr(span, ast::ExprKind::Call(expr, args)) |
970d7e83 | 243 | } |
f9f354fc | 244 | pub fn expr_call_ident(&self, span: Span, id: Ident, args: Vec<P<ast::Expr>>) -> P<ast::Expr> { |
7453a54e | 245 | self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args)) |
970d7e83 | 246 | } |
dfeec247 XL |
247 | pub fn expr_call_global( |
248 | &self, | |
249 | sp: Span, | |
f9f354fc | 250 | fn_path: Vec<Ident>, |
dfeec247 XL |
251 | args: Vec<P<ast::Expr>>, |
252 | ) -> P<ast::Expr> { | |
970d7e83 LB |
253 | let pathexpr = self.expr_path(self.path_global(sp, fn_path)); |
254 | self.expr_call(sp, pathexpr, args) | |
255 | } | |
dfeec247 XL |
256 | pub fn expr_method_call( |
257 | &self, | |
258 | span: Span, | |
259 | expr: P<ast::Expr>, | |
f9f354fc | 260 | ident: Ident, |
dfeec247 XL |
261 | mut args: Vec<P<ast::Expr>>, |
262 | ) -> P<ast::Expr> { | |
1a4d82fc | 263 | args.insert(0, expr); |
83c7162d | 264 | let segment = ast::PathSegment::from_ident(ident.with_span_pos(span)); |
f035d41b | 265 | self.expr(span, ast::ExprKind::MethodCall(segment, args, span)) |
970d7e83 | 266 | } |
416331ca | 267 | pub fn expr_block(&self, b: P<ast::Block>) -> P<ast::Expr> { |
94b46f34 | 268 | self.expr(b.span, ast::ExprKind::Block(b, None)) |
970d7e83 | 269 | } |
6a06907d XL |
270 | pub fn field_imm(&self, span: Span, ident: Ident, e: P<ast::Expr>) -> ast::ExprField { |
271 | ast::ExprField { | |
83c7162d | 272 | ident: ident.with_span_pos(span), |
32a655c1 | 273 | expr: e, |
3b2f2976 | 274 | span, |
32a655c1 | 275 | is_shorthand: false, |
dfeec247 | 276 | attrs: AttrVec::new(), |
e1599b0c XL |
277 | id: ast::DUMMY_NODE_ID, |
278 | is_placeholder: false, | |
32a655c1 | 279 | } |
970d7e83 | 280 | } |
416331ca | 281 | pub fn expr_struct( |
dfeec247 XL |
282 | &self, |
283 | span: Span, | |
284 | path: ast::Path, | |
6a06907d | 285 | fields: Vec<ast::ExprField>, |
416331ca | 286 | ) -> P<ast::Expr> { |
6a06907d XL |
287 | self.expr( |
288 | span, | |
289 | ast::ExprKind::Struct(P(ast::StructExpr { path, fields, rest: ast::StructRest::None })), | |
290 | ) | |
970d7e83 | 291 | } |
dfeec247 XL |
292 | pub fn expr_struct_ident( |
293 | &self, | |
294 | span: Span, | |
f9f354fc | 295 | id: Ident, |
6a06907d | 296 | fields: Vec<ast::ExprField>, |
dfeec247 | 297 | ) -> P<ast::Expr> { |
970d7e83 LB |
298 | self.expr_struct(span, self.path_ident(span, id), fields) |
299 | } | |
300 | ||
416331ca | 301 | pub fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P<ast::Expr> { |
48663c56 XL |
302 | let lit = ast::Lit::from_lit_kind(lit_kind, span); |
303 | self.expr(span, ast::ExprKind::Lit(lit)) | |
970d7e83 | 304 | } |
416331ca | 305 | pub fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr> { |
dfeec247 XL |
306 | self.expr_lit( |
307 | span, | |
308 | ast::LitKind::Int(i as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)), | |
309 | ) | |
970d7e83 | 310 | } |
416331ca | 311 | pub fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr> { |
dfeec247 | 312 | self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U32))) |
c34b1796 | 313 | } |
416331ca | 314 | pub fn expr_bool(&self, sp: Span, value: bool) -> P<ast::Expr> { |
7453a54e | 315 | self.expr_lit(sp, ast::LitKind::Bool(value)) |
970d7e83 LB |
316 | } |
317 | ||
416331ca | 318 | pub fn expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { |
32a655c1 | 319 | self.expr(sp, ast::ExprKind::Array(exprs)) |
970d7e83 | 320 | } |
416331ca | 321 | pub fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { |
1a4d82fc | 322 | self.expr_addr_of(sp, self.expr_vec(sp, exprs)) |
970d7e83 | 323 | } |
416331ca | 324 | pub fn expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr> { |
7453a54e | 325 | self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked)) |
970d7e83 | 326 | } |
1a4d82fc | 327 | |
416331ca | 328 | pub fn expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr> { |
7453a54e | 329 | self.expr(sp, ast::ExprKind::Cast(expr, ty)) |
1a4d82fc JJ |
330 | } |
331 | ||
416331ca | 332 | pub fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { |
dc9dc135 | 333 | let some = self.std_path(&[sym::option, sym::Option, sym::Some]); |
c30ab7b3 | 334 | self.expr_call_global(sp, some, vec![expr]) |
1a4d82fc JJ |
335 | } |
336 | ||
416331ca | 337 | pub fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { |
7453a54e | 338 | self.expr(sp, ast::ExprKind::Tup(exprs)) |
1a4d82fc JJ |
339 | } |
340 | ||
416331ca | 341 | pub fn expr_fail(&self, span: Span, msg: Symbol) -> P<ast::Expr> { |
970d7e83 LB |
342 | self.expr_call_global( |
343 | span, | |
416331ca | 344 | [sym::std, sym::rt, sym::begin_panic].iter().map(|s| Ident::new(*s, span)).collect(), |
dfeec247 XL |
345 | vec![self.expr_str(span, msg)], |
346 | ) | |
1a4d82fc JJ |
347 | } |
348 | ||
416331ca | 349 | pub fn expr_unreachable(&self, span: Span) -> P<ast::Expr> { |
476ff2be | 350 | self.expr_fail(span, Symbol::intern("internal error: entered unreachable code")) |
1a4d82fc JJ |
351 | } |
352 | ||
416331ca | 353 | pub fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { |
dc9dc135 | 354 | let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); |
c30ab7b3 | 355 | self.expr_call_global(sp, ok, vec![expr]) |
1a4d82fc JJ |
356 | } |
357 | ||
416331ca | 358 | pub fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> { |
dc9dc135 | 359 | let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); |
85aaf69f | 360 | let ok_path = self.path_global(sp, ok); |
dc9dc135 | 361 | let err = self.std_path(&[sym::result, sym::Result, sym::Err]); |
85aaf69f | 362 | let err_path = self.path_global(sp, err); |
1a4d82fc | 363 | |
3dfed10e | 364 | let binding_variable = Ident::new(sym::__try_var, sp); |
1a4d82fc JJ |
365 | let binding_pat = self.pat_ident(sp, binding_variable); |
366 | let binding_expr = self.expr_ident(sp, binding_variable); | |
367 | ||
dc9dc135 | 368 | // `Ok(__try_var)` pattern |
9e0c209e | 369 | let ok_pat = self.pat_tuple_struct(sp, ok_path, vec![binding_pat.clone()]); |
1a4d82fc | 370 | |
dc9dc135 | 371 | // `Err(__try_var)` (pattern and expression respectively) |
9e0c209e | 372 | let err_pat = self.pat_tuple_struct(sp, err_path.clone(), vec![binding_pat]); |
dfeec247 XL |
373 | let err_inner_expr = |
374 | self.expr_call(sp, self.expr_path(err_path), vec![binding_expr.clone()]); | |
dc9dc135 | 375 | // `return Err(__try_var)` |
7453a54e | 376 | let err_expr = self.expr(sp, ast::ExprKind::Ret(Some(err_inner_expr))); |
1a4d82fc | 377 | |
dc9dc135 | 378 | // `Ok(__try_var) => __try_var` |
e1599b0c | 379 | let ok_arm = self.arm(sp, ok_pat, binding_expr); |
dc9dc135 | 380 | // `Err(__try_var) => return Err(__try_var)` |
e1599b0c | 381 | let err_arm = self.arm(sp, err_pat, err_expr); |
1a4d82fc | 382 | |
dc9dc135 | 383 | // `match head { Ok() => ..., Err() => ... }` |
c30ab7b3 | 384 | self.expr_match(sp, head, vec![ok_arm, err_arm]) |
970d7e83 LB |
385 | } |
386 | ||
e74abb32 | 387 | pub fn pat(&self, span: Span, kind: PatKind) -> P<ast::Pat> { |
3dfed10e | 388 | P(ast::Pat { id: ast::DUMMY_NODE_ID, kind, span, tokens: None }) |
970d7e83 | 389 | } |
416331ca | 390 | pub fn pat_wild(&self, span: Span) -> P<ast::Pat> { |
7453a54e | 391 | self.pat(span, PatKind::Wild) |
970d7e83 | 392 | } |
416331ca | 393 | pub fn pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat> { |
7453a54e | 394 | self.pat(span, PatKind::Lit(expr)) |
970d7e83 | 395 | } |
f9f354fc | 396 | pub fn pat_ident(&self, span: Span, ident: Ident) -> P<ast::Pat> { |
dfeec247 | 397 | let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Not); |
7453a54e | 398 | self.pat_ident_binding_mode(span, ident, binding_mode) |
970d7e83 LB |
399 | } |
400 | ||
dfeec247 XL |
401 | pub fn pat_ident_binding_mode( |
402 | &self, | |
403 | span: Span, | |
f9f354fc | 404 | ident: Ident, |
dfeec247 XL |
405 | bm: ast::BindingMode, |
406 | ) -> P<ast::Pat> { | |
83c7162d | 407 | let pat = PatKind::Ident(bm, ident.with_span_pos(span), None); |
970d7e83 LB |
408 | self.pat(span, pat) |
409 | } | |
416331ca | 410 | pub fn pat_path(&self, span: Span, path: ast::Path) -> P<ast::Pat> { |
9e0c209e | 411 | self.pat(span, PatKind::Path(None, path)) |
970d7e83 | 412 | } |
dfeec247 XL |
413 | pub fn pat_tuple_struct( |
414 | &self, | |
415 | span: Span, | |
416 | path: ast::Path, | |
417 | subpats: Vec<P<ast::Pat>>, | |
418 | ) -> P<ast::Pat> { | |
416331ca | 419 | self.pat(span, PatKind::TupleStruct(path, subpats)) |
9e0c209e | 420 | } |
dfeec247 XL |
421 | pub fn pat_struct( |
422 | &self, | |
423 | span: Span, | |
424 | path: ast::Path, | |
6a06907d | 425 | field_pats: Vec<ast::PatField>, |
dfeec247 | 426 | ) -> P<ast::Pat> { |
9e0c209e | 427 | self.pat(span, PatKind::Struct(path, field_pats, false)) |
970d7e83 | 428 | } |
416331ca XL |
429 | pub fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> { |
430 | self.pat(span, PatKind::Tuple(pats)) | |
1a4d82fc JJ |
431 | } |
432 | ||
416331ca | 433 | pub fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> { |
dc9dc135 | 434 | let some = self.std_path(&[sym::option, sym::Option, sym::Some]); |
1a4d82fc | 435 | let path = self.path_global(span, some); |
9e0c209e | 436 | self.pat_tuple_struct(span, path, vec![pat]) |
1a4d82fc JJ |
437 | } |
438 | ||
e1599b0c | 439 | pub fn arm(&self, span: Span, pat: P<ast::Pat>, expr: P<ast::Expr>) -> ast::Arm { |
1a4d82fc | 440 | ast::Arm { |
c30ab7b3 | 441 | attrs: vec![], |
e1599b0c | 442 | pat, |
970d7e83 | 443 | guard: None, |
ea8adc8c | 444 | body: expr, |
dc9dc135 | 445 | span, |
e1599b0c XL |
446 | id: ast::DUMMY_NODE_ID, |
447 | is_placeholder: false, | |
970d7e83 LB |
448 | } |
449 | } | |
450 | ||
416331ca | 451 | pub fn arm_unreachable(&self, span: Span) -> ast::Arm { |
e1599b0c | 452 | self.arm(span, self.pat_wild(span), self.expr_unreachable(span)) |
1a4d82fc JJ |
453 | } |
454 | ||
416331ca | 455 | pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr> { |
7453a54e | 456 | self.expr(span, ast::ExprKind::Match(arg, arms)) |
970d7e83 LB |
457 | } |
458 | ||
dfeec247 XL |
459 | pub fn expr_if( |
460 | &self, | |
461 | span: Span, | |
462 | cond: P<ast::Expr>, | |
463 | then: P<ast::Expr>, | |
464 | els: Option<P<ast::Expr>>, | |
465 | ) -> P<ast::Expr> { | |
1a4d82fc | 466 | let els = els.map(|x| self.expr_block(self.block_expr(x))); |
7453a54e | 467 | self.expr(span, ast::ExprKind::If(cond, self.block_expr(then), els)) |
970d7e83 LB |
468 | } |
469 | ||
f9f354fc | 470 | pub fn lambda(&self, span: Span, ids: Vec<Ident>, body: P<ast::Expr>) -> P<ast::Expr> { |
970d7e83 | 471 | let fn_decl = self.fn_decl( |
e1599b0c | 472 | ids.iter().map(|id| self.param(span, *id, self.ty(span, ast::TyKind::Infer))).collect(), |
74b04a01 | 473 | ast::FnRetTy::Default(span), |
dfeec247 | 474 | ); |
970d7e83 | 475 | |
a7813a04 XL |
476 | // FIXME -- We are using `span` as the span of the `|...|` |
477 | // part of the lambda, but it probably (maybe?) corresponds to | |
478 | // the entire lambda body. Probably we should extend the API | |
479 | // here, but that's not entirely clear. | |
dfeec247 XL |
480 | self.expr( |
481 | span, | |
482 | ast::ExprKind::Closure( | |
483 | ast::CaptureBy::Ref, | |
74b04a01 | 484 | ast::Async::No, |
dfeec247 XL |
485 | ast::Movability::Movable, |
486 | fn_decl, | |
487 | body, | |
488 | span, | |
489 | ), | |
490 | ) | |
970d7e83 | 491 | } |
a7813a04 | 492 | |
416331ca | 493 | pub fn lambda0(&self, span: Span, body: P<ast::Expr>) -> P<ast::Expr> { |
476ff2be | 494 | self.lambda(span, Vec::new(), body) |
970d7e83 LB |
495 | } |
496 | ||
f9f354fc | 497 | pub fn lambda1(&self, span: Span, body: P<ast::Expr>, ident: Ident) -> P<ast::Expr> { |
476ff2be | 498 | self.lambda(span, vec![ident], body) |
970d7e83 LB |
499 | } |
500 | ||
f9f354fc | 501 | pub fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>, ident: Ident) -> P<ast::Expr> { |
476ff2be | 502 | self.lambda1(span, self.expr_block(self.block(span, stmts)), ident) |
970d7e83 LB |
503 | } |
504 | ||
f9f354fc | 505 | pub fn param(&self, span: Span, ident: Ident, ty: P<ast::Ty>) -> ast::Param { |
970d7e83 | 506 | let arg_pat = self.pat_ident(span, ident); |
e1599b0c | 507 | ast::Param { |
dfeec247 | 508 | attrs: AttrVec::default(), |
48663c56 | 509 | id: ast::DUMMY_NODE_ID, |
dc9dc135 | 510 | pat: arg_pat, |
416331ca | 511 | span, |
dc9dc135 | 512 | ty, |
e1599b0c | 513 | is_placeholder: false, |
970d7e83 LB |
514 | } |
515 | } | |
516 | ||
dc9dc135 | 517 | // FIXME: unused `self` |
74b04a01 | 518 | pub fn fn_decl(&self, inputs: Vec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl> { |
dfeec247 | 519 | P(ast::FnDecl { inputs, output }) |
970d7e83 LB |
520 | } |
521 | ||
dfeec247 XL |
522 | pub fn item( |
523 | &self, | |
524 | span: Span, | |
525 | name: Ident, | |
526 | attrs: Vec<ast::Attribute>, | |
527 | kind: ast::ItemKind, | |
528 | ) -> P<ast::Item> { | |
1a4d82fc | 529 | // FIXME: Would be nice if our generated code didn't violate |
970d7e83 | 530 | // Rust coding conventions |
1a4d82fc JJ |
531 | P(ast::Item { |
532 | ident: name, | |
3b2f2976 | 533 | attrs, |
1a4d82fc | 534 | id: ast::DUMMY_NODE_ID, |
e74abb32 | 535 | kind, |
1b1a35ee XL |
536 | vis: ast::Visibility { |
537 | span: span.shrink_to_lo(), | |
538 | kind: ast::VisibilityKind::Inherited, | |
539 | tokens: None, | |
540 | }, | |
3b2f2976 XL |
541 | span, |
542 | tokens: None, | |
1a4d82fc | 543 | }) |
970d7e83 LB |
544 | } |
545 | ||
dfeec247 XL |
546 | pub fn item_static( |
547 | &self, | |
548 | span: Span, | |
549 | name: Ident, | |
550 | ty: P<ast::Ty>, | |
551 | mutbl: ast::Mutability, | |
552 | expr: P<ast::Expr>, | |
553 | ) -> P<ast::Item> { | |
74b04a01 | 554 | self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr))) |
1a4d82fc JJ |
555 | } |
556 | ||
dfeec247 XL |
557 | pub fn item_const( |
558 | &self, | |
559 | span: Span, | |
560 | name: Ident, | |
561 | ty: P<ast::Ty>, | |
562 | expr: P<ast::Expr>, | |
563 | ) -> P<ast::Item> { | |
74b04a01 XL |
564 | let def = ast::Defaultness::Final; |
565 | self.item(span, name, Vec::new(), ast::ItemKind::Const(def, ty, Some(expr))) | |
1a4d82fc JJ |
566 | } |
567 | ||
416331ca XL |
568 | pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute { |
569 | attr::mk_attr_outer(mi) | |
970d7e83 LB |
570 | } |
571 | ||
f9f354fc | 572 | pub fn meta_word(&self, sp: Span, w: Symbol) -> ast::MetaItem { |
416331ca | 573 | attr::mk_word_item(Ident::new(w, sp)) |
970d7e83 | 574 | } |
970d7e83 | 575 | } |