Skip to content

Do not suggest as_deref for a slice pattern on Err - #165406

Open
lapla-cogito wants to merge 1 commit into
rust-lang:mainfrom
lapla-cogito:issue_165365
Open

lapla-cogito wants to merge 1 commit into
rust-lang:mainfrom
lapla-cogito:issue_165365

Conversation

@lapla-cogito

@lapla-cogito lapla-cogito commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Closes #165365

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 3, 2026
@rustbot

rustbot commented Nov 3, 2026

Copy link
Copy Markdown
Collaborator

r? @adwinwhite

rustbot has assigned @adwinwhite.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 77 candidates
  • Random selection from 22 candidates

Comment thread compiler/rustc_hir_typeck/src/pat.rs Outdated
Comment on lines +3292 to +3293
let deref_ty = args.type_at(0).peel_refs();
if self.can_eq(self.param_env, expected_ty.peel_refs(), deref_ty) {

@dianne dianne Nov 3, 2026 •

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.

this might need to account for the constructor(s) used in the pattern? it e.g. still produces false positives when the success and error types of Result are the same, such as for Err([]) matching on Result<Vec<E>, Vec<E>>

or for a more contrived example where the pattern itself matters,

enum Contrived<'a> {
    Layer(&'a Contrived<'a>),
    Value(Vec<E>),
}

impl Deref for Contrived<'_> {
    type Target = [E];
    fn deref(&self) -> &[E] {
        match self {
            Contrived::Layer(peeled) => peeled.deref(),
            Contrived::Value(value) => value.deref(),
        }
    }
}

fn contrived(opt: Option<Contrived<'_>>) {
    match opt {
        // suggests `.as_deref()`, but that causes a type mismatch:
        Some(Contrived::Layer([])) => {}
        _ => {}
    }
}

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks! Now only suggest when the slice pattern is the payload of Some or Ok itself.

})
}

fn slice_pattern_is_direct_payload(

@dianne dianne Nov 4, 2026 •

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.

this traversal looks pretty complicated relative to what we'd be gaining from it. a few thoughts:

  • maybe it could help to use a hir parent iterator to start at the slice pattern and go up to the top? that way it wouldn't have to search each or-pattern alternative
  • instead of tracking state with the AsDerefPatPos enum, maybe it would be clearer to have a helper that peels off &s/guards/or-patterns/etc.? with a hir parent iterator I imagine you could check that doing that once gets you to an Ok/Some and doing it again gets you to the top of the pattern
  • the cases that continue searching with AsDerefPatPos::Rejected look like they could just return false instead

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It makes sense. Thanks.

Comment thread compiler/rustc_hir_typeck/src/pat.rs Outdated
Comment on lines +3367 to +3369
PatKind::Struct(_, fields, _) => {
fields.iter().any(|field| step(field.pat, AsDerefPatPos::Rejected))
}

@dianne dianne Nov 4, 2026 •

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.

probably rare enough that it's not worth accounting for, but just in case it's easy, I feel obliged to note that Some { 0: [] } and Ok { 0: [] } are equivalent to Some([]) and Ok([])

View changes since the review

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

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[E0529] can wrongly suggest as_deref()

4 participants