Skip to content

Commit 27c8c1f

Browse files
committed
---
yaml --- r: 172891 b: refs/heads/batch c: e183277 h: refs/heads/master i: 172889: 3a431f7 172887: b560d63 v: v3
1 parent 5b9fc63 commit 27c8c1f

File tree

3 files changed

+34
-20
lines changed

3 files changed

+34
-20
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
2929
refs/heads/issue-18208-method-dispatch-2: 9e1eae4fb9b6527315b4441cf8a0f5ca911d1671
3030
refs/heads/automation-fail: 1bf06495443584539b958873e04cc2f864ab10e4
3131
refs/heads/issue-18208-method-dispatch-3-quick-reject: 2009f85b9f99dedcec4404418eda9ddba90258a2
32-
refs/heads/batch: dc0de42035dc5c71e47ded2968fc6fd7c76641c6
32+
refs/heads/batch: e1832779483df51b59367250850213d8e7fe159a
3333
refs/heads/building: 126db549b038c84269a1e4fe46f051b2c15d6970
3434
refs/heads/beta: 44a287e6eb22ec3c2a687fc156813577464017f7
3535
refs/heads/windistfix: 7608dbad651f02e837ed05eef3d74a6662a6e928

branches/batch/src/librustc/middle/traits/error_reporting.rs

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use fmt_macros::{Parser, Piece, Position};
2222
use middle::infer::InferCtxt;
2323
use middle::ty::{self, AsPredicate, ReferencesError, ToPolyTraitRef, TraitRef};
2424
use std::collections::HashMap;
25-
use syntax::codemap::Span;
25+
use syntax::codemap::{DUMMY_SP, Span};
2626
use syntax::attr::{AttributeMethods, AttrMetaMethods};
2727
use util::ppaux::{Repr, UserString};
2828

@@ -66,13 +66,20 @@ pub fn report_projection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
6666
}
6767

6868
fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
69-
trait_ref: &TraitRef<'tcx>) -> Option<String> {
69+
trait_ref: &TraitRef<'tcx>,
70+
span: Span) -> Option<String> {
7071
let def_id = trait_ref.def_id;
7172
let mut report = None;
7273
ty::each_attr(infcx.tcx, def_id, |item| {
7374
if item.check_name("on_unimplemented") {
75+
let err_sp = if item.meta().span == DUMMY_SP {
76+
span
77+
} else {
78+
item.meta().span
79+
};
80+
let def = ty::lookup_trait_def(infcx.tcx, def_id);
81+
let trait_str = def.trait_ref.user_string(infcx.tcx);
7482
if let Some(ref istring) = item.value_str() {
75-
let def = ty::lookup_trait_def(infcx.tcx, def_id);
7683
let mut generic_map = def.generics.types.iter_enumerated()
7784
.map(|(param, i, gen)| {
7885
(gen.name.as_str().to_string(),
@@ -91,20 +98,24 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
9198
Some(val) => Some(val.as_slice()),
9299
None => {
93100
infcx.tcx.sess
94-
.span_err(item.meta().span,
95-
format!("there is no type parameter \
96-
{} on trait {}",
97-
s, def.trait_ref
98-
.user_string(infcx.tcx))
101+
.span_err(err_sp,
102+
format!("the #[on_unimplemented] attribute on \
103+
trait definition for {} refers to \
104+
non-existent type parameter {}",
105+
trait_str, s)
99106
.as_slice());
100107
errored = true;
101108
None
102109
}
103110
},
104111
_ => {
105-
infcx.tcx.sess.span_err(item.meta().span,
106-
"only named substitution \
107-
parameters are allowed");
112+
infcx.tcx.sess
113+
.span_err(err_sp,
114+
format!("the #[on_unimplemented] attribute on \
115+
trait definition for {} must have named \
116+
format arguments, \
117+
eg `#[on_unimplemented = \"foo {{T}}\"]`",
118+
trait_str).as_slice());
108119
errored = true;
109120
None
110121
}
@@ -116,9 +127,11 @@ fn report_on_unimplemented<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
116127
report = Some(err);
117128
}
118129
} else {
119-
infcx.tcx.sess.span_err(item.meta().span,
120-
"this attribute must have a value, \
121-
eg `#[on_unimplemented = \"foo\"]`")
130+
infcx.tcx.sess.span_err(err_sp,
131+
format!("the #[on_unimplemented] attribute on \
132+
trait definition for {} must have a value, \
133+
eg `#[on_unimplemented = \"foo\"]`",
134+
trait_str).as_slice());
122135
}
123136
false
124137
} else {
@@ -154,15 +167,16 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
154167
infcx.resolve_type_vars_if_possible(trait_predicate);
155168
if !trait_predicate.references_error() {
156169
let trait_ref = trait_predicate.to_poly_trait_ref();
157-
// Check if it has a custom "#[on_unimplemented]" error message,
158-
// report with that message if it does
159-
let custom_note = report_on_unimplemented(infcx, &*trait_ref.0);
160170
infcx.tcx.sess.span_err(
161171
obligation.cause.span,
162172
format!(
163173
"the trait `{}` is not implemented for the type `{}`",
164174
trait_ref.user_string(infcx.tcx),
165175
trait_ref.self_ty().user_string(infcx.tcx)).as_slice());
176+
// Check if it has a custom "#[on_unimplemented]" error message,
177+
// report with that message if it does
178+
let custom_note = report_on_unimplemented(infcx, &*trait_ref.0,
179+
obligation.cause.span);
166180
if let Some(s) = custom_note {
167181
infcx.tcx.sess.span_note(
168182
obligation.cause.span,

branches/batch/src/test/compile-fail/on-unimplemented.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ fn collect<A, I: Iterator<Item=A>, B: MyFromIterator<A>>(it: I) -> B {
2626
MyFromIterator::my_from_iter(it)
2727
}
2828

29-
#[on_unimplemented] //~ ERROR this attribute must have a value
29+
#[on_unimplemented] //~ ERROR the #[on_unimplemented] attribute on trait definition for BadAnnotation1 must have a value, eg `#[on_unimplemented = "foo"]`
3030
trait BadAnnotation1 {}
3131

3232
#[on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
33-
//~^ ERROR there is no type parameter C on trait BadAnnotation2<A, B>
33+
//~^ ERROR the #[on_unimplemented] attribute on trait definition for BadAnnotation2<A, B> refers to non-existent type parameter C
3434
trait BadAnnotation2<A,B> {}
3535

3636
fn trigger1<T: BadAnnotation1>(t: T) {}

0 commit comments

Comments
 (0)