Skip to content

Commit 9ffd0bf

Browse files
committed
do away with _Self and TraitName and check generic params for rustc_on_unimplemented
1 parent c9b6ccc commit 9ffd0bf

14 files changed

+152
-138
lines changed

compiler/rustc_span/src/symbol.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,6 @@ symbols! {
398398
Wrapping,
399399
Yield,
400400
_DECLS,
401-
_Self,
402401
__D,
403402
__H,
404403
__S,

compiler/rustc_trait_selection/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,8 @@ trait_selection_rustc_on_unimplemented_expected_one_predicate_in_not = expected
337337
.label = unexpected quantity of predicates here
338338
trait_selection_rustc_on_unimplemented_invalid_flag = invalid flag in `on`-clause
339339
.label = expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `{$invalid_flag}`
340+
trait_selection_rustc_on_unimplemented_invalid_name = invalid name in `on`-clause
341+
.label = expected one of `cause`, `from_desugaring`, `Self` or any generic parameter of the trait, not `{$invalid_name}`
340342
trait_selection_rustc_on_unimplemented_invalid_predicate = this predicate is invalid
341343
.label = expected one of `any`, `all` or `not` here, not `{$invalid_pred}`
342344
trait_selection_rustc_on_unimplemented_missing_value = this attribute must have a value

compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,19 @@ impl<'tcx> OnUnimplementedDirective {
429429
.next()
430430
.ok_or_else(|| tcx.dcx().emit_err(InvalidOnClause::Empty { span }))?;
431431

432-
match OnUnimplementedCondition::parse(cond) {
432+
let generics: Vec<Symbol> = tcx
433+
.generics_of(item_def_id)
434+
.own_params
435+
.iter()
436+
.filter_map(|param| {
437+
if matches!(param.kind, GenericParamDefKind::Lifetime) {
438+
None
439+
} else {
440+
Some(param.name)
441+
}
442+
})
443+
.collect();
444+
match OnUnimplementedCondition::parse(cond, &generics) {
433445
Ok(condition) => Some(condition),
434446
Err(e) => return Err(tcx.dcx().emit_err(e)),
435447
}

compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_condition.rs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@ impl OnUnimplementedCondition {
2626
})
2727
}
2828

29-
pub(crate) fn parse(input: &MetaItemInner) -> Result<Self, InvalidOnClause> {
29+
pub(crate) fn parse(
30+
input: &MetaItemInner,
31+
generics: &[Symbol],
32+
) -> Result<Self, InvalidOnClause> {
3033
let span = input.span();
31-
let pred = Predicate::parse(input)?;
34+
let pred = Predicate::parse(input, generics)?;
3235
Ok(OnUnimplementedCondition { span, pred })
3336
}
3437
}
@@ -52,7 +55,7 @@ enum Predicate {
5255
}
5356

5457
impl Predicate {
55-
fn parse(input: &MetaItemInner) -> Result<Self, InvalidOnClause> {
58+
fn parse(input: &MetaItemInner, generics: &[Symbol]) -> Result<Self, InvalidOnClause> {
5659
let meta_item = match input {
5760
MetaItemInner::MetaItem(meta_item) => meta_item,
5861
MetaItemInner::Lit(lit) => {
@@ -69,10 +72,10 @@ impl Predicate {
6972

7073
match meta_item.kind {
7174
MetaItemKind::List(ref mis) => match predicate.name {
72-
sym::any => Ok(Predicate::Any(Predicate::parse_sequence(mis)?)),
73-
sym::all => Ok(Predicate::All(Predicate::parse_sequence(mis)?)),
75+
sym::any => Ok(Predicate::Any(Predicate::parse_sequence(mis, generics)?)),
76+
sym::all => Ok(Predicate::All(Predicate::parse_sequence(mis, generics)?)),
7477
sym::not => match &**mis {
75-
[one] => Ok(Predicate::Not(Box::new(Predicate::parse(one)?))),
78+
[one] => Ok(Predicate::Not(Box::new(Predicate::parse(one, generics)?))),
7679
[first, .., last] => Err(InvalidOnClause::ExpectedOnePredInNot {
7780
span: first.span().to(last.span()),
7881
}),
@@ -83,7 +86,7 @@ impl Predicate {
8386
}
8487
},
8588
MetaItemKind::NameValue(MetaItemLit { symbol, .. }) => {
86-
let name = Name::parse(predicate);
89+
let name = Name::parse(predicate, generics)?;
8790
let value = FilterFormatString::parse(symbol);
8891
let kv = NameValue { name, value };
8992
Ok(Predicate::Match(kv))
@@ -95,8 +98,11 @@ impl Predicate {
9598
}
9699
}
97100

98-
fn parse_sequence(sequence: &[MetaItemInner]) -> Result<Vec<Self>, InvalidOnClause> {
99-
sequence.iter().map(Predicate::parse).collect()
101+
fn parse_sequence(
102+
sequence: &[MetaItemInner],
103+
generics: &[Symbol],
104+
) -> Result<Vec<Self>, InvalidOnClause> {
105+
sequence.iter().map(|item| Predicate::parse(item, generics)).collect()
100106
}
101107

102108
fn eval(&self, eval: &mut impl FnMut(FlagOrNv<'_>) -> bool) -> bool {
@@ -156,14 +162,13 @@ enum Name {
156162
}
157163

158164
impl Name {
159-
fn parse(Ident { name, .. }: Ident) -> Self {
165+
fn parse(Ident { name, span }: Ident, generics: &[Symbol]) -> Result<Self, InvalidOnClause> {
160166
match name {
161-
sym::_Self | kw::SelfUpper => Name::SelfUpper,
162-
sym::from_desugaring => Name::FromDesugaring,
163-
sym::cause => Name::Cause,
164-
// FIXME(mejrs) Perhaps we should start checking that
165-
// this actually is a valid generic parameter?
166-
generic => Name::GenericArg(generic),
167+
kw::SelfUpper => Ok(Name::SelfUpper),
168+
sym::from_desugaring => Ok(Name::FromDesugaring),
169+
sym::cause => Ok(Name::Cause),
170+
generic if generics.contains(&generic) => Ok(Name::GenericArg(generic)),
171+
invalid_name => Err(InvalidOnClause::InvalidName { invalid_name, span }),
167172
}
168173
}
169174
}

compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented_format.rs

Lines changed: 6 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::fmt;
22
use std::ops::Range;
33

44
use errors::*;
5-
use rustc_middle::ty::TyCtxt;
65
use rustc_middle::ty::print::TraitRefPrintSugared;
6+
use rustc_middle::ty::{GenericParamDefKind, TyCtxt};
77
use rustc_parse_format::{
88
Alignment, Argument, Count, FormatSpec, ParseError, ParseMode, Parser, Piece as RpfPiece,
99
Position,
@@ -232,48 +232,16 @@ fn parse_arg<'tcx>(
232232
) -> FormatArg {
233233
let (Ctx::RustcOnUnimplemented { tcx, trait_def_id }
234234
| Ctx::DiagnosticOnUnimplemented { tcx, trait_def_id }) = ctx;
235-
let trait_name = tcx.item_ident(*trait_def_id);
236-
let generics = tcx.generics_of(trait_def_id);
235+
237236
let span = slice_span(input_span, arg.position_span.clone());
238237

239238
match arg.position {
240239
// Something like "hello {name}"
241240
Position::ArgumentNamed(name) => match (ctx, Symbol::intern(name)) {
242-
// accepted, but deprecated
243-
(Ctx::RustcOnUnimplemented { .. }, sym::_Self) => {
244-
warnings
245-
.push(FormatWarning::FutureIncompat { span, help: String::from("use {Self}") });
246-
FormatArg::SelfUpper
247-
}
248-
(
249-
Ctx::RustcOnUnimplemented { .. },
250-
sym::from_desugaring
251-
| sym::crate_local
252-
| sym::direct
253-
| sym::cause
254-
| sym::float
255-
| sym::integer_
256-
| sym::integral,
257-
) => {
258-
warnings.push(FormatWarning::FutureIncompat {
259-
span,
260-
help: String::from("don't use this in a format string"),
261-
});
262-
FormatArg::AsIs(String::new())
263-
}
264-
265241
// Only `#[rustc_on_unimplemented]` can use these
266242
(Ctx::RustcOnUnimplemented { .. }, sym::ItemContext) => FormatArg::ItemContext,
267243
(Ctx::RustcOnUnimplemented { .. }, sym::This) => FormatArg::This,
268244
(Ctx::RustcOnUnimplemented { .. }, sym::Trait) => FormatArg::Trait,
269-
// `{ThisTraitsName}`. Some attrs in std use this, but I'd like to change it to the more general `{This}`
270-
// because that'll be simpler to parse and extend in the future
271-
(Ctx::RustcOnUnimplemented { .. }, name) if name == trait_name.name => {
272-
warnings
273-
.push(FormatWarning::FutureIncompat { span, help: String::from("use {This}") });
274-
FormatArg::This
275-
}
276-
277245
// Any attribute can use these
278246
(
279247
Ctx::RustcOnUnimplemented { .. } | Ctx::DiagnosticOnUnimplemented { .. },
@@ -282,7 +250,10 @@ fn parse_arg<'tcx>(
282250
(
283251
Ctx::RustcOnUnimplemented { .. } | Ctx::DiagnosticOnUnimplemented { .. },
284252
generic_param,
285-
) if generics.own_params.iter().any(|param| param.name == generic_param) => {
253+
) if tcx.generics_of(trait_def_id).own_params.iter().any(|param| {
254+
!matches!(param.kind, GenericParamDefKind::Lifetime) && param.name == generic_param
255+
}) =>
256+
{
286257
FormatArg::GenericParam { generic_param }
287258
}
288259

@@ -375,39 +346,4 @@ pub mod errors {
375346
#[diag(trait_selection_missing_options_for_on_unimplemented_attr)]
376347
#[help]
377348
pub struct MissingOptionsForOnUnimplementedAttr;
378-
379-
#[derive(LintDiagnostic)]
380-
#[diag(trait_selection_ignored_diagnostic_option)]
381-
pub struct IgnoredDiagnosticOption {
382-
pub option_name: &'static str,
383-
#[label]
384-
pub span: Span,
385-
#[label(trait_selection_other_label)]
386-
pub prev_span: Span,
387-
}
388-
389-
impl IgnoredDiagnosticOption {
390-
pub fn maybe_emit_warning<'tcx>(
391-
tcx: TyCtxt<'tcx>,
392-
item_def_id: DefId,
393-
new: Option<Span>,
394-
old: Option<Span>,
395-
option_name: &'static str,
396-
) {
397-
if let (Some(new_item), Some(old_item)) = (new, old) {
398-
if let Some(item_def_id) = item_def_id.as_local() {
399-
tcx.emit_node_span_lint(
400-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
401-
tcx.local_def_id_to_hir_id(item_def_id),
402-
new_item,
403-
IgnoredDiagnosticOption {
404-
span: new_item,
405-
prev_span: old_item,
406-
option_name,
407-
},
408-
);
409-
}
410-
}
411-
}
412-
}
413349
}

compiler/rustc_trait_selection/src/errors.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ pub enum InvalidOnClause {
7272
span: Span,
7373
invalid_flag: Symbol,
7474
},
75+
#[diag(trait_selection_rustc_on_unimplemented_invalid_name, code = E0232)]
76+
InvalidName {
77+
#[primary_span]
78+
#[label]
79+
span: Span,
80+
invalid_name: Symbol,
81+
},
7582
}
7683

7784
#[derive(Diagnostic)]

src/tools/clippy/tests/ui/duplicated_attributes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn foo() {}
2121
fn bar() {}
2222

2323
// No warning:
24-
#[rustc_on_unimplemented(on(_Self = "&str", label = "`a"), on(_Self = "alloc::string::String", label = "a"))]
24+
#[rustc_on_unimplemented(on(Self = "&str", label = "`a"), on(Self = "alloc::string::String", label = "a"))]
2525
trait Abc {}
2626

2727
#[proc_macro_attr::duplicated_attr()] // Should not warn!

tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//@ reference: attributes.diagnostic.on_unimplemented.syntax
44
//@ reference: attributes.diagnostic.on_unimplemented.invalid-formats
55
#[diagnostic::on_unimplemented(
6-
on(_Self = "&str"),
6+
on(Self = "&str"),
77
//~^WARN malformed `on_unimplemented` attribute
88
//~|WARN malformed `on_unimplemented` attribute
99
message = "trait has `{Self}` and `{T}` as params",
@@ -41,7 +41,7 @@ impl Bar for i32 {}
4141
//~|WARN there is no parameter `integral` on trait `Baz`
4242
//~|WARN there is no parameter `integer` on trait `Baz`
4343
//~|WARN there is no parameter `integer` on trait `Baz`
44-
label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
44+
label = "{float}{_Self}{crate_local}{Trait}{ItemContext}{This}"
4545
//~^WARN there is no parameter `float` on trait `Baz`
4646
//~|WARN there is no parameter `float` on trait `Baz`
4747
//~|WARN there is no parameter `_Self` on trait `Baz`
@@ -52,6 +52,8 @@ impl Bar for i32 {}
5252
//~|WARN there is no parameter `Trait` on trait `Baz`
5353
//~|WARN there is no parameter `ItemContext` on trait `Baz`
5454
//~|WARN there is no parameter `ItemContext` on trait `Baz`
55+
//~|WARN there is no parameter `This` on trait `Baz`
56+
//~|WARN there is no parameter `This` on trait `Baz`
5557
)]
5658
trait Baz {}
5759

0 commit comments

Comments
 (0)