Skip to content

Commit 996e26c

Browse files
committed
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
2 parents fc323ba + 5ae3801 commit 996e26c

File tree

4 files changed

+38
-26
lines changed

4 files changed

+38
-26
lines changed

src/librustc/traits/on_unimplemented.rs

+28-16
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
131131
parse_error(tcx, item.span,
132132
"this attribute must have a valid value",
133133
"expected value here",
134-
Some(r#"eg `#[rustc_on_unimplemented = "foo"]`"#));
134+
Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#));
135135
}
136136

137137
if errored {
@@ -170,7 +170,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
170170
return Err(parse_error(tcx, attr.span,
171171
"`#[rustc_on_unimplemented]` requires a value",
172172
"value required here",
173-
Some(r#"eg `#[rustc_on_unimplemented = "foo"]`"#)));
173+
Some(r#"eg `#[rustc_on_unimplemented(message="foo")]`"#)));
174174
};
175175
debug!("of_item({:?}/{:?}) = {:?}", trait_def_id, impl_def_id, result);
176176
result
@@ -213,10 +213,13 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedDirective {
213213
}
214214
}
215215

216+
let options: FxHashMap<String, String> = options.into_iter()
217+
.filter_map(|(k, v)| v.as_ref().map(|v| (k.to_owned(), v.to_owned())))
218+
.collect();
216219
OnUnimplementedNote {
217-
label: label.map(|l| l.format(tcx, trait_ref)),
218-
message: message.map(|m| m.format(tcx, trait_ref)),
219-
note: note.map(|n| n.format(tcx, trait_ref)),
220+
label: label.map(|l| l.format(tcx, trait_ref, &options)),
221+
message: message.map(|m| m.format(tcx, trait_ref, &options)),
222+
note: note.map(|n| n.format(tcx, trait_ref, &options)),
220223
}
221224
}
222225
}
@@ -251,24 +254,25 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
251254
Position::ArgumentNamed(s) if s == "Self" => (),
252255
// `{ThisTraitsName}` is allowed
253256
Position::ArgumentNamed(s) if s == name => (),
257+
// `{from_method}` is allowed
258+
Position::ArgumentNamed(s) if s == "from_method" => (),
259+
// `{from_desugaring}` is allowed
260+
Position::ArgumentNamed(s) if s == "from_desugaring" => (),
254261
// So is `{A}` if A is a type parameter
255262
Position::ArgumentNamed(s) => match generics.params.iter().find(|param| {
256263
param.name == s
257264
}) {
258265
Some(_) => (),
259266
None => {
260267
span_err!(tcx.sess, span, E0230,
261-
"there is no parameter \
262-
{} on trait {}",
263-
s, name);
268+
"there is no parameter `{}` on trait `{}`", s, name);
264269
result = Err(ErrorReported);
265270
}
266271
},
267272
// `{:1}` and `{}` are not to be used
268273
Position::ArgumentIs(_) | Position::ArgumentImplicitlyIs(_) => {
269274
span_err!(tcx.sess, span, E0231,
270-
"only named substitution \
271-
parameters are allowed");
275+
"only named substitution parameters are allowed");
272276
result = Err(ErrorReported);
273277
}
274278
}
@@ -280,7 +284,8 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
280284

281285
pub fn format(&self,
282286
tcx: TyCtxt<'a, 'gcx, 'tcx>,
283-
trait_ref: ty::TraitRef<'tcx>)
287+
trait_ref: ty::TraitRef<'tcx>,
288+
options: &FxHashMap<String, String>)
284289
-> String
285290
{
286291
let name = tcx.item_name(trait_ref.def_id);
@@ -296,6 +301,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
296301
let name = param.name.to_string();
297302
Some((name, value))
298303
}).collect::<FxHashMap<String, String>>();
304+
let empty_string = String::new();
299305

300306
let parser = Parser::new(&self.0, None);
301307
parser.map(|p| {
@@ -308,14 +314,20 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
308314
&trait_str
309315
}
310316
None => {
311-
bug!("broken on_unimplemented {:?} for {:?}: \
312-
no argument matching {:?}",
313-
self.0, trait_ref, s)
317+
if let Some(val) = options.get(s) {
318+
val
319+
} else if s == "from_desugaring" || s == "from_method" {
320+
// don't break messages using these two arguments incorrectly
321+
&empty_string
322+
} else {
323+
bug!("broken on_unimplemented {:?} for {:?}: \
324+
no argument matching {:?}",
325+
self.0, trait_ref, s)
326+
}
314327
}
315328
},
316329
_ => {
317-
bug!("broken on_unimplemented {:?} - bad \
318-
format arg", self.0)
330+
bug!("broken on_unimplemented {:?} - bad format arg", self.0)
319331
}
320332
}
321333
}

src/test/ui/error-codes/E0232.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0232]: `#[rustc_on_unimplemented]` requires a value
44
LL | #[rustc_on_unimplemented]
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^ value required here
66
|
7-
= note: eg `#[rustc_on_unimplemented = "foo"]`
7+
= note: eg `#[rustc_on_unimplemented(message="foo")]`
88

99
error: aborting due to previous error
1010

src/test/ui/on-unimplemented/bad-annotation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ trait BadAnnotation1
2828
{}
2929

3030
#[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
31-
//~^ ERROR there is no parameter C on trait BadAnnotation2
31+
//~^ ERROR there is no parameter `C` on trait `BadAnnotation2`
3232
trait BadAnnotation2<A,B>
3333
{}
3434

src/test/ui/on-unimplemented/bad-annotation.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ error[E0232]: `#[rustc_on_unimplemented]` requires a value
44
LL | #[rustc_on_unimplemented] //~ ERROR `#[rustc_on_unimplemented]` requires a value
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^ value required here
66
|
7-
= note: eg `#[rustc_on_unimplemented = "foo"]`
7+
= note: eg `#[rustc_on_unimplemented(message="foo")]`
88

9-
error[E0230]: there is no parameter C on trait BadAnnotation2
9+
error[E0230]: there is no parameter `C` on trait `BadAnnotation2`
1010
--> $DIR/bad-annotation.rs:30:1
1111
|
1212
LL | #[rustc_on_unimplemented = "Unimplemented trait error on `{Self}` with params `<{A},{B},{C}>`"]
@@ -24,31 +24,31 @@ error[E0232]: this attribute must have a valid value
2424
LL | #[rustc_on_unimplemented(lorem="")]
2525
| ^^^^^^^^ expected value here
2626
|
27-
= note: eg `#[rustc_on_unimplemented = "foo"]`
27+
= note: eg `#[rustc_on_unimplemented(message="foo")]`
2828

2929
error[E0232]: this attribute must have a valid value
3030
--> $DIR/bad-annotation.rs:44:26
3131
|
3232
LL | #[rustc_on_unimplemented(lorem(ipsum(dolor)))]
3333
| ^^^^^^^^^^^^^^^^^^^ expected value here
3434
|
35-
= note: eg `#[rustc_on_unimplemented = "foo"]`
35+
= note: eg `#[rustc_on_unimplemented(message="foo")]`
3636

3737
error[E0232]: this attribute must have a valid value
3838
--> $DIR/bad-annotation.rs:48:39
3939
|
4040
LL | #[rustc_on_unimplemented(message="x", message="y")]
4141
| ^^^^^^^^^^^ expected value here
4242
|
43-
= note: eg `#[rustc_on_unimplemented = "foo"]`
43+
= note: eg `#[rustc_on_unimplemented(message="foo")]`
4444

4545
error[E0232]: this attribute must have a valid value
4646
--> $DIR/bad-annotation.rs:52:39
4747
|
4848
LL | #[rustc_on_unimplemented(message="x", on(desugared, message="y"))]
4949
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here
5050
|
51-
= note: eg `#[rustc_on_unimplemented = "foo"]`
51+
= note: eg `#[rustc_on_unimplemented(message="foo")]`
5252

5353
error[E0232]: empty `on`-clause in `#[rustc_on_unimplemented]`
5454
--> $DIR/bad-annotation.rs:56:26
@@ -62,15 +62,15 @@ error[E0232]: this attribute must have a valid value
6262
LL | #[rustc_on_unimplemented(on="x", message="y")]
6363
| ^^^^^^ expected value here
6464
|
65-
= note: eg `#[rustc_on_unimplemented = "foo"]`
65+
= note: eg `#[rustc_on_unimplemented(message="foo")]`
6666

6767
error[E0232]: this attribute must have a valid value
6868
--> $DIR/bad-annotation.rs:67:40
6969
|
7070
LL | #[rustc_on_unimplemented(on(desugared, on(desugared, message="x")), message="y")]
7171
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected value here
7272
|
73-
= note: eg `#[rustc_on_unimplemented = "foo"]`
73+
= note: eg `#[rustc_on_unimplemented(message="foo")]`
7474

7575
error: aborting due to 10 previous errors
7676

0 commit comments

Comments
 (0)