Skip to content

Commit

Permalink
Add external macro specific diagnostic to check-cfg
Browse files Browse the repository at this point in the history
  • Loading branch information
Urgau committed Nov 19, 2024
1 parent 0ab3ae8 commit e2fbeec
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 12 deletions.
4 changes: 4 additions & 0 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -803,10 +803,14 @@ 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_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
lint_unexpected_cfg_doc_rustc = see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
lint_unexpected_cfg_from_external_macro_origin = using a cfg inside a {$macro_kind} will use the cfgs from the destination crate and not the ones from the defining crate
lint_unexpected_cfg_from_external_macro_refer = try refering to `{$macro_name}` crate for guidance on how handle this unexpected cfg
lint_unexpected_cfg_name = unexpected `cfg` condition name: `{$name}`
lint_unexpected_cfg_name_expected_names = expected names are: {$possibilities}{$and_more ->
[0] {""}
Expand Down
57 changes: 49 additions & 8 deletions compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::bug;
use rustc_session::Session;
use rustc_session::config::ExpectedValues;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::symbol::Ident;
use rustc_span::{Span, Symbol, sym};
use rustc_span::{ExpnKind, Span, Symbol, sym};

use crate::lints;

Expand Down Expand Up @@ -60,6 +61,35 @@ fn cargo_help_sub(
}
}

fn rustc_macro_help(span: Span) -> Option<lints::UnexpectedCfgRustcMacroHelp> {
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
{
Some(lints::UnexpectedCfgRustcMacroHelp { macro_kind: macro_kind.descr(), macro_name })
} else {
None
}
}

fn cargo_macro_help(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
{
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),
})
} else {
None
}
}

pub(super) fn unexpected_cfg_name(
sess: &Session,
(name, name_span): (Symbol, Span),
Expand Down Expand Up @@ -186,16 +216,21 @@ pub(super) fn unexpected_cfg_name(
};

let invocation_help = if is_from_cargo {
let sub = if !is_feature_cfg && !is_from_external_macro {
let help = if !is_feature_cfg && !is_from_external_macro {
Some(cargo_help_sub(sess, &inst))
} else {
None
};
lints::unexpected_cfg_name::InvocationHelp::Cargo { sub }
lints::unexpected_cfg_name::InvocationHelp::Cargo {
help,
macro_help: cargo_macro_help(name_span),
}
} else {
lints::unexpected_cfg_name::InvocationHelp::Rustc(lints::UnexpectedCfgRustcHelp::new(
&inst(EscapeQuotes::No),
))
let help = lints::UnexpectedCfgRustcHelp::new(&inst(EscapeQuotes::No));
lints::unexpected_cfg_name::InvocationHelp::Rustc {
help,
macro_help: rustc_macro_help(name_span),
}
};

lints::UnexpectedCfgName { code_sugg, invocation_help, name }
Expand Down Expand Up @@ -302,14 +337,20 @@ pub(super) fn unexpected_cfg_value(
} else {
None
};
lints::unexpected_cfg_value::InvocationHelp::Cargo(help)
lints::unexpected_cfg_value::InvocationHelp::Cargo {
help,
macro_help: cargo_macro_help(name_span),
}
} else {
let help = if can_suggest_adding_value {
Some(lints::UnexpectedCfgRustcHelp::new(&inst(EscapeQuotes::No)))
} else {
None
};
lints::unexpected_cfg_value::InvocationHelp::Rustc(help)
lints::unexpected_cfg_value::InvocationHelp::Rustc {
help,
macro_help: rustc_macro_help(name_span),
}
};

lints::UnexpectedCfgValue {
Expand Down
44 changes: 40 additions & 4 deletions compiler/rustc_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2131,6 +2131,25 @@ impl UnexpectedCfgRustcHelp {
}
}

#[derive(Subdiagnostic)]
#[note(lint_unexpected_cfg_from_external_macro_origin)]
#[help(lint_unexpected_cfg_from_external_macro_refer)]
pub(crate) struct UnexpectedCfgRustcMacroHelp {
pub macro_kind: &'static str,
pub macro_name: Symbol,
}

#[derive(Subdiagnostic)]
#[note(lint_unexpected_cfg_from_external_macro_origin)]
#[help(lint_unexpected_cfg_from_external_macro_refer)]
#[help(lint_unexpected_cfg_cargo_update)]
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,
}

#[derive(LintDiagnostic)]
#[diag(lint_unexpected_cfg_name)]
pub(crate) struct UnexpectedCfgName {
Expand Down Expand Up @@ -2235,10 +2254,17 @@ pub(crate) mod unexpected_cfg_name {
#[note(lint_unexpected_cfg_doc_cargo)]
Cargo {
#[subdiagnostic]
sub: Option<super::UnexpectedCfgCargoHelp>,
macro_help: Option<super::UnexpectedCfgCargoMacroHelp>,
#[subdiagnostic]
help: Option<super::UnexpectedCfgCargoHelp>,
},
#[note(lint_unexpected_cfg_doc_rustc)]
Rustc(#[subdiagnostic] super::UnexpectedCfgRustcHelp),
Rustc {
#[subdiagnostic]
macro_help: Option<super::UnexpectedCfgRustcMacroHelp>,
#[subdiagnostic]
help: super::UnexpectedCfgRustcHelp,
},
}
}

Expand Down Expand Up @@ -2341,9 +2367,19 @@ pub(crate) mod unexpected_cfg_value {
#[derive(Subdiagnostic)]
pub(crate) enum InvocationHelp {
#[note(lint_unexpected_cfg_doc_cargo)]
Cargo(#[subdiagnostic] Option<CargoHelp>),
Cargo {
#[subdiagnostic]
help: Option<CargoHelp>,
#[subdiagnostic]
macro_help: Option<super::UnexpectedCfgCargoMacroHelp>,
},
#[note(lint_unexpected_cfg_doc_rustc)]
Rustc(#[subdiagnostic] Option<super::UnexpectedCfgRustcHelp>),
Rustc {
#[subdiagnostic]
help: Option<super::UnexpectedCfgRustcHelp>,
#[subdiagnostic]
macro_help: Option<super::UnexpectedCfgRustcMacroHelp>,
},
}

#[derive(Subdiagnostic)]
Expand Down
9 changes: 9 additions & 0 deletions tests/ui/check-cfg/report-in-external-macros.cargo.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ 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`
= 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)
Expand All @@ -16,6 +19,9 @@ 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`
= 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)

Expand All @@ -26,6 +32,9 @@ 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`
= 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)

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/check-cfg/report-in-external-macros.rustc.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ 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: to expect this configuration use `--check-cfg=cfg(my_lib_cfg)`
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
Expand All @@ -17,6 +19,8 @@ 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
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.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)

Expand All @@ -28,6 +32,8 @@ LL | cfg_macro::my_lib_macro_feature!();
|
= note: no expected values for `feature`
= help: to expect this configuration use `--check-cfg=cfg(feature, values("UNEXPECTED_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
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.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)

Expand Down

0 comments on commit e2fbeec

Please sign in to comment.