AssociatedKind::Method => !self.method_has_self_argument,
}
}
+
+ pub fn signature<'a, 'tcx>(&self, tcx: &TyCtxt<'a, 'tcx, 'tcx>) -> String {
+ match self.kind {
+ ty::AssociatedKind::Method => {
+ // We skip the binder here because the binder would deanonymize all
+ // late-bound regions, and we don't want method signatures to show up
+ // `as for<'r> fn(&'r MyType)`. Pretty-printing handles late-bound
+ // regions just fine, showing `fn(&MyType)`.
+ format!("{}", tcx.type_of(self.def_id).fn_sig().skip_binder())
+ }
+ ty::AssociatedKind::Type => format!("type {};", self.name.to_string()),
+ ty::AssociatedKind::Const => {
+ format!("const {}: {:?};", self.name.to_string(), tcx.type_of(self.def_id))
+ }
+ }
+ }
}
#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)]
self
}
+ pub fn note_trait_signature(&mut self, name: String, signature: String) -> &mut Self {
+ self.highlighted_note(vec![
+ (format!("`{}` from trait: `", name), Style::NoStyle),
+ (signature, Style::Highlight),
+ ("`".to_string(), Style::NoStyle)]);
+ self
+ }
+
pub fn note(&mut self, msg: &str) -> &mut Self {
self.sub(Level::Note, msg, MultiSpan::new(), None);
self
format!("expected `{}` in impl", self_descr));
if let Some(span) = tcx.hir.span_if_local(trait_m.def_id) {
err.span_label(span, format!("`{}` used in trait", self_descr));
+ } else {
+ err.note_trait_signature(trait_m.name.to_string(),
+ trait_m.signature(&tcx));
}
err.emit();
return Err(ErrorReported);
} else {
format!("{} parameter", trait_number_args)
}));
+ } else {
+ err.note_trait_signature(trait_m.name.to_string(),
+ trait_m.signature(&tcx));
}
err.span_label(impl_span,
format!("expected {}, found {}",
}
}
- let signature = |item: &ty::AssociatedItem| {
- match item.kind {
- ty::AssociatedKind::Method => {
- format!("{}", tcx.type_of(item.def_id).fn_sig().0)
- }
- ty::AssociatedKind::Type => format!("type {};", item.name.to_string()),
- ty::AssociatedKind::Const => {
- format!("const {}: {:?};", item.name.to_string(), tcx.type_of(item.def_id))
- }
- }
- };
-
if !missing_items.is_empty() {
let mut err = struct_span_err!(tcx.sess, impl_span, E0046,
"not all trait items implemented, missing: `{}`",
if let Some(span) = tcx.hir.span_if_local(trait_item.def_id) {
err.span_label(span, format!("`{}` from trait", trait_item.name));
} else {
- err.note(&format!("`{}` from trait: `{}`",
- trait_item.name,
- signature(&trait_item)));
+ err.note_trait_signature(trait_item.name.to_string(),
+ trait_item.signature(&tcx));
}
}
err.emit();
--- /dev/null
+// 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.
+
+struct MyType;
+struct MyType2;
+struct MyType3;
+struct MyType4;
+
+impl std::fmt::Display for MyType {
+ fn fmt(&self, x: &str) -> () { }
+}
+
+impl std::fmt::Display for MyType2 {
+ fn fmt(&self) -> () { }
+}
+
+impl std::fmt::Display for MyType3 {
+ fn fmt() -> () { }
+}
+
+impl std::fmt::Display for MyType4 {}
+
+fn main() {}
--- /dev/null
+error[E0053]: method `fmt` has an incompatible type for trait
+ --> $DIR/trait_type.rs:17:4
+ |
+17 | fn fmt(&self, x: &str) -> () { }
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability
+ |
+ = note: expected type `fn(&MyType, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
+ found type `fn(&MyType, &str)`
+
+error[E0050]: method `fmt` has 1 parameter but the declaration in trait `std::fmt::Display::fmt` has 2
+ --> $DIR/trait_type.rs:21:11
+ |
+21 | fn fmt(&self) -> () { }
+ | ^^^^^ expected 2 parameters, found 1
+ |
+ = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
+
+error[E0186]: method `fmt` has a `&self` declaration in the trait, but not in the impl
+ --> $DIR/trait_type.rs:25:4
+ |
+25 | fn fmt() -> () { }
+ | ^^^^^^^^^^^^^^^^^^ expected `&self` in impl
+ |
+ = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
+
+error[E0046]: not all trait items implemented, missing: `fmt`
+ --> $DIR/trait_type.rs:28:1
+ |
+28 | impl std::fmt::Display for MyType4 {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `fmt` in implementation
+ |
+ = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
+
+error: aborting due to previous error(s)
+