about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJosh Stone <cuviper@gmail.com>2019-03-27 18:15:18 -0700
committerGitHub <noreply@github.com>2019-03-27 18:15:18 -0700
commit74a69f2e746eea409aa433ce560a74b1ec272de7 (patch)
treec71ff3f6bc932553d34e1c8c7b53949f8e99daf1 /src
parent33ef0bad21d6bb646c7c3ab0dbf381ca96c324bf (diff)
parent4093bec80d39f94d69754d3a30cb14d9d4954424 (diff)
downloadrust-74a69f2e746eea409aa433ce560a74b1ec272de7.tar.gz
rust-74a69f2e746eea409aa433ce560a74b1ec272de7.zip
Rollup merge of #57293 - Zoxc:incr-passes3, r=michaelwoerister
Make some lints incremental

Blocked on https://github.com/rust-lang/rust/pull/57253

r? @michaelwoerister
Diffstat (limited to 'src')
-rw-r--r--src/librustc/dep_graph/dep_node.rs1
-rw-r--r--src/librustc/hir/map/mod.rs11
-rw-r--r--src/librustc/lint/context.rs86
-rw-r--r--src/librustc/lint/mod.rs1
-rw-r--r--src/librustc/ty/query/mod.rs2
-rw-r--r--src/librustc/ty/query/plumbing.rs1
-rw-r--r--src/librustc_interface/passes.rs2
-rw-r--r--src/librustc_lint/builtin.rs1
-rw-r--r--src/librustc_lint/lib.rs55
-rw-r--r--src/librustc_lint/nonstandard_style.rs8
-rw-r--r--src/librustc_privacy/lib.rs3
-rw-r--r--src/test/ui/lint/lint-impl-fn.stderr16
-rw-r--r--src/test/ui/lint/suggestions.stderr36
13 files changed, 168 insertions, 55 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 4babadb67bc..9c6d03af9f5 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -469,6 +469,7 @@ rustc_dep_node_append!([define_dep_nodes!][ <'tcx>
     [] UnsafetyCheckResult(DefId),
     [] UnsafeDeriveOnReprPacked(DefId),
 
+    [] LintMod(DefId),
     [] CheckModAttrs(DefId),
     [] CheckModLoops(DefId),
     [] CheckModUnstableApiUsage(DefId),
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index d810a9310c5..2ffb4959951 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -580,17 +580,17 @@ impl<'hir> Map<'hir> {
         &self.forest.krate.attrs
     }
 
-    pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, NodeId)
-    {
+    pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId) {
         let node_id = self.as_local_node_id(module).unwrap();
+        let hir_id = self.node_to_hir_id(node_id);
         self.read(node_id);
         match self.find_entry(node_id).unwrap().node {
             Node::Item(&Item {
                 span,
                 node: ItemKind::Mod(ref m),
                 ..
-            }) => (m, span, node_id),
-            Node::Crate => (&self.forest.krate.module, self.forest.krate.span, node_id),
+            }) => (m, span, hir_id),
+            Node::Crate => (&self.forest.krate.module, self.forest.krate.span, hir_id),
             _ => panic!("not a module")
         }
     }
@@ -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 94f1d9c2710..953d0116aa2 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -27,6 +27,7 @@ use crate::rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
 use crate::session::{config, early_error, Session};
 use crate::ty::{self, TyCtxt, Ty};
 use crate::ty::layout::{LayoutError, LayoutOf, TyLayout};
+use crate::ty::query::Providers;
 use crate::util::nodemap::FxHashMap;
 use crate::util::common::time;
 
@@ -36,8 +37,9 @@ use syntax::edition;
 use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}};
 use errors::DiagnosticBuilder;
 use crate::hir;
-use crate::hir::def_id::LOCAL_CRATE;
+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;
 
@@ -55,6 +57,7 @@ pub struct LintStore {
     pre_expansion_passes: Option<Vec<EarlyLintPassObject>>,
     early_passes: Option<Vec<EarlyLintPassObject>>,
     late_passes: Option<Vec<LateLintPassObject>>,
+    late_module_passes: Option<Vec<LateLintPassObject>>,
 
     /// Lints indexed by name.
     by_name: FxHashMap<String, TargetLint>,
@@ -150,6 +153,7 @@ impl LintStore {
             pre_expansion_passes: Some(vec![]),
             early_passes: Some(vec![]),
             late_passes: Some(vec![]),
+            late_module_passes: Some(vec![]),
             by_name: Default::default(),
             future_incompatible: Default::default(),
             lint_groups: Default::default(),
@@ -199,9 +203,14 @@ impl LintStore {
     pub fn register_late_pass(&mut self,
                               sess: Option<&Session>,
                               from_plugin: bool,
+                              per_module: bool,
                               pass: LateLintPassObject) {
         self.push_pass(sess, from_plugin, &pass);
-        self.late_passes.as_mut().unwrap().push(pass);
+        if per_module {
+            self.late_module_passes.as_mut().unwrap().push(pass);
+        } else {
+            self.late_passes.as_mut().unwrap().push(pass);
+        }
     }
 
     // Helper method for register_early/late_pass
@@ -508,6 +517,7 @@ pub struct LateContext<'a, 'tcx: 'a> {
     pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     /// Side-tables for the body we are in.
+    // FIXME: Make this lazy to avoid running the TypeckTables query?
     pub tables: &'a ty::TypeckTables<'tcx>,
 
     /// Parameter environment for the item we are in.
@@ -523,6 +533,9 @@ pub struct LateContext<'a, 'tcx: 'a> {
 
     /// Generic type parameters in scope for the item we are in.
     pub generics: Option<&'tcx hir::Generics>,
+
+    /// We are only looking at one module
+    only_module: bool,
 }
 
 /// Context for lint checking of the AST, after expansion, before lowering to
@@ -803,6 +816,12 @@ impl<'a, 'tcx> LateContext<'a, 'tcx> {
     pub fn current_lint_root(&self) -> hir::HirId {
         self.last_node_with_lint_attrs
     }
+
+    fn process_mod(&mut self, m: &'tcx hir::Mod, s: Span, n: hir::HirId) {
+        run_lints!(self, check_mod, m, s, n);
+        hir_visit::walk_mod(self, m, n);
+        run_lints!(self, check_mod_post, m, s, n);
+    }
 }
 
 impl<'a, 'tcx> LayoutOf for LateContext<'a, 'tcx> {
@@ -934,9 +953,9 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
     }
 
     fn visit_mod(&mut self, m: &'tcx hir::Mod, s: Span, n: hir::HirId) {
-        run_lints!(self, check_mod, m, s, n);
-        hir_visit::walk_mod(self, m, n);
-        run_lints!(self, check_mod_post, m, s, n);
+        if !self.only_module {
+            self.process_mod(m, s, n);
+        }
     }
 
     fn visit_local(&mut self, l: &'tcx hir::Local) {
@@ -1203,11 +1222,48 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
     }
 }
 
+pub fn lint_mod<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
+    let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
 
-/// Performs lint checking on a crate.
-///
-/// Consumes the `lint_store` field of the `Session`.
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    let store = &tcx.sess.lint_store;
+    let passes = store.borrow_mut().late_module_passes.take();
+
+    let mut cx = LateContext {
+        tcx,
+        tables: &ty::TypeckTables::empty(None),
+        param_env: ty::ParamEnv::empty(),
+        access_levels,
+        lint_sess: LintSession {
+            lints: store.borrow(),
+            passes,
+        },
+        last_node_with_lint_attrs: tcx.hir().as_local_hir_id(module_def_id).unwrap(),
+        generics: None,
+        only_module: true,
+    };
+
+    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);
+    store.borrow_mut().late_module_passes = passes;
+}
+
+pub(crate) fn provide(providers: &mut Providers<'_>) {
+    *providers = Providers {
+        lint_mod,
+        ..*providers
+    };
+}
+
+fn lint_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
 
     let krate = tcx.hir().krate();
@@ -1225,6 +1281,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
             },
             last_node_with_lint_attrs: hir::CRATE_HIR_ID,
             generics: None,
+            only_module: false,
         };
 
         // Visit the whole crate.
@@ -1244,6 +1301,17 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.sess.lint_store.borrow_mut().late_passes = passes;
 }
 
+/// Performs lint checking on a crate.
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    // Run per-module lints
+    for &module in tcx.hir().krate().modules.keys() {
+        tcx.ensure().lint_mod(tcx.hir().local_def_id(module));
+    }
+
+    // Run whole crate non-incremental lints
+    lint_crate(tcx);
+}
+
 struct EarlyLintPassObjects<'a> {
     lints: &'a mut [EarlyLintPassObject],
 }
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index ae44210bcff..cf1c5d50000 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -824,6 +824,7 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for LintLevelMapBuilder<'a, 'tcx> {
 
 pub fn provide(providers: &mut Providers<'_>) {
     providers.lint_levels = lint_levels;
+    context::provide(providers);
 }
 
 /// Returns whether `span` originates in a foreign crate's external macro.
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index 85c2afd1159..9c705104d18 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -217,6 +217,8 @@ rustc_query_append! { [define_queries!][ <'tcx>
     },
 
     Other {
+        [] fn lint_mod: LintMod(DefId) -> (),
+
         /// Checks the attributes in the module
         [] fn check_mod_attrs: CheckModAttrs(DefId) -> (),
 
diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs
index adac19d3410..b2b141fd0f5 100644
--- a/src/librustc/ty/query/plumbing.rs
+++ b/src/librustc/ty/query/plumbing.rs
@@ -1262,6 +1262,7 @@ pub fn force_from_dep_node<'tcx>(
         DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); }
         DepKind::UnsafetyCheckResult => { force!(unsafety_check_result, def_id!()); }
         DepKind::UnsafeDeriveOnReprPacked => { force!(unsafe_derive_on_repr_packed, def_id!()); }
+        DepKind::LintMod => { force!(lint_mod, def_id!()); }
         DepKind::CheckModAttrs => { force!(check_mod_attrs, def_id!()); }
         DepKind::CheckModLoops => { force!(check_mod_loops, def_id!()); }
         DepKind::CheckModUnstableApiUsage => { force!(check_mod_unstable_api_usage, def_id!()); }
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index c199829b298..b6daadb1b45 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -328,7 +328,7 @@ pub fn register_plugins<'a>(
         ls.register_early_pass(Some(sess), true, false, pass);
     }
     for pass in late_lint_passes {
-        ls.register_late_pass(Some(sess), true, pass);
+        ls.register_late_pass(Some(sess), true, false, pass);
     }
 
     for (name, (to, deprecated_name)) in lint_groups {
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 304e6eb712e..492ac1bf14d 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1360,6 +1360,7 @@ fn check_const(cx: &LateContext<'_, '_>, body_id: hir::BodyId) {
         promoted: None
     };
     // trigger the query once for all constants since that will already report the errors
+    // FIXME: Use ensure here
     let _ = cx.tcx.const_eval(param_env.and(cid));
 }
 
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 73a32f6d200..4c624a267af 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -125,37 +125,72 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
         store.register_early_pass(sess, false, true, box BuiltinCombinedEarlyLintPass::new());
     }
 
-    late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedLateLintPass, [
+    late_lint_methods!(declare_combined_late_lint_pass, [BuiltinCombinedModuleLateLintPass, [
         HardwiredLints: HardwiredLints,
         WhileTrue: WhileTrue,
         ImproperCTypes: ImproperCTypes,
         VariantSizeDifferences: VariantSizeDifferences,
         BoxPointers: BoxPointers,
-        UnusedAttributes: UnusedAttributes,
         PathStatements: PathStatements,
+
+        // Depends on referenced function signatures in expressions
         UnusedResults: UnusedResults,
-        NonSnakeCase: NonSnakeCase,
+
         NonUpperCaseGlobals: NonUpperCaseGlobals,
         NonShorthandFieldPatterns: NonShorthandFieldPatterns,
         UnusedAllocation: UnusedAllocation,
+
+        // Depends on types used in type definitions
         MissingCopyImplementations: MissingCopyImplementations,
-        UnstableFeatures: UnstableFeatures,
-        InvalidNoMangleItems: InvalidNoMangleItems,
+
         PluginAsLibrary: PluginAsLibrary,
+
+        // Depends on referenced function signatures in expressions
         MutableTransmutes: MutableTransmutes,
+
+        // Depends on types of fields, checks if they implement Drop
         UnionsWithDropFields: UnionsWithDropFields,
-        UnreachablePub: UnreachablePub,
-        UnnameableTestItems: UnnameableTestItems::new(),
+
         TypeAliasBounds: TypeAliasBounds,
-        UnusedBrokenConst: UnusedBrokenConst,
+
         TrivialConstraints: TrivialConstraints,
         TypeLimits: TypeLimits::new(),
+
+        NonSnakeCase: NonSnakeCase,
+        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, [
+        // FIXME: Look into regression when this is used as a module lint
+        // May Depend on constants elsewhere
+        UnusedBrokenConst: UnusedBrokenConst,
+
+        // 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, box BuiltinCombinedLateLintPass::new());
+    store.register_late_pass(sess, false, false, box BuiltinCombinedLateLintPass::new());
 
     add_lint_group!(sess,
                     "nonstandard_style",
diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs
index fa18dd1eb8d..7a164dbcdf1 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| {
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index bbd03e82a37..b532e5c94d5 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -1790,8 +1790,7 @@ fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
         current_item: hir::DUMMY_HIR_ID,
         empty_tables: &empty_tables,
     };
-    let (module, span, node_id) = tcx.hir().get_module(module_def_id);
-    let hir_id = tcx.hir().node_to_hir_id(node_id);
+    let (module, span, hir_id) = tcx.hir().get_module(module_def_id);
     intravisit::walk_mod(&mut visitor, module, hir_id);
 
     // Check privacy of explicitly written types and traits as well as
diff --git a/src/test/ui/lint/lint-impl-fn.stderr b/src/test/ui/lint/lint-impl-fn.stderr
index 2c9a264287c..56f85111d42 100644
--- a/src/test/ui/lint/lint-impl-fn.stderr
+++ b/src/test/ui/lint/lint-impl-fn.stderr
@@ -11,25 +11,25 @@ LL |     #[deny(while_true)]
    |            ^^^^^^^^^^
 
 error: denote infinite loops with `loop { ... }`
-  --> $DIR/lint-impl-fn.rs:18:25
+  --> $DIR/lint-impl-fn.rs:27:5
    |
-LL |         fn foo(&self) { while true {} }
-   |                         ^^^^^^^^^^ help: use `loop`
+LL |     while true {}
+   |     ^^^^^^^^^^ help: use `loop`
    |
 note: lint level defined here
-  --> $DIR/lint-impl-fn.rs:13:8
+  --> $DIR/lint-impl-fn.rs:25:8
    |
 LL | #[deny(while_true)]
    |        ^^^^^^^^^^
 
 error: denote infinite loops with `loop { ... }`
-  --> $DIR/lint-impl-fn.rs:27:5
+  --> $DIR/lint-impl-fn.rs:18:25
    |
-LL |     while true {}
-   |     ^^^^^^^^^^ help: use `loop`
+LL |         fn foo(&self) { while true {} }
+   |                         ^^^^^^^^^^ help: use `loop`
    |
 note: lint level defined here
-  --> $DIR/lint-impl-fn.rs:25:8
+  --> $DIR/lint-impl-fn.rs:13:8
    |
 LL | #[deny(while_true)]
    |        ^^^^^^^^^^
diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr
index c28814aeee8..5aaa9947f99 100644
--- a/src/test/ui/lint/suggestions.stderr
+++ b/src/test/ui/lint/suggestions.stderr
@@ -65,6 +65,24 @@ LL | pub fn defiant<T>(_t: T) {}
    |
    = note: #[warn(no_mangle_generic_items)] on by default
 
+warning: denote infinite loops with `loop { ... }`
+  --> $DIR/suggestions.rs:46:5
+   |
+LL |     while true {
+   |     ^^^^^^^^^^ help: use `loop`
+   |
+   = note: #[warn(while_true)] on by default
+
+warning: the `warp_factor:` in this pattern is redundant
+  --> $DIR/suggestions.rs:61:23
+   |
+LL |             Equinox { warp_factor: warp_factor } => {}
+   |                       ------------^^^^^^^^^^^^
+   |                       |
+   |                       help: remove this
+   |
+   = note: #[warn(non_shorthand_field_patterns)] on by default
+
 error: const items should never be #[no_mangle]
   --> $DIR/suggestions.rs:22:18
    |
@@ -97,23 +115,5 @@ LL |     #[no_mangle] pub(crate) fn crossfield<T>() {}
    |     |
    |     help: remove this attribute
 
-warning: denote infinite loops with `loop { ... }`
-  --> $DIR/suggestions.rs:46:5
-   |
-LL |     while true {
-   |     ^^^^^^^^^^ help: use `loop`
-   |
-   = note: #[warn(while_true)] on by default
-
-warning: the `warp_factor:` in this pattern is redundant
-  --> $DIR/suggestions.rs:61:23
-   |
-LL |             Equinox { warp_factor: warp_factor } => {}
-   |                       ------------^^^^^^^^^^^^
-   |                       |
-   |                       help: remove this
-   |
-   = note: #[warn(non_shorthand_field_patterns)] on by default
-
 error: aborting due to 3 previous errors