1 use crate::base::ExtCtxt; 2 3 use rustc_ast::attr; 4 use rustc_ast::ptr::P; 5 use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, PatKind, UnOp}; 6 use rustc_span::source_map::Spanned; 7 use rustc_span::symbol::{kw, sym, Ident, Symbol}; 8 9 use rustc_span::Span; 10 11 impl<'a> ExtCtxt<'a> { path(&self, span: Span, strs: Vec<Ident>) -> ast::Path12 pub fn path(&self, span: Span, strs: Vec<Ident>) -> ast::Path { 13 self.path_all(span, false, strs, vec![]) 14 } path_ident(&self, span: Span, id: Ident) -> ast::Path15 pub fn path_ident(&self, span: Span, id: Ident) -> ast::Path { 16 self.path(span, vec![id]) 17 } path_global(&self, span: Span, strs: Vec<Ident>) -> ast::Path18 pub fn path_global(&self, span: Span, strs: Vec<Ident>) -> ast::Path { 19 self.path_all(span, true, strs, vec![]) 20 } path_all( &self, span: Span, global: bool, mut idents: Vec<Ident>, args: Vec<ast::GenericArg>, ) -> ast::Path21 pub fn path_all( 22 &self, 23 span: Span, 24 global: bool, 25 mut idents: Vec<Ident>, 26 args: Vec<ast::GenericArg>, 27 ) -> ast::Path { 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 } 34 let last_ident = idents.pop().unwrap(); 35 segments.extend( 36 idents.into_iter().map(|ident| ast::PathSegment::from_ident(ident.with_span_pos(span))), 37 ); 38 let args = if !args.is_empty() { 39 let args = args.into_iter().map(ast::AngleBracketedArg::Arg).collect(); 40 ast::AngleBracketedArgs { args, span }.into() 41 } else { 42 None 43 }; 44 segments.push(ast::PathSegment { 45 ident: last_ident.with_span_pos(span), 46 id: ast::DUMMY_NODE_ID, 47 args, 48 }); 49 ast::Path { span, segments, tokens: None } 50 } 51 ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy52 pub fn ty_mt(&self, ty: P<ast::Ty>, mutbl: ast::Mutability) -> ast::MutTy { 53 ast::MutTy { ty, mutbl } 54 } 55 ty(&self, span: Span, kind: ast::TyKind) -> P<ast::Ty>56 pub fn ty(&self, span: Span, kind: ast::TyKind) -> P<ast::Ty> { 57 P(ast::Ty { id: ast::DUMMY_NODE_ID, span, kind, tokens: None }) 58 } 59 ty_path(&self, path: ast::Path) -> P<ast::Ty>60 pub fn ty_path(&self, path: ast::Path) -> P<ast::Ty> { 61 self.ty(path.span, ast::TyKind::Path(None, path)) 62 } 63 64 // Might need to take bounds as an argument in the future, if you ever want 65 // to generate a bounded existential trait type. ty_ident(&self, span: Span, ident: Ident) -> P<ast::Ty>66 pub fn ty_ident(&self, span: Span, ident: Ident) -> P<ast::Ty> { 67 self.ty_path(self.path_ident(span, ident)) 68 } 69 anon_const(&self, span: Span, kind: ast::ExprKind) -> ast::AnonConst70 pub fn anon_const(&self, span: Span, kind: ast::ExprKind) -> ast::AnonConst { 71 ast::AnonConst { 72 id: ast::DUMMY_NODE_ID, 73 value: P(ast::Expr { 74 id: ast::DUMMY_NODE_ID, 75 kind, 76 span, 77 attrs: AttrVec::new(), 78 tokens: None, 79 }), 80 } 81 } 82 const_ident(&self, span: Span, ident: Ident) -> ast::AnonConst83 pub fn const_ident(&self, span: Span, ident: Ident) -> ast::AnonConst { 84 self.anon_const(span, ast::ExprKind::Path(None, self.path_ident(span, ident))) 85 } 86 ty_rptr( &self, span: Span, ty: P<ast::Ty>, lifetime: Option<ast::Lifetime>, mutbl: ast::Mutability, ) -> P<ast::Ty>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))) 95 } 96 ty_ptr(&self, span: Span, ty: P<ast::Ty>, mutbl: ast::Mutability) -> P<ast::Ty>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))) 99 } 100 typaram( &self, span: Span, ident: Ident, attrs: Vec<ast::Attribute>, bounds: ast::GenericBounds, default: Option<P<ast::Ty>>, ) -> ast::GenericParam101 pub fn typaram( 102 &self, 103 span: Span, 104 ident: Ident, 105 attrs: Vec<ast::Attribute>, 106 bounds: ast::GenericBounds, 107 default: Option<P<ast::Ty>>, 108 ) -> ast::GenericParam { 109 ast::GenericParam { 110 ident: ident.with_span_pos(span), 111 id: ast::DUMMY_NODE_ID, 112 attrs: attrs.into(), 113 bounds, 114 kind: ast::GenericParamKind::Type { default }, 115 is_placeholder: false, 116 } 117 } 118 trait_ref(&self, path: ast::Path) -> ast::TraitRef119 pub fn trait_ref(&self, path: ast::Path) -> ast::TraitRef { 120 ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID } 121 } 122 poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef123 pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { 124 ast::PolyTraitRef { 125 bound_generic_params: Vec::new(), 126 trait_ref: self.trait_ref(path), 127 span, 128 } 129 } 130 trait_bound(&self, path: ast::Path) -> ast::GenericBound131 pub fn trait_bound(&self, path: ast::Path) -> ast::GenericBound { 132 ast::GenericBound::Trait( 133 self.poly_trait_ref(path.span, path), 134 ast::TraitBoundModifier::None, 135 ) 136 } 137 lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime138 pub fn lifetime(&self, span: Span, ident: Ident) -> ast::Lifetime { 139 ast::Lifetime { id: ast::DUMMY_NODE_ID, ident: ident.with_span_pos(span) } 140 } 141 stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt142 pub fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt { 143 ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr) } 144 } 145 stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P<ast::Expr>) -> ast::Stmt146 pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: Ident, ex: P<ast::Expr>) -> ast::Stmt { 147 let pat = if mutbl { 148 let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mut); 149 self.pat_ident_binding_mode(sp, ident, binding_mode) 150 } else { 151 self.pat_ident(sp, ident) 152 }; 153 let local = P(ast::Local { 154 pat, 155 ty: None, 156 id: ast::DUMMY_NODE_ID, 157 kind: LocalKind::Init(ex), 158 span: sp, 159 attrs: AttrVec::new(), 160 tokens: None, 161 }); 162 ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span: sp } 163 } 164 165 // Generates `let _: Type;`, which is usually used for type assertions. stmt_let_type_only(&self, span: Span, ty: P<ast::Ty>) -> ast::Stmt166 pub fn stmt_let_type_only(&self, span: Span, ty: P<ast::Ty>) -> ast::Stmt { 167 let local = P(ast::Local { 168 pat: self.pat_wild(span), 169 ty: Some(ty), 170 id: ast::DUMMY_NODE_ID, 171 kind: LocalKind::Decl, 172 span, 173 attrs: AttrVec::new(), 174 tokens: None, 175 }); 176 ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Local(local), span } 177 } 178 stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt179 pub fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> ast::Stmt { 180 ast::Stmt { id: ast::DUMMY_NODE_ID, kind: ast::StmtKind::Item(item), span: sp } 181 } 182 block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block>183 pub fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> { 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 ) 192 } block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block>193 pub fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block> { 194 P(ast::Block { 195 stmts, 196 id: ast::DUMMY_NODE_ID, 197 rules: BlockCheckMode::Default, 198 span, 199 tokens: None, 200 could_be_bare_literal: false, 201 }) 202 } 203 expr(&self, span: Span, kind: ast::ExprKind) -> P<ast::Expr>204 pub fn expr(&self, span: Span, kind: ast::ExprKind) -> P<ast::Expr> { 205 P(ast::Expr { id: ast::DUMMY_NODE_ID, kind, span, attrs: AttrVec::new(), tokens: None }) 206 } 207 expr_path(&self, path: ast::Path) -> P<ast::Expr>208 pub fn expr_path(&self, path: ast::Path) -> P<ast::Expr> { 209 self.expr(path.span, ast::ExprKind::Path(None, path)) 210 } 211 expr_ident(&self, span: Span, id: Ident) -> P<ast::Expr>212 pub fn expr_ident(&self, span: Span, id: Ident) -> P<ast::Expr> { 213 self.expr_path(self.path_ident(span, id)) 214 } expr_self(&self, span: Span) -> P<ast::Expr>215 pub fn expr_self(&self, span: Span) -> P<ast::Expr> { 216 self.expr_ident(span, Ident::with_dummy_span(kw::SelfLower)) 217 } 218 expr_binary( &self, sp: Span, op: ast::BinOpKind, lhs: P<ast::Expr>, rhs: P<ast::Expr>, ) -> P<ast::Expr>219 pub fn expr_binary( 220 &self, 221 sp: Span, 222 op: ast::BinOpKind, 223 lhs: P<ast::Expr>, 224 rhs: P<ast::Expr>, 225 ) -> P<ast::Expr> { 226 self.expr(sp, ast::ExprKind::Binary(Spanned { node: op, span: sp }, lhs, rhs)) 227 } 228 expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr>229 pub fn expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> { 230 self.expr(sp, ast::ExprKind::Unary(UnOp::Deref, e)) 231 } 232 expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr>233 pub fn expr_addr_of(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> { 234 self.expr(sp, ast::ExprKind::AddrOf(ast::BorrowKind::Ref, ast::Mutability::Not, e)) 235 } 236 expr_call( &self, span: Span, expr: P<ast::Expr>, args: Vec<P<ast::Expr>>, ) -> P<ast::Expr>237 pub fn expr_call( 238 &self, 239 span: Span, 240 expr: P<ast::Expr>, 241 args: Vec<P<ast::Expr>>, 242 ) -> P<ast::Expr> { 243 self.expr(span, ast::ExprKind::Call(expr, args)) 244 } expr_call_ident(&self, span: Span, id: Ident, args: Vec<P<ast::Expr>>) -> P<ast::Expr>245 pub fn expr_call_ident(&self, span: Span, id: Ident, args: Vec<P<ast::Expr>>) -> P<ast::Expr> { 246 self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args)) 247 } expr_call_global( &self, sp: Span, fn_path: Vec<Ident>, args: Vec<P<ast::Expr>>, ) -> P<ast::Expr>248 pub fn expr_call_global( 249 &self, 250 sp: Span, 251 fn_path: Vec<Ident>, 252 args: Vec<P<ast::Expr>>, 253 ) -> P<ast::Expr> { 254 let pathexpr = self.expr_path(self.path_global(sp, fn_path)); 255 self.expr_call(sp, pathexpr, args) 256 } expr_block(&self, b: P<ast::Block>) -> P<ast::Expr>257 pub fn expr_block(&self, b: P<ast::Block>) -> P<ast::Expr> { 258 self.expr(b.span, ast::ExprKind::Block(b, None)) 259 } field_imm(&self, span: Span, ident: Ident, e: P<ast::Expr>) -> ast::ExprField260 pub fn field_imm(&self, span: Span, ident: Ident, e: P<ast::Expr>) -> ast::ExprField { 261 ast::ExprField { 262 ident: ident.with_span_pos(span), 263 expr: e, 264 span, 265 is_shorthand: false, 266 attrs: AttrVec::new(), 267 id: ast::DUMMY_NODE_ID, 268 is_placeholder: false, 269 } 270 } expr_struct( &self, span: Span, path: ast::Path, fields: Vec<ast::ExprField>, ) -> P<ast::Expr>271 pub fn expr_struct( 272 &self, 273 span: Span, 274 path: ast::Path, 275 fields: Vec<ast::ExprField>, 276 ) -> P<ast::Expr> { 277 self.expr( 278 span, 279 ast::ExprKind::Struct(P(ast::StructExpr { 280 qself: None, 281 path, 282 fields, 283 rest: ast::StructRest::None, 284 })), 285 ) 286 } expr_struct_ident( &self, span: Span, id: Ident, fields: Vec<ast::ExprField>, ) -> P<ast::Expr>287 pub fn expr_struct_ident( 288 &self, 289 span: Span, 290 id: Ident, 291 fields: Vec<ast::ExprField>, 292 ) -> P<ast::Expr> { 293 self.expr_struct(span, self.path_ident(span, id), fields) 294 } 295 expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P<ast::Expr>296 pub fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P<ast::Expr> { 297 let lit = ast::Lit::from_lit_kind(lit_kind, span); 298 self.expr(span, ast::ExprKind::Lit(lit)) 299 } expr_usize(&self, span: Span, i: usize) -> P<ast::Expr>300 pub fn expr_usize(&self, span: Span, i: usize) -> P<ast::Expr> { 301 self.expr_lit( 302 span, 303 ast::LitKind::Int(i as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize)), 304 ) 305 } expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr>306 pub fn expr_u32(&self, sp: Span, u: u32) -> P<ast::Expr> { 307 self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U32))) 308 } expr_bool(&self, sp: Span, value: bool) -> P<ast::Expr>309 pub fn expr_bool(&self, sp: Span, value: bool) -> P<ast::Expr> { 310 self.expr_lit(sp, ast::LitKind::Bool(value)) 311 } 312 expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>313 pub fn expr_vec(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { 314 self.expr(sp, ast::ExprKind::Array(exprs)) 315 } expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>316 pub fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { 317 self.expr_addr_of(sp, self.expr_vec(sp, exprs)) 318 } expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr>319 pub fn expr_str(&self, sp: Span, s: Symbol) -> P<ast::Expr> { 320 self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked)) 321 } 322 expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr>323 pub fn expr_cast(&self, sp: Span, expr: P<ast::Expr>, ty: P<ast::Ty>) -> P<ast::Expr> { 324 self.expr(sp, ast::ExprKind::Cast(expr, ty)) 325 } 326 expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr>327 pub fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { 328 let some = self.std_path(&[sym::option, sym::Option, sym::Some]); 329 self.expr_call_global(sp, some, vec![expr]) 330 } 331 expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr>332 pub fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { 333 self.expr(sp, ast::ExprKind::Tup(exprs)) 334 } 335 expr_fail(&self, span: Span, msg: Symbol) -> P<ast::Expr>336 pub fn expr_fail(&self, span: Span, msg: Symbol) -> P<ast::Expr> { 337 self.expr_call_global( 338 span, 339 [sym::std, sym::rt, sym::begin_panic].iter().map(|s| Ident::new(*s, span)).collect(), 340 vec![self.expr_str(span, msg)], 341 ) 342 } 343 expr_unreachable(&self, span: Span) -> P<ast::Expr>344 pub fn expr_unreachable(&self, span: Span) -> P<ast::Expr> { 345 self.expr_fail(span, Symbol::intern("internal error: entered unreachable code")) 346 } 347 expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr>348 pub fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { 349 let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); 350 self.expr_call_global(sp, ok, vec![expr]) 351 } 352 expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr>353 pub fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> { 354 let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); 355 let ok_path = self.path_global(sp, ok); 356 let err = self.std_path(&[sym::result, sym::Result, sym::Err]); 357 let err_path = self.path_global(sp, err); 358 359 let binding_variable = Ident::new(sym::__try_var, sp); 360 let binding_pat = self.pat_ident(sp, binding_variable); 361 let binding_expr = self.expr_ident(sp, binding_variable); 362 363 // `Ok(__try_var)` pattern 364 let ok_pat = self.pat_tuple_struct(sp, ok_path, vec![binding_pat.clone()]); 365 366 // `Err(__try_var)` (pattern and expression respectively) 367 let err_pat = self.pat_tuple_struct(sp, err_path.clone(), vec![binding_pat]); 368 let err_inner_expr = 369 self.expr_call(sp, self.expr_path(err_path), vec![binding_expr.clone()]); 370 // `return Err(__try_var)` 371 let err_expr = self.expr(sp, ast::ExprKind::Ret(Some(err_inner_expr))); 372 373 // `Ok(__try_var) => __try_var` 374 let ok_arm = self.arm(sp, ok_pat, binding_expr); 375 // `Err(__try_var) => return Err(__try_var)` 376 let err_arm = self.arm(sp, err_pat, err_expr); 377 378 // `match head { Ok() => ..., Err() => ... }` 379 self.expr_match(sp, head, vec![ok_arm, err_arm]) 380 } 381 pat(&self, span: Span, kind: PatKind) -> P<ast::Pat>382 pub fn pat(&self, span: Span, kind: PatKind) -> P<ast::Pat> { 383 P(ast::Pat { id: ast::DUMMY_NODE_ID, kind, span, tokens: None }) 384 } pat_wild(&self, span: Span) -> P<ast::Pat>385 pub fn pat_wild(&self, span: Span) -> P<ast::Pat> { 386 self.pat(span, PatKind::Wild) 387 } pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat>388 pub fn pat_lit(&self, span: Span, expr: P<ast::Expr>) -> P<ast::Pat> { 389 self.pat(span, PatKind::Lit(expr)) 390 } pat_ident(&self, span: Span, ident: Ident) -> P<ast::Pat>391 pub fn pat_ident(&self, span: Span, ident: Ident) -> P<ast::Pat> { 392 let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Not); 393 self.pat_ident_binding_mode(span, ident, binding_mode) 394 } 395 pat_ident_binding_mode( &self, span: Span, ident: Ident, bm: ast::BindingMode, ) -> P<ast::Pat>396 pub fn pat_ident_binding_mode( 397 &self, 398 span: Span, 399 ident: Ident, 400 bm: ast::BindingMode, 401 ) -> P<ast::Pat> { 402 let pat = PatKind::Ident(bm, ident.with_span_pos(span), None); 403 self.pat(span, pat) 404 } pat_path(&self, span: Span, path: ast::Path) -> P<ast::Pat>405 pub fn pat_path(&self, span: Span, path: ast::Path) -> P<ast::Pat> { 406 self.pat(span, PatKind::Path(None, path)) 407 } pat_tuple_struct( &self, span: Span, path: ast::Path, subpats: Vec<P<ast::Pat>>, ) -> P<ast::Pat>408 pub fn pat_tuple_struct( 409 &self, 410 span: Span, 411 path: ast::Path, 412 subpats: Vec<P<ast::Pat>>, 413 ) -> P<ast::Pat> { 414 self.pat(span, PatKind::TupleStruct(None, path, subpats)) 415 } pat_struct( &self, span: Span, path: ast::Path, field_pats: Vec<ast::PatField>, ) -> P<ast::Pat>416 pub fn pat_struct( 417 &self, 418 span: Span, 419 path: ast::Path, 420 field_pats: Vec<ast::PatField>, 421 ) -> P<ast::Pat> { 422 self.pat(span, PatKind::Struct(None, path, field_pats, false)) 423 } pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat>424 pub fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> { 425 self.pat(span, PatKind::Tuple(pats)) 426 } 427 pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat>428 pub fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> { 429 let some = self.std_path(&[sym::option, sym::Option, sym::Some]); 430 let path = self.path_global(span, some); 431 self.pat_tuple_struct(span, path, vec![pat]) 432 } 433 arm(&self, span: Span, pat: P<ast::Pat>, expr: P<ast::Expr>) -> ast::Arm434 pub fn arm(&self, span: Span, pat: P<ast::Pat>, expr: P<ast::Expr>) -> ast::Arm { 435 ast::Arm { 436 attrs: AttrVec::new(), 437 pat, 438 guard: None, 439 body: expr, 440 span, 441 id: ast::DUMMY_NODE_ID, 442 is_placeholder: false, 443 } 444 } 445 arm_unreachable(&self, span: Span) -> ast::Arm446 pub fn arm_unreachable(&self, span: Span) -> ast::Arm { 447 self.arm(span, self.pat_wild(span), self.expr_unreachable(span)) 448 } 449 expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr>450 pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr> { 451 self.expr(span, ast::ExprKind::Match(arg, arms)) 452 } 453 expr_if( &self, span: Span, cond: P<ast::Expr>, then: P<ast::Expr>, els: Option<P<ast::Expr>>, ) -> P<ast::Expr>454 pub fn expr_if( 455 &self, 456 span: Span, 457 cond: P<ast::Expr>, 458 then: P<ast::Expr>, 459 els: Option<P<ast::Expr>>, 460 ) -> P<ast::Expr> { 461 let els = els.map(|x| self.expr_block(self.block_expr(x))); 462 self.expr(span, ast::ExprKind::If(cond, self.block_expr(then), els)) 463 } 464 lambda(&self, span: Span, ids: Vec<Ident>, body: P<ast::Expr>) -> P<ast::Expr>465 pub fn lambda(&self, span: Span, ids: Vec<Ident>, body: P<ast::Expr>) -> P<ast::Expr> { 466 let fn_decl = self.fn_decl( 467 ids.iter().map(|id| self.param(span, *id, self.ty(span, ast::TyKind::Infer))).collect(), 468 ast::FnRetTy::Default(span), 469 ); 470 471 // FIXME -- We are using `span` as the span of the `|...|` 472 // part of the lambda, but it probably (maybe?) corresponds to 473 // the entire lambda body. Probably we should extend the API 474 // here, but that's not entirely clear. 475 self.expr( 476 span, 477 ast::ExprKind::Closure( 478 ast::CaptureBy::Ref, 479 ast::Async::No, 480 ast::Movability::Movable, 481 fn_decl, 482 body, 483 span, 484 ), 485 ) 486 } 487 lambda0(&self, span: Span, body: P<ast::Expr>) -> P<ast::Expr>488 pub fn lambda0(&self, span: Span, body: P<ast::Expr>) -> P<ast::Expr> { 489 self.lambda(span, Vec::new(), body) 490 } 491 lambda1(&self, span: Span, body: P<ast::Expr>, ident: Ident) -> P<ast::Expr>492 pub fn lambda1(&self, span: Span, body: P<ast::Expr>, ident: Ident) -> P<ast::Expr> { 493 self.lambda(span, vec![ident], body) 494 } 495 lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>, ident: Ident) -> P<ast::Expr>496 pub fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>, ident: Ident) -> P<ast::Expr> { 497 self.lambda1(span, self.expr_block(self.block(span, stmts)), ident) 498 } 499 param(&self, span: Span, ident: Ident, ty: P<ast::Ty>) -> ast::Param500 pub fn param(&self, span: Span, ident: Ident, ty: P<ast::Ty>) -> ast::Param { 501 let arg_pat = self.pat_ident(span, ident); 502 ast::Param { 503 attrs: AttrVec::default(), 504 id: ast::DUMMY_NODE_ID, 505 pat: arg_pat, 506 span, 507 ty, 508 is_placeholder: false, 509 } 510 } 511 512 // FIXME: unused `self` fn_decl(&self, inputs: Vec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl>513 pub fn fn_decl(&self, inputs: Vec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl> { 514 P(ast::FnDecl { inputs, output }) 515 } 516 item( &self, span: Span, name: Ident, attrs: Vec<ast::Attribute>, kind: ast::ItemKind, ) -> P<ast::Item>517 pub fn item( 518 &self, 519 span: Span, 520 name: Ident, 521 attrs: Vec<ast::Attribute>, 522 kind: ast::ItemKind, 523 ) -> P<ast::Item> { 524 // FIXME: Would be nice if our generated code didn't violate 525 // Rust coding conventions 526 P(ast::Item { 527 ident: name, 528 attrs, 529 id: ast::DUMMY_NODE_ID, 530 kind, 531 vis: ast::Visibility { 532 span: span.shrink_to_lo(), 533 kind: ast::VisibilityKind::Inherited, 534 tokens: None, 535 }, 536 span, 537 tokens: None, 538 }) 539 } 540 item_static( &self, span: Span, name: Ident, ty: P<ast::Ty>, mutbl: ast::Mutability, expr: P<ast::Expr>, ) -> P<ast::Item>541 pub fn item_static( 542 &self, 543 span: Span, 544 name: Ident, 545 ty: P<ast::Ty>, 546 mutbl: ast::Mutability, 547 expr: P<ast::Expr>, 548 ) -> P<ast::Item> { 549 self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr))) 550 } 551 item_const( &self, span: Span, name: Ident, ty: P<ast::Ty>, expr: P<ast::Expr>, ) -> P<ast::Item>552 pub fn item_const( 553 &self, 554 span: Span, 555 name: Ident, 556 ty: P<ast::Ty>, 557 expr: P<ast::Expr>, 558 ) -> P<ast::Item> { 559 let def = ast::Defaultness::Final; 560 self.item(span, name, Vec::new(), ast::ItemKind::Const(def, ty, Some(expr))) 561 } 562 attribute(&self, mi: ast::MetaItem) -> ast::Attribute563 pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute { 564 attr::mk_attr_outer(mi) 565 } 566 meta_word(&self, sp: Span, w: Symbol) -> ast::MetaItem567 pub fn meta_word(&self, sp: Span, w: Symbol) -> ast::MetaItem { 568 attr::mk_word_item(Ident::new(w, sp)) 569 } 570 } 571