Skip to content

Commit

Permalink
Address review comments
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Goulet <michael@errs.io>
  • Loading branch information
weiznich and compiler-errors committed Sep 8, 2023
1 parent fe719f9 commit e0d4bc0
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 56 deletions.
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl Attribute {
}
}

pub fn is_path(&self, name: &[Symbol]) -> bool {
pub fn path_matches(&self, name: &[Symbol]) -> bool {
match &self.kind {
AttrKind::Normal(normal) => {
normal.item.path.segments.len() == name.len()
Expand All @@ -109,7 +109,7 @@ impl Attribute {
.segments
.iter()
.zip(name)
.all(|(s, n)| s.ident == Ident::with_dummy_span(*n))
.all(|(s, n)| s.args.is_none() && s.ident.name == *n)
}
AttrKind::DocComment(..) => false,
}
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ hir_analysis_copy_impl_on_type_with_dtor =
the trait `Copy` cannot be implemented for this type; the type has a destructor
.label = `Copy` not allowed on types with destructors
hir_analysis_diagnostic_on_unimplemented_only_for_traits =
`#[diagnostic::on_unimplemented]` can only be applied to trait definitions
hir_analysis_drop_impl_negative = negative `Drop` impls are not supported
hir_analysis_drop_impl_on_wrong_item =
Expand Down
26 changes: 2 additions & 24 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
use rustc_infer::traits::{Obligation, TraitEngineExt as _};
use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
use rustc_macros::LintDiagnostic;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::stability::EvalResult;
use rustc_middle::traits::DefiningAnchor;
Expand All @@ -28,9 +27,7 @@ use rustc_middle::ty::{
self, AdtDef, ParamEnv, RegionKind, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
TypeVisitableExt,
};
use rustc_session::lint::builtin::{
UNINHABITED_STATIC, UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNSUPPORTED_CALLING_CONVENTIONS,
};
use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
use rustc_span::symbol::sym;
use rustc_span::{self, Span};
use rustc_target::abi::FieldIdx;
Expand All @@ -43,10 +40,6 @@ use rustc_type_ir::fold::TypeFoldable;

use std::ops::ControlFlow;

#[derive(LintDiagnostic)]
#[diag(hir_analysis_diagnostic_on_unimplemented_only_for_traits)]
pub struct DiagnosticOnUnimplementedOnlyForTraits;

pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
match tcx.sess.target.is_abi_supported(abi) {
Some(true) => (),
Expand Down Expand Up @@ -574,22 +567,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
tcx.def_path_str(id.owner_id)
);
let _indenter = indenter();
let def_kind = tcx.def_kind(id.owner_id);
if !matches!(def_kind, DefKind::Trait) {
let item_def_id = id.owner_id.to_def_id();
if let Some(attr) = tcx
.get_attrs_by_path(item_def_id, Box::new([sym::diagnostic, sym::on_unimplemented]))
.next()
{
tcx.emit_spanned_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local()),
vec![attr.span],
DiagnosticOnUnimplementedOnlyForTraits,
);
}
}
match def_kind {
match tcx.def_kind(id.owner_id) {
DefKind::Static(..) => {
tcx.ensure().typeck(id.owner_id.def_id);
maybe_check_static_with_link_section(tcx, id.owner_id.def_id);
Expand Down
17 changes: 8 additions & 9 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2410,18 +2410,17 @@ impl<'tcx> TyCtxt<'tcx> {
}
}

pub fn get_attrs_by_path(
pub fn get_attrs_by_path<'attr>(
self,
did: impl Into<DefId>,
attr: Box<[Symbol]>,
) -> impl Iterator<Item = &'tcx ast::Attribute> {
let did: DefId = did.into();
let s = attr[0];
let filter_fn = move |a: &&ast::Attribute| a.is_path(&attr);
did: DefId,
attr: &'attr [Symbol],
) -> impl Iterator<Item = &'tcx ast::Attribute> + 'attr
where
'tcx: 'attr,
{
let filter_fn = move |a: &&ast::Attribute| a.path_matches(&attr);
if let Some(did) = did.as_local() {
self.hir().attrs(self.hir().local_def_id_to_hir_id(did)).iter().filter(filter_fn)
} else if cfg!(debug_assertions) && rustc_feature::is_builtin_only_local(s) {
bug!("tried to access the `only_local` attribute `{}` from an extern crate", s);
} else {
self.item_attrs(did).iter().filter(filter_fn)
}
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ passes_deprecated_annotation_has_no_effect =
passes_deprecated_attribute =
deprecated attribute must be paired with either stable or unstable attribute
passes_diagnostic_diagnostic_on_unimplemented_only_for_traits =
`#[diagnostic::on_unimplemented]` can only be applied to trait definitions
passes_diagnostic_item_first_defined =
the diagnostic item is first defined here
Expand Down
22 changes: 21 additions & 1 deletion compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use rustc_hir::{
self, FnSig, ForeignItem, HirId, Item, ItemKind, TraitItem, CRATE_HIR_ID, CRATE_OWNER_ID,
};
use rustc_hir::{MethodKind, Target, Unsafety};
use rustc_macros::LintDiagnostic;
use rustc_middle::hir::nested_filter;
use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
use rustc_middle::query::Providers;
Expand All @@ -24,7 +25,7 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::{
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
UNUSED_ATTRIBUTES,
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
};
use rustc_session::parse::feature_err;
use rustc_span::symbol::{kw, sym, Symbol};
Expand All @@ -36,6 +37,10 @@ use rustc_trait_selection::traits::ObligationCtxt;
use std::cell::Cell;
use std::collections::hash_map::Entry;

#[derive(LintDiagnostic)]
#[diag(passes_diagnostic_diagnostic_on_unimplemented_only_for_traits)]
pub struct DiagnosticOnUnimplementedOnlyForTraits;

pub(crate) fn target_from_impl_item<'tcx>(
tcx: TyCtxt<'tcx>,
impl_item: &hir::ImplItem<'_>,
Expand Down Expand Up @@ -104,6 +109,9 @@ impl CheckAttrVisitor<'_> {
let mut seen = FxHashMap::default();
let attrs = self.tcx.hir().attrs(hir_id);
for attr in attrs {
if attr.path_matches(&[sym::diagnostic, sym::on_unimplemented]) {
self.check_diagnostic_on_unimplemented(attr.span, hir_id, target);
}
match attr.name_or_empty() {
sym::do_not_recommend => self.check_do_not_recommend(attr.span, target),
sym::inline => self.check_inline(hir_id, attr, span, target),
Expand Down Expand Up @@ -284,6 +292,18 @@ impl CheckAttrVisitor<'_> {
}
}

/// Checks if `#[diagnostic::on_unimplemented]` is applied to a trait definition
fn check_diagnostic_on_unimplemented(&self, attr_span: Span, hir_id: HirId, target: Target) {
if !matches!(target, Target::Trait) {
self.tcx.emit_spanned_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
hir_id,
attr_span,
DiagnosticOnUnimplementedOnlyForTraits,
);
}
}

/// Checks if an `#[inline]` is applied to a function or a closure. Returns `true` if valid.
fn check_inline(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool {
match target {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ impl<'tcx> OnUnimplementedDirective {
&& label.is_none()
&& note.is_none()
&& !is_diagnostic_namespace_variant
// disallow filters for now
// FIXME(diagnostic_namespace): disallow filters for now
{
if let Some(items) = item.meta_item_list() {
match Self::parse(
Expand All @@ -423,7 +423,7 @@ impl<'tcx> OnUnimplementedDirective {
is_diagnostic_namespace_variant,
) {
Ok(Some(subcommand)) => subcommands.push(subcommand),
Ok(None) => unreachable!(
Ok(None) => bug!(
"This cannot happen for now as we only reach that if `is_diagnostic_namespace_variant` is false"
),
Err(reported) => errored = Some(reported),
Expand Down Expand Up @@ -476,11 +476,7 @@ impl<'tcx> OnUnimplementedDirective {
let Some(attr) = tcx.get_attr(item_def_id, sym::rustc_on_unimplemented).or_else(|| {
if tcx.features().diagnostic_namespace {
is_diagnostic_namespace_variant = true;
tcx.get_attrs_by_path(
item_def_id,
Box::new([sym::diagnostic, sym::on_unimplemented]),
)
.next()
tcx.get_attrs_by_path(item_def_id, &[sym::diagnostic, sym::on_unimplemented]).next()
} else {
None
}
Expand Down Expand Up @@ -510,7 +506,7 @@ impl<'tcx> OnUnimplementedDirective {
tcx.emit_spanned_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local()),
vec![attr.span],
attr.span,
NoValueInOnUnimplementedLint,
);
Ok(None)
Expand All @@ -519,7 +515,7 @@ impl<'tcx> OnUnimplementedDirective {
tcx.emit_spanned_lint(
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local()),
vec![attr.span],
attr.span,
NoValueInOnUnimplementedLint,
);
Ok(None)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
warning: malformed `on_unimplemented` attribute
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:3:32
|
LL | #[diagnostic::on_unimplemented(unsupported = "foo")]
| ^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default

warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:8:1
|
LL | #[diagnostic::on_unimplemented(message = "Baz")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default

warning: malformed `on_unimplemented` attribute
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:3:32
|
LL | #[diagnostic::on_unimplemented(unsupported = "foo")]
| ^^^^^^^^^^^^^^^^^^^

warning: malformed `on_unimplemented` attribute
--> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:12:50
Expand Down

0 comments on commit e0d4bc0

Please sign in to comment.