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:
commit
996e26c23f
4 changed files with 38 additions and 26 deletions
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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>
|
||||
{}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue