]> git.lizzy.rs Git - rust.git/commitdiff
rustc: track the current ty::ParamEnv in lint::LateContext.
authorEduard-Mihai Burtescu <edy.burt@gmail.com>
Wed, 7 Jun 2017 12:21:55 +0000 (15:21 +0300)
committerEduard-Mihai Burtescu <edy.burt@gmail.com>
Fri, 9 Jun 2017 09:27:56 +0000 (12:27 +0300)
src/librustc/lint/context.rs
src/librustc_lint/builtin.rs
src/librustc_lint/types.rs

index b14f549cbf6db9662028731500e8bac93e015f42..40734469718baea8057890212683e2470206fdcc 100644 (file)
@@ -27,6 +27,7 @@
 
 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 @@ fn exit_attrs(&mut self, attrs: &'a [ast::Attribute]) {
     }
 }
 
+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 @@ fn visit_body(&mut self, body: &'tcx hir::Body) {
 
     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 @@ fn visit_generics(&mut self, g: &'tcx hir::Generics) {
 
     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),
     };
index 3a4729e64548a732d74aa73f5be1d9c138ea598c..bccdac91423cdc3d9650adfd5f283ea405175f9f 100644 (file)
@@ -32,7 +32,7 @@
 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 @@ fn expr_refers_to_this_method(cx: &LateContext,
             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 @@ fn expr_refers_to_this_method(cx: &LateContext,
             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 @@ fn expr_refers_to_this_method(cx: &LateContext,
                     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 @@ fn expr_refers_to_this_method(cx: &LateContext,
 
         // 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 @@ fn method_call_refers_to_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     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 @@ fn get_lints(&self) -> LintArray {
 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, \
index 3019165bfbf9a9343b424a861e485d8b481f6ad7..32bde42b5261f64b4d6c25ffa0317698bb3d235c 100644 (file)
@@ -725,7 +725,7 @@ fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
                 // 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)