diff --git a/src/doc/unstable-book/src/language-features/tool-lints.md b/src/doc/unstable-book/src/language-features/tool-lints.md
deleted file mode 100644
index 5c0d33b5ab0c4..0000000000000
--- a/src/doc/unstable-book/src/language-features/tool-lints.md
+++ /dev/null
@@ -1,35 +0,0 @@
-# `tool_lints`
-
-The tracking issue for this feature is: [#44690]
-
-[#44690]: https://github.com/rust-lang/rust/issues/44690
-
-------------------------
-
-Tool lints let you use scoped lints, to `allow`, `warn`, `deny` or `forbid` lints of
-certain tools.
-
-Currently `clippy` is the only available lint tool.
-
-It is recommended for lint tools to implement the scoped lints like this:
-
-- `#[_(TOOL_NAME::lintname)]`: for lint names
-- `#[_(TOOL_NAME::lintgroup)]`: for groups of lints
-- `#[_(TOOL_NAME::all)]`: for (almost[^1]) all lints
-
-## An example
-
-```rust
-#![feature(tool_lints)]
-
-#![warn(clippy::pedantic)]
-
-#[allow(clippy::filter_map)]
-fn main() {
-    let v = vec![0; 10];
-    let _ = v.into_iter().filter(|&x| x < 1).map(|x| x + 1).collect::<Vec<_>>();
-    println!("No filter_map()!");
-}
-```
-
-[^1]: Some defined lint groups can be excluded here.
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 87d33e473e7f6..950754a07ab09 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -18,11 +18,10 @@ use lint::context::CheckLintNameResult;
 use lint::{self, Lint, LintId, Level, LintSource};
 use rustc_data_structures::stable_hasher::{HashStable, ToStableHashKey,
                                            StableHasher, StableHasherResult};
-use session::{config::nightly_options, Session};
+use session::Session;
 use syntax::ast;
 use syntax::attr;
 use syntax::source_map::MultiSpan;
-use syntax::feature_gate;
 use syntax::symbol::Symbol;
 use util::nodemap::FxHashMap;
 
@@ -228,18 +227,7 @@ impl<'a> LintLevelsBuilder<'a> {
                     }
                 };
                 let tool_name = if let Some(lint_tool) = word.is_scoped() {
-                    let gate_feature = !self.sess.features_untracked().tool_lints;
-                    let known_tool = attr::is_known_lint_tool(lint_tool);
-                    if gate_feature {
-                        feature_gate::emit_feature_err(
-                            &sess.parse_sess,
-                            "tool_lints",
-                            word.span,
-                            feature_gate::GateIssue::Language,
-                            &format!("scoped lint `{}` is experimental", word.ident),
-                        );
-                    }
-                    if !known_tool {
+                    if !attr::is_known_lint_tool(lint_tool) {
                         span_err!(
                             sess,
                             lint_tool.span,
@@ -247,9 +235,6 @@ impl<'a> LintLevelsBuilder<'a> {
                             "an unknown tool name found in scoped lint: `{}`",
                             word.ident
                         );
-                    }
-
-                    if gate_feature || !known_tool {
                         continue;
                     }
 
@@ -299,13 +284,7 @@ impl<'a> LintLevelsBuilder<'a> {
                                     "change it to",
                                     new_lint_name.to_string(),
                                     Applicability::MachineApplicable,
-                                );
-
-                                if nightly_options::is_nightly_build() {
-                                    err.emit();
-                                } else {
-                                    err.cancel();
-                                }
+                                ).emit();
 
                                 let src = LintSource::Node(Symbol::intern(&new_lint_name), li.span);
                                 for id in ids {
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 24ee24640558e..4ddbaee5aa443 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -433,9 +433,6 @@ declare_features! (
     // #[doc(alias = "...")]
     (active, doc_alias, "1.27.0", Some(50146), None),
 
-    // Scoped lints
-    (active, tool_lints, "1.28.0", Some(44690), None),
-
     // Allows irrefutable patterns in if-let and while-let statements (RFC 2086)
     (active, irrefutable_let_patterns, "1.27.0", Some(44495), None),
 
@@ -679,6 +676,8 @@ declare_features! (
     (accepted, pattern_parentheses, "1.31.0", Some(51087), None),
     // Allows the definition of `const fn` functions.
     (accepted, min_const_fn, "1.31.0", Some(53555), None),
+    // Scoped lints
+    (accepted, tool_lints, "1.31.0", Some(44690), None),
 );
 
 // If you change this, please modify src/doc/unstable-book as well. You must
diff --git a/src/test/run-pass/tool_lints.rs b/src/test/run-pass/tool_lints.rs
index 24ec43b12f60e..2705c03598a0d 100644
--- a/src/test/run-pass/tool_lints.rs
+++ b/src/test/run-pass/tool_lints.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tool_lints)]
+
 #![deny(unknown_lints)]
 
 #[allow(clippy::almost_swapped)]
diff --git a/src/test/run-pass/tool_lints_2018_preview.rs b/src/test/run-pass/tool_lints_2018_preview.rs
index 6cd57eaa19595..57df3e072a8dc 100644
--- a/src/test/run-pass/tool_lints_2018_preview.rs
+++ b/src/test/run-pass/tool_lints_2018_preview.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tool_lints)]
+
 #![feature(rust_2018_preview)]
 #![deny(unknown_lints)]
 
diff --git a/src/test/ui-fulldeps/lint_tool_test.rs b/src/test/ui-fulldeps/lint_tool_test.rs
index ebe10b3714f20..11b70d1d7809c 100644
--- a/src/test/ui-fulldeps/lint_tool_test.rs
+++ b/src/test/ui-fulldeps/lint_tool_test.rs
@@ -11,8 +11,8 @@
 // aux-build:lint_tool_test.rs
 // ignore-stage1
 // compile-flags: --cfg foo
+
 #![feature(plugin)]
-#![feature(tool_lints)]
 #![plugin(lint_tool_test)]
 #![allow(dead_code)]
 #![cfg_attr(foo, warn(test_lint))]
diff --git a/src/test/ui/feature-gates/feature-gate-tool_lints-fail.rs b/src/test/ui/feature-gates/feature-gate-tool_lints-fail.rs
deleted file mode 100644
index c311eb7ed7ae1..0000000000000
--- a/src/test/ui/feature-gates/feature-gate-tool_lints-fail.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[warn(clippy::assign_ops)] //~ ERROR scoped lint `clippy::assign_ops` is experimental
-fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-tool_lints-fail.stderr b/src/test/ui/feature-gates/feature-gate-tool_lints-fail.stderr
deleted file mode 100644
index 33ee79cd2011a..0000000000000
--- a/src/test/ui/feature-gates/feature-gate-tool_lints-fail.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: scoped lint `clippy::assign_ops` is experimental (see issue #44690)
-  --> $DIR/feature-gate-tool_lints-fail.rs:11:8
-   |
-LL | #[warn(clippy::assign_ops)] //~ ERROR scoped lint `clippy::assign_ops` is experimental
-   |        ^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(tool_lints)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/feature-gates/feature-gate-tool_lints.rs b/src/test/ui/feature-gates/feature-gate-tool_lints.rs
deleted file mode 100644
index 3ef67982be9a4..0000000000000
--- a/src/test/ui/feature-gates/feature-gate-tool_lints.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[warn(clippy::decimal_literal_representation)]
-//~^ ERROR scoped lint `clippy::decimal_literal_representation` is experimental
-fn main() {
-    let a = 65_535;
-}
diff --git a/src/test/ui/feature-gates/feature-gate-tool_lints.stderr b/src/test/ui/feature-gates/feature-gate-tool_lints.stderr
deleted file mode 100644
index 8019b1e6a28f6..0000000000000
--- a/src/test/ui/feature-gates/feature-gate-tool_lints.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0658]: scoped lint `clippy::decimal_literal_representation` is experimental (see issue #44690)
-  --> $DIR/feature-gate-tool_lints.rs:11:8
-   |
-LL | #[warn(clippy::decimal_literal_representation)]
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: add #![feature(tool_lints)] to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/tool_lints-fail.rs b/src/test/ui/tool_lints-fail.rs
index ea1efab4cb6f8..4134fca1ce6ca 100644
--- a/src/test/ui/tool_lints-fail.rs
+++ b/src/test/ui/tool_lints-fail.rs
@@ -10,7 +10,7 @@
 
 // Don't allow tool_lints, which aren't scoped
 
-#![feature(tool_lints)]
+
 #![deny(unknown_lints)]
 
 #![deny(clippy)] //~ ERROR: unknown lint: `clippy`
diff --git a/src/test/ui/tool_lints.rs b/src/test/ui/tool_lints.rs
index 71f90b17c18fc..001f2f11e5cb3 100644
--- a/src/test/ui/tool_lints.rs
+++ b/src/test/ui/tool_lints.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tool_lints)]
+
 
 #[warn(foo::bar)]
 //~^ ERROR an unknown tool name found in scoped lint: `foo::bar`
diff --git a/src/test/ui/unknown-lint-tool-name.rs b/src/test/ui/unknown-lint-tool-name.rs
index 78b736edcebe6..a1d6c27e518e5 100644
--- a/src/test/ui/unknown-lint-tool-name.rs
+++ b/src/test/ui/unknown-lint-tool-name.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(tool_lints)]
+
 
 #![deny(foo::bar)] //~ ERROR an unknown tool name found in scoped lint: `foo::bar`