Skip to content

Audit uses of sym::cfg and sym::cfg_attr (some ought to be replaced with sym::cfg_trace and sym::cfg_attr_trace resp.) #15982

@fmease

Description

@fmease

While working on cfg-related things in rustdoc, I noticed that clippy has 8 uses of sym::cfg and 2 uses of sym::cfg_attr. Most of these usages are probably fine but some should probably be replaced with sym::cfg_trace and sym::cfg_attr_trace, respectively.

Since rust-lang/rust#138844 and rust-lang/rust#138515 (March 2025), expanded active #[cfg{,_attr}]s get lowered to so-called traces. Meaning, when you're dealing with something that's running post-expansion, checking if the list of attributes of some given thing contains sym::cfg or sym::cfg_attr will always return false. For pre-expansion lints (etc.) on the other hand, that should still work.

For example I found fn is_hir_ty_cfg_dependant:

pub fn is_hir_ty_cfg_dependant(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind
&& let Res::Def(_, def_id) = path.res
{
return cx.tcx.has_attr(def_id, sym::cfg) || cx.tcx.has_attr(def_id, sym::cfg_attr);
}
false
}

which is to be used in LateContexts & HIR types (meaning: post-expansion) but it actually checks sym::cfg and sym::cfg_attr! This is quite clearly a bug! I wager that this function always returns false. Locally, I did modify it to check cfg_trace and cfg_attr_trace instead and no unit or UI tests failed, so this seems severely undertested.

As for concrete consequences / bugs, consider the following code which currently triggers the lint char-lit-as-u8 despite <Casts as LateLintPass>::check_expr returning early if the cast-to type is cfg-dependent:

#![deny(clippy::char_lit_as_u8)]

#[cfg(true)]
type Char = u8;

fn main() {
    let _ = 'x' as Char; //~ char_lit_as_u8
}

With my local +_trace modification, the lint no longer fires which was the original intention of the lint pass author(s).

Indeed, if you replace true with all() and run clippy-driver +nightly-2025-03-27 file.rs (the last nightly before the aforementioned rust-lang/rust#138844 landed) this compiles / the lint gets suppressed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions