about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2016-10-12 16:38:58 -0400
committerNiko Matsakis <niko@alum.mit.edu>2016-11-01 14:08:56 -0400
commitddabd509a862da4bd0e8cfb86baf598f45c2383b (patch)
tree8a33fa9449d842a78c69ce2292f75970ee7f4d52
parentf6526512751bfe29a0bf9535bc41db2076ff57ba (diff)
downloadrust-ddabd509a862da4bd0e8cfb86baf598f45c2383b.tar.gz
rust-ddabd509a862da4bd0e8cfb86baf598f45c2383b.zip
compare-method lint
-rw-r--r--src/librustc/infer/error_reporting.rs11
-rw-r--r--src/librustc/infer/mod.rs8
-rw-r--r--src/librustc/lint/builtin.rs9
-rw-r--r--src/librustc/lint/context.rs43
-rw-r--r--src/librustc/lint/mod.rs2
-rw-r--r--src/librustc/session/mod.rs10
-rw-r--r--src/librustc/traits/error_reporting.rs20
-rw-r--r--src/librustc/traits/mod.rs4
-rw-r--r--src/librustc/traits/structural_impls.rs4
-rw-r--r--src/librustc_errors/diagnostic.rs10
-rw-r--r--src/librustc_errors/diagnostic_builder.rs22
-rw-r--r--src/librustc_errors/lib.rs24
-rw-r--r--src/librustc_lint/lib.rs4
-rw-r--r--src/librustc_typeck/check/compare_method.rs1
-rw-r--r--src/test/compile-fail/issue-18937.rs2
-rw-r--r--src/test/ui/compare-method/proj-outlives-region.rs1
-rw-r--r--src/test/ui/compare-method/proj-outlives-region.stderr14
-rw-r--r--src/test/ui/compare-method/proj-outlives-region.stdout0
-rw-r--r--src/test/ui/compare-method/region-unrelated.rs1
-rw-r--r--src/test/ui/compare-method/region-unrelated.stderr14
-rw-r--r--src/test/ui/compare-method/region-unrelated.stdout0
-rw-r--r--src/test/ui/compare-method/region.rs1
-rw-r--r--src/test/ui/compare-method/region.stderr14
-rw-r--r--src/test/ui/compare-method/region.stdout0
24 files changed, 152 insertions, 67 deletions
diff --git a/src/librustc/infer/error_reporting.rs b/src/librustc/infer/error_reporting.rs
index c9850eb650a..5ebb58dbb36 100644
--- a/src/librustc/infer/error_reporting.rs
+++ b/src/librustc/infer/error_reporting.rs
@@ -646,13 +646,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         };
 
         if let SubregionOrigin::CompareImplMethodObligation {
-            span, item_name, impl_item_def_id, trait_item_def_id
+            span, item_name, impl_item_def_id, trait_item_def_id, lint_id
         } = origin {
             self.report_extra_impl_obligation(span,
                                               item_name,
                                               impl_item_def_id,
                                               trait_item_def_id,
-                                              &format!("`{}: {}`", bound_kind, sub))
+                                              &format!("`{}: {}`", bound_kind, sub),
+                                              lint_id)
                 .emit();
             return;
         }
@@ -977,12 +978,14 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             infer::CompareImplMethodObligation { span,
                                                  item_name,
                                                  impl_item_def_id,
-                                                 trait_item_def_id } => {
+                                                 trait_item_def_id,
+                                                 lint_id } => {
                 self.report_extra_impl_obligation(span,
                                                   item_name,
                                                   impl_item_def_id,
                                                   trait_item_def_id,
-                                                  &format!("`{}: {}`", sup, sub))
+                                                  &format!("`{}: {}`", sup, sub),
+                                                  lint_id)
             }
         }
     }
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 9d0d0b063be..56dc52d6103 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -368,6 +368,10 @@ pub enum SubregionOrigin<'tcx> {
         item_name: ast::Name,
         impl_item_def_id: DefId,
         trait_item_def_id: DefId,
+
+        // this is `Some(_)` if this error arises from the bug fix for
+        // #18937. This is a temporary measure.
+        lint_id: Option<ast::NodeId>,
     },
 }
 
@@ -1816,12 +1820,14 @@ impl<'tcx> SubregionOrigin<'tcx> {
 
             traits::ObligationCauseCode::CompareImplMethodObligation { item_name,
                                                                        impl_item_def_id,
-                                                                       trait_item_def_id } =>
+                                                                       trait_item_def_id,
+                                                                       lint_id } =>
                 SubregionOrigin::CompareImplMethodObligation {
                     span: cause.span,
                     item_name: item_name,
                     impl_item_def_id: impl_item_def_id,
                     trait_item_def_id: trait_item_def_id,
+                    lint_id: lint_id,
                 },
 
             _ => default(),
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 3472c77cf42..82a46f76401 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -198,6 +198,12 @@ declare_lint! {
     "patterns in functions without body were erroneously allowed"
 }
 
+declare_lint! {
+    pub EXTRA_REQUIREMENT_IN_IMPL,
+    Warn,
+    "detects extra requirements in impls that were erroneously allowed"
+}
+
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// which are used by other parts of the compiler.
 #[derive(Copy, Clone)]
@@ -235,7 +241,8 @@ impl LintPass for HardwiredLints {
             HR_LIFETIME_IN_ASSOC_TYPE,
             LIFETIME_UNDERSCORE,
             SAFE_EXTERN_STATICS,
-            PATTERNS_IN_FNS_WITHOUT_BODY
+            PATTERNS_IN_FNS_WITHOUT_BODY,
+            EXTRA_REQUIREMENT_IN_IMPL
         )
     }
 }
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 848f8b86639..be755aec660 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -42,7 +42,7 @@ use std::fmt;
 use syntax::attr;
 use syntax::parse::token::InternedString;
 use syntax::ast;
-use syntax_pos::Span;
+use syntax_pos::{MultiSpan, Span};
 use errors::{self, Diagnostic, DiagnosticBuilder};
 use hir;
 use hir::intravisit as hir_visit;
@@ -107,9 +107,12 @@ impl fmt::Debug for EarlyLint {
 }
 
 impl EarlyLint {
-    pub fn new(id: LintId, span: Span, msg: String) -> Self {
-        let mut diagnostic = Diagnostic::new(errors::Level::Warning, &msg);
-        diagnostic.set_span(span);
+    pub fn new<M: EarlyLintMessage>(id: LintId, span: Span, msg: M) -> Self {
+        let diagnostic = msg.into_diagnostic(span);
+        EarlyLint { id: id, span: span, diagnostic: diagnostic }
+    }
+
+    pub fn with_diagnostic(id: LintId, span: Span, diagnostic: Diagnostic) -> Self {
         EarlyLint { id: id, span: span, diagnostic: diagnostic }
     }
 
@@ -120,7 +123,23 @@ impl EarlyLint {
     }
 }
 
+pub trait EarlyLintMessage {
+    fn into_diagnostic(self, span: Span) -> Diagnostic;
+}
 
+impl EarlyLintMessage for String {
+    fn into_diagnostic(self, span: Span) -> Diagnostic {
+        let mut diagnostic = Diagnostic::new(errors::Level::Warning, &self);
+        diagnostic.set_span(span);
+        diagnostic
+    }
+}
+
+impl EarlyLintMessage for Diagnostic {
+    fn into_diagnostic(self, _span: Span) -> Diagnostic {
+        self
+    }
+}
 
 /// Extra information for a future incompatibility lint. See the call
 /// to `register_future_incompatible` in `librustc_lint/lib.rs` for
@@ -439,13 +458,15 @@ pub fn raw_emit_lint(sess: &Session,
     raw_struct_lint(sess, lints, lint, lvlsrc, span, msg).emit();
 }
 
-pub fn raw_struct_lint<'a>(sess: &'a Session,
-                           lints: &LintStore,
-                           lint: &'static Lint,
-                           lvlsrc: LevelSource,
-                           span: Option<Span>,
-                           msg: &str)
-                           -> DiagnosticBuilder<'a> {
+pub fn raw_struct_lint<'a, S>(sess: &'a Session,
+                              lints: &LintStore,
+                              lint: &'static Lint,
+                              lvlsrc: LevelSource,
+                              span: Option<S>,
+                              msg: &str)
+                              -> DiagnosticBuilder<'a>
+    where S: Into<MultiSpan>
+{
     let (mut level, source) = lvlsrc;
     if level == Allow {
         return sess.diagnostic().struct_dummy();
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index 0e11546e643..abbab299ca0 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -41,7 +41,7 @@ use hir;
 
 pub use lint::context::{LateContext, EarlyContext, LintContext, LintStore,
                         raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
-                        raw_struct_lint, FutureIncompatibleInfo, EarlyLint};
+                        raw_struct_lint, FutureIncompatibleInfo, EarlyLint, EarlyLintMessage};
 
 /// Specification of a single lint.
 #[derive(Copy, Clone, Debug)]
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index acfdfc9a027..3af0b7f27dd 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -258,11 +258,11 @@ impl Session {
     pub fn unimpl(&self, msg: &str) -> ! {
         self.diagnostic().unimpl(msg)
     }
-    pub fn add_lint(&self,
-                    lint: &'static lint::Lint,
-                    id: ast::NodeId,
-                    sp: Span,
-                    msg: String) {
+    pub fn add_lint<M: lint::EarlyLintMessage>(&self,
+                                               lint: &'static lint::Lint,
+                                               id: ast::NodeId,
+                                               sp: Span,
+                                               msg: M) {
         let lint_id = lint::LintId::of(lint);
         let mut lints = self.lints.borrow_mut();
         let early_lint = lint::EarlyLint::new(lint_id, sp, msg);
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 56ab8cb22ce..069cbc615f6 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -27,6 +27,7 @@ use super::{
 use fmt_macros::{Parser, Piece, Position};
 use hir::def_id::DefId;
 use infer::{self, InferCtxt, TypeOrigin};
+use rustc::lint::builtin::EXTRA_REQUIREMENT_IN_IMPL;
 use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
 use ty::error::ExpectedFound;
 use ty::fast_reject;
@@ -423,9 +424,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                         item_name: ast::Name,
                                         _impl_item_def_id: DefId,
                                         trait_item_def_id: DefId,
-                                        requirement: &fmt::Display)
+                                        requirement: &fmt::Display,
+                                        lint_id: Option<ast::NodeId>) // (*)
                                         -> DiagnosticBuilder<'tcx>
     {
+        // (*) This parameter is temporary and used only for phasing
+        // in the bug fix to #18937. If it is `Some`, it has a kind of
+        // weird effect -- the diagnostic is reported as a lint, and
+        // the builder which is returned is marked as canceled.
+
         let mut err =
             struct_span_err!(self.tcx.sess,
                              error_span,
@@ -441,6 +448,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             error_span,
             &format!("impl has extra requirement {}", requirement));
 
+        if let Some(node_id) = lint_id {
+            let diagnostic = (*err).clone();
+            self.tcx.sess.add_lint(EXTRA_REQUIREMENT_IN_IMPL, node_id, error_span, diagnostic);
+            err.cancel();
+        }
+
         err
     }
 
@@ -452,14 +465,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         let mut err = match *error {
             SelectionError::Unimplemented => {
                 if let ObligationCauseCode::CompareImplMethodObligation {
-                    item_name, impl_item_def_id, trait_item_def_id
+                    item_name, impl_item_def_id, trait_item_def_id, lint_id
                 } = obligation.cause.code {
                     self.report_extra_impl_obligation(
                         span,
                         item_name,
                         impl_item_def_id,
                         trait_item_def_id,
-                        &format!("`{}`", obligation.predicate))
+                        &format!("`{}`", obligation.predicate),
+                        lint_id)
                         .emit();
                     return;
                 } else {
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 64016da4de7..f1ac96a70b4 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -138,10 +138,12 @@ pub enum ObligationCauseCode<'tcx> {
 
     ImplDerivedObligation(DerivedObligationCause<'tcx>),
 
+    // error derived when matching traits/impls; see ObligationCause for more details
     CompareImplMethodObligation {
         item_name: ast::Name,
         impl_item_def_id: DefId,
-        trait_item_def_id: DefId
+        trait_item_def_id: DefId,
+        lint_id: Option<ast::NodeId>,
     },
 }
 
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index 57ae176c0e9..1e48911ed70 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -197,11 +197,13 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
             }
             super::CompareImplMethodObligation { item_name,
                                                  impl_item_def_id,
-                                                 trait_item_def_id } => {
+                                                 trait_item_def_id,
+                                                 lint_id } => {
                 Some(super::CompareImplMethodObligation {
                     item_name: item_name,
                     impl_item_def_id: impl_item_def_id,
                     trait_item_def_id: trait_item_def_id,
+                    lint_id: lint_id,
                 })
             }
         }
diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs
index cb03257a5ee..c378d5f8d5b 100644
--- a/src/librustc_errors/diagnostic.rs
+++ b/src/librustc_errors/diagnostic.rs
@@ -6,7 +6,7 @@ use std::fmt;
 use syntax_pos::{MultiSpan, Span};
 
 #[must_use]
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct Diagnostic {
     pub level: Level,
     pub message: String,
@@ -16,7 +16,7 @@ pub struct Diagnostic {
 }
 
 /// For example a note attached to an error.
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct SubDiagnostic {
     pub level: Level,
     pub message: String,
@@ -190,9 +190,3 @@ impl Diagnostic {
         self.children.push(sub);
     }
 }
-
-impl fmt::Debug for Diagnostic {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.message.fmt(f)
-    }
-}
diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs
index 69532823f5a..dd416cabb3c 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/src/librustc_errors/diagnostic_builder.rs
@@ -70,6 +70,21 @@ impl<'a> DiagnosticBuilder<'a> {
             return;
         }
 
+        match self.level {
+            Level::Bug |
+            Level::Fatal |
+            Level::PhaseFatal |
+            Level::Error => {
+                self.handler.bump_err_count();
+            }
+
+            Level::Warning |
+            Level::Note |
+            Level::Help |
+            Level::Cancelled => {
+            }
+        }
+
         self.handler.emitter.borrow_mut().emit(&self);
         self.cancel();
         self.handler.panic_if_treat_err_as_bug();
@@ -140,6 +155,13 @@ impl<'a> DiagnosticBuilder<'a> {
             diagnostic: Diagnostic::new_with_code(level, code, message)
         }
     }
+
+    pub fn into_diagnostic(mut self) -> Diagnostic {
+        // annoyingly, the Drop impl means we can't actually move
+        let result = self.diagnostic.clone();
+        self.cancel();
+        result
+    }
 }
 
 impl<'a> Debug for DiagnosticBuilder<'a> {
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 203b96d9f9a..d9ab0dd075b 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -57,7 +57,7 @@ mod lock;
 use syntax_pos::{BytePos, Loc, FileLinesResult, FileName, MultiSpan, Span, NO_EXPANSION};
 use syntax_pos::MacroBacktrace;
 
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub enum RenderSpan {
     /// A FullSpan renders with both with an initial line for the
     /// message, prefixed by file:linenum, followed by a summary of
@@ -71,7 +71,7 @@ pub enum RenderSpan {
     Suggestion(CodeSuggestion),
 }
 
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct CodeSuggestion {
     pub msp: MultiSpan,
     pub substitutes: Vec<String>,
@@ -293,7 +293,6 @@ impl Handler {
                                                    sp: S,
                                                    msg: &str)
                                                    -> DiagnosticBuilder<'a> {
-        self.bump_err_count();
         let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
         result.set_span(sp);
         result
@@ -303,21 +302,18 @@ impl Handler {
                                                              msg: &str,
                                                              code: &str)
                                                              -> DiagnosticBuilder<'a> {
-        self.bump_err_count();
         let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
         result.set_span(sp);
         result.code(code.to_owned());
         result
     }
     pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
-        self.bump_err_count();
         DiagnosticBuilder::new(self, Level::Error, msg)
     }
     pub fn struct_span_fatal<'a, S: Into<MultiSpan>>(&'a self,
                                                      sp: S,
                                                      msg: &str)
                                                      -> DiagnosticBuilder<'a> {
-        self.bump_err_count();
         let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
         result.set_span(sp);
         result
@@ -327,24 +323,16 @@ impl Handler {
                                                                msg: &str,
                                                                code: &str)
                                                                -> DiagnosticBuilder<'a> {
-        self.bump_err_count();
         let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
         result.set_span(sp);
         result.code(code.to_owned());
         result
     }
     pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
-        self.bump_err_count();
         DiagnosticBuilder::new(self, Level::Fatal, msg)
     }
 
     pub fn cancel(&self, err: &mut DiagnosticBuilder) {
-        if err.level == Level::Error || err.level == Level::Fatal {
-            self.err_count.set(self.err_count
-                .get()
-                .checked_sub(1)
-                .expect("cancelled an error but err_count is 0"));
-        }
         err.cancel();
     }
 
@@ -356,7 +344,6 @@ impl Handler {
 
     pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> FatalError {
         self.emit(&sp.into(), msg, Fatal);
-        self.bump_err_count();
         self.panic_if_treat_err_as_bug();
         return FatalError;
     }
@@ -366,13 +353,11 @@ impl Handler {
                                                     code: &str)
                                                     -> FatalError {
         self.emit_with_code(&sp.into(), msg, code, Fatal);
-        self.bump_err_count();
         self.panic_if_treat_err_as_bug();
         return FatalError;
     }
     pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.emit(&sp.into(), msg, Error);
-        self.bump_err_count();
         self.panic_if_treat_err_as_bug();
     }
     pub fn mut_span_err<'a, S: Into<MultiSpan>>(&'a self,
@@ -381,12 +366,10 @@ impl Handler {
                                                 -> DiagnosticBuilder<'a> {
         let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
         result.set_span(sp);
-        self.bump_err_count();
         result
     }
     pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) {
         self.emit_with_code(&sp.into(), msg, code, Error);
-        self.bump_err_count();
         self.panic_if_treat_err_as_bug();
     }
     pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
@@ -405,7 +388,6 @@ impl Handler {
     }
     pub fn span_bug_no_panic<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.emit(&sp.into(), msg, Bug);
-        self.bump_err_count();
     }
     pub fn span_note_without_error<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.emit(&sp.into(), msg, Note);
@@ -419,7 +401,6 @@ impl Handler {
         }
         let mut db = DiagnosticBuilder::new(self, Fatal, msg);
         db.emit();
-        self.bump_err_count();
         FatalError
     }
     pub fn err(&self, msg: &str) {
@@ -428,7 +409,6 @@ impl Handler {
         }
         let mut db = DiagnosticBuilder::new(self, Error, msg);
         db.emit();
-        self.bump_err_count();
     }
     pub fn warn(&self, msg: &str) {
         let mut db = DiagnosticBuilder::new(self, Warning, msg);
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 6f114e09a6c..0d1bc4fdfa8 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -229,6 +229,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
             id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
             reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
         },
+        FutureIncompatibleInfo {
+            id: LintId::of(EXTRA_REQUIREMENT_IN_IMPL),
+            reference: "issue #18937 <https://github.com/rust-lang/rust/issues/18937>",
+        },
         ]);
 
     // Register renamed and removed lints
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index a5b3811ec61..d9af317eab0 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -367,6 +367,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                     item_name: impl_m.name,
                     impl_item_def_id: impl_m.def_id,
                     trait_item_def_id: trait_m.def_id,
+                    lint_id: Some(impl_m_body_id),
                 },
             };
 
diff --git a/src/test/compile-fail/issue-18937.rs b/src/test/compile-fail/issue-18937.rs
index 321359cb96c..1285be1d312 100644
--- a/src/test/compile-fail/issue-18937.rs
+++ b/src/test/compile-fail/issue-18937.rs
@@ -10,6 +10,8 @@
 
 // Regression test for #18937.
 
+#![deny(extra_requirement_in_impl)]
+
 use std::fmt;
 
 #[derive(Debug)]
diff --git a/src/test/ui/compare-method/proj-outlives-region.rs b/src/test/ui/compare-method/proj-outlives-region.rs
index 631da7140ea..54cfe4be9c1 100644
--- a/src/test/ui/compare-method/proj-outlives-region.rs
+++ b/src/test/ui/compare-method/proj-outlives-region.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![allow(dead_code)]
+#![deny(extra_requirement_in_impl)]
 
 // Test that we elaborate `Type: 'region` constraints and infer various important things.
 
diff --git a/src/test/ui/compare-method/proj-outlives-region.stderr b/src/test/ui/compare-method/proj-outlives-region.stderr
index b36d64e3b9c..f5907c0ae59 100644
--- a/src/test/ui/compare-method/proj-outlives-region.stderr
+++ b/src/test/ui/compare-method/proj-outlives-region.stderr
@@ -1,11 +1,19 @@
 error[E0276]: impl has stricter requirements than trait
-  --> $DIR/proj-outlives-region.rs:21:5
+  --> $DIR/proj-outlives-region.rs:22:5
    |
-16 |     fn foo() where T: 'a;
+17 |     fn foo() where T: 'a;
    |     --------------------- definition of `foo` from trait
 ...
-21 |     fn foo() where U: 'a { } //~ ERROR E0276
+22 |     fn foo() where U: 'a { } //~ ERROR E0276
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `U: 'a`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #18937 <https://github.com/rust-lang/rust/issues/18937>
+note: lint level defined here
+  --> $DIR/proj-outlives-region.rs:12:9
+   |
+12 | #![deny(extra_requirement_in_impl)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/compare-method/proj-outlives-region.stdout b/src/test/ui/compare-method/proj-outlives-region.stdout
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/test/ui/compare-method/proj-outlives-region.stdout
diff --git a/src/test/ui/compare-method/region-unrelated.rs b/src/test/ui/compare-method/region-unrelated.rs
index 3c11b8bb1ef..8f79b30bd5f 100644
--- a/src/test/ui/compare-method/region-unrelated.rs
+++ b/src/test/ui/compare-method/region-unrelated.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![allow(dead_code)]
+#![deny(extra_requirement_in_impl)]
 
 // Test that we elaborate `Type: 'region` constraints and infer various important things.
 
diff --git a/src/test/ui/compare-method/region-unrelated.stderr b/src/test/ui/compare-method/region-unrelated.stderr
index fb3511867e5..b8084c4a2f3 100644
--- a/src/test/ui/compare-method/region-unrelated.stderr
+++ b/src/test/ui/compare-method/region-unrelated.stderr
@@ -1,11 +1,19 @@
 error[E0276]: impl has stricter requirements than trait
-  --> $DIR/region-unrelated.rs:21:5
+  --> $DIR/region-unrelated.rs:22:5
    |
-16 |     fn foo() where T: 'a;
+17 |     fn foo() where T: 'a;
    |     --------------------- definition of `foo` from trait
 ...
-21 |     fn foo() where V: 'a { }
+22 |     fn foo() where V: 'a { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `V: 'a`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #18937 <https://github.com/rust-lang/rust/issues/18937>
+note: lint level defined here
+  --> $DIR/region-unrelated.rs:12:9
+   |
+12 | #![deny(extra_requirement_in_impl)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/compare-method/region-unrelated.stdout b/src/test/ui/compare-method/region-unrelated.stdout
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/test/ui/compare-method/region-unrelated.stdout
diff --git a/src/test/ui/compare-method/region.rs b/src/test/ui/compare-method/region.rs
index 1942ca9504c..ef6a642143c 100644
--- a/src/test/ui/compare-method/region.rs
+++ b/src/test/ui/compare-method/region.rs
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 #![allow(dead_code)]
+#![deny(extra_requirement_in_impl)]
 
 // Test that we elaborate `Type: 'region` constraints and infer various important things.
 
diff --git a/src/test/ui/compare-method/region.stderr b/src/test/ui/compare-method/region.stderr
index 78e00e066bd..787433137b9 100644
--- a/src/test/ui/compare-method/region.stderr
+++ b/src/test/ui/compare-method/region.stderr
@@ -1,11 +1,19 @@
 error[E0276]: impl has stricter requirements than trait
-  --> $DIR/region.rs:21:5
+  --> $DIR/region.rs:22:5
    |
-16 |     fn foo();
+17 |     fn foo();
    |     --------- definition of `foo` from trait
 ...
-21 |     fn foo() where 'a: 'b { }
+22 |     fn foo() where 'a: 'b { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'a: 'b`
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #18937 <https://github.com/rust-lang/rust/issues/18937>
+note: lint level defined here
+  --> $DIR/region.rs:12:9
+   |
+12 | #![deny(extra_requirement_in_impl)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/compare-method/region.stdout b/src/test/ui/compare-method/region.stdout
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/test/ui/compare-method/region.stdout