Rollup merge of #134339 - Urgau:tcx-in-early-diag, r=jieyouxu

Pass `TyCtxt` to early diagostics decoration

This PR pass a `TyCtxt` to the early diagnostics decoration code so that diagnostics code that take advantage of (a very limited but still useful) `TyCtxt` in their note, help, suggestions, ...

This is particulary useful for #133221 which wants to get the crate name of a `DefId`, which is possible with `tcx.crate_name(...)`.

I highly recommend reviewing this PR commit by commit.

r? `@jieyouxu`
This commit is contained in:
许杰友 Jieyou Xu (Joe) 2024-12-16 01:52:23 +08:00 committed by GitHub
commit 56545cae69
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 84 additions and 112 deletions

View file

@ -76,6 +76,7 @@ fn pre_expansion_lint<'a>(
|| {
rustc_lint::check_ast_node(
sess,
None,
features,
true,
lint_store,
@ -310,6 +311,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
let lint_store = unerased_lint_store(tcx.sess);
rustc_lint::check_ast_node(
sess,
Some(tcx),
tcx.features(),
false,
lint_store,

View file

@ -806,7 +806,7 @@ lint_unexpected_cfg_add_build_rs_println = or consider adding `{$build_rs_printl
lint_unexpected_cfg_add_cargo_feature = consider using a Cargo feature instead
lint_unexpected_cfg_add_cargo_toml_lint_cfg = or consider adding in `Cargo.toml` the `check-cfg` lint config for the lint:{$cargo_toml_lint_cfg}
lint_unexpected_cfg_add_cmdline_arg = to expect this configuration use `{$cmdline_arg}`
lint_unexpected_cfg_cargo_update = the {$macro_kind} `{$macro_name}` may come from an old version of it's defining crate, try updating your dependencies with `cargo update`
lint_unexpected_cfg_cargo_update = the {$macro_kind} `{$macro_name}` may come from an old version of the `{$crate_name}` crate, try updating your dependency with `cargo update -p {$crate_name}`
lint_unexpected_cfg_define_features = consider defining some features in `Cargo.toml`
lint_unexpected_cfg_doc_cargo = see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration

View file

@ -20,7 +20,7 @@ use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths};
use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode};
use rustc_session::lint::{
BuiltinLintDiag, FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
};
use rustc_session::{LintStoreMarker, Session};
use rustc_span::Span;
@ -33,8 +33,6 @@ use self::TargetLint::*;
use crate::levels::LintLevelsBuilder;
use crate::passes::{EarlyLintPassObject, LateLintPassObject};
mod diagnostics;
type EarlyLintPassFactory = dyn Fn() -> EarlyLintPassObject + sync::DynSend + sync::DynSync;
type LateLintPassFactory =
dyn for<'tcx> Fn(TyCtxt<'tcx>) -> LateLintPassObject<'tcx> + sync::DynSend + sync::DynSync;
@ -511,38 +509,6 @@ pub struct EarlyContext<'a> {
pub buffered: LintBuffer,
}
impl EarlyContext<'_> {
/// Emit a lint at the appropriate level, with an associated span and an existing
/// diagnostic.
///
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
#[rustc_lint_diagnostics]
pub fn span_lint_with_diagnostics(
&self,
lint: &'static Lint,
span: MultiSpan,
diagnostic: BuiltinLintDiag,
) {
self.opt_span_lint_with_diagnostics(lint, Some(span), diagnostic);
}
/// Emit a lint at the appropriate level, with an optional associated span and an existing
/// diagnostic.
///
/// [`lint_level`]: rustc_middle::lint::lint_level#decorate-signature
#[rustc_lint_diagnostics]
pub fn opt_span_lint_with_diagnostics(
&self,
lint: &'static Lint,
span: Option<MultiSpan>,
diagnostic: BuiltinLintDiag,
) {
self.opt_span_lint(lint, span, |diag| {
diagnostics::decorate_lint(self.sess(), diagnostic, diag);
});
}
}
pub trait LintContext {
fn sess(&self) -> &Session;

View file

@ -9,35 +9,40 @@ use rustc_ast::visit::{self as ast_visit, Visitor, walk_list};
use rustc_ast::{self as ast, HasAttrs};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_feature::Features;
use rustc_middle::ty::RegisteredTools;
use rustc_middle::ty::{RegisteredTools, TyCtxt};
use rustc_session::Session;
use rustc_session::lint::{BufferedEarlyLint, LintBuffer, LintPass};
use rustc_span::Span;
use rustc_span::symbol::Ident;
use tracing::debug;
use crate::context::{EarlyContext, LintStore};
use crate::context::{EarlyContext, LintContext, LintStore};
use crate::passes::{EarlyLintPass, EarlyLintPassObject};
mod diagnostics;
macro_rules! lint_callback { ($cx:expr, $f:ident, $($args:expr),*) => ({
$cx.pass.$f(&$cx.context, $($args),*);
}) }
/// Implements the AST traversal for early lint passes. `T` provides the
/// `check_*` methods.
pub struct EarlyContextAndPass<'a, T: EarlyLintPass> {
context: EarlyContext<'a>,
pub struct EarlyContextAndPass<'ecx, 'tcx, T: EarlyLintPass> {
context: EarlyContext<'ecx>,
tcx: Option<TyCtxt<'tcx>>,
pass: T,
}
impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
impl<'ecx, 'tcx, T: EarlyLintPass> EarlyContextAndPass<'ecx, 'tcx, T> {
// This always-inlined function is for the hot call site.
#[inline(always)]
#[allow(rustc::diagnostic_outside_of_impl)]
fn inlined_check_id(&mut self, id: ast::NodeId) {
for early_lint in self.context.buffered.take(id) {
let BufferedEarlyLint { span, node_id: _, lint_id, diagnostic } = early_lint;
self.context.opt_span_lint_with_diagnostics(lint_id.lint, span, diagnostic);
self.context.opt_span_lint(lint_id.lint, span, |diag| {
diagnostics::decorate_lint(self.context.sess(), self.tcx, diagnostic, diag);
});
}
}
@ -49,7 +54,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
/// Merge the lints specified by any lint attributes into the
/// current lint context, call the provided function, then reset the
/// lints in effect to their previous state.
fn with_lint_attrs<F>(&mut self, id: ast::NodeId, attrs: &'a [ast::Attribute], f: F)
fn with_lint_attrs<F>(&mut self, id: ast::NodeId, attrs: &'_ [ast::Attribute], f: F)
where
F: FnOnce(&mut Self),
{
@ -67,19 +72,21 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
}
}
impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> {
fn visit_coroutine_kind(&mut self, coroutine_kind: &'a ast::CoroutineKind) -> Self::Result {
impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
for EarlyContextAndPass<'ecx, 'tcx, T>
{
fn visit_coroutine_kind(&mut self, coroutine_kind: &'ast ast::CoroutineKind) -> Self::Result {
self.check_id(coroutine_kind.closure_id());
}
fn visit_param(&mut self, param: &'a ast::Param) {
fn visit_param(&mut self, param: &'ast ast::Param) {
self.with_lint_attrs(param.id, &param.attrs, |cx| {
lint_callback!(cx, check_param, param);
ast_visit::walk_param(cx, param);
});
}
fn visit_item(&mut self, it: &'a ast::Item) {
fn visit_item(&mut self, it: &'ast ast::Item) {
self.with_lint_attrs(it.id, &it.attrs, |cx| {
lint_callback!(cx, check_item, it);
ast_visit::walk_item(cx, it);
@ -87,31 +94,31 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
})
}
fn visit_foreign_item(&mut self, it: &'a ast::ForeignItem) {
fn visit_foreign_item(&mut self, it: &'ast ast::ForeignItem) {
self.with_lint_attrs(it.id, &it.attrs, |cx| {
ast_visit::walk_item(cx, it);
})
}
fn visit_pat(&mut self, p: &'a ast::Pat) {
fn visit_pat(&mut self, p: &'ast ast::Pat) {
lint_callback!(self, check_pat, p);
self.check_id(p.id);
ast_visit::walk_pat(self, p);
lint_callback!(self, check_pat_post, p);
}
fn visit_pat_field(&mut self, field: &'a ast::PatField) {
fn visit_pat_field(&mut self, field: &'ast ast::PatField) {
self.with_lint_attrs(field.id, &field.attrs, |cx| {
ast_visit::walk_pat_field(cx, field);
});
}
fn visit_anon_const(&mut self, c: &'a ast::AnonConst) {
fn visit_anon_const(&mut self, c: &'ast ast::AnonConst) {
self.check_id(c.id);
ast_visit::walk_anon_const(self, c);
}
fn visit_expr(&mut self, e: &'a ast::Expr) {
fn visit_expr(&mut self, e: &'ast ast::Expr) {
self.with_lint_attrs(e.id, &e.attrs, |cx| {
lint_callback!(cx, check_expr, e);
ast_visit::walk_expr(cx, e);
@ -119,13 +126,13 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
})
}
fn visit_expr_field(&mut self, f: &'a ast::ExprField) {
fn visit_expr_field(&mut self, f: &'ast ast::ExprField) {
self.with_lint_attrs(f.id, &f.attrs, |cx| {
ast_visit::walk_expr_field(cx, f);
})
}
fn visit_stmt(&mut self, s: &'a ast::Stmt) {
fn visit_stmt(&mut self, s: &'ast ast::Stmt) {
// Add the statement's lint attributes to our
// current state when checking the statement itself.
// This allows us to handle attributes like
@ -145,33 +152,33 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
ast_visit::walk_stmt(self, s);
}
fn visit_fn(&mut self, fk: ast_visit::FnKind<'a>, span: Span, id: ast::NodeId) {
fn visit_fn(&mut self, fk: ast_visit::FnKind<'ast>, span: Span, id: ast::NodeId) {
lint_callback!(self, check_fn, fk, span, id);
self.check_id(id);
ast_visit::walk_fn(self, fk);
}
fn visit_variant_data(&mut self, s: &'a ast::VariantData) {
fn visit_variant_data(&mut self, s: &'ast ast::VariantData) {
if let Some(ctor_node_id) = s.ctor_node_id() {
self.check_id(ctor_node_id);
}
ast_visit::walk_struct_def(self, s);
}
fn visit_field_def(&mut self, s: &'a ast::FieldDef) {
fn visit_field_def(&mut self, s: &'ast ast::FieldDef) {
self.with_lint_attrs(s.id, &s.attrs, |cx| {
ast_visit::walk_field_def(cx, s);
})
}
fn visit_variant(&mut self, v: &'a ast::Variant) {
fn visit_variant(&mut self, v: &'ast ast::Variant) {
self.with_lint_attrs(v.id, &v.attrs, |cx| {
lint_callback!(cx, check_variant, v);
ast_visit::walk_variant(cx, v);
})
}
fn visit_ty(&mut self, t: &'a ast::Ty) {
fn visit_ty(&mut self, t: &'ast ast::Ty) {
lint_callback!(self, check_ty, t);
self.check_id(t.id);
ast_visit::walk_ty(self, t);
@ -181,55 +188,55 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
lint_callback!(self, check_ident, ident);
}
fn visit_local(&mut self, l: &'a ast::Local) {
fn visit_local(&mut self, l: &'ast ast::Local) {
self.with_lint_attrs(l.id, &l.attrs, |cx| {
lint_callback!(cx, check_local, l);
ast_visit::walk_local(cx, l);
})
}
fn visit_block(&mut self, b: &'a ast::Block) {
fn visit_block(&mut self, b: &'ast ast::Block) {
lint_callback!(self, check_block, b);
self.check_id(b.id);
ast_visit::walk_block(self, b);
}
fn visit_arm(&mut self, a: &'a ast::Arm) {
fn visit_arm(&mut self, a: &'ast ast::Arm) {
self.with_lint_attrs(a.id, &a.attrs, |cx| {
lint_callback!(cx, check_arm, a);
ast_visit::walk_arm(cx, a);
})
}
fn visit_generic_arg(&mut self, arg: &'a ast::GenericArg) {
fn visit_generic_arg(&mut self, arg: &'ast ast::GenericArg) {
lint_callback!(self, check_generic_arg, arg);
ast_visit::walk_generic_arg(self, arg);
}
fn visit_generic_param(&mut self, param: &'a ast::GenericParam) {
fn visit_generic_param(&mut self, param: &'ast ast::GenericParam) {
self.with_lint_attrs(param.id, &param.attrs, |cx| {
lint_callback!(cx, check_generic_param, param);
ast_visit::walk_generic_param(cx, param);
});
}
fn visit_generics(&mut self, g: &'a ast::Generics) {
fn visit_generics(&mut self, g: &'ast ast::Generics) {
lint_callback!(self, check_generics, g);
ast_visit::walk_generics(self, g);
}
fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) {
fn visit_where_predicate(&mut self, p: &'ast ast::WherePredicate) {
lint_callback!(self, enter_where_predicate, p);
ast_visit::walk_where_predicate(self, p);
lint_callback!(self, exit_where_predicate, p);
}
fn visit_poly_trait_ref(&mut self, t: &'a ast::PolyTraitRef) {
fn visit_poly_trait_ref(&mut self, t: &'ast ast::PolyTraitRef) {
lint_callback!(self, check_poly_trait_ref, t);
ast_visit::walk_poly_trait_ref(self, t);
}
fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
fn visit_assoc_item(&mut self, item: &'ast ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
self.with_lint_attrs(item.id, &item.attrs, |cx| {
match ctxt {
ast_visit::AssocCtxt::Trait => {
@ -243,32 +250,32 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
});
}
fn visit_lifetime(&mut self, lt: &'a ast::Lifetime, _: ast_visit::LifetimeCtxt) {
fn visit_lifetime(&mut self, lt: &'ast ast::Lifetime, _: ast_visit::LifetimeCtxt) {
self.check_id(lt.id);
ast_visit::walk_lifetime(self, lt);
}
fn visit_path(&mut self, p: &'a ast::Path, id: ast::NodeId) {
fn visit_path(&mut self, p: &'ast ast::Path, id: ast::NodeId) {
self.check_id(id);
ast_visit::walk_path(self, p);
}
fn visit_path_segment(&mut self, s: &'a ast::PathSegment) {
fn visit_path_segment(&mut self, s: &'ast ast::PathSegment) {
self.check_id(s.id);
ast_visit::walk_path_segment(self, s);
}
fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
fn visit_attribute(&mut self, attr: &'ast ast::Attribute) {
lint_callback!(self, check_attribute, attr);
ast_visit::walk_attribute(self, attr);
}
fn visit_mac_def(&mut self, mac: &'a ast::MacroDef, id: ast::NodeId) {
fn visit_mac_def(&mut self, mac: &'ast ast::MacroDef, id: ast::NodeId) {
lint_callback!(self, check_mac_def, mac);
self.check_id(id);
}
fn visit_mac_call(&mut self, mac: &'a ast::MacCall) {
fn visit_mac_call(&mut self, mac: &'ast ast::MacCall) {
lint_callback!(self, check_mac, mac);
ast_visit::walk_mac(self, mac);
}
@ -310,28 +317,18 @@ crate::early_lint_methods!(impl_early_lint_pass, []);
/// This trait generalizes over those nodes.
pub trait EarlyCheckNode<'a>: Copy {
fn id(self) -> ast::NodeId;
fn attrs<'b>(self) -> &'b [ast::Attribute]
where
'a: 'b;
fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>)
where
'a: 'b;
fn attrs(self) -> &'a [ast::Attribute];
fn check<'ecx, 'tcx, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'ecx, 'tcx, T>);
}
impl<'a> EarlyCheckNode<'a> for (&'a ast::Crate, &'a [ast::Attribute]) {
fn id(self) -> ast::NodeId {
ast::CRATE_NODE_ID
}
fn attrs<'b>(self) -> &'b [ast::Attribute]
where
'a: 'b,
{
fn attrs(self) -> &'a [ast::Attribute] {
self.1
}
fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>)
where
'a: 'b,
{
fn check<'ecx, 'tcx, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'ecx, 'tcx, T>) {
lint_callback!(cx, check_crate, self.0);
ast_visit::walk_crate(cx, self.0);
lint_callback!(cx, check_crate_post, self.0);
@ -342,16 +339,10 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast::
fn id(self) -> ast::NodeId {
self.0
}
fn attrs<'b>(self) -> &'b [ast::Attribute]
where
'a: 'b,
{
fn attrs(self) -> &'a [ast::Attribute] {
self.1
}
fn check<'b, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'b, T>)
where
'a: 'b,
{
fn check<'ecx, 'tcx, T: EarlyLintPass>(self, cx: &mut EarlyContextAndPass<'ecx, 'tcx, T>) {
walk_list!(cx, visit_attribute, self.1);
walk_list!(cx, visit_item, self.2);
}
@ -359,6 +350,7 @@ impl<'a> EarlyCheckNode<'a> for (ast::NodeId, &'a [ast::Attribute], &'a [P<ast::
pub fn check_ast_node<'a>(
sess: &Session,
tcx: Option<TyCtxt<'_>>,
features: &Features,
pre_expansion: bool,
lint_store: &LintStore,
@ -382,22 +374,23 @@ pub fn check_ast_node<'a>(
let passes =
if pre_expansion { &lint_store.pre_expansion_passes } else { &lint_store.early_passes };
if passes.is_empty() {
check_ast_node_inner(sess, check_node, context, builtin_lints);
check_ast_node_inner(sess, tcx, check_node, context, builtin_lints);
} else {
let mut passes: Vec<_> = passes.iter().map(|mk_pass| (mk_pass)()).collect();
passes.push(Box::new(builtin_lints));
let pass = RuntimeCombinedEarlyLintPass { passes: &mut passes[..] };
check_ast_node_inner(sess, check_node, context, pass);
check_ast_node_inner(sess, tcx, check_node, context, pass);
}
}
fn check_ast_node_inner<'a, T: EarlyLintPass>(
sess: &Session,
tcx: Option<TyCtxt<'_>>,
check_node: impl EarlyCheckNode<'a>,
context: EarlyContext<'_>,
pass: T,
) {
let mut cx = EarlyContextAndPass { context, pass };
let mut cx = EarlyContextAndPass { context, tcx, pass };
cx.with_lint_attrs(check_node.id(), check_node.attrs(), |cx| check_node.check(cx));

View file

@ -8,6 +8,7 @@ use rustc_errors::{
Applicability, Diag, DiagArgValue, LintDiagnostic, elided_lifetime_in_path_suggestion,
};
use rustc_middle::middle::stability;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution};
use rustc_span::BytePos;
@ -18,7 +19,12 @@ use crate::lints::{self, ElidedNamedLifetime};
mod check_cfg;
pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) {
pub(super) fn decorate_lint(
sess: &Session,
tcx: Option<TyCtxt<'_>>,
diagnostic: BuiltinLintDiag,
diag: &mut Diag<'_, ()>,
) {
match diagnostic {
BuiltinLintDiag::UnicodeTextFlow(comment_span, content) => {
let spans: Vec<_> = content
@ -199,10 +205,10 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
.decorate_lint(diag);
}
BuiltinLintDiag::UnexpectedCfgName(name, value) => {
check_cfg::unexpected_cfg_name(sess, name, value).decorate_lint(diag);
check_cfg::unexpected_cfg_name(sess, tcx, name, value).decorate_lint(diag);
}
BuiltinLintDiag::UnexpectedCfgValue(name, value) => {
check_cfg::unexpected_cfg_value(sess, name, value).decorate_lint(diag);
check_cfg::unexpected_cfg_value(sess, tcx, name, value).decorate_lint(diag);
}
BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => {
let suggestion = match sugg {

View file

@ -1,5 +1,6 @@
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_session::config::ExpectedValues;
use rustc_span::edit_distance::find_best_match_for_name;
@ -73,17 +74,20 @@ fn rustc_macro_help(span: Span) -> Option<lints::UnexpectedCfgRustcMacroHelp> {
}
}
fn cargo_macro_help(span: Span) -> Option<lints::UnexpectedCfgCargoMacroHelp> {
fn cargo_macro_help(
tcx: Option<TyCtxt<'_>>,
span: Span,
) -> Option<lints::UnexpectedCfgCargoMacroHelp> {
let oexpn = span.ctxt().outer_expn_data();
if let Some(def_id) = oexpn.macro_def_id
&& let ExpnKind::Macro(macro_kind, macro_name) = oexpn.kind
&& def_id.krate != LOCAL_CRATE
&& let Some(tcx) = tcx
{
Some(lints::UnexpectedCfgCargoMacroHelp {
macro_kind: macro_kind.descr(),
macro_name,
// FIXME: Get access to a `TyCtxt` from an `EarlyContext`
// crate_name: cx.tcx.crate_name(def_id.krate),
crate_name: tcx.crate_name(def_id.krate),
})
} else {
None
@ -92,6 +96,7 @@ fn cargo_macro_help(span: Span) -> Option<lints::UnexpectedCfgCargoMacroHelp> {
pub(super) fn unexpected_cfg_name(
sess: &Session,
tcx: Option<TyCtxt<'_>>,
(name, name_span): (Symbol, Span),
value: Option<(Symbol, Span)>,
) -> lints::UnexpectedCfgName {
@ -223,7 +228,7 @@ pub(super) fn unexpected_cfg_name(
};
lints::unexpected_cfg_name::InvocationHelp::Cargo {
help,
macro_help: cargo_macro_help(name_span),
macro_help: cargo_macro_help(tcx, name_span),
}
} else {
let help = lints::UnexpectedCfgRustcHelp::new(&inst(EscapeQuotes::No));
@ -238,6 +243,7 @@ pub(super) fn unexpected_cfg_name(
pub(super) fn unexpected_cfg_value(
sess: &Session,
tcx: Option<TyCtxt<'_>>,
(name, name_span): (Symbol, Span),
value: Option<(Symbol, Span)>,
) -> lints::UnexpectedCfgValue {
@ -339,7 +345,7 @@ pub(super) fn unexpected_cfg_value(
};
lints::unexpected_cfg_value::InvocationHelp::Cargo {
help,
macro_help: cargo_macro_help(name_span),
macro_help: cargo_macro_help(tcx, name_span),
}
} else {
let help = if can_suggest_adding_value {

View file

@ -2187,8 +2187,7 @@ pub(crate) struct UnexpectedCfgRustcMacroHelp {
pub(crate) struct UnexpectedCfgCargoMacroHelp {
pub macro_kind: &'static str,
pub macro_name: Symbol,
// FIXME: Figure out a way to get the crate name
// crate_name: String,
pub crate_name: Symbol,
}
#[derive(LintDiagnostic)]

View file

@ -7,7 +7,7 @@ LL | cfg_macro::my_lib_macro!();
= help: expected names are: `clippy`, `debug_assertions`, `doc`, `doctest`, `feature`, `fmt_debug`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `ub_checks`, `unix`, and `windows`
= note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
= help: try refering to `cfg_macro::my_lib_macro` crate for guidance on how handle this unexpected cfg
= help: the macro `cfg_macro::my_lib_macro` may come from an old version of it's defining crate, try updating your dependencies with `cargo update`
= help: the macro `cfg_macro::my_lib_macro` may come from an old version of the `cfg_macro` crate, try updating your dependency with `cargo update -p cfg_macro`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
= note: this warning originates in the macro `cfg_macro::my_lib_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
@ -21,7 +21,7 @@ LL | cfg_macro::my_lib_macro_value!();
= note: expected values for `panic` are: `abort` and `unwind`
= note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
= help: try refering to `cfg_macro::my_lib_macro_value` crate for guidance on how handle this unexpected cfg
= help: the macro `cfg_macro::my_lib_macro_value` may come from an old version of it's defining crate, try updating your dependencies with `cargo update`
= help: the macro `cfg_macro::my_lib_macro_value` may come from an old version of the `cfg_macro` crate, try updating your dependency with `cargo update -p cfg_macro`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: this warning originates in the macro `cfg_macro::my_lib_macro_value` (in Nightly builds, run with -Z macro-backtrace for more info)
@ -34,7 +34,7 @@ LL | cfg_macro::my_lib_macro_feature!();
= note: no expected values for `feature`
= note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
= help: try refering to `cfg_macro::my_lib_macro_feature` crate for guidance on how handle this unexpected cfg
= help: the macro `cfg_macro::my_lib_macro_feature` may come from an old version of it's defining crate, try updating your dependencies with `cargo update`
= help: the macro `cfg_macro::my_lib_macro_feature` may come from an old version of the `cfg_macro` crate, try updating your dependency with `cargo update -p cfg_macro`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
= note: this warning originates in the macro `cfg_macro::my_lib_macro_feature` (in Nightly builds, run with -Z macro-backtrace for more info)