Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to attach custom #[on_unimplemented] error messages for unimplemented traits #20889

Merged
merged 7 commits into from
Jan 12, 2015

Conversation

Manishearth
Copy link
Member

@nikomatsakis
Copy link
Contributor

👯

@Manishearth Manishearth force-pushed the trait-error branch 2 times, most recently from 6665642 to 6f0419f Compare January 10, 2015 20:53
@ghost
Copy link

ghost commented Jan 10, 2015

Awesome :] This should be very useful.

@sfackler
Copy link
Member

Cool!

@flaper87
Copy link
Contributor

looks better now, I think we should have an get_attr in ty but it can be left for a separate PR.

@nikomatsakis your call now :)

let mut report = None;
ty::each_attr(infcx.tcx, def_id, |item| {
if item.check_name("on_unimplemented") {
match item.meta().node {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pair of nested matchs can be if let Some(ref i) = item.value_str() { ... }.

@huonw
Copy link
Member

huonw commented Jan 11, 2015

Yay!

I wonder if we need to have a definition-site verification as well as the use-site behaviour, as it stands one will only get validation that the on_unimplemented message is valid when actually triggering an unimplemented error; that is, downstream users will get error messages about the invalidity of the format string.

E.g. AFAICT, this will compile fine in isolation

#[on_unimplemented = "foo {X}, {Y}, {unclosed"]
pub trait Foo {}

@Manishearth
Copy link
Member Author

@huonw fixed the other issues

@ftxqxd
Copy link
Contributor

ftxqxd commented Jan 11, 2015

It's great to see this! But I think the error message should still mention the specific trait (FromIterator in this case) somewhere, to show the actual reason why it doesn't work (and thus help towards resolving the error if the user is able to implement FromIterator for that type). That could either be done manually inside the specific #[on_unimplemented] attribute invocation or the attribute's behaviour could be changed in the compiler to add a help message instead of replacing the original error message. I personally don't have much of a preference either way.

@Manishearth
Copy link
Member Author

@P1start It is done manually, a {Self} placeholder can be used (see the fake "FromIterator" in the test)

@Manishearth
Copy link
Member Author

Oh, wait, I see, you want a placeholder for the trait name. I guess that can be done manually (or I can add a {trait} format arg, though that's just equivalent to directly writing path::to::Trait<{A}, {B}, {C}>). Got any idea for what the error for FromIterator should look like?

@Manishearth Manishearth force-pushed the trait-error branch 2 times, most recently from 82295a3 to dc0de42 Compare January 11, 2015 04:20
@Manishearth
Copy link
Member Author

@huon I made it a note, and added a lint/test.

@@ -88,12 +154,20 @@ pub fn report_selection_error<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
infcx.resolve_type_vars_if_possible(trait_predicate);
if !trait_predicate.references_error() {
let trait_ref = trait_predicate.to_poly_trait_ref();
// Check if it has a custom "#[on_unimplemented]" error message,
// report with that message if it does
let custom_note = report_on_unimplemented(infcx, &*trait_ref.0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably best run after the main error message, just in case the span_errs inside it are triggered, so that the output has a slightly more sensible order.

let custom_note = report_on_unimplemented(infcx, &*trait_ref.0,
obligation.cause.span);
if let Some(s) = custom_note {
infcx.tcx.sess.span_note(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation


#[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
//~^ ERROR there is no type parameter C on trait BadAnnotation2
trait BadAnnotation2<A,B> {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a test with an illegal thing, like {}?

@Manishearth Manishearth force-pushed the trait-error branch 2 times, most recently from 2f5767f to 02d0a8b Compare January 11, 2015 20:14
@bors bors merged commit 02d0a8b into rust-lang:master Jan 12, 2015
@Manishearth Manishearth deleted the trait-error branch January 12, 2015 06:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Custom errors for well-known traits
9 participants