do away with _Self and TraitName and check generic params for rustc_on_unimplemented
This commit is contained in:
@@ -398,7 +398,6 @@ symbols! {
|
||||
Wrapping,
|
||||
Yield,
|
||||
_DECLS,
|
||||
_Self,
|
||||
__D,
|
||||
__H,
|
||||
__S,
|
||||
|
||||
@@ -337,6 +337,8 @@ trait_selection_rustc_on_unimplemented_expected_one_predicate_in_not = expected
|
||||
.label = unexpected quantity of predicates here
|
||||
trait_selection_rustc_on_unimplemented_invalid_flag = invalid flag in `on`-clause
|
||||
.label = expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `{$invalid_flag}`
|
||||
trait_selection_rustc_on_unimplemented_invalid_name = invalid name in `on`-clause
|
||||
.label = expected one of `cause`, `from_desugaring`, `Self` or any generic parameter of the trait, not `{$invalid_name}`
|
||||
trait_selection_rustc_on_unimplemented_invalid_predicate = this predicate is invalid
|
||||
.label = expected one of `any`, `all` or `not` here, not `{$invalid_pred}`
|
||||
trait_selection_rustc_on_unimplemented_missing_value = this attribute must have a value
|
||||
|
||||
@@ -429,7 +429,19 @@ impl<'tcx> OnUnimplementedDirective {
|
||||
.next()
|
||||
.ok_or_else(|| tcx.dcx().emit_err(InvalidOnClause::Empty { span }))?;
|
||||
|
||||
match OnUnimplementedCondition::parse(cond) {
|
||||
let generics: Vec<Symbol> = tcx
|
||||
.generics_of(item_def_id)
|
||||
.own_params
|
||||
.iter()
|
||||
.filter_map(|param| {
|
||||
if matches!(param.kind, GenericParamDefKind::Lifetime) {
|
||||
None
|
||||
} else {
|
||||
Some(param.name)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
match OnUnimplementedCondition::parse(cond, &generics) {
|
||||
Ok(condition) => Some(condition),
|
||||
Err(e) => return Err(tcx.dcx().emit_err(e)),
|
||||
}
|
||||
|
||||
@@ -26,9 +26,12 @@ impl OnUnimplementedCondition {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn parse(input: &MetaItemInner) -> Result<Self, InvalidOnClause> {
|
||||
pub(crate) fn parse(
|
||||
input: &MetaItemInner,
|
||||
generics: &[Symbol],
|
||||
) -> Result<Self, InvalidOnClause> {
|
||||
let span = input.span();
|
||||
let pred = Predicate::parse(input)?;
|
||||
let pred = Predicate::parse(input, generics)?;
|
||||
Ok(OnUnimplementedCondition { span, pred })
|
||||
}
|
||||
}
|
||||
@@ -52,7 +55,7 @@ enum Predicate {
|
||||
}
|
||||
|
||||
impl Predicate {
|
||||
fn parse(input: &MetaItemInner) -> Result<Self, InvalidOnClause> {
|
||||
fn parse(input: &MetaItemInner, generics: &[Symbol]) -> Result<Self, InvalidOnClause> {
|
||||
let meta_item = match input {
|
||||
MetaItemInner::MetaItem(meta_item) => meta_item,
|
||||
MetaItemInner::Lit(lit) => {
|
||||
@@ -69,10 +72,10 @@ impl Predicate {
|
||||
|
||||
match meta_item.kind {
|
||||
MetaItemKind::List(ref mis) => match predicate.name {
|
||||
sym::any => Ok(Predicate::Any(Predicate::parse_sequence(mis)?)),
|
||||
sym::all => Ok(Predicate::All(Predicate::parse_sequence(mis)?)),
|
||||
sym::any => Ok(Predicate::Any(Predicate::parse_sequence(mis, generics)?)),
|
||||
sym::all => Ok(Predicate::All(Predicate::parse_sequence(mis, generics)?)),
|
||||
sym::not => match &**mis {
|
||||
[one] => Ok(Predicate::Not(Box::new(Predicate::parse(one)?))),
|
||||
[one] => Ok(Predicate::Not(Box::new(Predicate::parse(one, generics)?))),
|
||||
[first, .., last] => Err(InvalidOnClause::ExpectedOnePredInNot {
|
||||
span: first.span().to(last.span()),
|
||||
}),
|
||||
@@ -83,7 +86,7 @@ impl Predicate {
|
||||
}
|
||||
},
|
||||
MetaItemKind::NameValue(MetaItemLit { symbol, .. }) => {
|
||||
let name = Name::parse(predicate);
|
||||
let name = Name::parse(predicate, generics)?;
|
||||
let value = FilterFormatString::parse(symbol);
|
||||
let kv = NameValue { name, value };
|
||||
Ok(Predicate::Match(kv))
|
||||
@@ -95,8 +98,11 @@ impl Predicate {
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_sequence(sequence: &[MetaItemInner]) -> Result<Vec<Self>, InvalidOnClause> {
|
||||
sequence.iter().map(Predicate::parse).collect()
|
||||
fn parse_sequence(
|
||||
sequence: &[MetaItemInner],
|
||||
generics: &[Symbol],
|
||||
) -> Result<Vec<Self>, InvalidOnClause> {
|
||||
sequence.iter().map(|item| Predicate::parse(item, generics)).collect()
|
||||
}
|
||||
|
||||
fn eval(&self, eval: &mut impl FnMut(FlagOrNv<'_>) -> bool) -> bool {
|
||||
@@ -156,14 +162,13 @@ enum Name {
|
||||
}
|
||||
|
||||
impl Name {
|
||||
fn parse(Ident { name, .. }: Ident) -> Self {
|
||||
fn parse(Ident { name, span }: Ident, generics: &[Symbol]) -> Result<Self, InvalidOnClause> {
|
||||
match name {
|
||||
sym::_Self | kw::SelfUpper => Name::SelfUpper,
|
||||
sym::from_desugaring => Name::FromDesugaring,
|
||||
sym::cause => Name::Cause,
|
||||
// FIXME(mejrs) Perhaps we should start checking that
|
||||
// this actually is a valid generic parameter?
|
||||
generic => Name::GenericArg(generic),
|
||||
kw::SelfUpper => Ok(Name::SelfUpper),
|
||||
sym::from_desugaring => Ok(Name::FromDesugaring),
|
||||
sym::cause => Ok(Name::Cause),
|
||||
generic if generics.contains(&generic) => Ok(Name::GenericArg(generic)),
|
||||
invalid_name => Err(InvalidOnClause::InvalidName { invalid_name, span }),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ use std::fmt;
|
||||
use std::ops::Range;
|
||||
|
||||
use errors::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_middle::ty::print::TraitRefPrintSugared;
|
||||
use rustc_middle::ty::{GenericParamDefKind, TyCtxt};
|
||||
use rustc_parse_format::{
|
||||
Alignment, Argument, Count, FormatSpec, ParseError, ParseMode, Parser, Piece as RpfPiece,
|
||||
Position,
|
||||
@@ -232,48 +232,16 @@ fn parse_arg<'tcx>(
|
||||
) -> FormatArg {
|
||||
let (Ctx::RustcOnUnimplemented { tcx, trait_def_id }
|
||||
| Ctx::DiagnosticOnUnimplemented { tcx, trait_def_id }) = ctx;
|
||||
let trait_name = tcx.item_ident(*trait_def_id);
|
||||
let generics = tcx.generics_of(trait_def_id);
|
||||
|
||||
let span = slice_span(input_span, arg.position_span.clone());
|
||||
|
||||
match arg.position {
|
||||
// Something like "hello {name}"
|
||||
Position::ArgumentNamed(name) => match (ctx, Symbol::intern(name)) {
|
||||
// accepted, but deprecated
|
||||
(Ctx::RustcOnUnimplemented { .. }, sym::_Self) => {
|
||||
warnings
|
||||
.push(FormatWarning::FutureIncompat { span, help: String::from("use {Self}") });
|
||||
FormatArg::SelfUpper
|
||||
}
|
||||
(
|
||||
Ctx::RustcOnUnimplemented { .. },
|
||||
sym::from_desugaring
|
||||
| sym::crate_local
|
||||
| sym::direct
|
||||
| sym::cause
|
||||
| sym::float
|
||||
| sym::integer_
|
||||
| sym::integral,
|
||||
) => {
|
||||
warnings.push(FormatWarning::FutureIncompat {
|
||||
span,
|
||||
help: String::from("don't use this in a format string"),
|
||||
});
|
||||
FormatArg::AsIs(String::new())
|
||||
}
|
||||
|
||||
// Only `#[rustc_on_unimplemented]` can use these
|
||||
(Ctx::RustcOnUnimplemented { .. }, sym::ItemContext) => FormatArg::ItemContext,
|
||||
(Ctx::RustcOnUnimplemented { .. }, sym::This) => FormatArg::This,
|
||||
(Ctx::RustcOnUnimplemented { .. }, sym::Trait) => FormatArg::Trait,
|
||||
// `{ThisTraitsName}`. Some attrs in std use this, but I'd like to change it to the more general `{This}`
|
||||
// because that'll be simpler to parse and extend in the future
|
||||
(Ctx::RustcOnUnimplemented { .. }, name) if name == trait_name.name => {
|
||||
warnings
|
||||
.push(FormatWarning::FutureIncompat { span, help: String::from("use {This}") });
|
||||
FormatArg::This
|
||||
}
|
||||
|
||||
// Any attribute can use these
|
||||
(
|
||||
Ctx::RustcOnUnimplemented { .. } | Ctx::DiagnosticOnUnimplemented { .. },
|
||||
@@ -282,7 +250,10 @@ fn parse_arg<'tcx>(
|
||||
(
|
||||
Ctx::RustcOnUnimplemented { .. } | Ctx::DiagnosticOnUnimplemented { .. },
|
||||
generic_param,
|
||||
) if generics.own_params.iter().any(|param| param.name == generic_param) => {
|
||||
) if tcx.generics_of(trait_def_id).own_params.iter().any(|param| {
|
||||
!matches!(param.kind, GenericParamDefKind::Lifetime) && param.name == generic_param
|
||||
}) =>
|
||||
{
|
||||
FormatArg::GenericParam { generic_param }
|
||||
}
|
||||
|
||||
@@ -375,39 +346,4 @@ pub mod errors {
|
||||
#[diag(trait_selection_missing_options_for_on_unimplemented_attr)]
|
||||
#[help]
|
||||
pub struct MissingOptionsForOnUnimplementedAttr;
|
||||
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(trait_selection_ignored_diagnostic_option)]
|
||||
pub struct IgnoredDiagnosticOption {
|
||||
pub option_name: &'static str,
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(trait_selection_other_label)]
|
||||
pub prev_span: Span,
|
||||
}
|
||||
|
||||
impl IgnoredDiagnosticOption {
|
||||
pub fn maybe_emit_warning<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
item_def_id: DefId,
|
||||
new: Option<Span>,
|
||||
old: Option<Span>,
|
||||
option_name: &'static str,
|
||||
) {
|
||||
if let (Some(new_item), Some(old_item)) = (new, old) {
|
||||
if let Some(item_def_id) = item_def_id.as_local() {
|
||||
tcx.emit_node_span_lint(
|
||||
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
|
||||
tcx.local_def_id_to_hir_id(item_def_id),
|
||||
new_item,
|
||||
IgnoredDiagnosticOption {
|
||||
span: new_item,
|
||||
prev_span: old_item,
|
||||
option_name,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,13 @@ pub enum InvalidOnClause {
|
||||
span: Span,
|
||||
invalid_flag: Symbol,
|
||||
},
|
||||
#[diag(trait_selection_rustc_on_unimplemented_invalid_name, code = E0232)]
|
||||
InvalidName {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
span: Span,
|
||||
invalid_name: Symbol,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
||||
@@ -21,7 +21,7 @@ fn foo() {}
|
||||
fn bar() {}
|
||||
|
||||
// No warning:
|
||||
#[rustc_on_unimplemented(on(_Self = "&str", label = "`a"), on(_Self = "alloc::string::String", label = "a"))]
|
||||
#[rustc_on_unimplemented(on(Self = "&str", label = "`a"), on(Self = "alloc::string::String", label = "a"))]
|
||||
trait Abc {}
|
||||
|
||||
#[proc_macro_attr::duplicated_attr()] // Should not warn!
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//@ reference: attributes.diagnostic.on_unimplemented.syntax
|
||||
//@ reference: attributes.diagnostic.on_unimplemented.invalid-formats
|
||||
#[diagnostic::on_unimplemented(
|
||||
on(_Self = "&str"),
|
||||
on(Self = "&str"),
|
||||
//~^WARN malformed `on_unimplemented` attribute
|
||||
//~|WARN malformed `on_unimplemented` attribute
|
||||
message = "trait has `{Self}` and `{T}` as params",
|
||||
@@ -41,7 +41,7 @@ impl Bar for i32 {}
|
||||
//~|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}"
|
||||
label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
//~^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`
|
||||
@@ -52,6 +52,8 @@ impl Bar for i32 {}
|
||||
//~|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`
|
||||
//~|WARN there is no parameter `This` on trait `Baz`
|
||||
//~|WARN there is no parameter `This` on trait `Baz`
|
||||
)]
|
||||
trait Baz {}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ LL | #[diagnostic::on_unimplemented(message = "Not allowed to apply it on a impl
|
||||
warning: malformed `on_unimplemented` attribute
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:6:5
|
||||
|
|
||||
LL | on(_Self = "&str"),
|
||||
| ^^^^^^^^^^^^^^^^^^ invalid option found here
|
||||
LL | on(Self = "&str"),
|
||||
| ^^^^^^^^^^^^^^^^^ invalid option found here
|
||||
|
|
||||
= help: only `message`, `note` and `label` are allowed as options
|
||||
|
||||
@@ -81,7 +81,7 @@ LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}",
|
||||
warning: there is no parameter `float` on trait `Baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:15
|
||||
|
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
| ^^^^^
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
@@ -89,7 +89,7 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
warning: there is no parameter `_Self` on trait `Baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:22
|
||||
|
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
| ^^^^^
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
@@ -97,7 +97,7 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
warning: there is no parameter `crate_local` on trait `Baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:29
|
||||
|
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
@@ -105,7 +105,7 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
warning: there is no parameter `Trait` on trait `Baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:42
|
||||
|
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
| ^^^^^
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
@@ -113,16 +113,24 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
warning: there is no parameter `ItemContext` on trait `Baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:49
|
||||
|
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
|
||||
warning: there is no parameter `This` on trait `Baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:62
|
||||
|
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
| ^^^^
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
|
||||
warning: malformed `on_unimplemented` attribute
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:6:5
|
||||
|
|
||||
LL | on(_Self = "&str"),
|
||||
| ^^^^^^^^^^^^^^^^^^ invalid option found here
|
||||
LL | on(Self = "&str"),
|
||||
| ^^^^^^^^^^^^^^^^^ invalid option found here
|
||||
|
|
||||
= help: only `message`, `note` and `label` are allowed as options
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
@@ -146,7 +154,7 @@ LL | append_const_msg
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: trait has `()` and `i32` as params
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:63:15
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:65:15
|
||||
|
|
||||
LL | takes_foo(());
|
||||
| --------- ^^ trait has `()` and `i32` as params
|
||||
@@ -161,7 +169,7 @@ help: this trait has no implementations, consider adding one
|
||||
LL | trait Foo<T> {}
|
||||
| ^^^^^^^^^^^^
|
||||
note: required by a bound in `takes_foo`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:58:22
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:60:22
|
||||
|
|
||||
LL | fn takes_foo(_: impl Foo<i32>) {}
|
||||
| ^^^^^^^^ required by this bound in `takes_foo`
|
||||
@@ -176,7 +184,7 @@ LL | #[diagnostic::on_unimplemented = "Message"]
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: the trait bound `(): Bar` is not satisfied
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:65:15
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:67:15
|
||||
|
|
||||
LL | takes_bar(());
|
||||
| --------- ^^ the trait `Bar` is not implemented for `()`
|
||||
@@ -185,7 +193,7 @@ LL | takes_bar(());
|
||||
|
|
||||
= help: the trait `Bar` is implemented for `i32`
|
||||
note: required by a bound in `takes_bar`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:59:22
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:61:22
|
||||
|
|
||||
LL | fn takes_bar(_: impl Bar) {}
|
||||
| ^^^ required by this bound in `takes_bar`
|
||||
@@ -238,7 +246,7 @@ LL | message = "{from_desugaring}{direct}{cause}{integral}{integer}",
|
||||
warning: there is no parameter `float` on trait `Baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:15
|
||||
|
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
| ^^^^^
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
@@ -247,7 +255,7 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
warning: there is no parameter `_Self` on trait `Baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:22
|
||||
|
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
| ^^^^^
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
@@ -256,7 +264,7 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
warning: there is no parameter `crate_local` on trait `Baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:29
|
||||
|
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
@@ -265,7 +273,7 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
warning: there is no parameter `Trait` on trait `Baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:42
|
||||
|
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
| ^^^^^
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
@@ -274,32 +282,41 @@ LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
warning: there is no parameter `ItemContext` on trait `Baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:49
|
||||
|
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
warning: there is no parameter `This` on trait `Baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:44:62
|
||||
|
|
||||
LL | label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
|
||||
| ^^^^
|
||||
|
|
||||
= help: expect either a generic argument name or `{Self}` as format argument
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: {from_desugaring}{direct}{cause}{integral}{integer}
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:67:15
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:69:15
|
||||
|
|
||||
LL | takes_baz(());
|
||||
| --------- ^^ {float}{_Self}{crate_local}{Trait}{ItemContext}
|
||||
| --------- ^^ {float}{_Self}{crate_local}{Trait}{ItemContext}{This}
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `Baz` is not implemented for `()`
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:56:1
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:58:1
|
||||
|
|
||||
LL | trait Baz {}
|
||||
| ^^^^^^^^^
|
||||
note: required by a bound in `takes_baz`
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:60:22
|
||||
--> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:62:22
|
||||
|
|
||||
LL | fn takes_baz(_: impl Baz) {}
|
||||
| ^^^ required by this bound in `takes_baz`
|
||||
|
||||
error: aborting due to 3 previous errors; 29 warnings emitted
|
||||
error: aborting due to 3 previous errors; 31 warnings emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
||||
@@ -14,11 +14,15 @@ struct Bar {}
|
||||
//~|WARN malformed `on_unimplemented` attribute
|
||||
trait Baz {}
|
||||
|
||||
#[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message = "whatever"))]
|
||||
#[diagnostic::on_unimplemented(message = "Boom", on(Self = "i32", message = "whatever"))]
|
||||
//~^WARN malformed `on_unimplemented` attribute
|
||||
//~|WARN malformed `on_unimplemented` attribute
|
||||
trait Boom {}
|
||||
|
||||
#[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message = "whatever"))]
|
||||
//~^WARN malformed `on_unimplemented` attribute
|
||||
trait _Self {}
|
||||
|
||||
#[diagnostic::on_unimplemented = "boom"]
|
||||
//~^WARN malformed `on_unimplemented` attribute
|
||||
trait Doom {}
|
||||
|
||||
@@ -25,13 +25,21 @@ LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")]
|
||||
warning: malformed `on_unimplemented` attribute
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:17:50
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented(message = "Boom", on(Self = "i32", message = "whatever"))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
|
||||
|
|
||||
= help: only `message`, `note` and `label` are allowed as options
|
||||
|
||||
warning: malformed `on_unimplemented` attribute
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:22:50
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message = "whatever"))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
|
||||
|
|
||||
= help: only `message`, `note` and `label` are allowed as options
|
||||
|
||||
warning: malformed `on_unimplemented` attribute
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:22:32
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:26:32
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented = "boom"]
|
||||
| ^^^^^^^^ invalid option found here
|
||||
@@ -39,7 +47,7 @@ LL | #[diagnostic::on_unimplemented = "boom"]
|
||||
= help: only `message`, `note` and `label` are allowed as options
|
||||
|
||||
warning: missing options for `on_unimplemented` attribute
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:26:1
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:30:1
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -47,7 +55,7 @@ LL | #[diagnostic::on_unimplemented]
|
||||
= help: at least one of the `message`, `note` and `label` options are expected
|
||||
|
||||
warning: there is no parameter `DoesNotExist` on trait `Test`
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:44
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:35:44
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
|
||||
| ^^^^^^^^^^^^
|
||||
@@ -64,7 +72,7 @@ LL | #[diagnostic::on_unimplemented(unsupported = "foo")]
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: the trait bound `i32: Foo` is not satisfied
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:43:14
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:47:14
|
||||
|
|
||||
LL | take_foo(1_i32);
|
||||
| -------- ^^^^^ the trait `Foo` is not implemented for `i32`
|
||||
@@ -77,7 +85,7 @@ help: this trait has no implementations, consider adding one
|
||||
LL | trait Foo {}
|
||||
| ^^^^^^^^^
|
||||
note: required by a bound in `take_foo`
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:36:21
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:40:21
|
||||
|
|
||||
LL | fn take_foo(_: impl Foo) {}
|
||||
| ^^^ required by this bound in `take_foo`
|
||||
@@ -92,7 +100,7 @@ LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")]
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: Boom
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:45:14
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:49:14
|
||||
|
|
||||
LL | take_baz(1_i32);
|
||||
| -------- ^^^^^ the trait `Baz` is not implemented for `i32`
|
||||
@@ -105,7 +113,7 @@ help: this trait has no implementations, consider adding one
|
||||
LL | trait Baz {}
|
||||
| ^^^^^^^^^
|
||||
note: required by a bound in `take_baz`
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:37:21
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:41:21
|
||||
|
|
||||
LL | fn take_baz(_: impl Baz) {}
|
||||
| ^^^ required by this bound in `take_baz`
|
||||
@@ -113,14 +121,14 @@ LL | fn take_baz(_: impl Baz) {}
|
||||
warning: malformed `on_unimplemented` attribute
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:17:50
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message = "whatever"))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
|
||||
LL | #[diagnostic::on_unimplemented(message = "Boom", on(Self = "i32", message = "whatever"))]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
|
||||
|
|
||||
= help: only `message`, `note` and `label` are allowed as options
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: Boom
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:47:15
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:51:15
|
||||
|
|
||||
LL | take_boom(1_i32);
|
||||
| --------- ^^^^^ the trait `Boom` is not implemented for `i32`
|
||||
@@ -133,13 +141,13 @@ help: this trait has no implementations, consider adding one
|
||||
LL | trait Boom {}
|
||||
| ^^^^^^^^^^
|
||||
note: required by a bound in `take_boom`
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:38:22
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:42:22
|
||||
|
|
||||
LL | fn take_boom(_: impl Boom) {}
|
||||
| ^^^^ required by this bound in `take_boom`
|
||||
|
||||
warning: missing options for `on_unimplemented` attribute
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:26:1
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:30:1
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -148,7 +156,7 @@ LL | #[diagnostic::on_unimplemented]
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: the trait bound `i32: Whatever` is not satisfied
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:49:19
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:53:19
|
||||
|
|
||||
LL | take_whatever(1_i32);
|
||||
| ------------- ^^^^^ the trait `Whatever` is not implemented for `i32`
|
||||
@@ -156,18 +164,18 @@ LL | take_whatever(1_i32);
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:29:1
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:33:1
|
||||
|
|
||||
LL | trait Whatever {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
note: required by a bound in `take_whatever`
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:39:26
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:43:26
|
||||
|
|
||||
LL | fn take_whatever(_: impl Whatever) {}
|
||||
| ^^^^^^^^ required by this bound in `take_whatever`
|
||||
|
||||
warning: there is no parameter `DoesNotExist` on trait `Test`
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:44
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:35:44
|
||||
|
|
||||
LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
|
||||
| ^^^^^^^^^^^^
|
||||
@@ -176,7 +184,7 @@ LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: {DoesNotExist}
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:51:15
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:55:15
|
||||
|
|
||||
LL | take_test(());
|
||||
| --------- ^^ the trait `Test` is not implemented for `()`
|
||||
@@ -184,16 +192,16 @@ LL | take_test(());
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:34:1
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:38:1
|
||||
|
|
||||
LL | trait Test {}
|
||||
| ^^^^^^^^^^
|
||||
note: required by a bound in `take_test`
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:40:22
|
||||
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:44:22
|
||||
|
|
||||
LL | fn take_test(_: impl Test) {}
|
||||
| ^^^^ required by this bound in `take_test`
|
||||
|
||||
error: aborting due to 5 previous errors; 12 warnings emitted
|
||||
error: aborting due to 5 previous errors; 13 warnings emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
||||
@@ -59,7 +59,7 @@ trait EmptyOn {}
|
||||
//~^^^ NOTE expected value here
|
||||
trait ExpectedPredicateInOn {}
|
||||
|
||||
#[rustc_on_unimplemented(on(x = "y"), message = "y")]
|
||||
#[rustc_on_unimplemented(on(Self = "y"), message = "y")]
|
||||
trait OnWithoutDirectives {}
|
||||
|
||||
#[rustc_on_unimplemented(on(from_desugaring, on(from_desugaring, message = "x")), message = "y")]
|
||||
@@ -107,3 +107,13 @@ trait InvalidPredicate {}
|
||||
//~^ ERROR invalid flag in `on`-clause
|
||||
//~^^ NOTE expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `something`
|
||||
trait InvalidFlag {}
|
||||
|
||||
#[rustc_on_unimplemented(on(_Self = "y", message = "y"))]
|
||||
//~^ ERROR invalid name in `on`-clause
|
||||
//~^^ NOTE expected one of `cause`, `from_desugaring`, `Self` or any generic parameter of the trait, not `_Self`
|
||||
trait InvalidName {}
|
||||
|
||||
#[rustc_on_unimplemented(on(abc = "y", message = "y"))]
|
||||
//~^ ERROR invalid name in `on`-clause
|
||||
//~^^ NOTE expected one of `cause`, `from_desugaring`, `Self` or any generic parameter of the trait, not `abc`
|
||||
trait InvalidName2 {}
|
||||
|
||||
@@ -125,7 +125,19 @@ error[E0232]: invalid flag in `on`-clause
|
||||
LL | #[rustc_on_unimplemented(on(something, message = "y"))]
|
||||
| ^^^^^^^^^ expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `something`
|
||||
|
||||
error: aborting due to 18 previous errors
|
||||
error[E0232]: invalid name in `on`-clause
|
||||
--> $DIR/bad-annotation.rs:111:29
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(_Self = "y", message = "y"))]
|
||||
| ^^^^^ expected one of `cause`, `from_desugaring`, `Self` or any generic parameter of the trait, not `_Self`
|
||||
|
||||
error[E0232]: invalid name in `on`-clause
|
||||
--> $DIR/bad-annotation.rs:116:29
|
||||
|
|
||||
LL | #[rustc_on_unimplemented(on(abc = "y", message = "y"))]
|
||||
| ^^^ expected one of `cause`, `from_desugaring`, `Self` or any generic parameter of the trait, not `abc`
|
||||
|
||||
error: aborting due to 20 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0230, E0231, E0232.
|
||||
For more information about an error, try `rustc --explain E0230`.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
pub mod Bar {
|
||||
#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{Foo}`"]
|
||||
#[rustc_on_unimplemented = "test error `{Self}` with `{Bar}` `{Baz}` `{Quux}` in `{This}`"]
|
||||
pub trait Foo<Bar, Baz, Quux> {}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user