Skip to content

fixed: differentiation between uninitialized and possibly uninitialized#157507

Merged
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
mazam-97:fix-uninit-vs-possibly-uninitialized
Jun 15, 2026
Merged

fixed: differentiation between uninitialized and possibly uninitialized#157507
rust-bors[bot] merged 1 commit into
rust-lang:mainfrom
mazam-97:fix-uninit-vs-possibly-uninitialized

Conversation

@mazam-97

@mazam-97 mazam-97 commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

@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 Jun 5, 2026
@rustbot

rustbot commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @tiif (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue
Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: borrowck, compiler
  • borrowck, compiler expanded to 73 candidates
  • Random selection from 21 candidates

@mazam-97 mazam-97 force-pushed the fix-uninit-vs-possibly-uninitialized branch from c44dc16 to 5c47002 Compare June 5, 2026 19:49
@Unique-Usman

Copy link
Copy Markdown
Contributor

Thanks for the pr, can we change it commit message to something like "avoid reporting unreachable initializations for uninitialized uses" ?

@Unique-Usman

Copy link
Copy Markdown
Contributor

Also, we need to add more test i.e one for match expression, one or two if we have multiple block of if or match expressions.

@Unique-Usman

Copy link
Copy Markdown
Contributor

cc: @estebank

| - binding declared here but left uninitialized
...
LL | println!("{x}");
| ^ `x` used here but it isn't initialized

@Unique-Usman Unique-Usman Jun 5, 2026

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.

Here, we might want to have something like

"`x` used here, but all known initializations occur on control-flow paths that do not reach this use"  

or a shorter version

`x` used here, but it is not initialized on any path leading to this point

because, x was actually initialized but, it was initilized on another branch or block which will never reach the error block.

There would probably be another else if statement in this block -> https://github.com/rust-lang/rust/blob/main/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs#L820C86-L845C40

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.

I think what you say makes sense. The error should be more explicit. I will add one more block.

@mazam-97

mazam-97 commented Jun 6, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the pr, can we change it commit message to something like "avoid reporting unreachable initializations for uninitialized uses" ?

Thanks for reviewing the PR @Unique-Usman. I will modify the commit messge as suggested.

@mazam-97

mazam-97 commented Jun 6, 2026

Copy link
Copy Markdown
Contributor Author

Also, we need to add more test i.e one for match expression, one or two if we have multiple block of if or match expressions.

Sure, I will add more tests having match expression and if else blocks.

@mazam-97 mazam-97 force-pushed the fix-uninit-vs-possibly-uninitialized branch from 5c47002 to 82f933b Compare June 6, 2026 23:35
@rust-log-analyzer

This comment has been minimized.

@mazam-97 mazam-97 force-pushed the fix-uninit-vs-possibly-uninitialized branch 2 times, most recently from 852819d to 6e04da5 Compare June 7, 2026 01:36
}

println!("{x}"); //~ ERROR E0381
}

@Unique-Usman Unique-Usman Jun 7, 2026

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.

This should be something like

fn main() {
    let x;

    match true {
        true => x = 42,
        false =>  println!("{x}"), //~ ERROR E0381
    }
}

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.

Addressed.

}

println!("{x}"); //~ ERROR E0381
}

@Unique-Usman Unique-Usman Jun 7, 2026

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.

if you want to have multiple match, do not nested it like this. You can have something like this.

enum PrimaryColor {
  RED,
  BLUE,
  GREEN
}

fn main() {
    let x;
    let pc = PrimaryColor::RED,

    match pc {
        PrimaryColor::RED => x = 1,
        PrimaryColor::BLUE => x = 3,
        PrimaryColor::GREEN =>  println!("{x}"); //~ ERROR E0381
    }

}

Also, something similar for the if and else i.e for multiple branch.

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.

Addressed. Added a test having an enum with match

@mazam-97 mazam-97 force-pushed the fix-uninit-vs-possibly-uninitialized branch from 6e04da5 to 5a8f234 Compare June 7, 2026 02:22
@rust-log-analyzer

This comment has been minimized.

@mazam-97 mazam-97 force-pushed the fix-uninit-vs-possibly-uninitialized branch from 5a8f234 to e4cb2a6 Compare June 7, 2026 02:54
@rust-log-analyzer

This comment has been minimized.

@mazam-97 mazam-97 force-pushed the fix-uninit-vs-possibly-uninitialized branch from e4cb2a6 to c868e83 Compare June 7, 2026 10:42
@rust-log-analyzer

This comment has been minimized.

@mazam-97 mazam-97 force-pushed the fix-uninit-vs-possibly-uninitialized branch from c868e83 to 29826f9 Compare June 7, 2026 11:12
@estebank

estebank commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

As follow up work, we should point at the places where when a condition is true, the binding would be initialized, explaining that if that condition isn't true, the binding wouldn't be initialized. This is because there are some code patterns like state machines where you are doing work on a loop, and the first loop cycle a certain condition would be true, inicializing the binding, but the compiler/type system can't see that. The person that wrote the code might get confused when looking at the other branches and seeing that the binding is initialized elsewhere, so lets be proactive and point at the conditions.

Given:

let x;
if foo { x = 1; }
println!("{x}");

We should point at foo saying "if this condition isn't met, then x isn't initialized", and point at x = 1; saying "if foo isn't true, then this won't be reached". We should also account for multiple paths initializing x, and avoid having more than a handful of labels pointing at initializers (imagine 1000 places where x is initialized, and we missed one, we don't want to spam the output).

Doing a review on the code now, I feel like this is likely in a mergeable state already.

Comment thread compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
…uses

Mentored-by: Usman Akinyemi <usmanakinyemi202@gmail.com>
Signed-off-by: Dilshad Azam <azam.dilshad@gmail.com>
@mazam-97 mazam-97 force-pushed the fix-uninit-vs-possibly-uninitialized branch from 29826f9 to 417015d Compare June 8, 2026 18:12
@mazam-97

mazam-97 commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

As follow up work, we should point at the places where when a condition is true, the binding would be initialized, explaining that if that condition isn't true, the binding wouldn't be initialized. This is because there are some code patterns like state machines where you are doing work on a loop, and the first loop cycle a certain condition would be true, inicializing the binding, but the compiler/type system can't see that. The person that wrote the code might get confused when looking at the other branches and seeing that the binding is initialized elsewhere, so lets be proactive and point at the conditions.

Given:

let x;
if foo { x = 1; }
println!("{x}");

We should point at foo saying "if this condition isn't met, then x isn't initialized", and point at x = 1; saying "if foo isn't true, then this won't be reached". We should also account for multiple paths initializing x, and avoid having more than a handful of labels pointing at initializers (imagine 1000 places where x is initialized, and we missed one, we don't want to spam the output).

Doing a review on the code now, I feel like this is likely in a mergeable state already.

I agree, It makes sense. Pointing at the conditions that guard initialization would likely make the diagnostic more actionable. We should work on it as a follow up.

@Unique-Usman

Copy link
Copy Markdown
Contributor

pinging: @estebank

@tiif

tiif commented Jun 15, 2026

Copy link
Copy Markdown
Member

Thanks for your contribution! I took a close look at this PR, and it seems correct to me. But unfortunately I am not familiar enough with this part of the compiler to merge it, so

r? @estebank

since you took a look at it.

@rustbot rustbot assigned estebank and unassigned tiif Jun 15, 2026
@tiif

tiif commented Jun 15, 2026

Copy link
Copy Markdown
Member

Also, since this is an extra analysis, it might have perf impact. I will run perf just in case.

@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 Jun 15, 2026
@rust-bors

This comment has been minimized.

rust-bors Bot pushed a commit that referenced this pull request Jun 15, 2026
…, r=<try>

fixed: differentiation between uninitialized and possibly uninitialized
@rust-bors

rust-bors Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

☀️ Try build successful (CI)
Build commit: 8a523a6 (8a523a604b2ca1b50e5ba16e03a8d762207cbad2, parent: b5d46ecb51c3e4134b82570cfe718f093daa6390)

@rust-timer

This comment has been minimized.

@rust-timer

Copy link
Copy Markdown
Collaborator

Finished benchmarking commit (8a523a6): comparison URL.

Overall result: no relevant changes - no action needed

Benchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up.

@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

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

Max RSS (memory usage)

Results (primary -5.6%, secondary -1.5%)

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)
- - 0
Improvements ✅
(primary)
-5.6% [-5.6%, -5.6%] 1
Improvements ✅
(secondary)
-1.5% [-2.2%, -0.7%] 2
All ❌✅ (primary) -5.6% [-5.6%, -5.6%] 1

Cycles

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

Binary size

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

Bootstrap: 522.814s -> 519.939s (-0.55%)
Artifact size: 400.99 MiB -> 401.44 MiB (0.11%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jun 15, 2026
@estebank

Copy link
Copy Markdown
Contributor

@bors r+

Thank you for the contribution!

@rust-bors

rust-bors Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 417015d has been approved by estebank

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 15, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jun 15, 2026
…initialized, r=estebank

fixed: differentiation between uninitialized and possibly uninitialized

Fix: rust-lang#157267
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Jun 15, 2026
…initialized, r=estebank

fixed: differentiation between uninitialized and possibly uninitialized

Fix: rust-lang#157267
rust-bors Bot pushed a commit that referenced this pull request Jun 15, 2026
Rollup of 13 pull requests

Successful merges:

 - #152544 (Stabilize `int_format_into` feature)
 - #157507 (fixed: differentiation between uninitialized and possibly uninitialized)
 - #155750 (Document that `ManuallyDrop`'s `Box` interaction has been fixed)
 - #157075 (lower edition requirements for some async-closure test helpers)
 - #157627 (remove LLVM `va_end` calls)
 - #157660 (normalize instead of evaluating type const patterns)
 - #157692 (Don't emit `unused_parens` suggestion for proc-macro-synthesized parens around bounds)
 - #157908 (fix binding const argument to assoc type suggestion)
 - #157915 (scalable vecs size incl. num vecs + no sret for scalable vecs)
 - #157916 (Avoid ICE on invalid crate-level cfg_attr predicates)
 - #157919 (mention in the `extern "tail"` error that it's supported on x86)
 - #157920 (mailmap: add mu001999)
 - #157924 (Update books)
@rust-bors rust-bors Bot merged commit 4020cba into rust-lang:main Jun 15, 2026
13 checks passed
@rustbot rustbot added this to the 1.98.0 milestone Jun 16, 2026
rust-timer added a commit that referenced this pull request Jun 16, 2026
Rollup merge of #157507 - mazam-97:fix-uninit-vs-possibly-uninitialized, r=estebank

fixed: differentiation between uninitialized and possibly uninitialized

Fix: #157267
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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 differentiation of uninitialized and possibly-uninitialized

7 participants