1
Fork 0

Auto merge of #53295 - estebank:on-unimplemented, r=michaelwoerister

Various changes to `rustc_on_unimplemented`

- Add `from_method` and `from_desugaring` to formatting options
- Change wording of errors slightly
This commit is contained in:
bors 2018-08-16 06:34:13 +00:00
commit 996e26c23f
4 changed files with 38 additions and 26 deletions

View file

@ -131,7 +131,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
parse_error(tcx, item.span,
"this attribute must have a valid value",
"expected value here",
Some(r#"eg `#[rustc_on_unimplemented = "foo"]`"#));
Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#));
}
if errored {
@ -170,7 +170,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
return Err(parse_error(tcx, attr.span,
"`#[rustc_on_unimplemented]` requires a value",
"value required here",
Some(r#"eg `#[rustc_on_unimplemented = "foo"]`"#)));
Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#)));
};
debug!("of_item({:?}/{:?}) = {:?}", trait_def_id, impl_def_id, result);
result
@ -213,10 +213,13 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
}
}
let options: FxHashMap<String, String> = options.into_iter()
.filter_map(|(k, v)| v.as_ref().map(|v| (k.to_owned(), v.to_owned())))
.collect();
OnUnimplementedNote {
label: label.map(|l| l.format(tcx, trait_ref)),
message: message.map(|m| m.format(tcx, trait_ref)),
note: note.map(|n| n.format(tcx, trait_ref)),
label: label.map(|l| l.format(tcx, trait_ref, &options)),
message: message.map(|m| m.format(tcx, trait_ref, &options)),
note: note.map(|n| n.format(tcx, trait_ref, &options)),
}
}
}
@ -251,6 +254,10 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
Position::ArgumentNamed(s) if s == "Self" => (),
// `{ThisTraitsName}` is allowed
Position::ArgumentNamed(s) if s == name => (),
// `{from_method}` is allowed
Position::ArgumentNamed(s) if s == "from_method" => (),
// `{from_desugaring}` is allowed
Position::ArgumentNamed(s) if s == "from_desugaring" => (),
// So is `{A}` if A is a type parameter
Position::ArgumentNamed(s) => match generics.params.iter().find(|param| {
param.name == s
@ -258,17 +265,14 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
Some(_) => (),
None => {
span_err!(tcx.sess, span, E0230,
"there is no parameter \
{} on trait {}",
s, name);
"there is no parameter `{}` on trait `{}`", s, name);
result = Err(ErrorReported);
}
},
// `{:1}` and `{}` are not to be used
Position::ArgumentIs(_) | Position::ArgumentImplicitlyIs(_) => {
span_err!(tcx.sess, span, E0231,
"only named substitution \
parameters are allowed");
"only named substitution parameters are allowed");
result = Err(ErrorReported);
}
}
@ -280,7 +284,8 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
pub fn format(&self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
trait_ref: ty::TraitRef<'tcx>)
trait_ref: ty::TraitRef<'tcx>,
options: &FxHashMap<String, String>)
-> String
{
let name = tcx.item_name(trait_ref.def_id);
@ -296,6 +301,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
let name = param.name.to_string();
Some((name, value))
}).collect::<FxHashMap<String, String>>();
let empty_string = String::new();
let parser = Parser::new(&self.0, None);
parser.map(|p| {
@ -308,14 +314,20 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
&trait_str
}
None => {
bug!("broken on_unimplemented {:?} for {:?}: \
no argument matching {:?}",
self.0, trait_ref, s)
if let Some(val) = options.get(s) {
val
} else if s == "from_desugaring" || s == "from_method" {
// don't break messages using these two arguments incorrectly
&empty_string
} else {
bug!("broken on_unimplemented {:?} for {:?}: \
no argument matching {:?}",
self.0, trait_ref, s)
}
}
},
_ => {
bug!("broken on_unimplemented {:?} - bad \
format arg", self.0)
bug!("broken on_unimplemented {:?} - bad format arg", self.0)
}
}
}

View file

@ -4,7 +4,7 @@ error[E0232]: `#[rustc_on_unimplemented]` requires a value
LL | #[rustc_on_unimplemented]
| ^^^^^^^^^^^^^^^^^^^^^^^^^ value required here
|
= note: eg `#[rustc_on_unimplemented = "foo"]`
= note: eg `#[rustc_on_unimplemented(message="foo")]`
error: aborting due to previous error

View file

@ -28,7 +28,7 @@ trait BadAnnotation1
{}
#[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
//~^ ERROR there is no parameter C on trait BadAnnotation2
//~^ ERROR there is no parameter `C` on trait `BadAnnotation2`
trait BadAnnotation2<A,B>
{}

View file

@ -4,9 +4,9 @@ error[E0232]: `#[rustc_on_unimplemented]` requires a value
LL | #[rustc_on_unimplemented] //~ ERROR `#[rustc_on_unimplemented]` requires a value
| ^^^^^^^^^^^^^^^^^^^^^^^^^ value required here
|
= note: eg `#[rustc_on_unimplemented = "foo"]`
= note: eg `#[rustc_on_unimplemented(message="foo")]`
error[E0230]: there is no parameter C on trait BadAnnotation2
error[E0230]: there is no parameter `C` on trait `BadAnnotation2`
--> $DIR/bad-annotation.rs:30:1
|
LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
@ -24,7 +24,7 @@ error[E0232]: this attribute must have a valid value
LL | #[rustc_on_unimplemented(lorem="")]
| ^^^^^^^^ expected value here
|
= note: eg `#[rustc_on_unimplemented = "foo"]`
= note: eg `#[rustc_on_unimplemented(message="foo")]`
error[E0232]: this attribute must have a valid value
--> $DIR/bad-annotation.rs:44:26
@ -32,7 +32,7 @@ error[E0232]: this attribute must have a valid value
LL | #[rustc_on_unimplemented(lorem(ipsum(dolor)))]
| ^^^^^^^^^^^^^^^^^^^ expected value here
|
= note: eg `#[rustc_on_unimplemented = "foo"]`
= note: eg `#[rustc_on_unimplemented(message="foo")]`
error[E0232]: this attribute must have a valid value
--> $DIR/bad-annotation.rs:48:39
@ -40,7 +40,7 @@ error[E0232]: this attribute must have a valid value
LL | #[rustc_on_unimplemented(message="x", message="y")]
| ^^^^^^^^^^^ expected value here
|
= note: eg `#[rustc_on_unimplemented = "foo"]`
= note: eg `#[rustc_on_unimplemented(message="foo")]`
error[E0232]: this attribute must have a valid value
--> $DIR/bad-annotation.rs:52:39
@ -48,7 +48,7 @@ error[E0232]: this attribute must have a valid value
LL | #[rustc_on_unimplemented(message="x", on(desugared, message="y"))]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here
|
= note: eg `#[rustc_on_unimplemented = "foo"]`
= note: eg `#[rustc_on_unimplemented(message="foo")]`
error[E0232]: empty `on`-clause in `#[rustc_on_unimplemented]`
--> $DIR/bad-annotation.rs:56:26
@ -62,7 +62,7 @@ error[E0232]: this attribute must have a valid value
LL | #[rustc_on_unimplemented(on="x", message="y")]
| ^^^^^^ expected value here
|
= note: eg `#[rustc_on_unimplemented = "foo"]`
= note: eg `#[rustc_on_unimplemented(message="foo")]`
error[E0232]: this attribute must have a valid value
--> $DIR/bad-annotation.rs:67:40
@ -70,7 +70,7 @@ error[E0232]: this attribute must have a valid value
LL | #[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here
|
= note: eg `#[rustc_on_unimplemented = "foo"]`
= note: eg `#[rustc_on_unimplemented(message="foo")]`
error: aborting due to 10 previous errors