Skip to content

Commit

Permalink
add lint levels to VisibilityScope
Browse files Browse the repository at this point in the history
  • Loading branch information
arielb1 committed Sep 24, 2017
1 parent acb73db commit 8c7500f
Show file tree
Hide file tree
Showing 24 changed files with 269 additions and 53 deletions.
18 changes: 18 additions & 0 deletions src/librustc/ich/impls_mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ impl_stable_hash_for!(struct mir::LocalDecl<'tcx> {
name,
source_info,
internal,
lexical_scope,
is_user_variable
});
impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref });
Expand Down Expand Up @@ -75,6 +76,22 @@ for mir::Terminator<'gcx> {
}
}

impl<'gcx, T> HashStable<StableHashingContext<'gcx>> for mir::ClearOnDecode<T>
where T: HashStable<StableHashingContext<'gcx>>
{
#[inline]
fn hash_stable<W: StableHasherResult>(&self,
hcx: &mut StableHashingContext<'gcx>,
hasher: &mut StableHasher<W>) {
mem::discriminant(self).hash_stable(hcx, hasher);
match *self {
mir::ClearOnDecode::Clear => {}
mir::ClearOnDecode::Set(ref value) => {
value.hash_stable(hcx, hasher);
}
}
}
}

impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Local {
#[inline]
Expand Down Expand Up @@ -347,6 +364,7 @@ for mir::ProjectionElem<'gcx, V, T>
}

impl_stable_hash_for!(struct mir::VisibilityScopeData { span, parent_scope });
impl_stable_hash_for!(struct mir::VisibilityScopeInfo { lint_root });

impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::Operand<'gcx> {
fn hash_stable<W: StableHasherResult>(&self,
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/lint/levels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,11 @@ impl LintLevelMap {
self.sets.get_lint_level(lint, *idx, None)
})
}

/// Returns if this `id` has lint level information.
pub fn lint_level_set(&self, id: HirId) -> Option<u32> {
self.id_to_set.get(&id).cloned()
}
}

impl<'gcx> HashStable<StableHashingContext<'gcx>> for LintLevelMap {
Expand Down
45 changes: 44 additions & 1 deletion src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
use rustc_data_structures::control_flow_graph::dominators::{Dominators, dominators};
use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccessors};
use rustc_data_structures::control_flow_graph::ControlFlowGraph;
use rustc_serialize as serialize;
use hir::def::CtorKind;
use hir::def_id::DefId;
use ty::subst::{Subst, Substs};
Expand All @@ -33,7 +34,7 @@ use std::fmt::{self, Debug, Formatter, Write};
use std::{iter, u32};
use std::ops::{Index, IndexMut};
use std::vec::IntoIter;
use syntax::ast::Name;
use syntax::ast::{self, Name};
use syntax_pos::Span;

mod cache;
Expand Down Expand Up @@ -96,6 +97,10 @@ pub struct Mir<'tcx> {
/// and used (eventually) for debuginfo. Indexed by a `VisibilityScope`.
pub visibility_scopes: IndexVec<VisibilityScope, VisibilityScopeData>,

/// Crate-local information for each visibility scope, that can't (and
/// needn't) be tracked across crates.
pub visibility_scope_info: ClearOnDecode<IndexVec<VisibilityScope, VisibilityScopeInfo>>,

/// 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
/// in scope, but a separate set of locals.
Expand Down Expand Up @@ -151,6 +156,8 @@ pub const START_BLOCK: BasicBlock = BasicBlock(0);
impl<'tcx> Mir<'tcx> {
pub fn new(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
visibility_scopes: IndexVec<VisibilityScope, VisibilityScopeData>,
visibility_scope_info: ClearOnDecode<IndexVec<VisibilityScope,
VisibilityScopeInfo>>,
promoted: IndexVec<Promoted, Mir<'tcx>>,
return_ty: Ty<'tcx>,
yield_ty: Option<Ty<'tcx>>,
Expand All @@ -167,6 +174,7 @@ impl<'tcx> Mir<'tcx> {
Mir {
basic_blocks,
visibility_scopes,
visibility_scope_info,
promoted,
return_ty,
yield_ty,
Expand Down Expand Up @@ -278,9 +286,16 @@ impl<'tcx> Mir<'tcx> {
}
}

#[derive(Clone, Debug)]
pub struct VisibilityScopeInfo {
/// A NodeId with lint levels equivalent to this scope's lint levels.
pub lint_root: ast::NodeId,
}

impl_stable_hash_for!(struct Mir<'tcx> {
basic_blocks,
visibility_scopes,
visibility_scope_info,
promoted,
return_ty,
yield_ty,
Expand Down Expand Up @@ -310,6 +325,24 @@ impl<'tcx> IndexMut<BasicBlock> for Mir<'tcx> {
}
}

#[derive(Clone, Debug)]
pub enum ClearOnDecode<T> {
Clear,
Set(T)
}

impl<T> serialize::Encodable for ClearOnDecode<T> {
fn encode<S: serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
serialize::Encodable::encode(&(), s)
}
}

impl<T> serialize::Decodable for ClearOnDecode<T> {
fn decode<D: serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> {
serialize::Decodable::decode(d).map(|()| ClearOnDecode::Clear)
}
}

/// Grouped information about the source code origin of a MIR entity.
/// Intended to be inspected by diagnostics and debuginfo.
/// Most passes can work with it as a whole, within a single function.
Expand Down Expand Up @@ -438,6 +471,12 @@ pub struct LocalDecl<'tcx> {

/// Source info of the local.
pub source_info: SourceInfo,

/// The *lexical* visibility scope the local is defined
/// in. If the local was defined in a let-statement, this
/// is *within* the let-statement, rather than outside
/// of iit.
pub lexical_scope: VisibilityScope,
}

impl<'tcx> LocalDecl<'tcx> {
Expand All @@ -452,6 +491,7 @@ impl<'tcx> LocalDecl<'tcx> {
span,
scope: ARGUMENT_VISIBILITY_SCOPE
},
lexical_scope: ARGUMENT_VISIBILITY_SCOPE,
internal: false,
is_user_variable: false
}
Expand All @@ -468,6 +508,7 @@ impl<'tcx> LocalDecl<'tcx> {
span,
scope: ARGUMENT_VISIBILITY_SCOPE
},
lexical_scope: ARGUMENT_VISIBILITY_SCOPE,
internal: true,
is_user_variable: false
}
Expand All @@ -485,6 +526,7 @@ impl<'tcx> LocalDecl<'tcx> {
span,
scope: ARGUMENT_VISIBILITY_SCOPE
},
lexical_scope: ARGUMENT_VISIBILITY_SCOPE,
internal: false,
name: None, // FIXME maybe we do want some name here?
is_user_variable: false
Expand Down Expand Up @@ -1607,6 +1649,7 @@ impl<'tcx> TypeFoldable<'tcx> for Mir<'tcx> {
Mir {
basic_blocks: self.basic_blocks.fold_with(folder),
visibility_scopes: self.visibility_scopes.clone(),
visibility_scope_info: self.visibility_scope_info.clone(),
promoted: self.promoted.fold_with(folder),
return_ty: self.return_ty.fold_with(folder),
yield_ty: self.yield_ty.fold_with(folder),
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/mir/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,11 +690,13 @@ macro_rules! make_mir_visitor {
name: _,
ref $($mutability)* source_info,
internal: _,
ref $($mutability)* lexical_scope,
is_user_variable: _,
} = *local_decl;

self.visit_ty(ty, Lookup::Src(*source_info));
self.visit_source_info(source_info);
self.visit_visibility_scope(lexical_scope);
}

fn super_visibility_scope(&mut self,
Expand Down
7 changes: 4 additions & 3 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,15 +1009,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
// FIXME: ariel points SimplifyBranches should run after
// mir-borrowck; otherwise code within `if false { ... }` would
// not be checked.
passes.push_pass(MIR_VALIDATED,
mir::transform::simplify_branches::SimplifyBranches::new("initial"));
passes.push_pass(MIR_VALIDATED, mir::transform::simplify::SimplifyCfg::new("qualify-consts"));
passes.push_pass(MIR_VALIDATED, mir::transform::nll::NLL);

// borrowck runs between MIR_VALIDATED and MIR_OPTIMIZED.

// These next passes must be executed together
passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
passes.push_pass(MIR_OPTIMIZED,
mir::transform::simplify_branches::SimplifyBranches::new("initial"));

// These next passes must be executed together
passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::CriticalCallEdges);
passes.push_pass(MIR_OPTIMIZED, mir::transform::elaborate_drops::ElaborateDrops);
passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
Expand Down
18 changes: 13 additions & 5 deletions src/librustc_mir/build/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let Block { region_scope, opt_destruction_scope, span, stmts, expr, targeted_by_break } =
self.hir.mirror(ast_block);
self.in_opt_scope(opt_destruction_scope.map(|de|(de, source_info)), block, move |this| {
this.in_scope((region_scope, source_info), block, move |this| {
this.in_scope((region_scope, source_info), LintLevel::Inherited, block, move |this| {
if targeted_by_break {
// This is a `break`-able block (currently only `catch { ... }`)
let exit_block = this.cfg.start_new_block();
Expand Down Expand Up @@ -76,27 +76,35 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
StmtKind::Expr { scope, expr } => {
unpack!(block = this.in_opt_scope(
opt_destruction_scope.map(|de|(de, source_info)), block, |this| {
this.in_scope((scope, source_info), block, |this| {
let si = (scope, source_info);
this.in_scope(si, LintLevel::Inherited, block, |this| {
let expr = this.hir.mirror(expr);
this.stmt_expr(block, expr)
})
}));
}
StmtKind::Let { remainder_scope, init_scope, pattern, initializer } => {
StmtKind::Let {
remainder_scope,
init_scope,
pattern,
initializer,
lint_level
} => {
// Enter the remainder scope, i.e. the bindings' destruction scope.
this.push_scope((remainder_scope, source_info));
let_scope_stack.push(remainder_scope);

// Declare the bindings, which may create a visibility scope.
let remainder_span = remainder_scope.span(this.hir.tcx(),
&this.hir.region_scope_tree);
let scope = this.declare_bindings(None, remainder_span, &pattern);
let scope = this.declare_bindings(None, remainder_span, lint_level, &pattern);

// Evaluate the initializer, if present.
if let Some(init) = initializer {
unpack!(block = this.in_opt_scope(
opt_destruction_scope.map(|de|(de, source_info)), block, move |this| {
this.in_scope((init_scope, source_info), block, move |this| {
let scope = (init_scope, source_info);
this.in_scope(scope, lint_level, block, move |this| {
// FIXME #30046 ^~~~
this.expr_into_pattern(block, pattern, init)
})
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/build/expr/as_constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let Expr { ty, temp_lifetime: _, span, kind }
= expr;
match kind {
ExprKind::Scope { region_scope: _, value } =>
ExprKind::Scope { region_scope: _, lint_level: _, value } =>
this.as_constant(value),
ExprKind::Literal { literal } =>
Constant { span: span, ty: ty, literal: literal },
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/build/expr/as_lvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let expr_span = expr.span;
let source_info = this.source_info(expr_span);
match expr.kind {
ExprKind::Scope { region_scope, value } => {
this.in_scope((region_scope, source_info), block, |this| {
ExprKind::Scope { region_scope, lint_level, value } => {
this.in_scope((region_scope, source_info), lint_level, block, |this| {
this.as_lvalue(block, value)
})
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/build/expr/as_operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
debug!("expr_as_operand(block={:?}, expr={:?})", block, expr);
let this = self;

if let ExprKind::Scope { region_scope, value } = expr.kind {
if let ExprKind::Scope { region_scope, lint_level, value } = expr.kind {
let source_info = this.source_info(expr.span);
let region_scope = (region_scope, source_info);
return this.in_scope(region_scope, block, |this| {
return this.in_scope(region_scope, lint_level, block, |this| {
this.as_operand(block, scope, value)
});
}
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_mir/build/expr/as_rvalue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let source_info = this.source_info(expr_span);

match expr.kind {
ExprKind::Scope { region_scope, value } => {
ExprKind::Scope { region_scope, lint_level, value } => {
let region_scope = (region_scope, source_info);
this.in_scope(region_scope, block, |this| this.as_rvalue(block, scope, value))
this.in_scope(region_scope, lint_level, block,
|this| this.as_rvalue(block, scope, value))
}
ExprKind::Repeat { value, count } => {
let value_operand = unpack!(block = this.as_operand(block, scope, value));
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/build/expr/as_temp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {

let expr_span = expr.span;
let source_info = this.source_info(expr_span);
if let ExprKind::Scope { region_scope, value } = expr.kind {
return this.in_scope((region_scope, source_info), block, |this| {
if let ExprKind::Scope { region_scope, lint_level, value } = expr.kind {
return this.in_scope((region_scope, source_info), lint_level, block, |this| {
this.as_temp(block, temp_lifetime, value)
});
}
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_mir/build/expr/into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
let source_info = this.source_info(expr_span);

match expr.kind {
ExprKind::Scope { region_scope, value } => {
ExprKind::Scope { region_scope, lint_level, value } => {
let region_scope = (region_scope, source_info);
this.in_scope(region_scope, block, |this| this.into(destination, block, value))
this.in_scope(region_scope, lint_level, block,
|this| this.into(destination, block, value))
}
ExprKind::Block { body: ast_block } => {
this.ast_block(destination, block, ast_block, source_info)
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/build/expr/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
// Handle a number of expressions that don't need a destination at all. This
// avoids needing a mountain of temporary `()` variables.
match expr.kind {
ExprKind::Scope { region_scope, value } => {
ExprKind::Scope { region_scope, lint_level, value } => {
let value = this.hir.mirror(value);
this.in_scope((region_scope, source_info), block, |this| {
this.in_scope((region_scope, source_info), lint_level, block, |this| {
this.stmt_expr(block, value)
})
}
Expand Down
Loading

0 comments on commit 8c7500f

Please sign in to comment.