Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use of uninitialized variable after pattern error #60350

Closed
matthewjasper opened this issue Apr 28, 2019 · 3 comments · Fixed by #67668
Closed

Use of uninitialized variable after pattern error #60350

matthewjasper opened this issue Apr 28, 2019 · 3 comments · Fixed by #67668
Labels
A-NLL Area: Non-lexical lifetimes (NLL) E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. NLL-fixed-by-NLL Bugs fixed, but only when NLL is enabled.

Comments

@matthewjasper
Copy link
Contributor

The following code reports a warning that x is uninitialized as well as the expected pattern error.

fn destructure_slice(s: &[i32]) {
    let [x] = *s;
    drop(x);
}

playground

@matthewjasper matthewjasper added the A-NLL Area: Non-lexical lifetimes (NLL) label Apr 28, 2019
@matthewjasper matthewjasper added E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. labels May 12, 2019
@Pulkit07
Copy link
Contributor

I will like to work on this bug.

On initial findings, the initial pattern error is coming from https://github.com/rust-lang/rust/blob/master/src/librustc_mir/hair/pattern/check_match.rs#L261.

My hypothesis is that because of the pattern error, we don't add x to a list of initialized variables and hence we get the uninitialized error.

Does that sounds like a good start?

@matthewjasper
Copy link
Contributor Author

matthewjasper commented May 16, 2019

KindThe place to start looking would be here:

pub fn place_into_pattern(
&mut self,
block: BasicBlock,
irrefutable_pat: Pattern<'tcx>,
initializer: &Place<'tcx>,
set_match_place: bool,
) -> BlockAnd<()> {
// create a dummy candidate
let mut candidate = Candidate {
span: irrefutable_pat.span,
match_pairs: vec![MatchPair::new(initializer.clone(), &irrefutable_pat)],
bindings: vec![],
ascriptions: vec![],
// since we don't call `match_candidates`, next fields are unused
otherwise_block: None,
pre_binding_block: block,
next_candidate_pre_binding_block: block,
};
// Simplify the candidate. Since the pattern is irrefutable, this should
// always convert all match-pairs into bindings.
self.simplify_candidate(&mut candidate);
if !candidate.match_pairs.is_empty() {
// ICE if no other errors have been emitted. This used to be a hard error that wouldn't
// be reached because `hair::pattern::check_match::check_match` wouldn't have let the
// compiler continue. In our tests this is only ever hit by
// `ui/consts/const-match-check.rs` with `--cfg eval1`, and that file already generates
// a different error before hand.
self.hir.tcx().sess.delay_span_bug(
candidate.match_pairs[0].pattern.span,
&format!(
"match pairs {:?} remaining after simplifying irrefutable pattern",
candidate.match_pairs,
),
);
}
// for matches and function arguments, the place that is being matched
// can be set when creating the variables. But the place for
// let PATTERN = ... might not even exist until we do the assignment.
// so we set it here instead
if set_match_place {
for binding in &candidate.bindings {
let local = self.var_local_id(binding.var_id, OutsideGuard);
if let Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
opt_match_place: Some((ref mut match_place, _)),
..
}))) = self.local_decls[local].is_user_variable
{
*match_place = Some(initializer.clone());
} else {

You'll need to use the functions in rustc_mir::build::matches::test to extract any bindings from the match_pairs.

@Centril Centril added the NLL-fixed-by-NLL Bugs fixed, but only when NLL is enabled. label Sep 5, 2019
@Centril
Copy link
Contributor

Centril commented Sep 27, 2019

@matthewjasper We now have two errors instead... is there anything more to do here, e.g. improving diagnostics?

bors added a commit that referenced this issue Dec 28, 2019
Implement MIR lowering for or-patterns

This is the last thing needed to get meaningful run-pass tests for or-patterns. There probably need to be more tests before stabilizing this, but the most important cases should have been covered.

Note: we can generate exponentially large MIR CFGs when using or-patterns containing bindings, type ascriptions, or that are for a match arm with a guard. `src/test/mir-opt/exponential-or.rs` shows the best case for what we currently do.

cc #54883
closes #60350
closes #67514

cc @Centril
r? @pnkfelix
@bors bors closed this as completed in 42a0bd2 Feb 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-NLL Area: Non-lexical lifetimes (NLL) E-medium Call for participation: Medium difficulty. Experience needed to fix: Intermediate. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. NLL-fixed-by-NLL Bugs fixed, but only when NLL is enabled.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants