Expand description
Customize the error message when a trait is not implemented.
It must be used on the declaration of said trait.
§Syntax
RustcOnUnimplementedAttribute ->
rustc_on_unimplemented ( ( Directive ),+ )
Directive ->
on ( Filter, ( DirectiveOption ),+ )
| ( DirectiveOption ),*
DirectiveOption ->
message = STRING_LITERAL
| label = STRING_LITERAL
| note = STRING_LITERAL
Filter ->
FilterAll
| FilterAny
| FilterNot
| FilterOption
FilterAll ->
all ( ( Filter ),* )
FilterAny ->
any ( ( Filter ),* )
FilterNot ->
not ( Filter )
FilterOption ->
crate_local
| direct
| from_desugaring ( = STRING_LITERAL )?
| cause = STRING_LITERAL
| IDENTIFIER = STRING_LITERAL
The following keys have the given meaning. At least one must be specified.
on- filters the application of the attribute. See #Filters.message— The text for the top level error message. May only be specified at most once.label— The text for the label shown inline in the broken code in the error message. May only be specified at most once.note— Provides additional note(s)
message, label, and note are available with the diagnostic::on_unimplemented
attribute. If possible, use that instead.
§Example
//@ dont-require-annotations: ERROR
//@ compile-flags: --crate-type lib -Z ui-testing=no
#![feature(rustc_attrs)]
#[rustc_on_unimplemented(
message = "cannot add `{Rhs}` to `{Self}`",
label = "no implementation for `{Self} + {Rhs}`",
)]
pub trait MyAdd<Rhs = Self> {
fn add(self, rhs: Rhs) -> Self;
}
fn main() {
MyAdd::add(42_u8, 42.0);
}produces:
error[E0277]: cannot add `_` to `u8`
--> $DIR/rustc_on_unimplemented.rs:15:16
|
15 | MyAdd::add(42_u8, 42.0);
| ---------- ^^^^^ no implementation for `u8 + _`
| |
| required by a bound introduced by this call
|
= help: the trait `MyAdd<_>` is not implemented for `u8`
help: this trait has no implementations, consider adding one
--> $DIR/rustc_on_unimplemented.rs:10:1
|
10 | pub trait MyAdd<Rhs = Self> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.§Filters
To allow more targeted error messages, it is possible to filter the
application of these keys with on.
You can filter on the following boolean flags:
crate_local: whether the code causing the trait bound to not be fulfilled is part of the user’s crate. This is used to avoid suggesting code changes that would require modifying a dependency.direct: whether this is a user-specified rather than derived obligation.from_desugaring: whether we are in some kind of desugaring, like?or atryblock for example. This flag can also be matched on, see below.
You can match on the following names and values, using name = "value":
cause: Match against one variant of theObligationCauseCodeenum. Only"MainFunctionType"is supported.from_desugaring: Match against a particular variant of theDesugaringKindenum. The desugaring is identified by its variant name, for example"QuestionMark"for?desugaring, or"TryBlock"fortryblocks.Selfand any generic arguments of the trait, likeSelf = "alloc::string::String"orRhs="i32".
The compiler provides several values to match on, for example:
- the self_ty, pretty printed with and without type arguments resolved.
"{integral}", if self_ty is an integral of which the type is known."[]","[{ty}]","[{ty}; _]","[{ty}; $N]"when applicable.- references to said slices and arrays.
"fn","unsafe fn"or"#[target_feature] fn"when self is a function."{integer}"and"{float}"if the type is a number but we haven’t inferred it yet."{struct}","{enum}"and"{union}"to match self as an ADT- combinations of the above, like
"[{integral}; _]".
//@ dont-require-annotations: ERROR
//@ compile-flags: --crate-type lib -Z ui-testing=no
#![feature(rustc_attrs)]
#[rustc_on_unimplemented(
on(all(Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",),
on(all(Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",),
message = "cannot add `{Rhs}` to `{Self}`",
label = "no implementation for `{Self} + {Rhs}`"
)]
pub trait MyAdd<Rhs = Self> {
fn add(self, rhs: Rhs) -> Self;
}
fn main() {
MyAdd::add(42_u8, 42.0);
}produces:
error[E0277]: cannot add `_` to `u8`
--> $DIR/rustc_on_unimplemented_filter.rs:17:16
|
17 | MyAdd::add(42_u8, 42.0);
| ---------- ^^^^^ no implementation for `u8 + _`
| |
| required by a bound introduced by this call
|
= help: the trait `MyAdd<_>` is not implemented for `u8`
help: this trait has no implementations, consider adding one
--> $DIR/rustc_on_unimplemented_filter.rs:12:1
|
12 | pub trait MyAdd<Rhs = Self> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.§Formatting
The string literals are format strings that accept parameters wrapped in braces - positional and listed parameters are not accepted. The following parameter names are valid:
Selfand all generic parameters of the trait.This: the name of the trait the attribute is on, without generics.This:path: the full path of the trait the attribute is on, with unresolved generics.This:resolved: the full path of the trait the attribute is on, with resolved generics. Additionally, this will “sugar” theFn(...)traits.ItemContext: the kind ofhir::Nodewe’re in, things like"an async block","a function","an async function", etc.
//@ dont-require-annotations: ERROR
//@ compile-flags: --crate-type lib -Z ui-testing=no
#![feature(rustc_attrs)]
#[rustc_on_unimplemented(message = "Self = `{Self}`, \n \
T = `{T}`, this = `{This}`, path = `{This:path}`, \n \
resolved = `{This:resolved}`, context = `{ItemContext}`")]
pub trait From<T>: Sized {
fn from(x: T) -> Self;
}
fn main() {
let x: i8 = From::from(42_i32);
}produces:
error[E0277]: Self = `i8`,
T = `i32`, this = `From`, path = `From<T>`,
resolved = `From<i32>`, context = `a function`
--> $DIR/rustc_on_unimplemented_format.rs:14:28
|
14 | let x: i8 = From::from(42_i32);
| ---------- ^^^^^^ the trait `From<i32>` is not implemented for `i8`
| |
| required by a bound introduced by this call
|
help: this trait has no implementations, consider adding one
--> $DIR/rustc_on_unimplemented_format.rs:9:1
|
9 | pub trait From<T>: Sized {
| ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.