Repository navigation
binding-less matches on borrowed data are incorrectly allowed #45045
Copy link
Copy link
Closed
Labels
A-NLLArea: Non-lexical lifetimes (NLL)Area: Non-lexical lifetimes (NLL)A-borrow-checkerArea: The borrow checkerArea: The borrow checkerC-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityMedium priorityfixed-by-NLLBugs fixed, but only when NLL is enabled.Bugs fixed, but only when NLL is enabled.
Milestone
Description
Activity
- addedA-borrow-checkerArea: The borrow checkerArea: The borrow checkerI-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
on Oct 5, 2017 This is actually an unsoundness in AST borrowck
Does this imply that this is another bug on the pile of things fixed by MIR borrowck?
Does this imply that this is another bug on the pile of things fixed by MIR borrowck?
Yeah.
- addedA-NLLArea: Non-lexical lifetimes (NLL)Area: Non-lexical lifetimes (NLL)
on Dec 21, 2017 This still compiles with MIR borrowck, so I guess more work is needed.
Is this same problem as #27282 ?
It seems like the problem is that the
discriminantstatement is not considered an access. Here is the relevant portion of the MIR:bb0: { StorageLive(_1); // bb0[0]: scope 0 at src/main.rs:9:9: 9:14 _1 = Xyz::A; // bb0[1]: scope 0 at src/main.rs:9:17: 9:23 StorageLive(_2); // bb0[2]: scope 1 at src/main.rs:10:9: 10:10 _2 = &mut _1; // bb0[3]: scope 1 at src/main.rs:10:13: 10:19 _4 = discriminant(_1); // bb0[4]: scope 3 at src/main.rs:12:9: 12:15 switchInt(move _4) -> [0isize: bb1, 1isize: bb2, otherwise: bb3]; // bb0[5]: scope 3 at src/main.rs:12:9: 12:15 }@pnkfelix points out that two-phase borrows may be the cause. This example gets an error:
#![feature(nll)] enum Xyz { A, B, } fn main() { let mut e = Xyz::A; let f = &mut e; let g = f; match e { Xyz::A => println!("a"), Xyz::B => println!("b"), }; *g = Xyz::B; }
this gets the following output:
error[E0503]: cannot use `e` because it was mutably borrowed --> src/main.rs:13:9 | 10 | let f = &mut e; | ------ borrow of `e` occurs here ... 13 | Xyz::A => println!("a"), | ^^^^^^ use of borrowed `e`That's indeed what I expect under 2-phase borrows.
- added a commit that references this issue
on Jan 15, 2018 - modified the milestones: This milestone has been deleted, This milestone has been deleted
on Jan 19, 2018 - addedfixed-by-NLLBugs fixed, but only when NLL is enabled.Bugs fixed, but only when NLL is enabled.
on Oct 9, 2018
Metadata
Metadata
Assignees
Labels
A-NLLArea: Non-lexical lifetimes (NLL)Area: Non-lexical lifetimes (NLL)A-borrow-checkerArea: The borrow checkerArea: The borrow checkerC-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-mediumMedium priorityMedium priorityfixed-by-NLLBugs fixed, but only when NLL is enabled.Bugs fixed, but only when NLL is enabled.
This is actually an unsoundness in AST borrowck: AST borrowck doesn't check things that are matched on for conflicting borrows unless there are actually pattern bindings, e.g. this compiles:
That is unsound because of e.g. data races. For example, this code compiles and runs, and semi-reliably segfaults: