mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
Auto merge of #155662 - mejrs:this_the_thing, r=petrochenkov
Permit `{This}` in diagnostic attribute format literals
My motivation was that yesterday I wanted to write something like this and reference `$name` in the string literal.
```rust
pub mod sym {
// stuff here
}
macro_rules! my_macro {
($name:ident $(,)?) => {{
#[diagnostic::on_unknown(
message = "this is not present in symbol table",
note = "you must add it to rustc_span::symbol::symbol!"
)]
use sym::$name as name;
// ...
}}
}
```
That is (as far as I can tell) impossible or at least very unergonomic. This adds the ability to just reference the name of the item the attribute is on. I imagine that's useful for use inside macros generally, so it's also added for some other attributes.
The affected attributes are all unstable, it is not implemented for diagnostic::on_unimplemented (will do in its own PR).
Note that `{This}` is already usable in `#[rustc_on_unimplemented]`, so this does not implement it but just enables some more.
This PR also migrates one lint away from AttributeLintKind, and improves the messages for that lint.
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
Directive, FilterFormatString, Flag, FormatArg, FormatString, LitOrArg, Name, NameValue,
|
||||
OnUnimplementedCondition, Piece, Predicate,
|
||||
};
|
||||
use rustc_hir::lints::FormatWarning;
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_parse_format::{
|
||||
Argument, FormatSpec, ParseError, ParseMode, Parser, Piece as RpfPiece, Position,
|
||||
@@ -19,9 +18,8 @@
|
||||
|
||||
use crate::context::{AcceptContext, Stage};
|
||||
use crate::errors::{
|
||||
DisallowedPlaceholder, DisallowedPositionalArgument, IgnoredDiagnosticOption,
|
||||
InvalidFormatSpecifier, MalFormedDiagnosticAttributeLint, MissingOptionsForDiagnosticAttribute,
|
||||
NonMetaItemDiagnosticAttribute, WrappedParserError,
|
||||
FormatWarning, IgnoredDiagnosticOption, MalFormedDiagnosticAttributeLint,
|
||||
MissingOptionsForDiagnosticAttribute, NonMetaItemDiagnosticAttribute, WrappedParserError,
|
||||
};
|
||||
use crate::parser::{ArgParser, MetaItemListParser, MetaItemOrLitParser, MetaItemParser};
|
||||
|
||||
@@ -88,6 +86,29 @@ fn allowed_options(&self) -> &'static str {
|
||||
Self::DiagnosticOnUnmatchArgs => DEFAULT,
|
||||
}
|
||||
}
|
||||
|
||||
fn allowed_format_arguments(&self) -> &'static str {
|
||||
match self {
|
||||
Self::RustcOnUnimplemented => {
|
||||
"see <https://rustc-dev-guide.rust-lang.org/diagnostics.html#rustc_on_unimplemented> for allowed format arguments"
|
||||
}
|
||||
Self::DiagnosticOnUnimplemented => {
|
||||
"only `Self` and generics of the trait are allowed as a format argument"
|
||||
}
|
||||
Self::DiagnosticOnConst => {
|
||||
"only `Self` and generics of the implementation are allowed as a format argument"
|
||||
}
|
||||
Self::DiagnosticOnMove => {
|
||||
"only `This`, `Self` and generics of the type are allowed as a format argument"
|
||||
}
|
||||
Self::DiagnosticOnUnknown => {
|
||||
"only `This` is allowed as a format argument, referring to the failed import"
|
||||
}
|
||||
Self::DiagnosticOnUnmatchArgs => {
|
||||
"only `This` is allowed as a format argument, referring to the macro's name"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn merge_directives<S: Stage>(
|
||||
@@ -257,22 +278,13 @@ fn parse_directive_items<'p, S: Stage>(
|
||||
match parse_format_string(input.name, snippet, input.span, mode) {
|
||||
Ok((f, warnings)) => {
|
||||
for warning in warnings {
|
||||
let (FormatWarning::InvalidSpecifier { span, .. }
|
||||
| FormatWarning::PositionalArgument { span, .. }
|
||||
| FormatWarning::DisallowedPlaceholder { span }) = warning;
|
||||
let (FormatWarning::InvalidSpecifier { span }
|
||||
| FormatWarning::PositionalArgument { span }
|
||||
| FormatWarning::IndexedArgument { span }
|
||||
| FormatWarning::DisallowedPlaceholder { span, .. }) = warning;
|
||||
cx.emit_dyn_lint(
|
||||
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
|
||||
move |dcx, level| match warning {
|
||||
FormatWarning::PositionalArgument { .. } => {
|
||||
DisallowedPositionalArgument.into_diag(dcx, level)
|
||||
}
|
||||
FormatWarning::InvalidSpecifier { .. } => {
|
||||
InvalidFormatSpecifier.into_diag(dcx, level)
|
||||
}
|
||||
FormatWarning::DisallowedPlaceholder { .. } => {
|
||||
DisallowedPlaceholder.into_diag(dcx, level)
|
||||
}
|
||||
},
|
||||
move |dcx, level| warning.into_diag(dcx, level),
|
||||
span,
|
||||
);
|
||||
}
|
||||
@@ -422,38 +434,74 @@ fn parse_arg(
|
||||
is_source_literal: bool,
|
||||
) -> FormatArg {
|
||||
let span = slice_span(input_span, arg.position_span.clone(), is_source_literal);
|
||||
if matches!(mode, Mode::DiagnosticOnUnknown) {
|
||||
warnings.push(FormatWarning::DisallowedPlaceholder { span });
|
||||
return FormatArg::AsIs(sym::empty_braces);
|
||||
}
|
||||
|
||||
match arg.position {
|
||||
// Something like "hello {name}"
|
||||
Position::ArgumentNamed(name) => match (mode, Symbol::intern(name)) {
|
||||
// Only `#[rustc_on_unimplemented]` can use these
|
||||
(Mode::RustcOnUnimplemented { .. }, sym::ItemContext) => FormatArg::ItemContext,
|
||||
(Mode::RustcOnUnimplemented { .. } | Mode::DiagnosticOnUnmatchArgs, sym::This) => {
|
||||
FormatArg::This
|
||||
(Mode::RustcOnUnimplemented, sym::ItemContext) => FormatArg::ItemContext,
|
||||
|
||||
// Like `{This}`, but sugared.
|
||||
// FIXME(mejrs) maybe rename/rework this or something
|
||||
// if we want to apply this to other attrs?
|
||||
(Mode::RustcOnUnimplemented, sym::Trait) => FormatArg::Trait,
|
||||
|
||||
// Some diagnostic attributes can use `{This}` to refer to the annotated item.
|
||||
// For those that don't, we continue and maybe use it as a generic parameter.
|
||||
//
|
||||
// FIXME(mejrs) `DiagnosticOnUnimplemented` is intentionally not here;
|
||||
// that requires lang approval which is best kept for a standalone PR.
|
||||
(
|
||||
Mode::RustcOnUnimplemented
|
||||
| Mode::DiagnosticOnUnknown
|
||||
| Mode::DiagnosticOnMove
|
||||
| Mode::DiagnosticOnUnmatchArgs,
|
||||
sym::This,
|
||||
) => FormatArg::This,
|
||||
|
||||
// `{Self}`; the self type.
|
||||
// - For trait declaration attributes that's the type that does not implement it.
|
||||
// - for trait impl attributes, the implemented for type.
|
||||
// - For ADT attributes, that's the type (which will be identical to `{This}`)
|
||||
// - For everything else it doesn't make sense.
|
||||
(
|
||||
Mode::RustcOnUnimplemented
|
||||
| Mode::DiagnosticOnUnimplemented
|
||||
| Mode::DiagnosticOnMove
|
||||
| Mode::DiagnosticOnConst,
|
||||
kw::SelfUpper,
|
||||
) => FormatArg::SelfUpper,
|
||||
|
||||
// Generic parameters.
|
||||
// FIXME(mejrs) unfortunately, all the "special" symbols above might fall through,
|
||||
// but at this time we are not aware of what generic parameters the trait actually has.
|
||||
// If we find `ItemContext` or something we have to assume that's a generic parameter.
|
||||
// We lint against that in `check_attr.rs` though.
|
||||
(
|
||||
Mode::RustcOnUnimplemented
|
||||
| Mode::DiagnosticOnUnimplemented
|
||||
| Mode::DiagnosticOnMove
|
||||
| Mode::DiagnosticOnConst,
|
||||
generic_param,
|
||||
) => FormatArg::GenericParam { generic_param, span },
|
||||
|
||||
// Generics are explicitly not allowed, we print those back as is.
|
||||
(Mode::DiagnosticOnUnknown | Mode::DiagnosticOnUnmatchArgs, as_is) => {
|
||||
warnings.push(FormatWarning::DisallowedPlaceholder {
|
||||
span,
|
||||
attr: mode.as_str(),
|
||||
allowed: mode.allowed_format_arguments(),
|
||||
});
|
||||
return FormatArg::AsIs(Symbol::intern(&format!("{{{as_is}}}")));
|
||||
}
|
||||
(Mode::RustcOnUnimplemented { .. }, sym::Trait) => FormatArg::Trait,
|
||||
// Any attribute can use these
|
||||
(_, kw::SelfUpper) => FormatArg::SelfUpper,
|
||||
(_, generic_param) => FormatArg::GenericParam { generic_param, span },
|
||||
},
|
||||
|
||||
// `{:1}` and `{}` are ignored
|
||||
Position::ArgumentIs(idx) => {
|
||||
warnings.push(FormatWarning::PositionalArgument {
|
||||
span,
|
||||
help: format!("use `{{{idx}}}` to print a number in braces"),
|
||||
});
|
||||
warnings.push(FormatWarning::IndexedArgument { span });
|
||||
FormatArg::AsIs(Symbol::intern(&format!("{{{idx}}}")))
|
||||
}
|
||||
Position::ArgumentImplicitlyIs(_) => {
|
||||
warnings.push(FormatWarning::PositionalArgument {
|
||||
span,
|
||||
help: String::from("use `{{}}` to print empty braces"),
|
||||
});
|
||||
warnings.push(FormatWarning::PositionalArgument { span });
|
||||
FormatArg::AsIs(sym::empty_braces)
|
||||
}
|
||||
}
|
||||
@@ -473,7 +521,7 @@ fn warn_on_format_spec(
|
||||
.as_ref()
|
||||
.map(|inner| slice_span(input_span, inner.clone(), is_source_literal))
|
||||
.unwrap_or(input_span);
|
||||
warnings.push(FormatWarning::InvalidSpecifier { span, name: spec.ty.into() })
|
||||
warnings.push(FormatWarning::InvalidSpecifier { span })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -357,23 +357,6 @@ pub(crate) struct MalFormedDiagnosticAttributeLint {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("positional format arguments are not allowed here")]
|
||||
#[help(
|
||||
"only named format arguments with the name of one of the generic types are allowed in this context"
|
||||
)]
|
||||
pub(crate) struct DisallowedPositionalArgument;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("format arguments are not allowed here")]
|
||||
#[help("consider removing this format argument")]
|
||||
pub(crate) struct DisallowedPlaceholder;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("invalid format specifier")]
|
||||
#[help("no format specifier are supported in this position")]
|
||||
pub(crate) struct InvalidFormatSpecifier;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("{$description}")]
|
||||
pub(crate) struct WrappedParserError<'a> {
|
||||
@@ -407,3 +390,34 @@ pub(crate) struct MissingOptionsForDiagnosticAttribute {
|
||||
"only literals are allowed as values for the `message`, `note` and `label` options. These options must be separated by a comma"
|
||||
)]
|
||||
pub(crate) struct NonMetaItemDiagnosticAttribute;
|
||||
|
||||
#[derive(Diagnostic, Clone, Copy)]
|
||||
pub(crate) enum FormatWarning {
|
||||
#[diag("positional arguments are not permitted in diagnostic attributes")]
|
||||
#[help("you can print empty braces by escaping them")]
|
||||
PositionalArgument {
|
||||
#[label("remove this format argument")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
#[diag("indexed format arguments are not permitted in diagnostic attributes")]
|
||||
IndexedArgument {
|
||||
#[label("remove this format argument")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
#[diag("format specifiers are not permitted in diagnostic attributes")]
|
||||
InvalidSpecifier {
|
||||
#[label("remove this format specifier")]
|
||||
span: Span,
|
||||
},
|
||||
|
||||
#[diag("this format argument is not allowed in `#[{$attr}]`")]
|
||||
#[note("{$allowed}")]
|
||||
DisallowedPlaceholder {
|
||||
#[label("remove this format argument")]
|
||||
span: Span,
|
||||
attr: &'static str,
|
||||
allowed: &'static str,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use rustc_data_structures::sync::{DynSend, DynSync};
|
||||
use rustc_error_messages::MultiSpan;
|
||||
use rustc_errors::{Diag, DiagCtxtHandle, Level};
|
||||
pub use rustc_lint_defs::AttributeLintKind;
|
||||
use rustc_lint_defs::LintId;
|
||||
pub use rustc_lint_defs::{AttributeLintKind, FormatWarning};
|
||||
|
||||
use crate::HirId;
|
||||
|
||||
|
||||
@@ -658,13 +658,6 @@ pub enum AttributeLintKind {
|
||||
UnexpectedCfgValue((Symbol, Span), Option<(Symbol, Span)>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, HashStable_Generic)]
|
||||
pub enum FormatWarning {
|
||||
PositionalArgument { span: Span, help: String },
|
||||
InvalidSpecifier { name: String, span: Span },
|
||||
DisallowedPlaceholder { span: Span },
|
||||
}
|
||||
|
||||
pub type RegisteredTools = FxIndexSet<Ident>;
|
||||
|
||||
/// Declares a static item of type `&'static Lint`.
|
||||
|
||||
@@ -201,9 +201,6 @@ fn check_attributes(
|
||||
},
|
||||
Attribute::Parsed(AttributeKind::OnUnimplemented{directive,..}) => {self.check_diagnostic_on_unimplemented(hir_id, directive.as_deref())},
|
||||
Attribute::Parsed(AttributeKind::OnConst{span, ..}) => {self.check_diagnostic_on_const(*span, hir_id, target, item)},
|
||||
Attribute::Parsed(AttributeKind::OnUnmatchArgs { directive, .. }) => {
|
||||
self.check_diagnostic_on_unmatch_args(hir_id, directive.as_deref())
|
||||
},
|
||||
Attribute::Parsed(AttributeKind::OnMove { directive , .. }) => {
|
||||
self.check_diagnostic_on_move(hir_id, directive.as_deref())
|
||||
},
|
||||
@@ -256,6 +253,7 @@ fn check_attributes(
|
||||
| AttributeKind::NoMangle(..)
|
||||
| AttributeKind::NoStd { .. }
|
||||
| AttributeKind::OnUnknown { .. }
|
||||
| AttributeKind::OnUnmatchArgs { .. }
|
||||
| AttributeKind::Optimize(..)
|
||||
| AttributeKind::PanicRuntime
|
||||
| AttributeKind::PatchableFunctionEntry { .. }
|
||||
@@ -562,20 +560,6 @@ fn check_diagnostic_on_const(
|
||||
// ...whose generics would that be, anyway? The traits' or the impls'?
|
||||
}
|
||||
|
||||
/// Checks use of generic formatting parameters in `#[diagnostic::on_unmatch_args]`.
|
||||
fn check_diagnostic_on_unmatch_args(&self, hir_id: HirId, directive: Option<&Directive>) {
|
||||
if let Some(directive) = directive {
|
||||
directive.visit_params(&mut |argument_name, span| {
|
||||
self.tcx.emit_node_span_lint(
|
||||
MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
|
||||
hir_id,
|
||||
span,
|
||||
errors::OnUnmatchArgsMalformedFormatLiterals { name: argument_name },
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks use of generic formatting parameters in `#[diagnostic::on_move]`
|
||||
fn check_diagnostic_on_move(&self, hir_id: HirId, directive: Option<&Directive>) {
|
||||
if let Some(directive) = directive {
|
||||
|
||||
@@ -1303,10 +1303,3 @@ pub(crate) struct UnknownFormatParameterForOnUnimplementedAttr {
|
||||
pub(crate) struct OnMoveMalformedFormatLiterals {
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("unknown parameter `{$name}`")]
|
||||
#[help(r#"use {"`{This}`"} to refer to the macro name"#)]
|
||||
pub(crate) struct OnUnmatchArgsMalformedFormatLiterals {
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
use std::mem;
|
||||
|
||||
use itertools::Itertools;
|
||||
use rustc_ast::{Item, NodeId};
|
||||
use rustc_attr_parsing::AttributeParser;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
|
||||
@@ -879,8 +880,14 @@ fn throw_unresolved_import_error(
|
||||
let (message, label, notes) =
|
||||
// Feature gating for `on_unknown_attr` happens initialization of the field
|
||||
if let Some(directive) = errors[0].1.on_unknown_attr.as_ref().map(|a| &a.directive) {
|
||||
let this = errors.iter().map(|(_import, err)| {
|
||||
|
||||
// Is this unwrap_or reachable?
|
||||
err.segment.unwrap_or(kw::Underscore)
|
||||
}).join(", ");
|
||||
|
||||
let args = FormatArgs {
|
||||
this: paths.join(", "),
|
||||
this,
|
||||
// Unused
|
||||
this_sugared: String::new(),
|
||||
// Unused
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
use rustc_hir::attrs::diagnostic::{ConditionOptions, CustomDiagnostic, FormatArgs};
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::find_attr;
|
||||
pub use rustc_hir::lints::FormatWarning;
|
||||
use rustc_middle::ty::print::PrintTraitRefExt;
|
||||
use rustc_middle::ty::{self, GenericParamDef, GenericParamDefKind};
|
||||
use rustc_span::Symbol;
|
||||
|
||||
@@ -31,17 +31,17 @@ pub trait MultiLine4 {}
|
||||
#[diagnostic::on_unimplemented(message = "here is a big \
|
||||
multiline string \
|
||||
{Self:+}")]
|
||||
//~^ ERROR invalid format specifier [malformed_diagnostic_format_literals]
|
||||
//~^ ERROR format specifiers are not permitted in diagnostic attributes [malformed_diagnostic_format_literals]
|
||||
pub trait MultiLineFmt {}
|
||||
|
||||
#[diagnostic::on_unimplemented(message = "here is a big \
|
||||
multiline string {Self:X}")]
|
||||
//~^ ERROR invalid format specifier [malformed_diagnostic_format_literals]
|
||||
//~^ ERROR format specifiers are not permitted in diagnostic attributes [malformed_diagnostic_format_literals]
|
||||
pub trait MultiLineFmt2 {}
|
||||
|
||||
#[diagnostic::on_unimplemented(message = "here is a big \
|
||||
multiline string {Self:#}")]
|
||||
//~^ ERROR invalid format specifier [malformed_diagnostic_format_literals]
|
||||
//~^ ERROR format specifiers are not permitted in diagnostic attributes [malformed_diagnostic_format_literals]
|
||||
pub trait MultiLineFmt3 {}
|
||||
|
||||
|
||||
@@ -51,5 +51,5 @@ pub trait MultiLineFmt3 {}
|
||||
\
|
||||
\
|
||||
multiline string {Self:?}")]
|
||||
//~^ ERROR invalid format specifier [malformed_diagnostic_format_literals]
|
||||
//~^ ERROR format specifiers are not permitted in diagnostic attributes [malformed_diagnostic_format_literals]
|
||||
pub trait MultiLineFmt4 {}
|
||||
|
||||
@@ -36,37 +36,29 @@ LL | multiline string {unknown}")]
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
|
||||
error: invalid format specifier
|
||||
error: format specifiers are not permitted in diagnostic attributes
|
||||
--> $DIR/multiline_spans.rs:33:47
|
||||
|
|
||||
LL | ... {Self:+}")]
|
||||
| ^^
|
||||
|
|
||||
= help: no format specifier are supported in this position
|
||||
| ^^ remove this format specifier
|
||||
|
||||
error: invalid format specifier
|
||||
error: format specifiers are not permitted in diagnostic attributes
|
||||
--> $DIR/multiline_spans.rs:38:64
|
||||
|
|
||||
LL | ... multiline string {Self:X}")]
|
||||
| ^^
|
||||
|
|
||||
= help: no format specifier are supported in this position
|
||||
| ^^ remove this format specifier
|
||||
|
||||
error: invalid format specifier
|
||||
error: format specifiers are not permitted in diagnostic attributes
|
||||
--> $DIR/multiline_spans.rs:43:27
|
||||
|
|
||||
LL | multiline string {Self:#}")]
|
||||
| ^^
|
||||
|
|
||||
= help: no format specifier are supported in this position
|
||||
| ^^ remove this format specifier
|
||||
|
||||
error: invalid format specifier
|
||||
error: format specifiers are not permitted in diagnostic attributes
|
||||
--> $DIR/multiline_spans.rs:53:27
|
||||
|
|
||||
LL | multiline string {Self:?}")]
|
||||
| ^^
|
||||
|
|
||||
= help: no format specifier are supported in this position
|
||||
| ^^ remove this format specifier
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//@ dont-require-annotations: NOTE
|
||||
#![feature(diagnostic_on_move)]
|
||||
|
||||
#[diagnostic::on_move(
|
||||
@@ -10,6 +11,7 @@
|
||||
#[diagnostic::on_move(
|
||||
message="Foo for {X}",
|
||||
label="Bar for {X}",
|
||||
note = "This is `{This}`",
|
||||
)]
|
||||
struct MyType<X> {
|
||||
_x: X,
|
||||
@@ -21,12 +23,15 @@ fn takes_mytype<X>(_: MyType<X>) {}
|
||||
|
||||
fn main() {
|
||||
let foo = Foo;
|
||||
//~^ NOTE Bar for Foo
|
||||
takes_foo(foo);
|
||||
let bar = foo;
|
||||
//~^ERROR Foo for Foo
|
||||
|
||||
let mytype = MyType { _x: 0 };
|
||||
//~^ NOTE Bar for i32
|
||||
takes_mytype(mytype);
|
||||
let baz = mytype;
|
||||
//~^ERROR Foo for i32
|
||||
//~|NOTE This is `MyType`
|
||||
}
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
error[E0382]: Foo for Foo
|
||||
--> $DIR/on_move_with_format.rs:25:15
|
||||
--> $DIR/on_move_with_format.rs:28:15
|
||||
|
|
||||
LL | let foo = Foo;
|
||||
| --- Bar for Foo
|
||||
LL |
|
||||
LL | takes_foo(foo);
|
||||
| --- value moved here
|
||||
LL | let bar = foo;
|
||||
| ^^^ value used here after move
|
||||
|
|
||||
note: consider changing this parameter type in function `takes_foo` to borrow instead if owning the value isn't necessary
|
||||
--> $DIR/on_move_with_format.rs:18:17
|
||||
--> $DIR/on_move_with_format.rs:20:17
|
||||
|
|
||||
LL | fn takes_foo(_: Foo) {}
|
||||
| --------- ^^^ this parameter takes ownership of the value
|
||||
| |
|
||||
| in this function
|
||||
note: if `Foo` implemented `Clone`, you could clone the value
|
||||
--> $DIR/on_move_with_format.rs:8:1
|
||||
--> $DIR/on_move_with_format.rs:9:1
|
||||
|
|
||||
LL | struct Foo;
|
||||
| ^^^^^^^^^^ consider implementing `Clone` for this type
|
||||
@@ -25,24 +26,26 @@ LL | takes_foo(foo);
|
||||
| --- you could clone this value
|
||||
|
||||
error[E0382]: Foo for i32
|
||||
--> $DIR/on_move_with_format.rs:30:15
|
||||
--> $DIR/on_move_with_format.rs:34:15
|
||||
|
|
||||
LL | let mytype = MyType { _x: 0 };
|
||||
| ------ Bar for i32
|
||||
LL |
|
||||
LL | takes_mytype(mytype);
|
||||
| ------ value moved here
|
||||
LL | let baz = mytype;
|
||||
| ^^^^^^ value used here after move
|
||||
|
|
||||
= note: This is `MyType`
|
||||
note: consider changing this parameter type in function `takes_mytype` to borrow instead if owning the value isn't necessary
|
||||
--> $DIR/on_move_with_format.rs:20:23
|
||||
--> $DIR/on_move_with_format.rs:22:23
|
||||
|
|
||||
LL | fn takes_mytype<X>(_: MyType<X>) {}
|
||||
| ------------ ^^^^^^^^^ this parameter takes ownership of the value
|
||||
| |
|
||||
| in this function
|
||||
note: if `MyType<i32>` implemented `Clone`, you could clone the value
|
||||
--> $DIR/on_move_with_format.rs:14:1
|
||||
--> $DIR/on_move_with_format.rs:16:1
|
||||
|
|
||||
LL | struct MyType<X> {
|
||||
| ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
|
||||
|
||||
@@ -4,24 +4,24 @@
|
||||
trait ImportantTrait1 {}
|
||||
|
||||
#[diagnostic::on_unimplemented(message = "Test {}")]
|
||||
//~^WARN positional format arguments are not allowed here
|
||||
//~^WARN positional arguments are not permitted in diagnostic attributes
|
||||
trait ImportantTrait2 {}
|
||||
|
||||
#[diagnostic::on_unimplemented(message = "Test {1:}")]
|
||||
//~^WARN positional format arguments are not allowed here
|
||||
//~|WARN invalid format specifier [malformed_diagnostic_format_literals]
|
||||
//~^WARN indexed format arguments are not permitted in diagnostic attributes
|
||||
//~|WARN format specifiers are not permitted in diagnostic attributes [malformed_diagnostic_format_literals]
|
||||
trait ImportantTrait3 {}
|
||||
|
||||
#[diagnostic::on_unimplemented(message = "Test {Self:123}")]
|
||||
//~^WARN invalid format specifier
|
||||
//~^WARN format specifiers are not permitted in diagnostic attributes
|
||||
trait ImportantTrait4 {}
|
||||
|
||||
#[diagnostic::on_unimplemented(message = "Test {Self:!}")]
|
||||
//~^WARN invalid format specifier [malformed_diagnostic_format_literals]
|
||||
//~^WARN format specifiers are not permitted in diagnostic attributes [malformed_diagnostic_format_literals]
|
||||
trait ImportantTrait5 {}
|
||||
|
||||
#[diagnostic::on_unimplemented(message = "Test {Self:}")]
|
||||
//~^WARN invalid format specifier [malformed_diagnostic_format_literals]
|
||||
//~^WARN format specifiers are not permitted in diagnostic attributes [malformed_diagnostic_format_literals]
|
||||
trait ImportantTrait6 {}
|
||||
|
||||
|
||||
|
||||
@@ -8,53 +8,43 @@ LL | #[diagnostic::on_unimplemented(message = "{{Test } thing")]
|
||||
|
|
||||
= note: `#[warn(malformed_diagnostic_format_literals)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
|
||||
|
||||
warning: positional format arguments are not allowed here
|
||||
warning: positional arguments are not permitted in diagnostic attributes
|
||||
--> $DIR/broken_format.rs:6:49
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented(message = "Test {}")]
|
||||
| ^
|
||||
| ^ remove this format argument
|
||||
|
|
||||
= help: only named format arguments with the name of one of the generic types are allowed in this context
|
||||
= help: you can print empty braces by escaping them
|
||||
|
||||
warning: invalid format specifier
|
||||
warning: format specifiers are not permitted in diagnostic attributes
|
||||
--> $DIR/broken_format.rs:10:50
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented(message = "Test {1:}")]
|
||||
| ^
|
||||
|
|
||||
= help: no format specifier are supported in this position
|
||||
| ^ remove this format specifier
|
||||
|
||||
warning: positional format arguments are not allowed here
|
||||
warning: indexed format arguments are not permitted in diagnostic attributes
|
||||
--> $DIR/broken_format.rs:10:49
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented(message = "Test {1:}")]
|
||||
| ^
|
||||
|
|
||||
= help: only named format arguments with the name of one of the generic types are allowed in this context
|
||||
| ^ remove this format argument
|
||||
|
||||
warning: invalid format specifier
|
||||
warning: format specifiers are not permitted in diagnostic attributes
|
||||
--> $DIR/broken_format.rs:15:53
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented(message = "Test {Self:123}")]
|
||||
| ^^^^
|
||||
|
|
||||
= help: no format specifier are supported in this position
|
||||
| ^^^^ remove this format specifier
|
||||
|
||||
warning: invalid format specifier
|
||||
warning: format specifiers are not permitted in diagnostic attributes
|
||||
--> $DIR/broken_format.rs:19:53
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented(message = "Test {Self:!}")]
|
||||
| ^^
|
||||
|
|
||||
= help: no format specifier are supported in this position
|
||||
| ^^ remove this format specifier
|
||||
|
||||
warning: invalid format specifier
|
||||
warning: format specifiers are not permitted in diagnostic attributes
|
||||
--> $DIR/broken_format.rs:23:53
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented(message = "Test {Self:}")]
|
||||
| ^
|
||||
|
|
||||
= help: no format specifier are supported in this position
|
||||
| ^ remove this format specifier
|
||||
|
||||
error[E0277]: {{Test } thing
|
||||
--> $DIR/broken_format.rs:36:13
|
||||
|
||||
@@ -1,32 +1,35 @@
|
||||
#![feature(diagnostic_on_unknown)]
|
||||
|
||||
#[diagnostic::on_unknown(message = "foo {}")]
|
||||
//~^ WARN: format arguments are not allowed here
|
||||
//~^ WARN: positional arguments are not permitted in diagnostic attributes
|
||||
use std::does_not_exist;
|
||||
//~^ ERROR: foo {}
|
||||
|
||||
#[diagnostic::on_unknown(message = "foo {A}")]
|
||||
//~^ WARN: format arguments are not allowed here
|
||||
//~^ WARN: this format argument is not allowed in `#[diagnostic::on_unknown]`
|
||||
use std::does_not_exist2;
|
||||
//~^ ERROR: foo {}
|
||||
//~^ ERROR: foo {A}
|
||||
|
||||
#[diagnostic::on_unknown(label = "foo {}")]
|
||||
//~^ WARN: format arguments are not allowed here
|
||||
//~^ WARN: positional arguments are not permitted in diagnostic attributes
|
||||
use std::does_not_exist3;
|
||||
//~^ ERROR: unresolved import `std::does_not_exist3`
|
||||
|
||||
#[diagnostic::on_unknown(label = "foo {A}")]
|
||||
//~^ WARN: format arguments are not allowed here
|
||||
//~^ WARN: this format argument is not allowed in `#[diagnostic::on_unknown]`
|
||||
use std::does_not_exist4;
|
||||
//~^ ERROR: unresolved import `std::does_not_exist4`
|
||||
|
||||
#[diagnostic::on_unknown(note = "foo {}")]
|
||||
//~^ WARN: format arguments are not allowed here
|
||||
//~^ WARN: positional arguments are not permitted in diagnostic attributes
|
||||
use std::does_not_exist5;
|
||||
//~^ ERROR: unresolved import `std::does_not_exist5`
|
||||
|
||||
#[diagnostic::on_unknown(note = "foo {A}")]
|
||||
//~^ WARN: format arguments are not allowed here
|
||||
#[diagnostic::on_unknown(note = "foo {Self} {ItemContext} {Trait} {A}")]
|
||||
//~^ WARN: this format argument is not allowed in `#[diagnostic::on_unknown]`
|
||||
//~| WARN: this format argument is not allowed in `#[diagnostic::on_unknown]`
|
||||
//~| WARN: this format argument is not allowed in `#[diagnostic::on_unknown]`
|
||||
//~| WARN: this format argument is not allowed in `#[diagnostic::on_unknown]`
|
||||
use std::does_not_exist6;
|
||||
//~^ ERROR: unresolved import `std::does_not_exist6`
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ LL | use std::does_not_exist;
|
||||
|
|
||||
= note: unresolved import `std::does_not_exist`
|
||||
|
||||
error[E0432]: foo {}
|
||||
error[E0432]: foo {A}
|
||||
--> $DIR/incorrect_format_string.rs:10:5
|
||||
|
|
||||
LL | use std::does_not_exist2;
|
||||
@@ -24,7 +24,7 @@ error[E0432]: unresolved import `std::does_not_exist4`
|
||||
--> $DIR/incorrect_format_string.rs:20:5
|
||||
|
|
||||
LL | use std::does_not_exist4;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ foo {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^ foo {A}
|
||||
|
||||
error[E0432]: unresolved import `std::does_not_exist5`
|
||||
--> $DIR/incorrect_format_string.rs:25:5
|
||||
@@ -35,62 +35,86 @@ LL | use std::does_not_exist5;
|
||||
= note: foo {}
|
||||
|
||||
error[E0432]: unresolved import `std::does_not_exist6`
|
||||
--> $DIR/incorrect_format_string.rs:30:5
|
||||
--> $DIR/incorrect_format_string.rs:33:5
|
||||
|
|
||||
LL | use std::does_not_exist6;
|
||||
| ^^^^^^^^^^^^^^^^^^^^ no `does_not_exist6` in the root
|
||||
|
|
||||
= note: foo {}
|
||||
= note: foo {Self} {ItemContext} {Trait} {A}
|
||||
|
||||
warning: format arguments are not allowed here
|
||||
warning: positional arguments are not permitted in diagnostic attributes
|
||||
--> $DIR/incorrect_format_string.rs:3:42
|
||||
|
|
||||
LL | #[diagnostic::on_unknown(message = "foo {}")]
|
||||
| ^
|
||||
| ^ remove this format argument
|
||||
|
|
||||
= help: consider removing this format argument
|
||||
= help: you can print empty braces by escaping them
|
||||
= note: `#[warn(malformed_diagnostic_format_literals)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
|
||||
|
||||
warning: format arguments are not allowed here
|
||||
warning: this format argument is not allowed in `#[diagnostic::on_unknown]`
|
||||
--> $DIR/incorrect_format_string.rs:8:42
|
||||
|
|
||||
LL | #[diagnostic::on_unknown(message = "foo {A}")]
|
||||
| ^
|
||||
| ^ remove this format argument
|
||||
|
|
||||
= help: consider removing this format argument
|
||||
= note: only `This` is allowed as a format argument, referring to the failed import
|
||||
|
||||
warning: format arguments are not allowed here
|
||||
warning: positional arguments are not permitted in diagnostic attributes
|
||||
--> $DIR/incorrect_format_string.rs:13:40
|
||||
|
|
||||
LL | #[diagnostic::on_unknown(label = "foo {}")]
|
||||
| ^
|
||||
| ^ remove this format argument
|
||||
|
|
||||
= help: consider removing this format argument
|
||||
= help: you can print empty braces by escaping them
|
||||
|
||||
warning: format arguments are not allowed here
|
||||
warning: this format argument is not allowed in `#[diagnostic::on_unknown]`
|
||||
--> $DIR/incorrect_format_string.rs:18:40
|
||||
|
|
||||
LL | #[diagnostic::on_unknown(label = "foo {A}")]
|
||||
| ^
|
||||
| ^ remove this format argument
|
||||
|
|
||||
= help: consider removing this format argument
|
||||
= note: only `This` is allowed as a format argument, referring to the failed import
|
||||
|
||||
warning: format arguments are not allowed here
|
||||
warning: positional arguments are not permitted in diagnostic attributes
|
||||
--> $DIR/incorrect_format_string.rs:23:39
|
||||
|
|
||||
LL | #[diagnostic::on_unknown(note = "foo {}")]
|
||||
| ^
|
||||
| ^ remove this format argument
|
||||
|
|
||||
= help: consider removing this format argument
|
||||
= help: you can print empty braces by escaping them
|
||||
|
||||
warning: format arguments are not allowed here
|
||||
warning: this format argument is not allowed in `#[diagnostic::on_unknown]`
|
||||
--> $DIR/incorrect_format_string.rs:28:39
|
||||
|
|
||||
LL | #[diagnostic::on_unknown(note = "foo {A}")]
|
||||
| ^
|
||||
LL | #[diagnostic::on_unknown(note = "foo {Self} {ItemContext} {Trait} {A}")]
|
||||
| ^^^^ remove this format argument
|
||||
|
|
||||
= help: consider removing this format argument
|
||||
= note: only `This` is allowed as a format argument, referring to the failed import
|
||||
|
||||
error: aborting due to 6 previous errors; 6 warnings emitted
|
||||
warning: this format argument is not allowed in `#[diagnostic::on_unknown]`
|
||||
--> $DIR/incorrect_format_string.rs:28:46
|
||||
|
|
||||
LL | #[diagnostic::on_unknown(note = "foo {Self} {ItemContext} {Trait} {A}")]
|
||||
| ^^^^^^^^^^^ remove this format argument
|
||||
|
|
||||
= note: only `This` is allowed as a format argument, referring to the failed import
|
||||
|
||||
warning: this format argument is not allowed in `#[diagnostic::on_unknown]`
|
||||
--> $DIR/incorrect_format_string.rs:28:60
|
||||
|
|
||||
LL | #[diagnostic::on_unknown(note = "foo {Self} {ItemContext} {Trait} {A}")]
|
||||
| ^^^^^ remove this format argument
|
||||
|
|
||||
= note: only `This` is allowed as a format argument, referring to the failed import
|
||||
|
||||
warning: this format argument is not allowed in `#[diagnostic::on_unknown]`
|
||||
--> $DIR/incorrect_format_string.rs:28:68
|
||||
|
|
||||
LL | #[diagnostic::on_unknown(note = "foo {Self} {ItemContext} {Trait} {A}")]
|
||||
| ^ remove this format argument
|
||||
|
|
||||
= note: only `This` is allowed as a format argument, referring to the failed import
|
||||
|
||||
error: aborting due to 6 previous errors; 9 warnings emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0432`.
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#![feature(diagnostic_on_unknown)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub mod foo {}
|
||||
|
||||
#[diagnostic::on_unknown(note = "the name of this item is a single ident: `{This}`")]
|
||||
use foo::Foo;
|
||||
//~^ERROR unresolved import `foo::Foo`
|
||||
//~|NOTE the name of this item is a single ident: `Foo`
|
||||
//~|NOTE no `Foo` in `foo`
|
||||
|
||||
#[diagnostic::on_unknown(note = "the name of this item is a single ident: `{This}`")]
|
||||
use foo::foo::Foo;
|
||||
//~^ERROR unresolved import `foo::foo`
|
||||
//~|NOTE the name of this item is a single ident: `foo`
|
||||
//~|NOTE could not find `foo` in `foo`
|
||||
|
||||
#[diagnostic::on_unknown(note = "the name of this item is two idents: `{This}`")]
|
||||
use foo::{Bar, Foo};
|
||||
//~^ERROR unresolved imports `foo::Bar`, `foo::Foo`
|
||||
//~|NOTE the name of this item is two idents: `Bar, Foo`
|
||||
//~|NOTE no `Foo` in `foo`
|
||||
//~|NOTE no `Bar` in `foo`
|
||||
|
||||
#[diagnostic::on_unknown(note = "the name of this item is many idents: `{This}`")]
|
||||
use foo::{
|
||||
Foo,
|
||||
//~^ERROR unresolved imports `foo::Foo`, `foo::bar`
|
||||
//~|NOTE the name of this item is many idents: `Foo, bar`
|
||||
//~|NOTE no `Foo` in `foo`
|
||||
bar::{Baz, Biz},
|
||||
//~^NOTE could not find `bar` in `foo`
|
||||
};
|
||||
|
||||
#[diagnostic::on_unknown(note = "the name of this is: `{This}`")]
|
||||
pub use doesnt_exist::*;
|
||||
//~^ERROR unresolved import `doesnt_exist`
|
||||
//~|NOTE use of unresolved module or unlinked crate `doesnt_exist`
|
||||
//~|NOTE the name of this is: `doesnt_exist`
|
||||
|
||||
#[diagnostic::on_unknown(note = "the name of this item is a single ident: `{This}`")]
|
||||
use foo::Foo as DoNotUseForThisParam;
|
||||
//~^ERROR unresolved import `foo::Foo`
|
||||
//~|NOTE the name of this item is a single ident: `Foo`
|
||||
//~|NOTE no `Foo` in `foo`
|
||||
@@ -0,0 +1,60 @@
|
||||
error[E0432]: unresolved import `foo::Foo`
|
||||
--> $DIR/this_format_argument.rs:7:5
|
||||
|
|
||||
LL | use foo::Foo;
|
||||
| ^^^^^^^^ no `Foo` in `foo`
|
||||
|
|
||||
= note: the name of this item is a single ident: `Foo`
|
||||
|
||||
error[E0432]: unresolved import `foo::foo`
|
||||
--> $DIR/this_format_argument.rs:13:10
|
||||
|
|
||||
LL | use foo::foo::Foo;
|
||||
| ^^^ could not find `foo` in `foo`
|
||||
|
|
||||
= note: the name of this item is a single ident: `foo`
|
||||
|
||||
error[E0432]: unresolved imports `foo::Bar`, `foo::Foo`
|
||||
--> $DIR/this_format_argument.rs:19:11
|
||||
|
|
||||
LL | use foo::{Bar, Foo};
|
||||
| ^^^ ^^^ no `Foo` in `foo`
|
||||
| |
|
||||
| no `Bar` in `foo`
|
||||
|
|
||||
= note: the name of this item is two idents: `Bar, Foo`
|
||||
|
||||
error[E0432]: unresolved imports `foo::Foo`, `foo::bar`
|
||||
--> $DIR/this_format_argument.rs:27:5
|
||||
|
|
||||
LL | Foo,
|
||||
| ^^^ no `Foo` in `foo`
|
||||
...
|
||||
LL | bar::{Baz, Biz},
|
||||
| ^^^ could not find `bar` in `foo`
|
||||
|
|
||||
= note: the name of this item is many idents: `Foo, bar`
|
||||
|
||||
error[E0432]: unresolved import `doesnt_exist`
|
||||
--> $DIR/this_format_argument.rs:36:9
|
||||
|
|
||||
LL | pub use doesnt_exist::*;
|
||||
| ^^^^^^^^^^^^ use of unresolved module or unlinked crate `doesnt_exist`
|
||||
|
|
||||
= note: the name of this is: `doesnt_exist`
|
||||
help: you might be missing a crate named `doesnt_exist`, add it to your project and import it in your code
|
||||
|
|
||||
LL + extern crate doesnt_exist;
|
||||
|
|
||||
|
||||
error[E0432]: unresolved import `foo::Foo`
|
||||
--> $DIR/this_format_argument.rs:42:5
|
||||
|
|
||||
LL | use foo::Foo as DoNotUseForThisParam;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `Foo` in `foo`
|
||||
|
|
||||
= note: the name of this item is a single ident: `Foo`
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0432`.
|
||||
@@ -7,7 +7,7 @@ pub mod foo {
|
||||
message = "first message",
|
||||
label = "first label",
|
||||
note = "custom note",
|
||||
note = "custom note 2"
|
||||
note = "custom note 2",
|
||||
)]
|
||||
use foo::Foo;
|
||||
//~^ERROR first message
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
|
||||
#[diagnostic::on_unmatch_args(
|
||||
message = "{T}! is missing arguments",
|
||||
//~^ WARN unknown parameter `T`
|
||||
//~^ WARN this format argument is not allowed in `#[diagnostic::on_unmatch_args]`
|
||||
//~| NOTE only `This` is allowed as a format argument
|
||||
//~| NOTE remove this format argument
|
||||
//~| NOTE `#[warn(malformed_diagnostic_format_literals)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
|
||||
)]
|
||||
macro_rules! pair {
|
||||
($ty:ty, $value:expr) => {};
|
||||
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
warning: unknown parameter `T`
|
||||
warning: this format argument is not allowed in `#[diagnostic::on_unmatch_args]`
|
||||
--> $DIR/report_warning_on_invalid_formats.rs:5:17
|
||||
|
|
||||
LL | message = "{T}! is missing arguments",
|
||||
| ^
|
||||
| ^ remove this format argument
|
||||
|
|
||||
= help: use `{This}` to refer to the macro name
|
||||
= note: only `This` is allowed as a format argument, referring to the macro's name
|
||||
= note: `#[warn(malformed_diagnostic_format_literals)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
||||
@@ -23,7 +23,8 @@ trait NoContent {}
|
||||
trait ParameterNotPresent<A, B> {}
|
||||
|
||||
#[rustc_on_unimplemented(label = "Unimplemented error on `{Self}` with params `<{A},{B},{}>`")]
|
||||
//~^ WARN positional format arguments are not allowed here
|
||||
//~^ WARN positional arguments are not permitted in diagnostic attributes
|
||||
//~| NOTE remove this format argument
|
||||
trait NoPositionalArgs<A, B> {}
|
||||
|
||||
#[rustc_on_unimplemented(lorem = "")]
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
error[E0232]: invalid flag in `on`-clause
|
||||
--> $DIR/bad-annotation.rs:45:44
|
||||
--> $DIR/bad-annotation.rs:46:44
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(message = "x", on(desugared, message = "y"))]
|
||||
| ^^^^^^^^^ expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `desugared`
|
||||
|
||||
error[E0232]: empty `on`-clause in `#[rustc_on_unimplemented]`
|
||||
--> $DIR/bad-annotation.rs:50:26
|
||||
--> $DIR/bad-annotation.rs:51:26
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(), message = "y")]
|
||||
| ^^^^ empty `on`-clause here
|
||||
|
||||
error[E0232]: literals inside `on`-clauses are not supported
|
||||
--> $DIR/bad-annotation.rs:70:29
|
||||
--> $DIR/bad-annotation.rs:71:29
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on("y", message = "y"))]
|
||||
| ^^^ unexpected literal here
|
||||
|
||||
error[E0232]: literals inside `on`-clauses are not supported
|
||||
--> $DIR/bad-annotation.rs:75:29
|
||||
--> $DIR/bad-annotation.rs:76:29
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(42, message = "y"))]
|
||||
| ^^ unexpected literal here
|
||||
|
||||
error[E0232]: expected a single predicate in `not(..)`
|
||||
--> $DIR/bad-annotation.rs:80:32
|
||||
--> $DIR/bad-annotation.rs:81:32
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(not(a, b), message = "y"))]
|
||||
| ^^^^^^ unexpected quantity of predicates here
|
||||
|
||||
error[E0232]: expected a single predicate in `not(..)`
|
||||
--> $DIR/bad-annotation.rs:85:32
|
||||
--> $DIR/bad-annotation.rs:86:32
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(not(), message = "y"))]
|
||||
| ^^ unexpected quantity of predicates here
|
||||
|
||||
error[E0232]: expected an identifier inside this `on`-clause
|
||||
--> $DIR/bad-annotation.rs:90:29
|
||||
--> $DIR/bad-annotation.rs:91:29
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(thing::What, message = "y"))]
|
||||
| ^^^^^^^^^^^ expected an identifier here, not `thing::What`
|
||||
|
||||
error[E0232]: expected an identifier inside this `on`-clause
|
||||
--> $DIR/bad-annotation.rs:95:29
|
||||
--> $DIR/bad-annotation.rs:96:29
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(thing::What = "value", message = "y"))]
|
||||
| ^^^^^^^^^^^ expected an identifier here, not `thing::What`
|
||||
|
||||
error[E0232]: this predicate is invalid
|
||||
--> $DIR/bad-annotation.rs:100:29
|
||||
--> $DIR/bad-annotation.rs:101:29
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(aaaaaaaaaaaaaa(a, b), message = "y"))]
|
||||
| ^^^^^^^^^^^^^^ expected one of `any`, `all` or `not` here, not `aaaaaaaaaaaaaa`
|
||||
|
||||
error[E0232]: invalid flag in `on`-clause
|
||||
--> $DIR/bad-annotation.rs:105:29
|
||||
--> $DIR/bad-annotation.rs:106:29
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(something, message = "y"))]
|
||||
| ^^^^^^^^^ expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `something`
|
||||
@@ -67,13 +67,13 @@ LL | #[rustc_on_unimplemented(label = "Unimplemented error on `{Self}` with para
|
||||
= note: `#[warn(malformed_diagnostic_format_literals)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
|
||||
|
||||
warning: there is no parameter `_Self` on trait `InvalidName`
|
||||
--> $DIR/bad-annotation.rs:110:29
|
||||
--> $DIR/bad-annotation.rs:111:29
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(_Self = "y", message = "y"))]
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: there is no parameter `abc` on trait `InvalidName2`
|
||||
--> $DIR/bad-annotation.rs:114:29
|
||||
--> $DIR/bad-annotation.rs:115:29
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(abc = "y", message = "y"))]
|
||||
| ^^^^^^^^^
|
||||
@@ -87,16 +87,16 @@ LL | #[rustc_on_unimplemented]
|
||||
= help: see <https://rustc-dev-guide.rust-lang.org/diagnostics.html#rustc_on_unimplemented>
|
||||
= note: `#[warn(malformed_diagnostic_attributes)]` (part of `#[warn(unknown_or_malformed_diagnostic_attributes)]`) on by default
|
||||
|
||||
warning: positional format arguments are not allowed here
|
||||
warning: positional arguments are not permitted in diagnostic attributes
|
||||
--> $DIR/bad-annotation.rs:25:90
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(label = "Unimplemented error on `{Self}` with params `<{A},{B},{}>`")]
|
||||
| ^
|
||||
| ^ remove this format argument
|
||||
|
|
||||
= help: only named format arguments with the name of one of the generic types are allowed in this context
|
||||
= help: you can print empty braces by escaping them
|
||||
|
||||
warning: malformed `rustc_on_unimplemented` attribute
|
||||
--> $DIR/bad-annotation.rs:29:26
|
||||
--> $DIR/bad-annotation.rs:30:26
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(lorem = "")]
|
||||
| ^^^^^^^^^^ invalid option found here
|
||||
@@ -104,7 +104,7 @@ LL | #[rustc_on_unimplemented(lorem = "")]
|
||||
= help: see <https://rustc-dev-guide.rust-lang.org/diagnostics.html#rustc_on_unimplemented>
|
||||
|
||||
warning: malformed `rustc_on_unimplemented` attribute
|
||||
--> $DIR/bad-annotation.rs:34:26
|
||||
--> $DIR/bad-annotation.rs:35:26
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(lorem(ipsum(dolor)))]
|
||||
| ^^^^^^^^^^^^^^^^^^^ invalid option found here
|
||||
@@ -112,7 +112,7 @@ LL | #[rustc_on_unimplemented(lorem(ipsum(dolor)))]
|
||||
= help: see <https://rustc-dev-guide.rust-lang.org/diagnostics.html#rustc_on_unimplemented>
|
||||
|
||||
warning: `message` is ignored due to previous definition of `message`
|
||||
--> $DIR/bad-annotation.rs:39:41
|
||||
--> $DIR/bad-annotation.rs:40:41
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(message = "x", message = "y")]
|
||||
| ------------- ^^^^^^^^^^^^^ `message` is later redundantly declared here
|
||||
@@ -120,7 +120,7 @@ LL | #[rustc_on_unimplemented(message = "x", message = "y")]
|
||||
| `message` is first declared here
|
||||
|
||||
warning: malformed `rustc_on_unimplemented` attribute
|
||||
--> $DIR/bad-annotation.rs:55:26
|
||||
--> $DIR/bad-annotation.rs:56:26
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on = "x", message = "y")]
|
||||
| ^^^^^^^^ invalid option found here
|
||||
@@ -128,7 +128,7 @@ LL | #[rustc_on_unimplemented(on = "x", message = "y")]
|
||||
= help: see <https://rustc-dev-guide.rust-lang.org/diagnostics.html#rustc_on_unimplemented>
|
||||
|
||||
warning: malformed `rustc_on_unimplemented` attribute
|
||||
--> $DIR/bad-annotation.rs:60:26
|
||||
--> $DIR/bad-annotation.rs:61:26
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(Self = "y"), message = "y")]
|
||||
| ^^^^^^^^^^^^^^ invalid option found here
|
||||
@@ -136,7 +136,7 @@ LL | #[rustc_on_unimplemented(on(Self = "y"), message = "y")]
|
||||
= help: see <https://rustc-dev-guide.rust-lang.org/diagnostics.html#rustc_on_unimplemented>
|
||||
|
||||
warning: malformed `rustc_on_unimplemented` attribute
|
||||
--> $DIR/bad-annotation.rs:65:46
|
||||
--> $DIR/bad-annotation.rs:66:46
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(from_desugaring, on(from_desugaring, message = "x")), message = "y")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
|
||||
|
||||
Reference in New Issue
Block a user