diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index 9666741d032b..0d9c46461619 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -32,9 +32,9 @@ pub struct Mir<'tcx> { /// that indexes into this vector. pub basic_blocks: Vec>, - /// List of lexical scopes; these are referenced by statements and - /// used (eventually) for debuginfo. Indexed by a `ScopeId`. - pub scopes: Vec, + /// List of visibility (lexical) scopes; these are referenced by statements + /// and used (eventually) for debuginfo. Indexed by a `VisibilityScope`. + pub visibility_scopes: Vec, /// Rvalues promoted from this function, such as borrows of constants. /// Each of them is the Mir of a constant with the fn's type parameters @@ -173,7 +173,7 @@ pub struct VarDecl<'tcx> { pub ty: Ty<'tcx>, /// scope in which variable was declared - pub scope: ScopeId, + pub scope: VisibilityScope, /// span where variable was declared pub span: Span, @@ -276,7 +276,7 @@ pub struct BasicBlockData<'tcx> { #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct Terminator<'tcx> { pub span: Span, - pub scope: ScopeId, + pub scope: VisibilityScope, pub kind: TerminatorKind<'tcx> } @@ -588,7 +588,7 @@ pub enum AssertMessage<'tcx> { #[derive(Clone, RustcEncodable, RustcDecodable)] pub struct Statement<'tcx> { pub span: Span, - pub scope: ScopeId, + pub scope: VisibilityScope, pub kind: StatementKind<'tcx>, } @@ -754,29 +754,32 @@ impl<'tcx> Debug for Lvalue<'tcx> { /////////////////////////////////////////////////////////////////////////// // Scopes -impl Index for Vec { - type Output = ScopeData; +impl Index for Vec { + type Output = VisibilityScopeData; #[inline] - fn index(&self, index: ScopeId) -> &ScopeData { + fn index(&self, index: VisibilityScope) -> &VisibilityScopeData { &self[index.index()] } } -impl IndexMut for Vec { +impl IndexMut for Vec { #[inline] - fn index_mut(&mut self, index: ScopeId) -> &mut ScopeData { + fn index_mut(&mut self, index: VisibilityScope) -> &mut VisibilityScopeData { &mut self[index.index()] } } #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, RustcEncodable, RustcDecodable)] -pub struct ScopeId(u32); +pub struct VisibilityScope(u32); -impl ScopeId { - pub fn new(index: usize) -> ScopeId { +/// The visibility scope all arguments go into. +pub const ARGUMENT_VISIBILITY_SCOPE: VisibilityScope = VisibilityScope(0); + +impl VisibilityScope { + pub fn new(index: usize) -> VisibilityScope { assert!(index < (u32::MAX as usize)); - ScopeId(index as u32) + VisibilityScope(index as u32) } pub fn index(self) -> usize { @@ -785,9 +788,9 @@ impl ScopeId { } #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] -pub struct ScopeData { +pub struct VisibilityScopeData { pub span: Span, - pub parent_scope: Option, + pub parent_scope: Option, } /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 5c9582b945bb..d340695761de 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -97,9 +97,9 @@ macro_rules! make_mir_visitor { self.super_basic_block_data(block, data); } - fn visit_scope_data(&mut self, - scope_data: & $($mutability)* ScopeData) { - self.super_scope_data(scope_data); + fn visit_visibility_scope_data(&mut self, + scope_data: & $($mutability)* VisibilityScopeData) { + self.super_visibility_scope_data(scope_data); } fn visit_statement(&mut self, @@ -236,9 +236,9 @@ macro_rules! make_mir_visitor { self.super_arg_decl(arg_decl); } - fn visit_scope_id(&mut self, - scope_id: & $($mutability)* ScopeId) { - self.super_scope_id(scope_id); + fn visit_visibility_scope(&mut self, + scope: & $($mutability)* VisibilityScope) { + self.super_visibility_scope(scope); } // The `super_xxx` methods comprise the default behavior and are @@ -248,7 +248,7 @@ macro_rules! make_mir_visitor { mir: & $($mutability)* Mir<'tcx>) { let Mir { ref $($mutability)* basic_blocks, - ref $($mutability)* scopes, + ref $($mutability)* visibility_scopes, promoted: _, // Visited by passes separately. ref $($mutability)* return_ty, ref $($mutability)* var_decls, @@ -263,8 +263,8 @@ macro_rules! make_mir_visitor { self.visit_basic_block_data(block, data); } - for scope in scopes { - self.visit_scope_data(scope); + for scope in visibility_scopes { + self.visit_visibility_scope_data(scope); } self.visit_fn_output(return_ty); @@ -302,16 +302,16 @@ macro_rules! make_mir_visitor { } } - fn super_scope_data(&mut self, - scope_data: & $($mutability)* ScopeData) { - let ScopeData { + fn super_visibility_scope_data(&mut self, + scope_data: & $($mutability)* VisibilityScopeData) { + let VisibilityScopeData { ref $($mutability)* span, ref $($mutability)* parent_scope, } = *scope_data; self.visit_span(span); if let Some(ref $($mutability)* parent_scope) = *parent_scope { - self.visit_scope_id(parent_scope); + self.visit_visibility_scope(parent_scope); } } @@ -325,7 +325,7 @@ macro_rules! make_mir_visitor { } = *statement; self.visit_span(span); - self.visit_scope_id(scope); + self.visit_visibility_scope(scope); match *kind { StatementKind::Assign(ref $($mutability)* lvalue, ref $($mutability)* rvalue) => { @@ -352,7 +352,7 @@ macro_rules! make_mir_visitor { } = *terminator; self.visit_span(span); - self.visit_scope_id(scope); + self.visit_visibility_scope(scope); self.visit_terminator_kind(block, kind); } @@ -627,7 +627,7 @@ macro_rules! make_mir_visitor { } = *var_decl; self.visit_ty(ty); - self.visit_scope_id(scope); + self.visit_visibility_scope(scope); self.visit_span(span); } @@ -651,8 +651,8 @@ macro_rules! make_mir_visitor { self.visit_ty(ty); } - fn super_scope_id(&mut self, - _scope_id: & $($mutability)* ScopeId) { + fn super_visibility_scope(&mut self, + _scope: & $($mutability)* VisibilityScope) { } fn super_branch(&mut self, diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs index c1626b93f0c4..f4e4b78b6467 100644 --- a/src/librustc_mir/build/block.rs +++ b/src/librustc_mir/build/block.rs @@ -22,7 +22,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ast_block: &'tcx hir::Block) -> BlockAnd<()> { let Block { extent, span, stmts, expr } = self.hir.mirror(ast_block); - self.in_scope(extent, block, move |this, _| { + self.in_scope(extent, block, move |this| { // This convoluted structure is to avoid using recursion as we walk down a list // of statements. Basically, the structure we get back is something like: // @@ -40,27 +40,40 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // // First we build all the statements in the block. let mut let_extent_stack = Vec::with_capacity(8); + let outer_visibility_scope = this.visibility_scope; for stmt in stmts { let Stmt { span: _, kind } = this.hir.mirror(stmt); match kind { StmtKind::Expr { scope, expr } => { - unpack!(block = this.in_scope(scope, block, |this, _| { + unpack!(block = this.in_scope(scope, block, |this| { let expr = this.hir.mirror(expr); this.stmt_expr(block, expr) })); } StmtKind::Let { remainder_scope, init_scope, pattern, initializer } => { - let remainder_scope_id = this.push_scope(remainder_scope, block); + let tcx = this.hir.tcx(); + + // Enter the remainder scope, i.e. the bindings' destruction scope. + this.push_scope(remainder_scope, block); let_extent_stack.push(remainder_scope); - unpack!(block = this.in_scope(init_scope, block, move |this, _| { - // FIXME #30046 ^~~~ - if let Some(init) = initializer { - this.expr_into_pattern(block, remainder_scope_id, pattern, init) - } else { - this.declare_bindings(remainder_scope_id, &pattern); - block.unit() - } - })); + + // Declare the bindings, which may create a visibility scope. + let remainder_span = remainder_scope.span(&tcx.region_maps, &tcx.map); + let remainder_span = remainder_span.unwrap_or(span); + let scope = this.declare_bindings(None, remainder_span, &pattern); + + // Evaluate the initializer, if present. + if let Some(init) = initializer { + unpack!(block = this.in_scope(init_scope, block, move |this| { + // FIXME #30046 ^~~~ + this.expr_into_pattern(block, pattern, init) + })); + } + + // Enter the visibility scope, after evaluating the initializer. + if let Some(visibility_scope) = scope { + this.visibility_scope = visibility_scope; + } } } } @@ -78,6 +91,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { for extent in let_extent_stack.into_iter().rev() { unpack!(block = this.pop_scope(extent, block)); } + // Restore the original visibility scope. + this.visibility_scope = outer_visibility_scope; block.unit() }) } diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs index 4859257f291c..4045497575d3 100644 --- a/src/librustc_mir/build/cfg.rs +++ b/src/librustc_mir/build/cfg.rs @@ -50,7 +50,7 @@ impl<'tcx> CFG<'tcx> { pub fn push_assign(&mut self, block: BasicBlock, - scope: ScopeId, + scope: VisibilityScope, span: Span, lvalue: &Lvalue<'tcx>, rvalue: Rvalue<'tcx>) { @@ -63,7 +63,7 @@ impl<'tcx> CFG<'tcx> { pub fn push_assign_constant(&mut self, block: BasicBlock, - scope: ScopeId, + scope: VisibilityScope, span: Span, temp: &Lvalue<'tcx>, constant: Constant<'tcx>) { @@ -73,7 +73,7 @@ impl<'tcx> CFG<'tcx> { pub fn push_assign_unit(&mut self, block: BasicBlock, - scope: ScopeId, + scope: VisibilityScope, span: Span, lvalue: &Lvalue<'tcx>) { self.push_assign(block, scope, span, lvalue, Rvalue::Aggregate( @@ -83,7 +83,7 @@ impl<'tcx> CFG<'tcx> { pub fn terminate(&mut self, block: BasicBlock, - scope: ScopeId, + scope: VisibilityScope, span: Span, kind: TerminatorKind<'tcx>) { debug_assert!(self.block_data(block).terminator.is_none(), diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs index bb5aca2d8d7c..1f78071dfcea 100644 --- a/src/librustc_mir/build/expr/as_lvalue.rs +++ b/src/librustc_mir/build/expr/as_lvalue.rs @@ -38,7 +38,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let expr_span = expr.span; match expr.kind { ExprKind::Scope { extent, value } => { - this.in_scope(extent, block, |this, _| this.as_lvalue(block, value)) + this.in_scope(extent, block, |this| this.as_lvalue(block, value)) } ExprKind::Field { lhs, name } => { let lvalue = unpack!(block = this.as_lvalue(block, lhs)); diff --git a/src/librustc_mir/build/expr/as_operand.rs b/src/librustc_mir/build/expr/as_operand.rs index a059f2bdde9c..beb9ca256abf 100644 --- a/src/librustc_mir/build/expr/as_operand.rs +++ b/src/librustc_mir/build/expr/as_operand.rs @@ -35,7 +35,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let this = self; if let ExprKind::Scope { extent, value } = expr.kind { - return this.in_scope(extent, block, |this, _| this.as_operand(block, value)); + return this.in_scope(extent, block, |this| this.as_operand(block, value)); } let category = Category::of(&expr.kind).unwrap(); diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 67cf5473f79c..19a3bc4d0e91 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -46,7 +46,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { match expr.kind { ExprKind::Scope { extent, value } => { - this.in_scope(extent, block, |this, _| this.as_rvalue(block, value)) + this.in_scope(extent, block, |this| this.as_rvalue(block, value)) } ExprKind::InlineAsm { asm, outputs, inputs } => { let outputs = outputs.into_iter().map(|output| { @@ -100,7 +100,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let result = this.temp(expr.ty); // to start, malloc some memory of suitable type (thus far, uninitialized): this.cfg.push_assign(block, scope_id, expr_span, &result, Rvalue::Box(value.ty)); - this.in_scope(value_extents, block, |this, _| { + this.in_scope(value_extents, block, |this| { // schedule a shallow free of that memory, lest we unwind: this.schedule_box_free(expr_span, value_extents, &result, value.ty); // initialize the box contents: diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs index f33d3dd5190d..2a28f3318019 100644 --- a/src/librustc_mir/build/expr/as_temp.rs +++ b/src/librustc_mir/build/expr/as_temp.rs @@ -30,7 +30,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let this = self; if let ExprKind::Scope { extent, value } = expr.kind { - return this.in_scope(extent, block, |this, _| this.as_temp(block, value)); + return this.in_scope(extent, block, |this| this.as_temp(block, value)); } let expr_ty = expr.ty.clone(); diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 41610c90377b..fb77fc50f868 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -37,7 +37,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { match expr.kind { ExprKind::Scope { extent, value } => { - this.in_scope(extent, block, |this, _| this.into(destination, block, value)) + this.in_scope(extent, block, |this| this.into(destination, block, value)) } ExprKind::Block { body: ast_block } => { this.ast_block(destination, expr.ty.is_nil(), block, ast_block) diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs index 24369aaff3f5..add268d394ab 100644 --- a/src/librustc_mir/build/expr/stmt.rs +++ b/src/librustc_mir/build/expr/stmt.rs @@ -26,7 +26,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { match expr.kind { ExprKind::Scope { extent, value } => { let value = this.hir.mirror(value); - this.in_scope(extent, block, |this, _| this.stmt_expr(block, value)) + this.in_scope(extent, block, |this| this.stmt_expr(block, value)) } ExprKind::Assign { lhs, rhs } => { let lhs = this.hir.mirror(lhs); diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 88d7e41bc616..46c907009a37 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -44,21 +44,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { .collect(), }; - // Get the body expressions and their scopes, while declaring bindings. - let arm_bodies: Vec<_> = arms.iter().enumerate().map(|(i, arm)| { - // Assume that all expressions are wrapped in Scope. + // Get the arm bodies and their scopes, while declaring bindings. + let arm_bodies: Vec<_> = arms.iter().map(|arm| { let body = self.hir.mirror(arm.body.clone()); - match body.kind { - ExprKind::Scope { extent, value } => { - let scope_id = self.push_scope(extent, arm_blocks.blocks[i]); - self.declare_bindings(scope_id, &arm.patterns[0]); - (extent, self.scopes.pop().unwrap(), value) - } - _ => { - span_bug!(body.span, "arm body is not wrapped in Scope {:?}", - body.kind); - } - } + let scope = self.declare_bindings(None, body.span, &arm.patterns[0]); + (body, scope.unwrap_or(self.visibility_scope)) }).collect(); // assemble a list of candidates: there is one candidate per @@ -99,63 +89,48 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { // all the arm blocks will rejoin here let end_block = self.cfg.start_new_block(); - let scope_id = self.innermost_scope_id(); - for (arm_index, (extent, scope, body)) in arm_bodies.into_iter().enumerate() { + let outer_visibility_scope = self.innermost_scope_id(); + for (arm_index, (body, visibility_scope)) in arm_bodies.into_iter().enumerate() { let mut arm_block = arm_blocks.blocks[arm_index]; - // Re-enter the scope we created the bindings in. - self.scopes.push(scope); + // Re-enter the visibility scope we created the bindings in. + self.visibility_scope = visibility_scope; unpack!(arm_block = self.into(destination, arm_block, body)); - unpack!(arm_block = self.pop_scope(extent, arm_block)); self.cfg.terminate(arm_block, - scope_id, + outer_visibility_scope, span, TerminatorKind::Goto { target: end_block }); } + self.visibility_scope = outer_visibility_scope; end_block.unit() } pub fn expr_into_pattern(&mut self, mut block: BasicBlock, - var_scope_id: ScopeId, // lifetime of vars irrefutable_pat: Pattern<'tcx>, initializer: ExprRef<'tcx>) -> BlockAnd<()> { // optimize the case of `let x = ...` match *irrefutable_pat.kind { - PatternKind::Binding { mutability, - name, - mode: BindingMode::ByValue, + PatternKind::Binding { mode: BindingMode::ByValue, var, - ty, - subpattern: None } => { - let index = self.declare_binding(var_scope_id, - mutability, - name, - var, - ty, - irrefutable_pat.span); - let lvalue = Lvalue::Var(index); + subpattern: None, .. } => { + let lvalue = Lvalue::Var(self.var_indices[&var]); return self.into(&lvalue, block, initializer); } _ => {} } let lvalue = unpack!(block = self.as_lvalue(block, initializer)); self.lvalue_into_pattern(block, - var_scope_id, irrefutable_pat, &lvalue) } pub fn lvalue_into_pattern(&mut self, mut block: BasicBlock, - var_scope_id: ScopeId, irrefutable_pat: Pattern<'tcx>, initializer: &Lvalue<'tcx>) -> BlockAnd<()> { - // first, creating the bindings - self.declare_bindings(var_scope_id, &irrefutable_pat); - // create a dummy candidate let mut candidate = Candidate { span: irrefutable_pat.span, @@ -182,32 +157,43 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { block.unit() } - pub fn declare_bindings(&mut self, var_scope_id: ScopeId, pattern: &Pattern<'tcx>) { + /// Declares the bindings of the given pattern and returns the visibility scope + /// for the bindings in this patterns, if such a scope had to be created. + /// NOTE: Declaring the bindings should always be done in their drop scope. + pub fn declare_bindings(&mut self, + mut var_scope: Option, + scope_span: Span, + pattern: &Pattern<'tcx>) + -> Option { match *pattern.kind { PatternKind::Binding { mutability, name, mode: _, var, ty, ref subpattern } => { - self.declare_binding(var_scope_id, mutability, name, var, ty, pattern.span); + if var_scope.is_none() { + var_scope = Some(self.new_visibility_scope(scope_span)); + } + self.declare_binding(var_scope.unwrap(), mutability, name, var, ty, pattern.span); if let Some(subpattern) = subpattern.as_ref() { - self.declare_bindings(var_scope_id, subpattern); + var_scope = self.declare_bindings(var_scope, scope_span, subpattern); } } PatternKind::Array { ref prefix, ref slice, ref suffix } | PatternKind::Slice { ref prefix, ref slice, ref suffix } => { for subpattern in prefix.iter().chain(slice).chain(suffix) { - self.declare_bindings(var_scope_id, subpattern); + var_scope = self.declare_bindings(var_scope, scope_span, subpattern); } } PatternKind::Constant { .. } | PatternKind::Range { .. } | PatternKind::Wild => { } PatternKind::Deref { ref subpattern } => { - self.declare_bindings(var_scope_id, subpattern); + var_scope = self.declare_bindings(var_scope, scope_span, subpattern); } PatternKind::Leaf { ref subpatterns } | PatternKind::Variant { ref subpatterns, .. } => { for subpattern in subpatterns { - self.declare_bindings(var_scope_id, &subpattern.pattern); + var_scope = self.declare_bindings(var_scope, scope_span, &subpattern.pattern); } } } + var_scope } } @@ -635,7 +621,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } fn declare_binding(&mut self, - var_scope_id: ScopeId, + var_scope_id: VisibilityScope, mutability: Mutability, name: Name, var_id: NodeId, @@ -655,7 +641,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { span: span, }); let index = index as u32; - let extent = self.scope_auxiliary[var_scope_id].extent; + let extent = self.extent_of_innermost_scope(); self.schedule_drop(span, extent, &Lvalue::Var(index), var_ty); self.var_indices.insert(var_id, index); diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs index c3501140fc0a..a6294406ea56 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir/build/misc.rs @@ -103,7 +103,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { pub fn push_usize(&mut self, block: BasicBlock, - scope_id: ScopeId, + scope_id: VisibilityScope, span: Span, value: u64) -> Lvalue<'tcx> { diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 9d7818a9ba4d..27cced2ae1ac 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -15,6 +15,7 @@ use rustc::mir::repr::*; use rustc_data_structures::fnv::FnvHashMap; use rustc::hir; use std::ops::{Index, IndexMut}; +use std::u32; use syntax::abi::Abi; use syntax::ast; use syntax::codemap::Span; @@ -43,7 +44,8 @@ pub struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { /// the vector of all scopes that we have created thus far; /// we track this for debuginfo later - scope_datas: Vec, + visibility_scopes: Vec, + visibility_scope: VisibilityScope, var_decls: Vec>, var_indices: FnvHashMap, @@ -61,6 +63,20 @@ struct CFG<'tcx> { basic_blocks: Vec>, } +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct ScopeId(u32); + +impl ScopeId { + pub fn new(index: usize) -> ScopeId { + assert!(index < (u32::MAX as usize)); + ScopeId(index as u32) + } + + pub fn index(self) -> usize { + self.0 as usize + } +} + /// For each scope, we track the extent (from the HIR) and a /// single-entry-multiple-exit subgraph that contains all the /// statements/terminators within it. @@ -179,17 +195,16 @@ pub fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, tcx.region_maps.lookup_code_extent( CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body_id }); let mut block = START_BLOCK; - let mut arg_decls = unpack!(block = builder.in_scope(call_site_extent, block, - |builder, call_site_scope_id| { - let arg_decls = unpack!(block = builder.in_scope(arg_extent, block, - |builder, arg_scope_id| { - builder.args_and_body(block, return_ty, arguments, arg_scope_id, ast_block) + let mut arg_decls = unpack!(block = builder.in_scope(call_site_extent, block, |builder| { + let arg_decls = unpack!(block = builder.in_scope(arg_extent, block, |builder| { + builder.args_and_body(block, return_ty, arguments, arg_extent, ast_block) })); + let visibility_scope = builder.visibility_scope; let return_block = builder.return_block(); - builder.cfg.terminate(block, call_site_scope_id, span, + builder.cfg.terminate(block, visibility_scope, span, TerminatorKind::Goto { target: return_block }); - builder.cfg.terminate(return_block, call_site_scope_id, span, + builder.cfg.terminate(return_block, visibility_scope, span, TerminatorKind::Return); return_block.and(arg_decls) })); @@ -241,14 +256,15 @@ pub fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>, let extent = ROOT_CODE_EXTENT; let mut block = START_BLOCK; - let _ = builder.in_scope(extent, block, |builder, call_site_scope_id| { + let _ = builder.in_scope(extent, block, |builder| { let expr = builder.hir.mirror(ast_expr); unpack!(block = builder.into(&Lvalue::ReturnPointer, block, expr)); + let visibility_scope = builder.visibility_scope; let return_block = builder.return_block(); - builder.cfg.terminate(block, call_site_scope_id, span, + builder.cfg.terminate(block, visibility_scope, span, TerminatorKind::Goto { target: return_block }); - builder.cfg.terminate(return_block, call_site_scope_id, span, + builder.cfg.terminate(return_block, visibility_scope, span, TerminatorKind::Return); return_block.unit() @@ -265,7 +281,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { cfg: CFG { basic_blocks: vec![] }, fn_span: span, scopes: vec![], - scope_datas: vec![], + visibility_scopes: vec![], + visibility_scope: ARGUMENT_VISIBILITY_SCOPE, scope_auxiliary: ScopeAuxiliaryVec { vec: vec![] }, loop_scopes: vec![], temp_decls: vec![], @@ -277,6 +294,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }; assert_eq!(builder.cfg.start_new_block(), START_BLOCK); + assert_eq!(builder.new_visibility_scope(span), ARGUMENT_VISIBILITY_SCOPE); + builder.visibility_scopes[ARGUMENT_VISIBILITY_SCOPE].parent_scope = None; builder } @@ -294,7 +313,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { (Mir { basic_blocks: self.cfg.basic_blocks, - scopes: self.scope_datas, + visibility_scopes: self.visibility_scopes, promoted: vec![], var_decls: self.var_decls, arg_decls: arg_decls, @@ -309,24 +328,22 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { mut block: BasicBlock, return_ty: ty::FnOutput<'tcx>, arguments: A, - argument_scope_id: ScopeId, + argument_extent: CodeExtent, ast_block: &'gcx hir::Block) -> BlockAnd>> where A: Iterator, Option<&'gcx hir::Pat>)> { // to start, translate the argument patterns and collect the argument types. + let mut scope = None; let arg_decls = arguments.enumerate().map(|(index, (ty, pattern))| { let lvalue = Lvalue::Arg(index as u32); if let Some(pattern) = pattern { let pattern = self.hir.irrefutable_pat(pattern); - unpack!(block = self.lvalue_into_pattern(block, - argument_scope_id, - pattern, - &lvalue)); + scope = self.declare_bindings(scope, ast_block.span, &pattern); + unpack!(block = self.lvalue_into_pattern(block, pattern, &lvalue)); } // Make sure we drop (parts of) the argument even when not matched on. - let argument_extent = self.scope_auxiliary[argument_scope_id].extent; self.schedule_drop(pattern.as_ref().map_or(ast_block.span, |pat| pat.span), argument_extent, &lvalue, ty); @@ -344,6 +361,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { } }).collect(); + // Enter the argument pattern bindings visibility scope, if it exists. + if let Some(visibility_scope) = scope { + self.visibility_scope = visibility_scope; + } + // FIXME(#32959): temporary hack for the issue at hand let return_is_unit = if let ty::FnConverging(t) = return_ty { t.is_nil() diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index 209649dd2fd1..93ca01ba2ec4 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -86,7 +86,7 @@ should go to. */ -use build::{BlockAnd, BlockAndExtension, Builder, CFG, ScopeAuxiliary}; +use build::{BlockAnd, BlockAndExtension, Builder, CFG, ScopeAuxiliary, ScopeId}; use rustc::middle::region::{CodeExtent, CodeExtentData}; use rustc::middle::lang_items; use rustc::ty::subst::{Substs, Subst, VecPerParamSpace}; @@ -98,9 +98,12 @@ use rustc::middle::const_val::ConstVal; use rustc_const_math::ConstInt; pub struct Scope<'tcx> { - /// the scope-id within the scope_datas + /// the scope-id within the scope_auxiliary id: ScopeId, + /// The visibility scope this scope was created in. + visibility_scope: VisibilityScope, + /// the extent of this scope within source code; also stored in /// `ScopeAuxiliary`, but kept here for convenience extent: CodeExtent, @@ -237,11 +240,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Convenience wrapper that pushes a scope and then executes `f` /// to build its contents, popping the scope afterwards. pub fn in_scope(&mut self, extent: CodeExtent, mut block: BasicBlock, f: F) -> BlockAnd - where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>, ScopeId) -> BlockAnd + where F: FnOnce(&mut Builder<'a, 'gcx, 'tcx>) -> BlockAnd { debug!("in_scope(extent={:?}, block={:?})", extent, block); - let id = self.push_scope(extent, block); - let rv = unpack!(block = f(self, id)); + self.push_scope(extent, block); + let rv = unpack!(block = f(self)); unpack!(block = self.pop_scope(extent, block)); debug!("in_scope: exiting extent={:?} block={:?}", extent, block); block.and(rv) @@ -251,17 +254,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// scope and call `pop_scope` afterwards. Note that these two /// calls must be paired; using `in_scope` as a convenience /// wrapper maybe preferable. - pub fn push_scope(&mut self, extent: CodeExtent, entry: BasicBlock) -> ScopeId { + pub fn push_scope(&mut self, extent: CodeExtent, entry: BasicBlock) { debug!("push_scope({:?})", extent); - let parent_id = self.scopes.last().map(|s| s.id); - let id = ScopeId::new(self.scope_datas.len()); - let tcx = self.hir.tcx(); - self.scope_datas.push(ScopeData { - span: extent.span(&tcx.region_maps, &tcx.map).unwrap_or(DUMMY_SP), - parent_scope: parent_id, - }); + let id = ScopeId::new(self.scope_auxiliary.vec.len()); + let vis_scope = self.visibility_scope; self.scopes.push(Scope { id: id, + visibility_scope: vis_scope, extent: extent, drops: vec![], free: None, @@ -272,7 +271,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { dom: self.cfg.current_location(entry), postdoms: vec![] }); - id } /// Pops a scope, which should have extent `extent`, adding any @@ -320,7 +318,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { if let Some(ref free_data) = scope.free { let next = self.cfg.start_new_block(); let free = build_free(self.hir.tcx(), &tmp, free_data, next); - self.cfg.terminate(block, scope.id, span, free); + self.cfg.terminate(block, scope.visibility_scope, span, free); block = next; } self.scope_auxiliary[scope.id] @@ -334,11 +332,22 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { .next() .unwrap(); self.cfg.terminate(block, - scope.id, + scope.visibility_scope, span, TerminatorKind::Goto { target: target }); } + /// Creates a new visibility scope, nested in the current one. + pub fn new_visibility_scope(&mut self, span: Span) -> VisibilityScope { + let parent = self.visibility_scope; + let scope = VisibilityScope::new(self.visibility_scopes.len()); + self.visibility_scopes.push(VisibilityScopeData { + span: span, + parent_scope: Some(parent), + }); + scope + } + // Finding scopes // ============== /// Finds the loop scope for a given label. This is used for @@ -363,8 +372,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { }.unwrap_or_else(|| span_bug!(span, "no enclosing loop scope found?")) } - pub fn innermost_scope_id(&self) -> ScopeId { - self.scopes.last().map(|scope| scope.id).unwrap() + pub fn innermost_scope_id(&self) -> VisibilityScope { + self.visibility_scope } pub fn extent_of_innermost_scope(&self) -> CodeExtent { @@ -481,7 +490,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { target } else { let resumeblk = cfg.start_new_cleanup_block(); - cfg.terminate(resumeblk, scopes[0].id, self.fn_span, TerminatorKind::Resume); + cfg.terminate(resumeblk, + scopes[0].visibility_scope, + self.fn_span, + TerminatorKind::Resume); *cached_resume_block = Some(resumeblk); resumeblk }; @@ -658,7 +670,7 @@ fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>, earlier_scopes.iter().rev().flat_map(|s| s.cached_block()).next() }); let next = cfg.start_new_block(); - cfg.terminate(block, scope.id, drop_data.span, TerminatorKind::Drop { + cfg.terminate(block, scope.visibility_scope, drop_data.span, TerminatorKind::Drop { location: drop_data.location.clone(), target: next, unwind: on_diverge @@ -695,7 +707,7 @@ fn build_diverge_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, } else { let into = cfg.start_new_cleanup_block(); cfg.terminate(into, - scope.id, + scope.visibility_scope, free_data.span, build_free(tcx, unit_temp, free_data, target)); free_data.cached_block = Some(into); @@ -712,7 +724,7 @@ fn build_diverge_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, } else { let block = cfg.start_new_cleanup_block(); cfg.terminate(block, - scope.id, + scope.visibility_scope, drop_data.span, TerminatorKind::Drop { location: drop_data.location.clone(), diff --git a/src/librustc_mir/pretty.rs b/src/librustc_mir/pretty.rs index a6bbd55ffa7a..5849db6bbd27 100644 --- a/src/librustc_mir/pretty.rs +++ b/src/librustc_mir/pretty.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use build::{Location, ScopeAuxiliaryVec}; +use build::{Location, ScopeAuxiliaryVec, ScopeId}; use rustc::hir; use rustc::mir::repr::*; use rustc::mir::transform::MirSource; @@ -139,20 +139,11 @@ pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, write_mir_intro(tcx, src, mir, w)?; for block in mir.all_basic_blocks() { write_basic_block(tcx, block, mir, w, &annotations)?; + if block.index() + 1 != mir.basic_blocks.len() { + writeln!(w, "")?; + } } - // construct a scope tree and write it out - let mut scope_tree: FnvHashMap, Vec> = FnvHashMap(); - for (index, scope_data) in mir.scopes.iter().enumerate() { - scope_tree.entry(scope_data.parent_scope) - .or_insert(vec![]) - .push(ScopeId::new(index)); - } - - writeln!(w, "{}scope tree:", INDENT)?; - write_scope_tree(tcx, mir, auxiliary, &scope_tree, w, None, 1, false)?; - writeln!(w, "")?; - writeln!(w, "}}")?; Ok(()) } @@ -204,66 +195,59 @@ fn write_basic_block(tcx: TyCtxt, writeln!(w, "{}}}\n", INDENT) } -fn comment(tcx: TyCtxt, scope: ScopeId, span: Span) -> String { +fn comment(tcx: TyCtxt, scope: VisibilityScope, span: Span) -> String { format!("scope {} at {}", scope.index(), tcx.sess.codemap().span_to_string(span)) } fn write_scope_tree(tcx: TyCtxt, mir: &Mir, - auxiliary: Option<&ScopeAuxiliaryVec>, - scope_tree: &FnvHashMap, Vec>, + scope_tree: &FnvHashMap>, w: &mut Write, - parent: Option, - depth: usize, - same_line: bool) + parent: VisibilityScope, + depth: usize) -> io::Result<()> { - let indent = if same_line { - 0 - } else { - depth * INDENT.len() - }; + let indent = depth * INDENT.len(); let children = match scope_tree.get(&parent) { Some(childs) => childs, None => return Ok(()), }; - for (index, &child) in children.iter().enumerate() { - if index == 0 && same_line { - // We know we're going to output a scope, so prefix it with a space to separate it from - // the previous scopes on this line - write!(w, " ")?; + for &child in children { + let data = &mir.visibility_scopes[child]; + assert_eq!(data.parent_scope, Some(parent)); + writeln!(w, "{0:1$}scope {2} {{", "", indent, child.index())?; + + // User variable types (including the user's name in a comment). + for (i, var) in mir.var_decls.iter().enumerate() { + // Skip if not declared in this scope. + if var.scope != child { + continue; + } + + let mut_str = if var.mutability == Mutability::Mut { + "mut " + } else { + "" + }; + + let indent = indent + INDENT.len(); + let indented_var = format!("{0:1$}let {2}{3:?}: {4};", + INDENT, + indent, + mut_str, + Lvalue::Var(i as u32), + var.ty); + writeln!(w, "{0:1$} // \"{2}\" in {3}", + indented_var, + ALIGN, + var.name, + comment(tcx, var.scope, var.span))?; } - let data = &mir.scopes[child]; - assert_eq!(data.parent_scope, parent); - write!(w, "{0:1$}{2}", "", indent, child.index())?; + write_scope_tree(tcx, mir, scope_tree, w, child, depth + 1)?; - let indent = indent + INDENT.len(); - - if let Some(auxiliary) = auxiliary { - let extent = auxiliary[child].extent; - let data = tcx.region_maps.code_extent_data(extent); - writeln!(w, "{0:1$}Extent: {2:?}", "", indent, data)?; - } - - let child_count = scope_tree.get(&Some(child)).map(Vec::len).unwrap_or(0); - if child_count < 2 { - // Skip the braces when there's no or only a single subscope - write_scope_tree(tcx, mir, auxiliary, scope_tree, w, - Some(child), depth, true)?; - } else { - // 2 or more child scopes? Put them in braces and on new lines. - writeln!(w, " {{")?; - write_scope_tree(tcx, mir, auxiliary, scope_tree, w, - Some(child), depth + 1, false)?; - - write!(w, "\n{0:1$}}}", "", depth * INDENT.len())?; - } - - if !same_line && index + 1 < children.len() { - writeln!(w, "")?; - } + writeln!(w, "{0:1$}}}", "", depth * INDENT.len())?; } Ok(()) @@ -278,7 +262,23 @@ fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> io::Result<()> { write_mir_sig(tcx, src, mir, w)?; writeln!(w, " {{")?; - write_mir_decls(tcx, mir, w) + + // construct a scope tree and write it out + let mut scope_tree: FnvHashMap> = FnvHashMap(); + for (index, scope_data) in mir.visibility_scopes.iter().enumerate() { + if let Some(parent) = scope_data.parent_scope { + scope_tree.entry(parent) + .or_insert(vec![]) + .push(VisibilityScope::new(index)); + } else { + // Only the argument scope has no parent, because it's the root. + assert_eq!(index, ARGUMENT_VISIBILITY_SCOPE.index()); + } + } + + write_scope_tree(tcx, mir, &scope_tree, w, ARGUMENT_VISIBILITY_SCOPE, 1)?; + + write_mir_decls(mir, w) } fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write) @@ -318,29 +318,7 @@ fn write_mir_sig(tcx: TyCtxt, src: MirSource, mir: &Mir, w: &mut Write) } } -fn write_mir_decls(tcx: TyCtxt, mir: &Mir, w: &mut Write) - -> io::Result<()> -{ - // User variable types (including the user's name in a comment). - for (i, var) in mir.var_decls.iter().enumerate() { - let mut_str = if var.mutability == Mutability::Mut { - "mut " - } else { - "" - }; - - let indented_var = format!("{}let {}{:?}: {};", - INDENT, - mut_str, - Lvalue::Var(i as u32), - var.ty); - writeln!(w, "{0:1$} // \"{2}\" in {3}", - indented_var, - ALIGN, - var.name, - comment(tcx, var.scope, var.span))?; - } - +fn write_mir_decls(mir: &Mir, w: &mut Write) -> io::Result<()> { // Compiler-introduced temporary types. for (i, temp) in mir.temp_decls.iter().enumerate() { writeln!(w, "{}let mut {:?}: {};", INDENT, Lvalue::Temp(i as u32), temp.ty)?; diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index d81c4e2dfb68..0a533d6e289b 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -168,7 +168,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { statements: vec![], terminator: Some(Terminator { span: self.promoted.span, - scope: ScopeId::new(0), + scope: VisibilityScope::new(0), kind: TerminatorKind::Return }), is_cleanup: false @@ -180,7 +180,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let data = self.promoted.basic_blocks.last_mut().unwrap(); data.statements.push(Statement { span: span, - scope: ScopeId::new(0), + scope: VisibilityScope::new(0), kind: StatementKind::Assign(dest, rvalue) }); } @@ -367,7 +367,7 @@ pub fn promote_candidates<'a, 'tcx>(mir: &mut Mir<'tcx>, source: mir, promoted: Mir { basic_blocks: vec![], - scopes: vec![ScopeData { + visibility_scopes: vec![VisibilityScopeData { span: span, parent_scope: None }], diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs index bba0edd5f049..2c23be02ddcf 100644 --- a/src/librustc_trans/debuginfo/create_scope_map.rs +++ b/src/librustc_trans/debuginfo/create_scope_map.rs @@ -16,7 +16,7 @@ use llvm; use llvm::debuginfo::{DIScope, DISubprogram}; use common::{CrateContext, FunctionContext}; use rustc::hir::pat_util; -use rustc::mir::repr::{Mir, ScopeId}; +use rustc::mir::repr::{Mir, VisibilityScope}; use rustc::util::nodemap::NodeMap; use libc::c_uint; @@ -71,7 +71,7 @@ pub fn create_scope_map(cx: &CrateContext, /// If debuginfo is disabled, the returned vector is empty. pub fn create_mir_scopes(fcx: &FunctionContext) -> Vec { let mir = fcx.mir.clone().expect("create_mir_scopes: missing MIR for fn"); - let mut scopes = vec![ptr::null_mut(); mir.scopes.len()]; + let mut scopes = vec![ptr::null_mut(); mir.visibility_scopes.len()]; let fn_metadata = match fcx.debug_context { FunctionDebugContext::RegularContext(box ref data) => data.fn_metadata, @@ -82,14 +82,14 @@ pub fn create_mir_scopes(fcx: &FunctionContext) -> Vec { }; // Find all the scopes with variables defined in them. - let mut has_variables = BitVector::new(mir.scopes.len()); + let mut has_variables = BitVector::new(mir.visibility_scopes.len()); for var in &mir.var_decls { has_variables.insert(var.scope.index()); } // Instantiate all scopes. - for idx in 0..mir.scopes.len() { - let scope = ScopeId::new(idx); + for idx in 0..mir.visibility_scopes.len() { + let scope = VisibilityScope::new(idx); make_mir_scope(fcx.ccx, &mir, &has_variables, fn_metadata, scope, &mut scopes); } @@ -100,14 +100,14 @@ fn make_mir_scope(ccx: &CrateContext, mir: &Mir, has_variables: &BitVector, fn_metadata: DISubprogram, - scope: ScopeId, + scope: VisibilityScope, scopes: &mut [DIScope]) { let idx = scope.index(); if !scopes[idx].is_null() { return; } - let scope_data = &mir.scopes[scope]; + let scope_data = &mir.visibility_scopes[scope]; let parent_scope = if let Some(parent) = scope_data.parent_scope { make_mir_scope(ccx, mir, has_variables, fn_metadata, parent, scopes); scopes[parent.index()] diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index d1206550b13d..a6174cd4d371 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -266,16 +266,13 @@ fn arg_value_refs<'bcx, 'tcx>(bcx: &BlockAndBuilder<'bcx, 'tcx>, let mut idx = 0; let mut llarg_idx = fcx.fn_ty.ret.is_indirect() as usize; - // Get the argument scope assuming ScopeId(0) has no parent. - let arg_scope = mir.scopes.get(0).and_then(|data| { - let scope = scopes[0]; - if data.parent_scope.is_none() && !scope.is_null() && - bcx.sess().opts.debuginfo == FullDebugInfo { - Some(scope) - } else { - None - } - }); + // Get the argument scope, if it exists and if we need it. + let arg_scope = scopes[mir::ARGUMENT_VISIBILITY_SCOPE.index()]; + let arg_scope = if !arg_scope.is_null() && bcx.sess().opts.debuginfo == FullDebugInfo { + Some(arg_scope) + } else { + None + }; mir.arg_decls.iter().enumerate().map(|(arg_index, arg_decl)| { let arg_ty = bcx.monomorphize(&arg_decl.ty); diff --git a/src/test/debuginfo/function-prologue-stepping-no-stack-check.rs b/src/test/debuginfo/function-prologue-stepping-no-stack-check.rs index f0ecda929937..b5b6ca757270 100644 --- a/src/test/debuginfo/function-prologue-stepping-no-stack-check.rs +++ b/src/test/debuginfo/function-prologue-stepping-no-stack-check.rs @@ -247,11 +247,10 @@ // lldb-command:continue #![allow(dead_code, unused_assignments, unused_variables)] -#![feature(omit_gdb_pretty_printer_section, rustc_attrs)] +#![feature(omit_gdb_pretty_printer_section)] #![omit_gdb_pretty_printer_section] #[no_stack_check] -#[rustc_no_mir] // FIXME(#32949) MIR debuginfo shadows arguments with uninit vars. fn immediate_args(a: isize, b: bool, c: f64) { println!(""); } @@ -268,51 +267,43 @@ struct BigStruct { } #[no_stack_check] -#[rustc_no_mir] // FIXME(#32949) MIR debuginfo shadows arguments with uninit vars. fn non_immediate_args(a: BigStruct, b: BigStruct) { println!(""); } #[no_stack_check] -#[rustc_no_mir] // FIXME(#32949) MIR debuginfo shadows arguments with uninit vars. fn binding(a: i64, b: u64, c: f64) { let x = 0; println!(""); } #[no_stack_check] -#[rustc_no_mir] // FIXME(#32949) MIR debuginfo shadows arguments with uninit vars. fn assignment(mut a: u64, b: u64, c: f64) { a = b; println!(""); } #[no_stack_check] -#[rustc_no_mir] // FIXME(#32949) MIR debuginfo shadows arguments with uninit vars. fn function_call(x: u64, y: u64, z: f64) { println!("Hi!") } #[no_stack_check] -#[rustc_no_mir] // FIXME(#32949) MIR debuginfo shadows arguments with uninit vars. fn identifier(x: u64, y: u64, z: f64) -> u64 { x } #[no_stack_check] -#[rustc_no_mir] // FIXME(#32949) MIR debuginfo shadows arguments with uninit vars. fn return_expr(x: u64, y: u64, z: f64) -> u64 { return x; } #[no_stack_check] -#[rustc_no_mir] // FIXME(#32949) MIR debuginfo shadows arguments with uninit vars. fn arithmetic_expr(x: u64, y: u64, z: f64) -> u64 { x + y } #[no_stack_check] -#[rustc_no_mir] // FIXME(#32949) MIR debuginfo shadows arguments with uninit vars. fn if_expr(x: u64, y: u64, z: f64) -> u64 { if x + y < 1000 { x @@ -322,7 +313,6 @@ fn if_expr(x: u64, y: u64, z: f64) -> u64 { } #[no_stack_check] -#[rustc_no_mir] // FIXME(#32949) MIR debuginfo shadows arguments with uninit vars. fn while_expr(mut x: u64, y: u64, z: u64) -> u64 { while x + y < 1000 { x += z @@ -331,7 +321,6 @@ fn while_expr(mut x: u64, y: u64, z: u64) -> u64 { } #[no_stack_check] -#[rustc_no_mir] // FIXME(#32949) MIR debuginfo shadows arguments with uninit vars. fn loop_expr(mut x: u64, y: u64, z: u64) -> u64 { loop { x += z;