Skip to content

feat: Add [undeclared_type] lint to the [restriction] group - #17854

Open
nathanjf wants to merge 4 commits into
rust-lang:masterfrom
nathanjf:master
Open

nathanjf wants to merge 4 commits into
rust-lang:masterfrom
nathanjf:master

Conversation

@nathanjf

@nathanjf nathanjf commented Oct 7, 2026

Copy link
Copy Markdown

changelog: [undeclared_type]: Added [undeclared_type] lint.

This is a new lint in the restriction group that warns the user whenever they declare a new variable without explicitly declaring it's type.

@rustbot rustbot added the S-waiting-on-community-reviews Status: This is awaiting for positive reviews from the community before a maintainer is assigned. label Oct 7, 2026
@rustbot

rustbot commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome!

You should hear from one of our reviewers after this PR gets at least 2 reviews from the community.

Please see the contribution instructions for more information.

@rustbot rustbot added needs-fcp PRs that add, remove, or rename lints and need an FCP S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Oct 7, 2026
@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Lintcheck changes for b06b4db

Lint Added Removed Changed
clippy::undeclared_type 33045 0 0

This comment will be updated if you push new changes

@nathanjf nathanjf changed the title feat: Add 'undeclared_type' lint to the 'restriction' group feat: Add [undeclared_type] lint to the [restriction] group Oct 7, 2026

@DanielEScherzer DanielEScherzer left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

community review: looking at the lintcheck results, things like

                let frame = Frame {
                    dw_die_offset: Some(frames.function.dw_die_offset),
                    function: frames.function.name.clone().map(|name| FunctionName {
                        name,
                        language: frames.unit.lang,
                    }),
                    location: loc,
                };

from https://docs.rs/addr2line/0.24.0/src/addr2line/frame.rs.html#104 are being warned about, but there isn't any type inference needed here, because the value is coming from an explicit object creation, rather than from a method call

Can these cases be excluded, or at least have a configuration option to ignore them?

View changes since this review

@nathanjf

nathanjf commented Oct 7, 2026

Copy link
Copy Markdown
Author

Sure. I'll look into how to differentiate between those two cases and try to add in that configuration, but in my opinion it's still a variable being assigned a value, even though I do understand it's much more obvious what the intent is in that case.

// Obvious what's happening, but no explicit type
let frame = Frame {
    ...
}

// Obvious what's happening, with an explicit type
let frame: Frame = Frame {
    ...
}

What would an acceptable name for that configuration be? 'ignore_struct_literal' sounds reasonable to me.

@DanielEScherzer

Copy link
Copy Markdown
Contributor

Sure. I'll look into how to differentiate between those two cases and try to add in that configuration, but in my opinion it's still a variable being assigned a value, even though I do understand it's much more obvious what the intent is in that case.

What would an acceptable name for that configuration be? 'ignore_struct_literal' sounds reasonable to me.

Sounds reasonable to me for structs, but what about enums and unions? Would they have different configuration options?

@nathanjf

nathanjf commented Oct 8, 2026

Copy link
Copy Markdown
Author

The purpose of the rule would be to enforce declaring the types of variables. I personally would rather not add any of the configuration options because while clear in intent what those lines do, they are exceptions to the intent of the lint.

The simplest solution I can think of would be to add a configuration to check for only variables which are declared and assigned the return value of a function. Though with that said, I am unsure what a clear and concise name would be for that. Something like only_check_function_returns feels overly verbose, but maybe that's the way to go.

This is a default off lint in the restriction group so it might be reasonable to just say the user should know if they want to ignore it and disable the warning with:

#[allow(undeclared_type)]
let frame = Frame {
    ...
}

@CommanderStorm CommanderStorm left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Community review: I am a bit conearned about the number of lints, so this would defintively need an autofix

View changes since this review

Comment on lines +39 to +58
if local.ty.is_some() {
return;
}
if local.span.from_expansion() {
return;
}
if local.span.in_derive_expansion() {
return;
}
if local.span.in_external_macro(cx.tcx.deref().sess.source_map()) {
return;
}
span_lint_and_help(
cx,
UNDECLARED_TYPE,
local.span,
"declared variable has an undeclared type",
Some(local.span),
"declare a type for this variable",
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use if-let since it is much more readable

Suggested change
if local.ty.is_some() {
return;
}
if local.span.from_expansion() {
return;
}
if local.span.in_derive_expansion() {
return;
}
if local.span.in_external_macro(cx.tcx.deref().sess.source_map()) {
return;
}
span_lint_and_help(
cx,
UNDECLARED_TYPE,
local.span,
"declared variable has an undeclared type",
Some(local.span),
"declare a type for this variable",
);
if local.ty.is_none()
&& !local.span.from_expansion()
&& !local.span.in_derive_expansion()
&& !local.span.in_external_macro(cx.tcx.deref().sess.source_map()) {
span_lint_and_help(
cx,
UNDECLARED_TYPE,
local.span,
"declared variable has an undeclared type",
Some(local.span),
"declare a type for this variable",
);
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I much prefer not nesting code and doing early returns instead. I collapsed all the macro checks into one if statement. I am thinking about other ways to write it that would satisfy both you and I.

Comment thread clippy_lints/src/undeclared_type.rs Outdated
vec![]
}

fn main() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add an test case for the macro checks that you added so we don't accidentally regress because an bodged rebase or something

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will get this done as soon as I have time

@hashcatHitman hashcatHitman left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If anyone is interested, I ran this lint on a slightly outdated fork of cargo-geiger I had laying around. I committed all the auto-fixes that worked, and for those that initially produced code that wouldn't compile, I reverted the fix and added an expect. Maybe the suggestions could be improved to work better in these cases? I'm not sure. The branch is here: https://github.com/hashcatHitman/cargo-geiger/tree/undeclared_type_lint_testing

View changes since this review

@rustbot

rustbot commented Oct 11, 2026

Copy link
Copy Markdown
Collaborator

☔ The latest upstream changes (possibly #13598) made this pull request unmergeable. Please resolve the merge conflicts.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-fcp PRs that add, remove, or rename lints and need an FCP S-waiting-on-community-reviews Status: This is awaiting for positive reviews from the community before a maintainer is assigned. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants