diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 56c3c71339f1..2ffb4959951b 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -1013,7 +1013,7 @@ impl<'hir> Map<'hir> { /// corresponding to the Node ID pub fn attrs(&self, id: NodeId) -> &'hir [ast::Attribute] { self.read(id); // reveals attributes on the node - let attrs = match self.find(id) { + let attrs = match self.find_entry(id).map(|entry| entry.node) { Some(Node::Local(l)) => Some(&l.attrs[..]), Some(Node::Item(i)) => Some(&i.attrs[..]), Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]), @@ -1027,6 +1027,7 @@ impl<'hir> Map<'hir> { // Unit/tuple structs/variants take the attributes straight from // the struct/variant definition. Some(Node::Ctor(..)) => return self.attrs(self.get_parent(id)), + Some(Node::Crate) => Some(&self.forest.krate.attrs[..]), _ => None }; attrs.unwrap_or(&[]) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 6df3409d080e..953d0116aa2b 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -39,6 +39,7 @@ use errors::DiagnosticBuilder; use crate::hir; use crate::hir::def_id::{DefId, LOCAL_CRATE}; use crate::hir::intravisit as hir_visit; +use crate::hir::intravisit::Visitor; use syntax::util::lev_distance::find_best_match_for_name; use syntax::visit as ast_visit; @@ -1244,6 +1245,11 @@ pub fn lint_mod<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) { let (module, span, hir_id) = tcx.hir().get_module(module_def_id); cx.process_mod(module, span, hir_id); + // Visit the crate attributes + if hir_id == hir::CRATE_HIR_ID { + walk_list!(cx, visit_attribute, cx.tcx.hir().attrs_by_hir_id(hir::CRATE_HIR_ID)); + } + // Put the lint store levels and passes back in the session. let passes = cx.lint_sess.passes; drop(cx.lint_sess.lints); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index a5e5b570a4e6..2caaa0159921 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -125,8 +125,6 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { store.register_early_pass(sess, false, true, box BuiltinCombinedEarlyLintPass::new()); } - // FIXME: Make a separate lint type which do not require typeck tables - late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedModuleLateLintPass, [ HardwiredLints: HardwiredLints, WhileTrue: WhileTrue, @@ -134,7 +132,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { VariantSizeDifferences: VariantSizeDifferences, BoxPointers: BoxPointers, PathStatements: PathStatements, + + // Depends on referenced function signatures in expressions UnusedResults: UnusedResults, + NonUpperCaseGlobals: NonUpperCaseGlobals, NonShorthandFieldPatterns: NonShorthandFieldPatterns, UnusedAllocation: UnusedAllocation, @@ -157,39 +158,35 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { TrivialConstraints: TrivialConstraints, TypeLimits: TypeLimits::new(), - ]], ['tcx]); - store.register_late_pass(sess, false, true, box BuiltinCombinedModuleLateLintPass::new()); - - late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedLateLintPass, [ - - // Uses attr::is_used which is untracked, can't be an incremental module pass. - // Doesn't require type tables. Make a separate combined pass for that? - UnusedAttributes: UnusedAttributes, - - - // Checks crate attributes. Find out how that would work. NonSnakeCase: NonSnakeCase, - - - // Needs to look at crate attributes. Make sure that works - UnstableFeatures: UnstableFeatures, - - // Depends on access levels InvalidNoMangleItems: InvalidNoMangleItems, // Depends on access levels UnreachablePub: UnreachablePub, + ExplicitOutlivesRequirements: ExplicitOutlivesRequirements, + ]], ['tcx]); + + store.register_late_pass(sess, false, true, box BuiltinCombinedModuleLateLintPass::new()); + + late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedLateLintPass, [ + // Uses attr::is_used which is untracked, can't be an incremental module pass. + UnusedAttributes: UnusedAttributes, + + // Needs to run after UnusedAttributes as it marks all `feature` attributes as used. + UnstableFeatures: UnstableFeatures, + + // Tracks state across modules UnnameableTestItems: UnnameableTestItems::new(), // Tracks attributes of parents MissingDoc: MissingDoc::new(), // Depends on access levels + // FIXME: Turn the computation of types which implement Debug into a query + // and change this to a module lint pass MissingDebugImplementations: MissingDebugImplementations::new(), - - ExplicitOutlivesRequirements: ExplicitOutlivesRequirements, ]], ['tcx]); store.register_late_pass(sess, false, false, box BuiltinCombinedLateLintPass::new()); diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index fa18dd1eb8dd..7a164dbcdf12 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -267,11 +267,15 @@ impl LintPass for NonSnakeCase { } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { - fn check_crate(&mut self, cx: &LateContext<'_, '_>, cr: &hir::Crate) { + fn check_mod(&mut self, cx: &LateContext<'_, '_>, _: &'tcx hir::Mod, _: Span, id: hir::HirId) { + if id != hir::CRATE_HIR_ID { + return; + } + let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name { Some(Ident::from_str(name)) } else { - attr::find_by_name(&cr.attrs, "crate_name") + attr::find_by_name(&cx.tcx.hir().attrs_by_hir_id(hir::CRATE_HIR_ID), "crate_name") .and_then(|attr| attr.meta()) .and_then(|meta| { meta.name_value_literal().and_then(|lit| {