diff options
| author | Zack M. Davis <code@zackmdavis.net> | 2017-11-12 19:13:07 -0800 |
|---|---|---|
| committer | Zack M. Davis <code@zackmdavis.net> | 2017-11-12 19:34:27 -0800 |
| commit | 5cc488d2500999ef4b934c90f155022b25dcdd19 (patch) | |
| tree | da009dab79aa7543c7c91fc77df33a1ed09a0def /src | |
| parent | 7f43981ebfbfd771d4e60b44f270125fe3cb4902 (diff) | |
| download | rust-5cc488d2500999ef4b934c90f155022b25dcdd19.tar.gz rust-5cc488d2500999ef4b934c90f155022b25dcdd19.zip | |
deduplicate projection error (E0271) messages
The `ErrorId` variant takes a u16 so that `DiagnosticMessageId` can retain
its `Copy` status (the present author's first choice having been the "EXXX"
code as a string).
The duplicated "type mismatch resolving `{}`" literal is unfortunate, but
the `struct_span_err!` macro (which we want to mark that error code as
used) is fussy about taking a literal, and the one-time-diagnostics set
needs an owned string.
This is concerning #33941 and probably #45805!
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/session/mod.rs | 6 | ||||
| -rw-r--r-- | src/librustc/traits/error_reporting.rs | 21 | ||||
| -rw-r--r-- | src/test/ui/issue-33941.rs | 15 | ||||
| -rw-r--r-- | src/test/ui/issue-33941.stderr | 21 |
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 + |
