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

Projects
None yet
10 participants
@Manishearth
Copy link
Member

Manishearth commented Jan 10, 2015

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Jan 10, 2015

👯

@Manishearth Manishearth force-pushed the Manishearth:trait-error branch 2 times, most recently from 6665642 to 6f0419f Jan 10, 2015

@freebroccolo

This comment has been minimized.

Copy link
Contributor

freebroccolo commented Jan 10, 2015

Awesome :] This should be very useful.

@Manishearth Manishearth force-pushed the Manishearth:trait-error branch from 6f0419f to 6cde8cf Jan 10, 2015

@sfackler

This comment has been minimized.

Copy link
Member

sfackler commented Jan 10, 2015

Cool!

@flaper87

This comment has been minimized.

Copy link
Contributor

flaper87 commented Jan 10, 2015

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 {

This comment has been minimized.

@huonw

huonw Jan 11, 2015

Member

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

if item.check_name("on_unimplemented") {
match item.meta().node {
ast::MetaItem_::MetaNameValue(_, ref lit) => match lit.node {
ast::Lit_::LitStr(ref i, _) => {

This comment has been minimized.

@huonw

huonw Jan 11, 2015

Member

What's the name i meant to represent?

This comment has been minimized.

@Manishearth

Manishearth Jan 11, 2015

Author Member

An interned string. Updated.

None => {
infcx.tcx.sess
.span_err(item.meta().span,
format!("There is no type parameter \

This comment has been minimized.

@huonw

huonw Jan 11, 2015

Member

Error messages conventionally start with a lower-case letter.

(They're printed like error: There is no type ..., and that looks a bit peculiar.)

This comment has been minimized.

@Manishearth

Manishearth Jan 11, 2015

Author Member

Fixed

@huonw

This comment has been minimized.

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 Manishearth force-pushed the Manishearth:trait-error branch from 6cde8cf to c671926 Jan 11, 2015

@Manishearth

This comment has been minimized.

Copy link
Member Author

Manishearth commented Jan 11, 2015

@huonw fixed the other issues

@Manishearth Manishearth force-pushed the Manishearth:trait-error branch from c671926 to de683c4 Jan 11, 2015

@P1start

This comment has been minimized.

Copy link
Contributor

P1start 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

This comment has been minimized.

Copy link
Member Author

Manishearth commented Jan 11, 2015

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

@Manishearth

This comment has been minimized.

Copy link
Member Author

Manishearth commented Jan 11, 2015

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 Manishearth:trait-error branch 2 times, most recently from 82295a3 to dc0de42 Jan 11, 2015

@Manishearth

This comment has been minimized.

Copy link
Member Author

Manishearth commented Jan 11, 2015

@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);

This comment has been minimized.

@huonw

huonw Jan 11, 2015

Member

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.

Some(val) => Some(val.as_slice()),
None => {
infcx.tcx.sess
.span_err(item.meta().span,

This comment has been minimized.

@huonw

huonw Jan 11, 2015

Member

Hm, I suspect these spans are useless for the most part (I imagine they are usually cross-crate, and so unable to point to the actual attribute in question). It may be better to either use obligation.cause.span always, or detect if item.meta().span is syntax::codemap::DUMMY_SP or not and default to obligation.cause.span when it is DUMMY_SP.

This comment has been minimized.

@huonw

huonw Jan 11, 2015

Member

(In fact, thinking about it now, it may also make sense to make these error messages clearer that they are talking about the on_unimplemented message, not the code you're calling, something like invalid #[on_unimplemented] format: there is no....)

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

This comment has been minimized.

@Ms2ger

Ms2ger Jan 11, 2015

Contributor

Indentation

@Manishearth Manishearth force-pushed the Manishearth:trait-error branch from f0e6e8d to ad7e33e Jan 11, 2015


#[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> {}

This comment has been minimized.

@nikomatsakis

nikomatsakis Jan 11, 2015

Contributor

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

@Manishearth Manishearth force-pushed the Manishearth:trait-error branch 2 times, most recently from 2f5767f to 02d0a8b Jan 11, 2015

@nrc

This comment has been minimized.

Copy link

nrc commented on 02d0a8b Jan 12, 2015

r=nikomatsakis

@bors

This comment has been minimized.

Copy link
Contributor

bors commented on 02d0a8b Jan 12, 2015

saw approval from nikomatsakis
at Manishearth@02d0a8b

This comment has been minimized.

Copy link
Contributor

bors replied Jan 12, 2015

merging Manishearth/rust/trait-error = 02d0a8b into auto

This comment has been minimized.

Copy link
Contributor

bors replied Jan 12, 2015

status: {"merge_sha": "0aec4db1c09574da2f30e3844de6d252d79d4939"}

This comment has been minimized.

Copy link
Contributor

bors replied Jan 12, 2015

Manishearth/rust/trait-error = 02d0a8b merged ok, testing candidate = 0aec4db

This comment has been minimized.

Copy link
Contributor

bors replied Jan 12, 2015

fast-forwarding master to auto = 0aec4db

This comment has been minimized.

Copy link
Contributor

bors replied Jan 12, 2015

fast-forwarding master to auto = 0aec4db

bors added a commit that referenced this pull request Jan 12, 2015

@bors bors merged commit 02d0a8b into rust-lang:master Jan 12, 2015

2 checks passed

continuous-integration/travis-ci The Travis CI build passed
Details
default all tests passed

@Manishearth Manishearth deleted the Manishearth:trait-error branch Jan 12, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.