about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/session/mod.rs6
-rw-r--r--src/librustc/traits/error_reporting.rs21
-rw-r--r--src/test/ui/issue-33941.rs15
-rw-r--r--src/test/ui/issue-33941.stderr21
4 files changed, 54 insertions, 9 deletions
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 39cf50787ef..00a91eeb9c1 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -164,11 +164,13 @@ enum DiagnosticBuilderMethod {
     // add more variants as needed to support one-time diagnostics
 }
 
-/// Diagnostic message id - used in order to avoid emitting the same message more than once
+/// Diagnostic message ID—used by `Session.one_time_diagnostics` to avoid
+/// emitting the same message more than once
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 pub enum DiagnosticMessageId {
+    ErrorId(u16), // EXXXX error code as integer
     LintId(lint::LintId),
-    StabilityId(u32)
+    StabilityId(u32) // issue number
 }
 
 impl Session {
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index e2b23c12cf1..106b1b08656 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -36,6 +36,7 @@ use middle::const_val;
 use rustc::lint::builtin::EXTRA_REQUIREMENT_IN_IMPL;
 use std::fmt;
 use syntax::ast;
+use session::DiagnosticMessageId;
 use ty::{self, AdtKind, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
 use ty::error::ExpectedFound;
 use ty::fast_reject;
@@ -219,13 +220,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 }
             }
 
-            let mut diag = struct_span_err!(
-                self.tcx.sess, obligation.cause.span, E0271,
-                "type mismatch resolving `{}`", predicate
-            );
-            self.note_type_err(&mut diag, &obligation.cause, None, values, err);
-            self.note_obligation_cause(&mut diag, obligation);
-            diag.emit();
+            let msg = format!("type mismatch resolving `{}`", predicate);
+            let error_id = (DiagnosticMessageId::ErrorId(271),
+                            Some(obligation.cause.span), msg.clone());
+            let fresh = self.tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id);
+            if fresh {
+                let mut diag = struct_span_err!(
+                    self.tcx.sess, obligation.cause.span, E0271,
+                    "type mismatch resolving `{}`", predicate
+                );
+                self.note_type_err(&mut diag, &obligation.cause, None, values, err);
+                self.note_obligation_cause(&mut diag, obligation);
+                diag.emit();
+            }
         });
     }
 
diff --git a/src/test/ui/issue-33941.rs b/src/test/ui/issue-33941.rs
new file mode 100644
index 00000000000..eb111d33b99
--- /dev/null
+++ b/src/test/ui/issue-33941.rs
@@ -0,0 +1,15 @@
+// Copyright 2017 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.
+
+use std::collections::HashMap;
+
+fn main() {
+    for _ in HashMap::new().iter().cloned() {}
+}
diff --git a/src/test/ui/issue-33941.stderr b/src/test/ui/issue-33941.stderr
new file mode 100644
index 00000000000..5a8d1fab3f6
--- /dev/null
+++ b/src/test/ui/issue-33941.stderr
@@ -0,0 +1,21 @@
+error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`
+  --> $DIR/issue-33941.rs:14:36
+   |
+14 |     for _ in HashMap::new().iter().cloned() {}
+   |                                    ^^^^^^ expected tuple, found reference
+   |
+   = note: expected type `(&_, &_)`
+              found type `&_`
+
+error[E0271]: type mismatch resolving `<std::collections::hash_map::Iter<'_, _, _> as std::iter::Iterator>::Item == &_`
+  --> $DIR/issue-33941.rs:14:5
+   |
+14 |     for _ in HashMap::new().iter().cloned() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference
+   |
+   = note: expected type `(&_, &_)`
+              found type `&_`
+   = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Cloned<std::collections::hash_map::Iter<'_, _, _>>`
+
+error: aborting due to 2 previous errors
+