Skip to content

fix-155516: Don't suggest wrong unwrap expect#156497

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
lokirithm:fix-155516
Jun 11, 2026
Merged

fix-155516: Don't suggest wrong unwrap expect#156497
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
lokirithm:fix-155516

Conversation

@lokirithm

@lokirithm lokirithm commented May 12, 2026

Copy link
Copy Markdown
Contributor

View all comments

Fixes #155516

r? Kivooeo

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 12, 2026
@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label May 12, 2026
Comment thread tests/ui/destructuring-assignment/dont-suggest-wrong-expect-suggestion.rs Outdated
Comment thread compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs Outdated
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@Kivooeo

Kivooeo commented May 21, 2026

Copy link
Copy Markdown
Member

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label May 21, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request May 21, 2026
fix-155516: Don't suggest wrong upwrap expect
@rust-bors

rust-bors Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 8977e63 (8977e632bc55f12c46173d6e4acccc5bcad7378b, parent: b954122bbe6c4a244c511a9a168c6d5438d8f58f)

@rust-timer

This comment has been minimized.

@lokirithm lokirithm changed the title fix-155516: Don't suggest wrong upwrap expect fix-155516: Don't suggest wrong unwrap expect May 21, 2026
@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (8977e63): comparison URL.

Overall result: ❌✅ regressions and improvements - please read:

Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf.

Next, please: If you can, justify the regressions found in this try perf run in writing along with @rustbot label: +perf-regression-triaged. If not, fix the regressions and do another perf run. Neutral or positive results will clear the label automatically.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
0.0% [0.0%, 0.0%] 1
Improvements ✅
(primary)
-0.7% [-0.7%, -0.7%] 1
Improvements ✅
(secondary)
-0.3% [-0.4%, -0.1%] 2
All ❌✅ (primary) -0.7% [-0.7%, -0.7%] 1

Max RSS (memory usage)

Results (secondary -0.9%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.6% [2.5%, 2.8%] 2
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-2.7% [-4.2%, -2.1%] 4
All ❌✅ (primary) - - 0

Cycles

Results (secondary 2.2%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
3.8% [2.2%, 5.9%] 6
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-6.9% [-6.9%, -6.9%] 1
All ❌✅ (primary) - - 0

Binary size

This perf run didn't have relevant results for this metric.

Bootstrap: 514.377s -> 509.852s (-0.88%)
Artifact size: 400.61 MiB -> 402.59 MiB (0.50%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels May 21, 2026
@lokirithm

Copy link
Copy Markdown
Contributor Author

What does it say? The code is not optimal? I mean, is it taking more time or less time to compile/run programs?

@Kivooeo

Kivooeo commented May 21, 2026

Copy link
Copy Markdown
Member

for some reason perf is good 🤷‍♂️

because of early return likely

@Kivooeo

Kivooeo commented May 21, 2026

Copy link
Copy Markdown
Member

this needs another pair of eyes honestly, i'm not 100% confident about it but can't say why

@rustbot reroll

@rustbot rustbot assigned TaKO8Ki and unassigned Kivooeo May 21, 2026
@lokirithm

Copy link
Copy Markdown
Contributor Author

because of early return likely

But, afaik, there was only a single test in the whole test suite that was using the early return. also, the number of tests is increased by 1. So, intuitively the time taken should have increased, because changes aren't affecting the other tests (or at least increasing the time take because of the for loop).

@teor2345 teor2345 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.

Looks ok to me, but are there any other reasons to terminate the upward search for assignments?

For example, maybe we want to terminate at function/closure boundaries, module boundaries, or similar.

because of early return likely

But, afaik, there was only a single test in the whole test suite that was using the early return. also, the number of tests is increased by 1. So, intuitively the time taken should have increased, because changes aren't affecting the other tests (or at least increasing the time take because of the for loop).

The benchmarks measure the speed of specific crates and custom benchmark builds. Most tests aren't benchmarked.

In this case the most significant change is nalgebra, which seems reasonable.

View changes since this review

{
// if `expr` is the RHS in an Assign Expr and its span overlaps with the span
// of the LHS in the same Expr, we know this expression is result of
// desugering a destructuring assignment

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.

Looks like a spelling typo?
(There's another instance of this typo below.)

Suggested change
// desugering a destructuring assignment
// desugaring a destructuring assignment

@lokirithm

Copy link
Copy Markdown
Contributor Author

are there any other reasons to terminate the upward search for assignments?

No, i guess. At least, I can't think of any other terminating condition.

@teor2345

teor2345 commented May 23, 2026

Copy link
Copy Markdown
Contributor

are there any other reasons to terminate the upward search for assignments?

No, i guess. At least, I can't think of any other terminating condition.

Sorry, my comment wasn't clear.

The for loop that searches for parent items will go all the way up to the crate root. This is a waste of compiler time.

It should terminate at the first of:

  • the enclosing function: the first function, method, or closure definition item encountered in the search
  • the enclosing constant (for code running in a const context)
  • if there's any other items that can contain code, the enclosing item
  • the enclosing module (which might not ever happen, because there should be another item first)

@lokirithm

Copy link
Copy Markdown
Contributor Author
  • the enclosing function: the first function, method, or closure definition item encountered in the search

I guess, we don't require to go up to the enclosing function.

So, I think, the code is doing what you are saying, but a little bit earlier.

Instead of going up to the function, it stops at the first assignment expression which was not generated by the compiler to desugar the destructuring assignment syntax (and it checks this by checking whether the LHS and RHS of the expression have overlapping spans; it's impossible to write actual code or expression whose spans overlap).

Assuming a general case, an assignment expression will come before the enclosing function when we are going up the HIR tree. I mean, It's hard to imagine a function which no assignment expressions, unless very simple functions, for example sum(a, b) { a + b }. And I am unsure, if such a function can also have an assignment expression generated by the compiler during HIR creation. Even if there are no assignment expressions in the HIR of such simple functions, it's highly likely that these the result of such functions will be immediately assigned to some variable.

Actually, I myself have some doubts, but as per my understanding [I used AI to understand the concept, but not to write code], I feel it's correct.

@cjgillot

Copy link
Copy Markdown
Contributor

The terminating condition for the upwards search is 1. By definition, rhs.hir_id == expr.hir_id means that e is the parent of expr. No need to go higher. The loop can be simplified to a single call to tcx.parent_hir_node(expr.hir_id).

@rust-log-analyzer

This comment has been minimized.

@cjgillot

Copy link
Copy Markdown
Contributor

For a generic named struct, do we still suggest anything? Should we?

struct NamedStruct<O, R> {
    opt_field: O,
    res_field: R,
}

fn main() {
    let a: usize;
    let b: usize;

    NamedStruct {
        opt_field: a,
        res_field: b,
    } = NamedStruct {
        opt_field: Some(0),
        res_field: Ok(42_usize),
    };
}

@lokirithm

lokirithm commented May 31, 2026

Copy link
Copy Markdown
Contributor Author

do we still suggest anything?

Yes. The compiler suggests the same.

Should we?

As per my understanding, suggesting .expect() in LHS in a named struct would not make sense in any scenario.

@cjgillot

Copy link
Copy Markdown
Contributor

@bors r+ rollup

@rust-bors

rust-bors Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 9633071 has been approved by cjgillot

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 10, 2026
jhpratt added a commit to jhpratt/rust that referenced this pull request Jun 10, 2026
fix-155516: Don't suggest wrong unwrap expect

Fixes rust-lang#155516

r? Kivooeo
rust-bors Bot pushed a commit that referenced this pull request Jun 10, 2026
Rollup of 23 pull requests

Successful merges:

 - #157280 (traits: Allow escaping self types in ExistentialTraitRef::with_self_ty)
 - #157282 (Fix post-monomorphization error note race in the parallel frontend)
 - #157352 (Make the retained dep graph deterministic under the parallel frontend)
 - #157601 (Emit error for unused target expression in glob and list delegations)
 - #157611 (Update `browser-ui-test` version to `0.24.0`)
 - #157620 (Add a strategy FnMut to inject behavior into the flush cycle)
 - #157645 (Windows TLS - Only register the `atexit` hook when `cleanup` can be unloaded)
 - #157647 (Start using comptime for reflection intrinsics and their wrapper functions)
 - #157719 (resolve: Partially revert "Remove a special case for dummy imports")
 - #156497 (fix-155516: Don't suggest wrong unwrap expect)
 - #156583 (Support defaults for static EIIs)
 - #157013 (Ensure inferred let pattern types are well-formed)
 - #157230 (borrowck: avoid ICE describing fields on generic params)
 - #157288 (platform support: add SNaN erratum to MIPS targets)
 - #157350 (compiletest: ignore SVG `y` offset in by-lines comparison)
 - #157355 (Add `or_try_*` variants for `HashMap` and `BTreeMap` Entry APIs)
 - #157384 (Add `#[rustc_dump_generics]` attribute)
 - #157577 (Fix parser error recovery treating 'dyn' as a strict keyword in Rust 2015 when used in `dyn + dyn`)
 - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
 - #157691 (Move symbol hiding code to a new file)
 - #157697 (Add more tests that exercise the well-formedness checking of lazy type aliases)
 - #157700 (Rename `errors.rs` file to `diagnostics.rs` (5/N))
 - #157703 (Fix doc link to Instant sub in saturating caveat)

Failed merges:

 - #157699 (Arg splat experiment - hir FnDecl impl)
rust-bors Bot pushed a commit that referenced this pull request Jun 11, 2026
Rollup of 23 pull requests

Successful merges:

 - #157280 (traits: Allow escaping self types in ExistentialTraitRef::with_self_ty)
 - #157282 (Fix post-monomorphization error note race in the parallel frontend)
 - #157352 (Make the retained dep graph deterministic under the parallel frontend)
 - #157601 (Emit error for unused target expression in glob and list delegations)
 - #157611 (Update `browser-ui-test` version to `0.24.0`)
 - #157620 (Add a strategy FnMut to inject behavior into the flush cycle)
 - #157645 (Windows TLS - Only register the `atexit` hook when `cleanup` can be unloaded)
 - #157647 (Start using comptime for reflection intrinsics and their wrapper functions)
 - #157719 (resolve: Partially revert "Remove a special case for dummy imports")
 - #156497 (fix-155516: Don't suggest wrong unwrap expect)
 - #156583 (Support defaults for static EIIs)
 - #157013 (Ensure inferred let pattern types are well-formed)
 - #157230 (borrowck: avoid ICE describing fields on generic params)
 - #157288 (platform support: add SNaN erratum to MIPS targets)
 - #157350 (compiletest: ignore SVG `y` offset in by-lines comparison)
 - #157355 (Add `or_try_*` variants for `HashMap` and `BTreeMap` Entry APIs)
 - #157384 (Add `#[rustc_dump_generics]` attribute)
 - #157577 (Fix parser error recovery treating 'dyn' as a strict keyword in Rust 2015 when used in `dyn + dyn`)
 - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
 - #157691 (Move symbol hiding code to a new file)
 - #157697 (Add more tests that exercise the well-formedness checking of lazy type aliases)
 - #157700 (Rename `errors.rs` file to `diagnostics.rs` (5/N))
 - #157703 (Fix doc link to Instant sub in saturating caveat)

Failed merges:

 - #157699 (Arg splat experiment - hir FnDecl impl)
jhpratt added a commit to jhpratt/rust that referenced this pull request Jun 11, 2026
fix-155516: Don't suggest wrong unwrap expect

Fixes rust-lang#155516

r? Kivooeo
jhpratt added a commit to jhpratt/rust that referenced this pull request Jun 11, 2026
fix-155516: Don't suggest wrong unwrap expect

Fixes rust-lang#155516

r? Kivooeo
jhpratt added a commit to jhpratt/rust that referenced this pull request Jun 11, 2026
fix-155516: Don't suggest wrong unwrap expect

Fixes rust-lang#155516

r? Kivooeo
jhpratt added a commit to jhpratt/rust that referenced this pull request Jun 11, 2026
fix-155516: Don't suggest wrong unwrap expect

Fixes rust-lang#155516

r? Kivooeo
rust-bors Bot pushed a commit that referenced this pull request Jun 11, 2026
Rollup of 31 pull requests

Successful merges:

 - #141030 (Expand free alias types during variance computation)
 - #154853 (mgca: Register `ConstArgHasType` when normalizing projection consts)
 - #155527 (Replace printables table with `unicode_data.rs` tables)
 - #156629 (Stabilize `core::range::{legacy, RangeFull, RangeTo}`)
 - #157280 (traits: Allow escaping self types in ExistentialTraitRef::with_self_ty)
 - #157282 (Fix post-monomorphization error note race in the parallel frontend)
 - #157352 (Make the retained dep graph deterministic under the parallel frontend)
 - #157601 (Emit error for unused target expression in glob and list delegations)
 - #157611 (Update `browser-ui-test` version to `0.24.0`)
 - #157620 (Add a strategy FnMut to inject behavior into the flush cycle)
 - #157645 (Windows TLS - Only register the `atexit` hook when `cleanup` can be unloaded)
 - #157646 (Keep rename-imported main alive in dead-code analysis under `--test`)
 - #157647 (Start using comptime for reflection intrinsics and their wrapper functions)
 - #157719 (resolve: Partially revert "Remove a special case for dummy imports")
 - #155153 (Ensure Send/Sync is not implemented for std::env::Vars{,Os})
 - #155198 (fix(mgca): Allow specifying generic args (of enum) on enum itself in unit & tuple variant constructions in (direct) const args)
 - #155323 (refactor `TypeRelativePath::AssocItem` to use `AliasTerm`)
 - #156497 (fix-155516: Don't suggest wrong unwrap expect)
 - #156583 (Support defaults for static EIIs)
 - #157013 (Ensure inferred let pattern types are well-formed)
 - #157196 (Only suggest reborrowing a moved value where the reborrow is valid)
 - #157230 (borrowck: avoid ICE describing fields on generic params)
 - #157288 (platform support: add SNaN erratum to MIPS targets)
 - #157330 (remove `IsTypeConst` from `hir::TraitItemKind`)
 - #157350 (compiletest: ignore SVG `y` offset in by-lines comparison)
 - #157355 (Add `or_try_*` variants for `HashMap` and `BTreeMap` Entry APIs)
 - #157577 (Fix parser error recovery treating 'dyn' as a strict keyword in Rust 2015 when used in `dyn + dyn`)
 - #157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
 - #157691 (Move symbol hiding code to a new file)
 - #157700 (Rename `errors.rs` file to `diagnostics.rs` (5/N))
 - #157703 (Fix doc link to Instant sub in saturating caveat)

Failed merges:

 - #157699 (Arg splat experiment - hir FnDecl impl)
@rust-bors rust-bors Bot merged commit 30c9c47 into rust-lang:main Jun 11, 2026
12 checks passed
@rustbot rustbot added this to the 1.98.0 milestone Jun 11, 2026
rust-timer added a commit that referenced this pull request Jun 11, 2026
Rollup merge of #156497 - lokirithm:fix-155516, r=cjgillot

fix-155516: Don't suggest wrong unwrap expect

Fixes #155516

r? Kivooeo
LaneAsade pushed a commit to LaneAsade/rust that referenced this pull request Jun 11, 2026
Rollup of 31 pull requests

Successful merges:

 - rust-lang#141030 (Expand free alias types during variance computation)
 - rust-lang#154853 (mgca: Register `ConstArgHasType` when normalizing projection consts)
 - rust-lang#155527 (Replace printables table with `unicode_data.rs` tables)
 - rust-lang#156629 (Stabilize `core::range::{legacy, RangeFull, RangeTo}`)
 - rust-lang#157280 (traits: Allow escaping self types in ExistentialTraitRef::with_self_ty)
 - rust-lang#157282 (Fix post-monomorphization error note race in the parallel frontend)
 - rust-lang#157352 (Make the retained dep graph deterministic under the parallel frontend)
 - rust-lang#157601 (Emit error for unused target expression in glob and list delegations)
 - rust-lang#157611 (Update `browser-ui-test` version to `0.24.0`)
 - rust-lang#157620 (Add a strategy FnMut to inject behavior into the flush cycle)
 - rust-lang#157645 (Windows TLS - Only register the `atexit` hook when `cleanup` can be unloaded)
 - rust-lang#157646 (Keep rename-imported main alive in dead-code analysis under `--test`)
 - rust-lang#157647 (Start using comptime for reflection intrinsics and their wrapper functions)
 - rust-lang#157719 (resolve: Partially revert "Remove a special case for dummy imports")
 - rust-lang#155153 (Ensure Send/Sync is not implemented for std::env::Vars{,Os})
 - rust-lang#155198 (fix(mgca): Allow specifying generic args (of enum) on enum itself in unit & tuple variant constructions in (direct) const args)
 - rust-lang#155323 (refactor `TypeRelativePath::AssocItem` to use `AliasTerm`)
 - rust-lang#156497 (fix-155516: Don't suggest wrong unwrap expect)
 - rust-lang#156583 (Support defaults for static EIIs)
 - rust-lang#157013 (Ensure inferred let pattern types are well-formed)
 - rust-lang#157196 (Only suggest reborrowing a moved value where the reborrow is valid)
 - rust-lang#157230 (borrowck: avoid ICE describing fields on generic params)
 - rust-lang#157288 (platform support: add SNaN erratum to MIPS targets)
 - rust-lang#157330 (remove `IsTypeConst` from `hir::TraitItemKind`)
 - rust-lang#157350 (compiletest: ignore SVG `y` offset in by-lines comparison)
 - rust-lang#157355 (Add `or_try_*` variants for `HashMap` and `BTreeMap` Entry APIs)
 - rust-lang#157577 (Fix parser error recovery treating 'dyn' as a strict keyword in Rust 2015 when used in `dyn + dyn`)
 - rust-lang#157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
 - rust-lang#157691 (Move symbol hiding code to a new file)
 - rust-lang#157700 (Rename `errors.rs` file to `diagnostics.rs` (5/N))
 - rust-lang#157703 (Fix doc link to Instant sub in saturating caveat)

Failed merges:

 - rust-lang#157699 (Arg splat experiment - hir FnDecl impl)
LaneAsade pushed a commit to LaneAsade/rust that referenced this pull request Jun 11, 2026
Rollup of 31 pull requests

Successful merges:

 - rust-lang#141030 (Expand free alias types during variance computation)
 - rust-lang#154853 (mgca: Register `ConstArgHasType` when normalizing projection consts)
 - rust-lang#155527 (Replace printables table with `unicode_data.rs` tables)
 - rust-lang#156629 (Stabilize `core::range::{legacy, RangeFull, RangeTo}`)
 - rust-lang#157280 (traits: Allow escaping self types in ExistentialTraitRef::with_self_ty)
 - rust-lang#157282 (Fix post-monomorphization error note race in the parallel frontend)
 - rust-lang#157352 (Make the retained dep graph deterministic under the parallel frontend)
 - rust-lang#157601 (Emit error for unused target expression in glob and list delegations)
 - rust-lang#157611 (Update `browser-ui-test` version to `0.24.0`)
 - rust-lang#157620 (Add a strategy FnMut to inject behavior into the flush cycle)
 - rust-lang#157645 (Windows TLS - Only register the `atexit` hook when `cleanup` can be unloaded)
 - rust-lang#157646 (Keep rename-imported main alive in dead-code analysis under `--test`)
 - rust-lang#157647 (Start using comptime for reflection intrinsics and their wrapper functions)
 - rust-lang#157719 (resolve: Partially revert "Remove a special case for dummy imports")
 - rust-lang#155153 (Ensure Send/Sync is not implemented for std::env::Vars{,Os})
 - rust-lang#155198 (fix(mgca): Allow specifying generic args (of enum) on enum itself in unit & tuple variant constructions in (direct) const args)
 - rust-lang#155323 (refactor `TypeRelativePath::AssocItem` to use `AliasTerm`)
 - rust-lang#156497 (fix-155516: Don't suggest wrong unwrap expect)
 - rust-lang#156583 (Support defaults for static EIIs)
 - rust-lang#157013 (Ensure inferred let pattern types are well-formed)
 - rust-lang#157196 (Only suggest reborrowing a moved value where the reborrow is valid)
 - rust-lang#157230 (borrowck: avoid ICE describing fields on generic params)
 - rust-lang#157288 (platform support: add SNaN erratum to MIPS targets)
 - rust-lang#157330 (remove `IsTypeConst` from `hir::TraitItemKind`)
 - rust-lang#157350 (compiletest: ignore SVG `y` offset in by-lines comparison)
 - rust-lang#157355 (Add `or_try_*` variants for `HashMap` and `BTreeMap` Entry APIs)
 - rust-lang#157577 (Fix parser error recovery treating 'dyn' as a strict keyword in Rust 2015 when used in `dyn + dyn`)
 - rust-lang#157670 (Rename `errors.rs` file to `diagnostics.rs` (4/N))
 - rust-lang#157691 (Move symbol hiding code to a new file)
 - rust-lang#157700 (Rename `errors.rs` file to `diagnostics.rs` (5/N))
 - rust-lang#157703 (Fix doc link to Instant sub in saturating caveat)

Failed merges:

 - rust-lang#157699 (Arg splat experiment - hir FnDecl impl)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

perf-regression Performance regression. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

Incorrect suggestion when assigning Option<T> to a T in a struct pattern

8 participants