Skip to content

Commit e2fbeec

Browse files
committed
Add external macro specific diagnostic to check-cfg
1 parent 0ab3ae8 commit e2fbeec

File tree

5 files changed

+108
-12
lines changed

5 files changed

+108
-12
lines changed

compiler/rustc_lint/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -803,10 +803,14 @@ lint_unexpected_cfg_add_build_rs_println = or consider adding `{$build_rs_printl
803803
lint_unexpected_cfg_add_cargo_feature = consider using a Cargo feature instead
804804
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}
805805
lint_unexpected_cfg_add_cmdline_arg = to expect this configuration use `{$cmdline_arg}`
806+
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`
807+
806808
lint_unexpected_cfg_define_features = consider defining some features in `Cargo.toml`
807809
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
808810
lint_unexpected_cfg_doc_rustc = see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
809811
812+
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
813+
lint_unexpected_cfg_from_external_macro_refer = try refering to `{$macro_name}` crate for guidance on how handle this unexpected cfg
810814
lint_unexpected_cfg_name = unexpected `cfg` condition name: `{$name}`
811815
lint_unexpected_cfg_name_expected_names = expected names are: {$possibilities}{$and_more ->
812816
[0] {""}

compiler/rustc_lint/src/context/diagnostics/check_cfg.rs

+49-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1+
use rustc_hir::def_id::LOCAL_CRATE;
12
use rustc_middle::bug;
23
use rustc_session::Session;
34
use rustc_session::config::ExpectedValues;
45
use rustc_span::edit_distance::find_best_match_for_name;
56
use rustc_span::symbol::Ident;
6-
use rustc_span::{Span, Symbol, sym};
7+
use rustc_span::{ExpnKind, Span, Symbol, sym};
78

89
use crate::lints;
910

@@ -60,6 +61,35 @@ fn cargo_help_sub(
6061
}
6162
}
6263

64+
fn rustc_macro_help(span: Span) -> Option<lints::UnexpectedCfgRustcMacroHelp> {
65+
let oexpn = span.ctxt().outer_expn_data();
66+
if let Some(def_id) = oexpn.macro_def_id
67+
&& let ExpnKind::Macro(macro_kind, macro_name) = oexpn.kind
68+
&& def_id.krate != LOCAL_CRATE
69+
{
70+
Some(lints::UnexpectedCfgRustcMacroHelp { macro_kind: macro_kind.descr(), macro_name })
71+
} else {
72+
None
73+
}
74+
}
75+
76+
fn cargo_macro_help(span: Span) -> Option<lints::UnexpectedCfgCargoMacroHelp> {
77+
let oexpn = span.ctxt().outer_expn_data();
78+
if let Some(def_id) = oexpn.macro_def_id
79+
&& let ExpnKind::Macro(macro_kind, macro_name) = oexpn.kind
80+
&& def_id.krate != LOCAL_CRATE
81+
{
82+
Some(lints::UnexpectedCfgCargoMacroHelp {
83+
macro_kind: macro_kind.descr(),
84+
macro_name,
85+
// FIXME: Get access to a `TyCtxt` from an `EarlyContext`
86+
// crate_name: cx.tcx.crate_name(def_id.krate),
87+
})
88+
} else {
89+
None
90+
}
91+
}
92+
6393
pub(super) fn unexpected_cfg_name(
6494
sess: &Session,
6595
(name, name_span): (Symbol, Span),
@@ -186,16 +216,21 @@ pub(super) fn unexpected_cfg_name(
186216
};
187217

188218
let invocation_help = if is_from_cargo {
189-
let sub = if !is_feature_cfg && !is_from_external_macro {
219+
let help = if !is_feature_cfg && !is_from_external_macro {
190220
Some(cargo_help_sub(sess, &inst))
191221
} else {
192222
None
193223
};
194-
lints::unexpected_cfg_name::InvocationHelp::Cargo { sub }
224+
lints::unexpected_cfg_name::InvocationHelp::Cargo {
225+
help,
226+
macro_help: cargo_macro_help(name_span),
227+
}
195228
} else {
196-
lints::unexpected_cfg_name::InvocationHelp::Rustc(lints::UnexpectedCfgRustcHelp::new(
197-
&inst(EscapeQuotes::No),
198-
))
229+
let help = lints::UnexpectedCfgRustcHelp::new(&inst(EscapeQuotes::No));
230+
lints::unexpected_cfg_name::InvocationHelp::Rustc {
231+
help,
232+
macro_help: rustc_macro_help(name_span),
233+
}
199234
};
200235

201236
lints::UnexpectedCfgName { code_sugg, invocation_help, name }
@@ -302,14 +337,20 @@ pub(super) fn unexpected_cfg_value(
302337
} else {
303338
None
304339
};
305-
lints::unexpected_cfg_value::InvocationHelp::Cargo(help)
340+
lints::unexpected_cfg_value::InvocationHelp::Cargo {
341+
help,
342+
macro_help: cargo_macro_help(name_span),
343+
}
306344
} else {
307345
let help = if can_suggest_adding_value {
308346
Some(lints::UnexpectedCfgRustcHelp::new(&inst(EscapeQuotes::No)))
309347
} else {
310348
None
311349
};
312-
lints::unexpected_cfg_value::InvocationHelp::Rustc(help)
350+
lints::unexpected_cfg_value::InvocationHelp::Rustc {
351+
help,
352+
macro_help: rustc_macro_help(name_span),
353+
}
313354
};
314355

315356
lints::UnexpectedCfgValue {

compiler/rustc_lint/src/lints.rs

+40-4
Original file line numberDiff line numberDiff line change
@@ -2131,6 +2131,25 @@ impl UnexpectedCfgRustcHelp {
21312131
}
21322132
}
21332133

2134+
#[derive(Subdiagnostic)]
2135+
#[note(lint_unexpected_cfg_from_external_macro_origin)]
2136+
#[help(lint_unexpected_cfg_from_external_macro_refer)]
2137+
pub(crate) struct UnexpectedCfgRustcMacroHelp {
2138+
pub macro_kind: &'static str,
2139+
pub macro_name: Symbol,
2140+
}
2141+
2142+
#[derive(Subdiagnostic)]
2143+
#[note(lint_unexpected_cfg_from_external_macro_origin)]
2144+
#[help(lint_unexpected_cfg_from_external_macro_refer)]
2145+
#[help(lint_unexpected_cfg_cargo_update)]
2146+
pub(crate) struct UnexpectedCfgCargoMacroHelp {
2147+
pub macro_kind: &'static str,
2148+
pub macro_name: Symbol,
2149+
// FIXME: Figure out a way to get the crate name
2150+
// crate_name: String,
2151+
}
2152+
21342153
#[derive(LintDiagnostic)]
21352154
#[diag(lint_unexpected_cfg_name)]
21362155
pub(crate) struct UnexpectedCfgName {
@@ -2235,10 +2254,17 @@ pub(crate) mod unexpected_cfg_name {
22352254
#[note(lint_unexpected_cfg_doc_cargo)]
22362255
Cargo {
22372256
#[subdiagnostic]
2238-
sub: Option<super::UnexpectedCfgCargoHelp>,
2257+
macro_help: Option<super::UnexpectedCfgCargoMacroHelp>,
2258+
#[subdiagnostic]
2259+
help: Option<super::UnexpectedCfgCargoHelp>,
22392260
},
22402261
#[note(lint_unexpected_cfg_doc_rustc)]
2241-
Rustc(#[subdiagnostic] super::UnexpectedCfgRustcHelp),
2262+
Rustc {
2263+
#[subdiagnostic]
2264+
macro_help: Option<super::UnexpectedCfgRustcMacroHelp>,
2265+
#[subdiagnostic]
2266+
help: super::UnexpectedCfgRustcHelp,
2267+
},
22422268
}
22432269
}
22442270

@@ -2341,9 +2367,19 @@ pub(crate) mod unexpected_cfg_value {
23412367
#[derive(Subdiagnostic)]
23422368
pub(crate) enum InvocationHelp {
23432369
#[note(lint_unexpected_cfg_doc_cargo)]
2344-
Cargo(#[subdiagnostic] Option<CargoHelp>),
2370+
Cargo {
2371+
#[subdiagnostic]
2372+
help: Option<CargoHelp>,
2373+
#[subdiagnostic]
2374+
macro_help: Option<super::UnexpectedCfgCargoMacroHelp>,
2375+
},
23452376
#[note(lint_unexpected_cfg_doc_rustc)]
2346-
Rustc(#[subdiagnostic] Option<super::UnexpectedCfgRustcHelp>),
2377+
Rustc {
2378+
#[subdiagnostic]
2379+
help: Option<super::UnexpectedCfgRustcHelp>,
2380+
#[subdiagnostic]
2381+
macro_help: Option<super::UnexpectedCfgRustcMacroHelp>,
2382+
},
23472383
}
23482384

23492385
#[derive(Subdiagnostic)]

tests/ui/check-cfg/report-in-external-macros.cargo.stderr

+9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ LL | cfg_macro::my_lib_macro!();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
= 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`
8+
= note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
9+
= help: try refering to `cfg_macro::my_lib_macro` crate for guidance on how handle this unexpected cfg
10+
= 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`
811
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
912
= note: `#[warn(unexpected_cfgs)]` on by default
1013
= note: this warning originates in the macro `cfg_macro::my_lib_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
@@ -16,6 +19,9 @@ LL | cfg_macro::my_lib_macro_value!();
1619
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1720
|
1821
= note: expected values for `panic` are: `abort` and `unwind`
22+
= note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
23+
= help: try refering to `cfg_macro::my_lib_macro_value` crate for guidance on how handle this unexpected cfg
24+
= 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`
1925
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
2026
= note: this warning originates in the macro `cfg_macro::my_lib_macro_value` (in Nightly builds, run with -Z macro-backtrace for more info)
2127

@@ -26,6 +32,9 @@ LL | cfg_macro::my_lib_macro_feature!();
2632
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2733
|
2834
= note: no expected values for `feature`
35+
= note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
36+
= help: try refering to `cfg_macro::my_lib_macro_feature` crate for guidance on how handle this unexpected cfg
37+
= 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`
2938
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html> for more information about checking conditional configuration
3039
= note: this warning originates in the macro `cfg_macro::my_lib_macro_feature` (in Nightly builds, run with -Z macro-backtrace for more info)
3140

tests/ui/check-cfg/report-in-external-macros.rustc.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ LL | cfg_macro::my_lib_macro!();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
= 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`
8+
= note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
9+
= help: try refering to `cfg_macro::my_lib_macro` crate for guidance on how handle this unexpected cfg
810
= help: to expect this configuration use `--check-cfg=cfg(my_lib_cfg)`
911
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
1012
= note: `#[warn(unexpected_cfgs)]` on by default
@@ -17,6 +19,8 @@ LL | cfg_macro::my_lib_macro_value!();
1719
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1820
|
1921
= note: expected values for `panic` are: `abort` and `unwind`
22+
= note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
23+
= help: try refering to `cfg_macro::my_lib_macro_value` crate for guidance on how handle this unexpected cfg
2024
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
2125
= note: this warning originates in the macro `cfg_macro::my_lib_macro_value` (in Nightly builds, run with -Z macro-backtrace for more info)
2226

@@ -28,6 +32,8 @@ LL | cfg_macro::my_lib_macro_feature!();
2832
|
2933
= note: no expected values for `feature`
3034
= help: to expect this configuration use `--check-cfg=cfg(feature, values("UNEXPECTED_FEATURE"))`
35+
= note: using a cfg inside a macro will use the cfgs from the destination crate and not the ones from the defining crate
36+
= help: try refering to `cfg_macro::my_lib_macro_feature` crate for guidance on how handle this unexpected cfg
3137
= note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
3238
= note: this warning originates in the macro `cfg_macro::my_lib_macro_feature` (in Nightly builds, run with -Z macro-backtrace for more info)
3339

0 commit comments

Comments
 (0)