diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2017-06-07 15:21:55 +0300 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2017-06-09 12:27:56 +0300 |
| commit | 8b1b05bcebc1c6c8c2a7acdaa1970167c5b98cb4 (patch) | |
| tree | cc03b3870ce8fc531c476239d48127b3acd061b0 | |
| parent | 76a50706a8e19ecc253bb2a5749b1a3f4f5dc89d (diff) | |
| download | rust-8b1b05bcebc1c6c8c2a7acdaa1970167c5b98cb4.tar.gz rust-8b1b05bcebc1c6c8c2a7acdaa1970167c5b98cb4.zip | |
rustc: track the current ty::ParamEnv in lint::LateContext.
| -rw-r--r-- | src/librustc/lint/context.rs | 48 | ||||
| -rw-r--r-- | src/librustc_lint/builtin.rs | 19 | ||||
| -rw-r--r-- | src/librustc_lint/types.rs | 2 |
3 files changed, 45 insertions, 24 deletions
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index b14f549cbf6..40734469718 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -27,6 +27,7 @@ use self::TargetLint::*; use dep_graph::DepNode; use middle::privacy::AccessLevels; +use traits::Reveal; use ty::{self, TyCtxt}; use session::{config, early_error, Session}; use lint::{Level, LevelSource, Lint, LintId, LintPass, LintSource}; @@ -411,6 +412,9 @@ pub struct LateContext<'a, 'tcx: 'a> { /// Side-tables for the body we are in. pub tables: &'a ty::TypeckTables<'tcx>, + /// Parameter environment for the item we are in. + pub param_env: ty::ParamEnv<'tcx>, + /// Items accessible from the crate being checked. pub access_levels: &'a AccessLevels, @@ -866,6 +870,17 @@ impl<'a> LintContext<'a> for EarlyContext<'a> { } } +impl<'a, 'tcx> LateContext<'a, 'tcx> { + fn with_param_env<F>(&mut self, id: ast::NodeId, f: F) + where F: FnOnce(&mut Self), + { + let old_param_env = self.param_env; + self.param_env = self.tcx.param_env(self.tcx.hir.local_def_id(id)); + f(self); + self.param_env = old_param_env; + } +} + impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { /// Because lints are scoped lexically, we want to walk nested /// items in the context of the outer item, so enable @@ -899,17 +914,21 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { fn visit_item(&mut self, it: &'tcx hir::Item) { self.with_lint_attrs(&it.attrs, |cx| { - run_lints!(cx, check_item, late_passes, it); - hir_visit::walk_item(cx, it); - run_lints!(cx, check_item_post, late_passes, it); + cx.with_param_env(it.id, |cx| { + run_lints!(cx, check_item, late_passes, it); + hir_visit::walk_item(cx, it); + run_lints!(cx, check_item_post, late_passes, it); + }); }) } fn visit_foreign_item(&mut self, it: &'tcx hir::ForeignItem) { self.with_lint_attrs(&it.attrs, |cx| { - run_lints!(cx, check_foreign_item, late_passes, it); - hir_visit::walk_foreign_item(cx, it); - run_lints!(cx, check_foreign_item_post, late_passes, it); + cx.with_param_env(it.id, |cx| { + run_lints!(cx, check_foreign_item, late_passes, it); + hir_visit::walk_foreign_item(cx, it); + run_lints!(cx, check_foreign_item_post, late_passes, it); + }); }) } @@ -1023,17 +1042,21 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem) { self.with_lint_attrs(&trait_item.attrs, |cx| { - run_lints!(cx, check_trait_item, late_passes, trait_item); - hir_visit::walk_trait_item(cx, trait_item); - run_lints!(cx, check_trait_item_post, late_passes, trait_item); + cx.with_param_env(trait_item.id, |cx| { + run_lints!(cx, check_trait_item, late_passes, trait_item); + hir_visit::walk_trait_item(cx, trait_item); + run_lints!(cx, check_trait_item_post, late_passes, trait_item); + }); }); } fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem) { self.with_lint_attrs(&impl_item.attrs, |cx| { - run_lints!(cx, check_impl_item, late_passes, impl_item); - hir_visit::walk_impl_item(cx, impl_item); - run_lints!(cx, check_impl_item_post, late_passes, impl_item); + cx.with_param_env(impl_item.id, |cx| { + run_lints!(cx, check_impl_item, late_passes, impl_item); + hir_visit::walk_impl_item(cx, impl_item); + run_lints!(cx, check_impl_item_post, late_passes, impl_item); + }); }); } @@ -1327,6 +1350,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { let mut cx = LateContext { tcx: tcx, tables: &ty::TypeckTables::empty(), + param_env: ty::ParamEnv::empty(Reveal::UserFacing), access_levels: access_levels, lint_sess: LintSession::new(&tcx.sess.lint_store), }; diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 3a4729e6454..bccdac91423 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -32,7 +32,7 @@ use rustc::hir::def::Def; use rustc::hir::def_id::DefId; use rustc::cfg; use rustc::ty::subst::Substs; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, Ty}; use rustc::traits::{self, Reveal}; use rustc::hir::map as hir_map; use util::nodemap::NodeSet; @@ -893,7 +893,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { for adjustment in cx.tables.expr_adjustments(expr) { if let Adjust::Deref(Some(deref)) = adjustment.kind { let (def_id, substs) = deref.method_call(cx.tcx, source); - if method_call_refers_to_method(cx.tcx, method, def_id, substs, id) { + if method_call_refers_to_method(cx, method, def_id, substs, id) { return true; } } @@ -904,7 +904,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { if cx.tables.is_method_call(expr) { let def_id = cx.tables.type_dependent_defs[&id].def_id(); let substs = cx.tables.node_substs(id); - if method_call_refers_to_method(cx.tcx, method, def_id, substs, id) { + if method_call_refers_to_method(cx, method, def_id, substs, id) { return true; } } @@ -920,8 +920,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { match def { Def::Method(def_id) => { let substs = cx.tables.node_substs(callee.id); - method_call_refers_to_method( - cx.tcx, method, def_id, substs, id) + method_call_refers_to_method(cx, method, def_id, substs, id) } _ => false, } @@ -932,12 +931,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { // Check if the method call to the method with the ID `callee_id` // and instantiated with `callee_substs` refers to method `method`. - fn method_call_refers_to_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + fn method_call_refers_to_method<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, method: &ty::AssociatedItem, callee_id: DefId, callee_substs: &Substs<'tcx>, expr_id: ast::NodeId) -> bool { + let tcx = cx.tcx; let callee_item = tcx.associated_item(callee_id); match callee_item.container { @@ -951,10 +951,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnconditionalRecursion { let trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, callee_substs); let trait_ref = ty::Binder(trait_ref); let span = tcx.hir.span(expr_id); - let param_env = tcx.param_env(method.def_id); let obligation = traits::Obligation::new(traits::ObligationCause::misc(span, expr_id), - param_env, + cx.param_env, trait_ref.to_poly_trait_predicate()); tcx.infer_ctxt(()).enter(|infcx| { @@ -1224,11 +1223,9 @@ impl LintPass for UnionsWithDropFields { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnionsWithDropFields { fn check_item(&mut self, ctx: &LateContext, item: &hir::Item) { if let hir::ItemUnion(ref vdata, _) = item.node { - let item_def_id = ctx.tcx.hir.local_def_id(item.id); - let param_env = ctx.tcx.param_env(item_def_id); for field in vdata.fields() { let field_ty = ctx.tcx.type_of(ctx.tcx.hir.local_def_id(field.id)); - if field_ty.needs_drop(ctx.tcx, param_env) { + if field_ty.needs_drop(ctx.tcx, ctx.param_env) { ctx.span_lint(UNIONS_WITH_DROP_FIELDS, field.span, "union contains a field with possibly non-trivial drop code, \ diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 3019165bfbf..32bde42b526 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -725,7 +725,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences { // sizes only make sense for non-generic types let item_def_id = cx.tcx.hir.local_def_id(it.id); let t = cx.tcx.type_of(item_def_id); - let param_env = cx.tcx.param_env(item_def_id).reveal_all(); + let param_env = cx.param_env.reveal_all(); let ty = cx.tcx.erase_regions(&t); let layout = ty.layout(cx.tcx, param_env).unwrap_or_else(|e| { bug!("failed to get layout for `{}`: {}", t, e) |
