-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Restrict what symbols can be used in `#[diagnostic::on_unimplemented]…
…` format strings This commit restricts what symbols can be used in a format string for any option of the `diagnostic::on_unimplemented` attribute. We previously allowed all the ad-hoc options supported by the internal `#[rustc_on_unimplemented]` attribute. For the stable attribute we only want to support generic parameter names and `{Self}` as parameters. For any other parameter an warning is emitted and the parameter is replaced by the literal parameter string, so for example `{integer}` turns into `{integer}`. This follows the general design of attributes in the `#[diagnostic]` attribute namespace, that any syntax "error" is treated as warning and subsequently ignored.
- Loading branch information
Showing
6 changed files
with
524 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
...ostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 1,67 @@ | ||
#![feature(diagnostic_namespace)] | ||
|
||
#[diagnostic::on_unimplemented( | ||
on(_Self = "&str"), | ||
//~^WARN malformed `on_unimplemented` attribute | ||
//~|WARN malformed `on_unimplemented` attribute | ||
message = "trait has `{Self}` and `{T}` as params", | ||
label = "trait has `{Self}` and `{T}` as params", | ||
note = "trait has `{Self}` and `{T}` as params", | ||
parent_label = "in this scope", | ||
//~^WARN malformed `on_unimplemented` attribute | ||
//~|WARN malformed `on_unimplemented` attribute | ||
append_const_msg | ||
//~^WARN malformed `on_unimplemented` attribute | ||
//~|WARN malformed `on_unimplemented` attribute | ||
)] | ||
trait Foo<T> {} | ||
|
||
#[diagnostic::on_unimplemented = "Message"] | ||
//~^WARN malformed `on_unimplemented` attribute | ||
//~|WARN malformed `on_unimplemented` attribute | ||
trait Bar {} | ||
|
||
#[diagnostic::on_unimplemented(message = "Not allowed to apply it on a impl")] | ||
//~^WARN #[diagnostic::on_unimplemented]` can only be applied to trait definitions | ||
impl Bar for i32 {} | ||
|
||
// cannot use special rustc_on_unimplement symbols | ||
// in the format string | ||
#[diagnostic::on_unimplemented( | ||
message = "{from_desugaring}{direct}{cause}{integral}{integer}", | ||
//~^WARN there is no parameter `from_desugaring` on trait `Baz` | ||
//~|WARN there is no parameter `from_desugaring` on trait `Baz` | ||
//~|WARN there is no parameter `direct` on trait `Baz` | ||
//~|WARN there is no parameter `direct` on trait `Baz` | ||
//~|WARN there is no parameter `cause` on trait `Baz` | ||
//~|WARN there is no parameter `cause` on trait `Baz` | ||
//~|WARN there is no parameter `integral` on trait `Baz` | ||
//~|WARN there is no parameter `integral` on trait `Baz` | ||
//~|WARN there is no parameter `integer` on trait `Baz` | ||
//~|WARN there is no parameter `integer` on trait `Baz` | ||
label = "{float}{_Self}{crate_local}{Trait}{ItemContext}" | ||
//~^WARN there is no parameter `float` on trait `Baz` | ||
//~|WARN there is no parameter `float` on trait `Baz` | ||
//~|WARN there is no parameter `_Self` on trait `Baz` | ||
//~|WARN there is no parameter `_Self` on trait `Baz` | ||
//~|WARN there is no parameter `crate_local` on trait `Baz` | ||
//~|WARN there is no parameter `crate_local` on trait `Baz` | ||
//~|WARN there is no parameter `Trait` on trait `Baz` | ||
//~|WARN there is no parameter `Trait` on trait `Baz` | ||
//~|WARN there is no parameter `ItemContext` on trait `Baz` | ||
//~|WARN there is no parameter `ItemContext` on trait `Baz` | ||
)] | ||
trait Baz {} | ||
|
||
fn takes_foo(_: impl Foo<i32>) {} | ||
fn takes_bar(_: impl Bar) {} | ||
fn takes_baz(_: impl Baz) {} | ||
|
||
fn main() { | ||
takes_foo(()); | ||
//~^ERROR trait has `()` and `i32` as params | ||
takes_bar(()); | ||
//~^ERROR the trait bound `(): Bar` is not satisfied | ||
takes_baz(()); | ||
//~^ERROR {from_desugaring}{direct}{cause}{integral}{integer} | ||
} |
Oops, something went wrong.