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!
This commit is contained in:
parent
7f43981ebf
commit
5cc488d250
@ -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 {
|
||||
|
@ -36,6 +36,7 @@
|
||||
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 @@ fn report_projection_error(&self,
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
15
src/test/ui/issue-33941.rs
Normal file
15
src/test/ui/issue-33941.rs
Normal file
@ -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() {}
|
||||
}
|
21
src/test/ui/issue-33941.stderr
Normal file
21
src/test/ui/issue-33941.stderr
Normal file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user