]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/build/mod.rs
Rename `Stmt.node` to `Stmt.kind`
[rust.git] / src / librustc_mir / build / mod.rs
1 use crate::build;
2 use crate::build::scope::DropKind;
3 use crate::hair::cx::Cx;
4 use crate::hair::{LintLevel, BindingMode, PatternKind};
5 use crate::transform::MirSource;
6 use crate::util as mir_util;
7 use rustc::hir;
8 use rustc::hir::Node;
9 use rustc::hir::def_id::DefId;
10 use rustc::middle::region;
11 use rustc::mir::*;
12 use rustc::ty::{self, Ty, TyCtxt};
13 use rustc::util::nodemap::HirIdMap;
14 use rustc_target::spec::PanicStrategy;
15 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
16 use std::u32;
17 use rustc_target::spec::abi::Abi;
18 use syntax::attr::{self, UnwindAttr};
19 use syntax::symbol::kw;
20 use syntax_pos::Span;
21
22 use super::lints;
23
24 /// Construct the MIR for a given `DefId`.
25 pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
26     let id = tcx.hir().as_local_hir_id(def_id).unwrap();
27
28     // Figure out what primary body this item has.
29     let (body_id, return_ty_span) = match tcx.hir().get(id) {
30         Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, decl, body_id, _, _), .. })
31         | Node::Item(hir::Item { node: hir::ItemKind::Fn(decl, _, _, body_id), .. })
32         | Node::ImplItem(
33             hir::ImplItem {
34                 kind: hir::ImplItemKind::Method(hir::MethodSig { decl, .. }, body_id),
35                 ..
36             }
37         )
38         | Node::TraitItem(
39             hir::TraitItem {
40                 kind: hir::TraitItemKind::Method(
41                     hir::MethodSig { decl, .. },
42                     hir::TraitMethod::Provided(body_id),
43                 ),
44                 ..
45             }
46         ) => {
47             (*body_id, decl.output.span())
48         }
49         Node::Item(hir::Item { node: hir::ItemKind::Static(ty, _, body_id), .. })
50         | Node::Item(hir::Item { node: hir::ItemKind::Const(ty, body_id), .. })
51         | Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(ty, body_id), .. })
52         | Node::TraitItem(
53             hir::TraitItem { kind: hir::TraitItemKind::Const(ty, Some(body_id)), .. }
54         ) => {
55             (*body_id, ty.span)
56         }
57         Node::AnonConst(hir::AnonConst { body, hir_id, .. }) => {
58             (*body, tcx.hir().span(*hir_id))
59         }
60
61         _ => span_bug!(tcx.hir().span(id), "can't build MIR for {:?}", def_id),
62     };
63
64     tcx.infer_ctxt().enter(|infcx| {
65         let cx = Cx::new(&infcx, id);
66         let body = if cx.tables().tainted_by_errors {
67             build::construct_error(cx, body_id)
68         } else if cx.body_owner_kind.is_fn_or_closure() {
69             // fetch the fully liberated fn signature (that is, all bound
70             // types/lifetimes replaced)
71             let fn_sig = cx.tables().liberated_fn_sigs()[id].clone();
72             let fn_def_id = tcx.hir().local_def_id(id);
73
74             let ty = tcx.type_of(fn_def_id);
75             let mut abi = fn_sig.abi;
76             let implicit_argument = match ty.kind {
77                 ty::Closure(..) => {
78                     // HACK(eddyb) Avoid having RustCall on closures,
79                     // as it adds unnecessary (and wrong) auto-tupling.
80                     abi = Abi::Rust;
81                     Some(ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None))
82                 }
83                 ty::Generator(..) => {
84                     let gen_ty = tcx.body_tables(body_id).node_type(id);
85                     Some(ArgInfo(gen_ty, None, None, None))
86                 }
87                 _ => None,
88             };
89
90             let safety = match fn_sig.unsafety {
91                 hir::Unsafety::Normal => Safety::Safe,
92                 hir::Unsafety::Unsafe => Safety::FnUnsafe,
93             };
94
95             let body = tcx.hir().body(body_id);
96             let explicit_arguments =
97                 body.params
98                     .iter()
99                     .enumerate()
100                     .map(|(index, arg)| {
101                         let owner_id = tcx.hir().body_owner(body_id);
102                         let opt_ty_info;
103                         let self_arg;
104                         if let Some(ref fn_decl) = tcx.hir().fn_decl_by_hir_id(owner_id) {
105                             let ty_hir_id = fn_decl.inputs[index].hir_id;
106                             let ty_span = tcx.hir().span(ty_hir_id);
107                             opt_ty_info = Some(ty_span);
108                             self_arg = if index == 0 && fn_decl.implicit_self.has_implicit_self() {
109                                 match fn_decl.implicit_self {
110                                     hir::ImplicitSelfKind::Imm => Some(ImplicitSelfKind::Imm),
111                                     hir::ImplicitSelfKind::Mut => Some(ImplicitSelfKind::Mut),
112                                     hir::ImplicitSelfKind::ImmRef => Some(ImplicitSelfKind::ImmRef),
113                                     hir::ImplicitSelfKind::MutRef => Some(ImplicitSelfKind::MutRef),
114                                     _ => None,
115                                 }
116                             } else {
117                                 None
118                             };
119                         } else {
120                             opt_ty_info = None;
121                             self_arg = None;
122                         }
123
124                         ArgInfo(fn_sig.inputs()[index], opt_ty_info, Some(&arg), self_arg)
125                     });
126
127             let arguments = implicit_argument.into_iter().chain(explicit_arguments);
128
129             let (yield_ty, return_ty) = if body.generator_kind.is_some() {
130                 let gen_sig = match ty.kind {
131                     ty::Generator(gen_def_id, gen_substs, ..) =>
132                         gen_substs.sig(gen_def_id, tcx),
133                     _ =>
134                         span_bug!(tcx.hir().span(id),
135                                   "generator w/o generator type: {:?}", ty),
136                 };
137                 (Some(gen_sig.yield_ty), gen_sig.return_ty)
138             } else {
139                 (None, fn_sig.output())
140             };
141
142             build::construct_fn(cx, id, arguments, safety, abi,
143                                 return_ty, yield_ty, return_ty_span, body)
144         } else {
145             // Get the revealed type of this const. This is *not* the adjusted
146             // type of its body, which may be a subtype of this type. For
147             // example:
148             //
149             // fn foo(_: &()) {}
150             // static X: fn(&'static ()) = foo;
151             //
152             // The adjusted type of the body of X is `for<'a> fn(&'a ())` which
153             // is not the same as the type of X. We need the type of the return
154             // place to be the type of the constant because NLL typeck will
155             // equate them.
156
157             let return_ty = cx.tables().node_type(id);
158
159             build::construct_const(cx, body_id, return_ty, return_ty_span)
160         };
161
162         mir_util::dump_mir(tcx, None, "mir_map", &0,
163                            MirSource::item(def_id), &body, |_, _| Ok(()) );
164
165         lints::check(tcx, &body, def_id);
166
167         body
168     })
169 }
170
171 ///////////////////////////////////////////////////////////////////////////
172 // BuildMir -- walks a crate, looking for fn items and methods to build MIR from
173
174 fn liberated_closure_env_ty(
175     tcx: TyCtxt<'_>,
176     closure_expr_id: hir::HirId,
177     body_id: hir::BodyId,
178 ) -> Ty<'_> {
179     let closure_ty = tcx.body_tables(body_id).node_type(closure_expr_id);
180
181     let (closure_def_id, closure_substs) = match closure_ty.kind {
182         ty::Closure(closure_def_id, closure_substs) => (closure_def_id, closure_substs),
183         _ => bug!("closure expr does not have closure type: {:?}", closure_ty)
184     };
185
186     let closure_env_ty = tcx.closure_env_ty(closure_def_id, closure_substs).unwrap();
187     tcx.liberate_late_bound_regions(closure_def_id, &closure_env_ty)
188 }
189
190 #[derive(Debug, PartialEq, Eq)]
191 pub enum BlockFrame {
192     /// Evaluation is currently within a statement.
193     ///
194     /// Examples include:
195     /// 1. `EXPR;`
196     /// 2. `let _ = EXPR;`
197     /// 3. `let x = EXPR;`
198     Statement {
199         /// If true, then statement discards result from evaluating
200         /// the expression (such as examples 1 and 2 above).
201         ignores_expr_result: bool
202     },
203
204     /// Evaluation is currently within the tail expression of a block.
205     ///
206     /// Example: `{ STMT_1; STMT_2; EXPR }`
207     TailExpr {
208         /// If true, then the surrounding context of the block ignores
209         /// the result of evaluating the block's tail expression.
210         ///
211         /// Example: `let _ = { STMT_1; EXPR };`
212         tail_result_is_ignored: bool
213     },
214
215     /// Generic mark meaning that the block occurred as a subexpression
216     /// where the result might be used.
217     ///
218     /// Examples: `foo(EXPR)`, `match EXPR { ... }`
219     SubExpr,
220 }
221
222 impl BlockFrame {
223     fn is_tail_expr(&self) -> bool {
224         match *self {
225             BlockFrame::TailExpr { .. } => true,
226
227             BlockFrame::Statement { .. } |
228             BlockFrame::SubExpr => false,
229         }
230     }
231     fn is_statement(&self) -> bool {
232         match *self {
233             BlockFrame::Statement { .. } => true,
234
235             BlockFrame::TailExpr { .. } |
236             BlockFrame::SubExpr => false,
237         }
238     }
239  }
240
241 #[derive(Debug)]
242 struct BlockContext(Vec<BlockFrame>);
243
244 struct Builder<'a, 'tcx> {
245     hir: Cx<'a, 'tcx>,
246     cfg: CFG<'tcx>,
247
248     fn_span: Span,
249     arg_count: usize,
250     is_generator: bool,
251
252     /// The current set of scopes, updated as we traverse;
253     /// see the `scope` module for more details.
254     scopes: scope::Scopes<'tcx>,
255
256     /// The block-context: each time we build the code within an hair::Block,
257     /// we push a frame here tracking whether we are building a statement or
258     /// if we are pushing the tail expression of the block. This is used to
259     /// embed information in generated temps about whether they were created
260     /// for a block tail expression or not.
261     ///
262     /// It would be great if we could fold this into `self.scopes`
263     /// somehow, but right now I think that is very tightly tied to
264     /// the code generation in ways that we cannot (or should not)
265     /// start just throwing new entries onto that vector in order to
266     /// distinguish the context of EXPR1 from the context of EXPR2 in
267     /// `{ STMTS; EXPR1 } + EXPR2`.
268     block_context: BlockContext,
269
270     /// The current unsafe block in scope, even if it is hidden by
271     /// a `PushUnsafeBlock`.
272     unpushed_unsafe: Safety,
273
274     /// The number of `push_unsafe_block` levels in scope.
275     push_unsafe_count: usize,
276
277     /// The vector of all scopes that we have created thus far;
278     /// we track this for debuginfo later.
279     source_scopes: IndexVec<SourceScope, SourceScopeData>,
280     source_scope_local_data: IndexVec<SourceScope, SourceScopeLocalData>,
281     source_scope: SourceScope,
282
283     /// The guard-context: each time we build the guard expression for
284     /// a match arm, we push onto this stack, and then pop when we
285     /// finish building it.
286     guard_context: Vec<GuardFrame>,
287
288     /// Maps `HirId`s of variable bindings to the `Local`s created for them.
289     /// (A match binding can have two locals; the 2nd is for the arm's guard.)
290     var_indices: HirIdMap<LocalsForNode>,
291     local_decls: IndexVec<Local, LocalDecl<'tcx>>,
292     canonical_user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>,
293     __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
294     upvar_mutbls: Vec<Mutability>,
295     unit_temp: Option<Place<'tcx>>,
296
297     /// Cached block with the `RESUME` terminator; this is created
298     /// when first set of cleanups are built.
299     cached_resume_block: Option<BasicBlock>,
300     /// Cached block with the `RETURN` terminator.
301     cached_return_block: Option<BasicBlock>,
302     /// Cached block with the `UNREACHABLE` terminator.
303     cached_unreachable_block: Option<BasicBlock>,
304 }
305
306 impl<'a, 'tcx> Builder<'a, 'tcx> {
307     fn is_bound_var_in_guard(&self, id: hir::HirId) -> bool {
308         self.guard_context.iter().any(|frame| frame.locals.iter().any(|local| local.id == id))
309     }
310
311     fn var_local_id(&self, id: hir::HirId, for_guard: ForGuard) -> Local {
312         self.var_indices[&id].local_id(for_guard)
313     }
314 }
315
316 impl BlockContext {
317     fn new() -> Self { BlockContext(vec![]) }
318     fn push(&mut self, bf: BlockFrame) { self.0.push(bf); }
319     fn pop(&mut self) -> Option<BlockFrame> { self.0.pop() }
320
321     /// Traverses the frames on the `BlockContext`, searching for either
322     /// the first block-tail expression frame with no intervening
323     /// statement frame.
324     ///
325     /// Notably, this skips over `SubExpr` frames; this method is
326     /// meant to be used in the context of understanding the
327     /// relationship of a temp (created within some complicated
328     /// expression) with its containing expression, and whether the
329     /// value of that *containing expression* (not the temp!) is
330     /// ignored.
331     fn currently_in_block_tail(&self) -> Option<BlockTailInfo> {
332         for bf in self.0.iter().rev() {
333             match bf {
334                 BlockFrame::SubExpr => continue,
335                 BlockFrame::Statement { .. } => break,
336                 &BlockFrame::TailExpr { tail_result_is_ignored } =>
337                     return Some(BlockTailInfo { tail_result_is_ignored })
338             }
339         }
340
341         return None;
342     }
343
344     /// Looks at the topmost frame on the BlockContext and reports
345     /// whether its one that would discard a block tail result.
346     ///
347     /// Unlike `currently_within_ignored_tail_expression`, this does
348     /// *not* skip over `SubExpr` frames: here, we want to know
349     /// whether the block result itself is discarded.
350     fn currently_ignores_tail_results(&self) -> bool {
351         match self.0.last() {
352             // no context: conservatively assume result is read
353             None => false,
354
355             // sub-expression: block result feeds into some computation
356             Some(BlockFrame::SubExpr) => false,
357
358             // otherwise: use accumulated is_ignored state.
359             Some(BlockFrame::TailExpr { tail_result_is_ignored: ignored }) |
360             Some(BlockFrame::Statement { ignores_expr_result: ignored }) => *ignored,
361         }
362     }
363 }
364
365 #[derive(Debug)]
366 enum LocalsForNode {
367     /// In the usual case, a `HirId` for an identifier maps to at most
368     /// one `Local` declaration.
369     One(Local),
370
371     /// The exceptional case is identifiers in a match arm's pattern
372     /// that are referenced in a guard of that match arm. For these,
373     /// we have `2` Locals.
374     ///
375     /// * `for_arm_body` is the Local used in the arm body (which is
376     ///   just like the `One` case above),
377     ///
378     /// * `ref_for_guard` is the Local used in the arm's guard (which
379     ///   is a reference to a temp that is an alias of
380     ///   `for_arm_body`).
381     ForGuard { ref_for_guard: Local, for_arm_body: Local },
382 }
383
384 #[derive(Debug)]
385 struct GuardFrameLocal {
386     id: hir::HirId,
387 }
388
389 impl GuardFrameLocal {
390     fn new(id: hir::HirId, _binding_mode: BindingMode) -> Self {
391         GuardFrameLocal {
392             id: id,
393         }
394     }
395 }
396
397 #[derive(Debug)]
398 struct GuardFrame {
399     /// These are the id's of names that are bound by patterns of the
400     /// arm of *this* guard.
401     ///
402     /// (Frames higher up the stack will have the id's bound in arms
403     /// further out, such as in a case like:
404     ///
405     /// match E1 {
406     ///      P1(id1) if (... (match E2 { P2(id2) if ... => B2 })) => B1,
407     /// }
408     ///
409     /// here, when building for FIXME.
410     locals: Vec<GuardFrameLocal>,
411 }
412
413 /// `ForGuard` indicates whether we are talking about:
414 ///   1. The variable for use outside of guard expressions, or
415 ///   2. The temp that holds reference to (1.), which is actually what the
416 ///      guard expressions see.
417 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
418 enum ForGuard {
419     RefWithinGuard,
420     OutsideGuard,
421 }
422
423 impl LocalsForNode {
424     fn local_id(&self, for_guard: ForGuard) -> Local {
425         match (self, for_guard) {
426             (&LocalsForNode::One(local_id), ForGuard::OutsideGuard) |
427             (&LocalsForNode::ForGuard { ref_for_guard: local_id, .. }, ForGuard::RefWithinGuard) |
428             (&LocalsForNode::ForGuard { for_arm_body: local_id, .. }, ForGuard::OutsideGuard) =>
429                 local_id,
430
431             (&LocalsForNode::One(_), ForGuard::RefWithinGuard) =>
432                 bug!("anything with one local should never be within a guard."),
433         }
434     }
435 }
436
437 struct CFG<'tcx> {
438     basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
439 }
440
441 newtype_index! {
442     pub struct ScopeId { .. }
443 }
444
445 ///////////////////////////////////////////////////////////////////////////
446 /// The `BlockAnd` "monad" packages up the new basic block along with a
447 /// produced value (sometimes just unit, of course). The `unpack!`
448 /// macro (and methods below) makes working with `BlockAnd` much more
449 /// convenient.
450
451 #[must_use = "if you don't use one of these results, you're leaving a dangling edge"]
452 struct BlockAnd<T>(BasicBlock, T);
453
454 trait BlockAndExtension {
455     fn and<T>(self, v: T) -> BlockAnd<T>;
456     fn unit(self) -> BlockAnd<()>;
457 }
458
459 impl BlockAndExtension for BasicBlock {
460     fn and<T>(self, v: T) -> BlockAnd<T> {
461         BlockAnd(self, v)
462     }
463
464     fn unit(self) -> BlockAnd<()> {
465         BlockAnd(self, ())
466     }
467 }
468
469 /// Update a block pointer and return the value.
470 /// Use it like `let x = unpack!(block = self.foo(block, foo))`.
471 macro_rules! unpack {
472     ($x:ident = $c:expr) => {
473         {
474             let BlockAnd(b, v) = $c;
475             $x = b;
476             v
477         }
478     };
479
480     ($c:expr) => {
481         {
482             let BlockAnd(b, ()) = $c;
483             b
484         }
485     };
486 }
487
488 fn should_abort_on_panic(tcx: TyCtxt<'_>, fn_def_id: DefId, abi: Abi) -> bool {
489     // Not callable from C, so we can safely unwind through these
490     if abi == Abi::Rust || abi == Abi::RustCall { return false; }
491
492     // Validate `#[unwind]` syntax regardless of platform-specific panic strategy
493     let attrs = &tcx.get_attrs(fn_def_id);
494     let unwind_attr = attr::find_unwind_attr(Some(tcx.sess.diagnostic()), attrs);
495
496     // We never unwind, so it's not relevant to stop an unwind
497     if tcx.sess.panic_strategy() != PanicStrategy::Unwind { return false; }
498
499     // We cannot add landing pads, so don't add one
500     if tcx.sess.no_landing_pads() { return false; }
501
502     // This is a special case: some functions have a C abi but are meant to
503     // unwind anyway. Don't stop them.
504     match unwind_attr {
505         None => false, // FIXME(#58794)
506         Some(UnwindAttr::Allowed) => false,
507         Some(UnwindAttr::Aborts) => true,
508     }
509 }
510
511 ///////////////////////////////////////////////////////////////////////////
512 /// the main entry point for building MIR for a function
513
514 struct ArgInfo<'tcx>(Ty<'tcx>, Option<Span>, Option<&'tcx hir::Param>, Option<ImplicitSelfKind>);
515
516 fn construct_fn<'a, 'tcx, A>(
517     hir: Cx<'a, 'tcx>,
518     fn_id: hir::HirId,
519     arguments: A,
520     safety: Safety,
521     abi: Abi,
522     return_ty: Ty<'tcx>,
523     yield_ty: Option<Ty<'tcx>>,
524     return_ty_span: Span,
525     body: &'tcx hir::Body,
526 ) -> Body<'tcx>
527 where
528     A: Iterator<Item=ArgInfo<'tcx>>
529 {
530     let arguments: Vec<_> = arguments.collect();
531
532     let tcx = hir.tcx();
533     let tcx_hir = tcx.hir();
534     let span = tcx_hir.span(fn_id);
535
536     let hir_tables = hir.tables();
537     let fn_def_id = tcx_hir.local_def_id(fn_id);
538
539     // Gather the upvars of a closure, if any.
540     let mut upvar_mutbls = vec![];
541     // In analyze_closure() in upvar.rs we gathered a list of upvars used by a
542     // closure and we stored in a map called upvar_list in TypeckTables indexed
543     // with the closure's DefId. Here, we run through that vec of UpvarIds for
544     // the given closure and use the necessary information to create UpvarDecl.
545     let upvar_debuginfo: Vec<_> = hir_tables
546         .upvar_list
547         .get(&fn_def_id)
548         .into_iter()
549         .flatten()
550         .map(|(&var_hir_id, &upvar_id)| {
551             let capture = hir_tables.upvar_capture(upvar_id);
552             let by_ref = match capture {
553                 ty::UpvarCapture::ByValue => false,
554                 ty::UpvarCapture::ByRef(..) => true,
555             };
556             let mut debuginfo = UpvarDebuginfo {
557                 debug_name: kw::Invalid,
558                 by_ref,
559             };
560             let mut mutability = Mutability::Not;
561             if let Some(Node::Binding(pat)) = tcx_hir.find(var_hir_id) {
562                 if let hir::PatKind::Binding(_, _, ident, _) = pat.kind {
563                     debuginfo.debug_name = ident.name;
564                     if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
565                         if bm == ty::BindByValue(hir::MutMutable) {
566                             mutability = Mutability::Mut;
567                         } else {
568                             mutability = Mutability::Not;
569                         }
570                     } else {
571                         tcx.sess.delay_span_bug(pat.span, "missing binding mode");
572                     }
573                 }
574             }
575             upvar_mutbls.push(mutability);
576             debuginfo
577         })
578         .collect();
579
580     let mut builder = Builder::new(hir,
581         span,
582         arguments.len(),
583         safety,
584         return_ty,
585         return_ty_span,
586         upvar_debuginfo,
587         upvar_mutbls,
588         body.generator_kind.is_some());
589
590     let call_site_scope = region::Scope {
591         id: body.value.hir_id.local_id,
592         data: region::ScopeData::CallSite
593     };
594     let arg_scope = region::Scope {
595         id: body.value.hir_id.local_id,
596         data: region::ScopeData::Arguments
597     };
598     let mut block = START_BLOCK;
599     let source_info = builder.source_info(span);
600     let call_site_s = (call_site_scope, source_info);
601     unpack!(block = builder.in_scope(call_site_s, LintLevel::Inherited, |builder| {
602         if should_abort_on_panic(tcx, fn_def_id, abi) {
603             builder.schedule_abort();
604         }
605
606         let arg_scope_s = (arg_scope, source_info);
607         // `return_block` is called when we evaluate a `return` expression, so
608         // we just use `START_BLOCK` here.
609         unpack!(block = builder.in_breakable_scope(
610             None,
611             START_BLOCK,
612             Place::return_place(),
613             |builder| {
614                 builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| {
615                     builder.args_and_body(block, &arguments, arg_scope, &body.value)
616                 })
617             },
618         ));
619         // Attribute epilogue to function's closing brace
620         let fn_end = span.shrink_to_hi();
621         let source_info = builder.source_info(fn_end);
622         let return_block = builder.return_block();
623         builder.cfg.terminate(block, source_info,
624                               TerminatorKind::Goto { target: return_block });
625         builder.cfg.terminate(return_block, source_info,
626                               TerminatorKind::Return);
627         // Attribute any unreachable codepaths to the function's closing brace
628         if let Some(unreachable_block) = builder.cached_unreachable_block {
629             builder.cfg.terminate(unreachable_block, source_info,
630                                   TerminatorKind::Unreachable);
631         }
632         return_block.unit()
633     }));
634     assert_eq!(block, builder.return_block());
635
636     let mut spread_arg = None;
637     if abi == Abi::RustCall {
638         // RustCall pseudo-ABI untuples the last argument.
639         spread_arg = Some(Local::new(arguments.len()));
640     }
641     info!("fn_id {:?} has attrs {:?}", fn_def_id,
642           tcx.get_attrs(fn_def_id));
643
644     let mut body = builder.finish(yield_ty);
645     body.spread_arg = spread_arg;
646     body
647 }
648
649 fn construct_const<'a, 'tcx>(
650     hir: Cx<'a, 'tcx>,
651     body_id: hir::BodyId,
652     const_ty: Ty<'tcx>,
653     const_ty_span: Span,
654 ) -> Body<'tcx> {
655     let tcx = hir.tcx();
656     let owner_id = tcx.hir().body_owner(body_id);
657     let span = tcx.hir().span(owner_id);
658     let mut builder = Builder::new(
659         hir,
660         span,
661         0,
662         Safety::Safe,
663         const_ty,
664         const_ty_span,
665         vec![],
666         vec![],
667         false,
668     );
669
670     let mut block = START_BLOCK;
671     let ast_expr = &tcx.hir().body(body_id).value;
672     let expr = builder.hir.mirror(ast_expr);
673     unpack!(block = builder.into_expr(&Place::return_place(), block, expr));
674
675     let source_info = builder.source_info(span);
676     builder.cfg.terminate(block, source_info, TerminatorKind::Return);
677
678     // Constants can't `return` so a return block should not be created.
679     assert_eq!(builder.cached_return_block, None);
680
681     // Constants may be match expressions in which case an unreachable block may
682     // be created, so terminate it properly.
683     if let Some(unreachable_block) = builder.cached_unreachable_block {
684         builder.cfg.terminate(unreachable_block, source_info,
685                               TerminatorKind::Unreachable);
686     }
687
688     builder.finish(None)
689 }
690
691 fn construct_error<'a, 'tcx>(
692     hir: Cx<'a, 'tcx>,
693     body_id: hir::BodyId
694 ) -> Body<'tcx> {
695     let owner_id = hir.tcx().hir().body_owner(body_id);
696     let span = hir.tcx().hir().span(owner_id);
697     let ty = hir.tcx().types.err;
698     let mut builder = Builder::new(hir, span, 0, Safety::Safe, ty, span, vec![], vec![], false);
699     let source_info = builder.source_info(span);
700     builder.cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable);
701     builder.finish(None)
702 }
703
704 impl<'a, 'tcx> Builder<'a, 'tcx> {
705     fn new(hir: Cx<'a, 'tcx>,
706            span: Span,
707            arg_count: usize,
708            safety: Safety,
709            return_ty: Ty<'tcx>,
710            return_span: Span,
711            __upvar_debuginfo_codegen_only_do_not_use: Vec<UpvarDebuginfo>,
712            upvar_mutbls: Vec<Mutability>,
713            is_generator: bool)
714            -> Builder<'a, 'tcx> {
715         let lint_level = LintLevel::Explicit(hir.root_lint_level);
716         let mut builder = Builder {
717             hir,
718             cfg: CFG { basic_blocks: IndexVec::new() },
719             fn_span: span,
720             arg_count,
721             is_generator,
722             scopes: Default::default(),
723             block_context: BlockContext::new(),
724             source_scopes: IndexVec::new(),
725             source_scope: OUTERMOST_SOURCE_SCOPE,
726             source_scope_local_data: IndexVec::new(),
727             guard_context: vec![],
728             push_unsafe_count: 0,
729             unpushed_unsafe: safety,
730             local_decls: IndexVec::from_elem_n(
731                 LocalDecl::new_return_place(return_ty, return_span),
732                 1,
733             ),
734             canonical_user_type_annotations: IndexVec::new(),
735             __upvar_debuginfo_codegen_only_do_not_use,
736             upvar_mutbls,
737             var_indices: Default::default(),
738             unit_temp: None,
739             cached_resume_block: None,
740             cached_return_block: None,
741             cached_unreachable_block: None,
742         };
743
744         assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
745         assert_eq!(
746             builder.new_source_scope(span, lint_level, Some(safety)),
747             OUTERMOST_SOURCE_SCOPE);
748         builder.source_scopes[OUTERMOST_SOURCE_SCOPE].parent_scope = None;
749
750         builder
751     }
752
753     fn finish(self,
754               yield_ty: Option<Ty<'tcx>>)
755               -> Body<'tcx> {
756         for (index, block) in self.cfg.basic_blocks.iter().enumerate() {
757             if block.terminator.is_none() {
758                 span_bug!(self.fn_span, "no terminator on block {:?}", index);
759             }
760         }
761
762         Body::new(
763             self.cfg.basic_blocks,
764             self.source_scopes,
765             ClearCrossCrate::Set(self.source_scope_local_data),
766             yield_ty,
767             self.local_decls,
768             self.canonical_user_type_annotations,
769             self.arg_count,
770             self.__upvar_debuginfo_codegen_only_do_not_use,
771             self.fn_span,
772             self.hir.control_flow_destroyed(),
773         )
774     }
775
776     fn args_and_body(&mut self,
777                      mut block: BasicBlock,
778                      arguments: &[ArgInfo<'tcx>],
779                      argument_scope: region::Scope,
780                      ast_body: &'tcx hir::Expr)
781                      -> BlockAnd<()>
782     {
783         // Allocate locals for the function arguments
784         for &ArgInfo(ty, _, arg_opt, _) in arguments.iter() {
785             // If this is a simple binding pattern, give the local a name for
786             // debuginfo and so that error reporting knows that this is a user
787             // variable. For any other pattern the pattern introduces new
788             // variables which will be named instead.
789             let (name, span) = if let Some(arg) = arg_opt {
790                 (arg.pat.simple_ident().map(|ident| ident.name), arg.pat.span)
791             } else {
792                 (None, self.fn_span)
793             };
794
795             let source_info = SourceInfo { scope: OUTERMOST_SOURCE_SCOPE, span, };
796             self.local_decls.push(LocalDecl {
797                 mutability: Mutability::Mut,
798                 ty,
799                 user_ty: UserTypeProjections::none(),
800                 source_info,
801                 visibility_scope: source_info.scope,
802                 name,
803                 internal: false,
804                 is_user_variable: None,
805                 is_block_tail: None,
806             });
807         }
808
809         let mut scope = None;
810         // Bind the argument patterns
811         for (index, arg_info) in arguments.iter().enumerate() {
812             // Function arguments always get the first Local indices after the return place
813             let local = Local::new(index + 1);
814             let place = Place::from(local);
815             let &ArgInfo(ty, opt_ty_info, arg_opt, ref self_binding) = arg_info;
816
817             // Make sure we drop (parts of) the argument even when not matched on.
818             self.schedule_drop(
819                 arg_opt.as_ref().map_or(ast_body.span, |arg| arg.pat.span),
820                 argument_scope, local, ty, DropKind::Value,
821             );
822
823             if let Some(arg) = arg_opt {
824                 let pattern = self.hir.pattern_from_hir(&arg.pat);
825                 let original_source_scope = self.source_scope;
826                 let span = pattern.span;
827                 self.set_correct_source_scope_for_arg(arg.hir_id, original_source_scope, span);
828                 match *pattern.kind {
829                     // Don't introduce extra copies for simple bindings
830                     PatternKind::Binding {
831                         mutability,
832                         var,
833                         mode: BindingMode::ByValue,
834                         subpattern: None,
835                         ..
836                     } => {
837                         self.local_decls[local].mutability = mutability;
838                         self.local_decls[local].source_info.scope = self.source_scope;
839                         self.local_decls[local].is_user_variable =
840                             if let Some(kind) = self_binding {
841                                 Some(ClearCrossCrate::Set(BindingForm::ImplicitSelf(*kind)))
842                             } else {
843                                 let binding_mode = ty::BindingMode::BindByValue(mutability.into());
844                                 Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
845                                     binding_mode,
846                                     opt_ty_info,
847                                     opt_match_place: Some((Some(place.clone()), span)),
848                                     pat_span: span,
849                                 })))
850                             };
851                         self.var_indices.insert(var, LocalsForNode::One(local));
852                     }
853                     _ => {
854                         scope = self.declare_bindings(
855                             scope,
856                             ast_body.span,
857                             &pattern,
858                             matches::ArmHasGuard(false),
859                             Some((Some(&place), span)),
860                         );
861                         unpack!(block = self.place_into_pattern(block, pattern, &place, false));
862                     }
863                 }
864                 self.source_scope = original_source_scope;
865             }
866         }
867
868         // Enter the argument pattern bindings source scope, if it exists.
869         if let Some(source_scope) = scope {
870             self.source_scope = source_scope;
871         }
872
873         let body = self.hir.mirror(ast_body);
874         self.into(&Place::return_place(), block, body)
875     }
876
877     fn set_correct_source_scope_for_arg(
878         &mut self,
879         arg_hir_id: hir::HirId,
880         original_source_scope: SourceScope,
881         pattern_span: Span
882     ) {
883         let tcx = self.hir.tcx();
884         let current_root = tcx.maybe_lint_level_root_bounded(
885             arg_hir_id,
886             self.hir.root_lint_level
887         );
888         let parent_root = tcx.maybe_lint_level_root_bounded(
889             self.source_scope_local_data[original_source_scope].lint_root,
890             self.hir.root_lint_level,
891         );
892         if current_root != parent_root {
893             self.source_scope = self.new_source_scope(
894                 pattern_span,
895                 LintLevel::Explicit(current_root),
896                 None
897             );
898         }
899     }
900
901     fn get_unit_temp(&mut self) -> Place<'tcx> {
902         match self.unit_temp {
903             Some(ref tmp) => tmp.clone(),
904             None => {
905                 let ty = self.hir.unit_ty();
906                 let fn_span = self.fn_span;
907                 let tmp = self.temp(ty, fn_span);
908                 self.unit_temp = Some(tmp.clone());
909                 tmp
910             }
911         }
912     }
913
914     fn return_block(&mut self) -> BasicBlock {
915         match self.cached_return_block {
916             Some(rb) => rb,
917             None => {
918                 let rb = self.cfg.start_new_block();
919                 self.cached_return_block = Some(rb);
920                 rb
921             }
922         }
923     }
924 }
925
926 ///////////////////////////////////////////////////////////////////////////
927 // Builder methods are broken up into modules, depending on what kind
928 // of thing is being lowered. Note that they use the `unpack` macro
929 // above extensively.
930
931 mod block;
932 mod cfg;
933 mod expr;
934 mod into;
935 mod matches;
936 mod misc;
937 mod scope;