fn main() {
let foo = RwLock::new(Foo{});
let i = foo.write().unwrap().a();
match i {
None => {}
Some(i) => {
foo.write().unwrap().b(i);
}
}
}
The codes will work fine.
Shouldn't the lock release as soon as a() is called? I think the lock in the first case is temporary, but the fact is that it lives as long as b() get called.
So what's the difference between case 1 and case 2, is this a bug or design in purpose?
That is an intentional design. Rust keeps temporaries around until the end of the statement. Both let i and match i are equivalent in this case, but you see the problem because you do extra work inside the match.
If you try let i = (foo.write().unwrap().a(), foo.write().unwrap().a()) you'll also find it locked.
This interaction with if let is annoying indeed. You will have to use a temporary variable.
I don't think there are any plans so change this behaviour. Scope of temporaries is observable, so a fix for it could break code relying on the current behaviour.
The important thing is to note that for the program to be correct compiler and developer have to agree on the scope.
But if developer thinks scope is small and compiler thinks it's large the end result is usually easily fixable compile-time error.
If developer thinks scope is large and it's, in reality, small, then this can lead to strange and dangerous problems without triggering compiler-time errors.
Thus I guess current scope rules are good even if I, too, suffer from them sometimes.