-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
82 additions
and
0 deletions.
There are no files selected for viewing
58 changes: 58 additions & 0 deletions
58
src/test/ui/typeck/issue-73592-borrow_mut-through-deref.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// check-pass | ||
// | ||
// rust-lang/rust#73592: borrow_mut through Deref should work. | ||
// | ||
// Before #72280, when we see something like `&mut *rcvr.method()`, we | ||
// incorrectly requires `rcvr` to be type-checked as a mut place. While this | ||
// requirement is usually correct for smart pointers, it is overly restrictive | ||
// for types like `Mutex` or `RefCell` which can produce a guard that | ||
// implements `DerefMut` from `&self`. | ||
// | ||
// Making it more confusing, because we use Deref as the fallback when DerefMut | ||
// is implemented, we won't see an issue when the smart pointer does not | ||
// implement `DerefMut`. It only causes an issue when `rcvr` is obtained via a | ||
// type that implements both `Deref` or `DerefMut`. | ||
// | ||
// This bug is only discovered in #73592 after it is already fixed as a side-effect | ||
// of a refactoring made in #72280. | ||
|
||
#![warn(unused_mut)] | ||
|
||
use std::pin::Pin; | ||
use std::cell::RefCell; | ||
|
||
struct S(RefCell<()>); | ||
|
||
fn test_pin(s: Pin<&S>) { | ||
// This works before #72280. | ||
let _ = &mut *s.0.borrow_mut(); | ||
} | ||
|
||
fn test_pin_mut(s: Pin<&mut S>) { | ||
// This should compile but didn't before #72280. | ||
let _ = &mut *s.0.borrow_mut(); | ||
} | ||
|
||
fn test_vec(s: &Vec<RefCell<()>>) { | ||
// This should compile but didn't before #72280. | ||
let _ = &mut *s[0].borrow_mut(); | ||
} | ||
|
||
fn test_mut_pin(mut s: Pin<&S>) { | ||
//~^ WARN variable does not need to be mutable | ||
let _ = &mut *s.0.borrow_mut(); | ||
} | ||
|
||
fn test_mut_pin_mut(mut s: Pin<&mut S>) { | ||
//~^ WARN variable does not need to be mutable | ||
let _ = &mut *s.0.borrow_mut(); | ||
} | ||
|
||
fn main() { | ||
let mut s = S(RefCell::new(())); | ||
test_pin(Pin::new(&s)); | ||
test_pin_mut(Pin::new(&mut s)); | ||
test_mut_pin(Pin::new(&s)); | ||
test_mut_pin_mut(Pin::new(&mut s)); | ||
test_vec(&vec![s.0]); | ||
} |
24 changes: 24 additions & 0 deletions
24
src/test/ui/typeck/issue-73592-borrow_mut-through-deref.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
warning: variable does not need to be mutable | ||
--> $DIR/issue-73592-borrow_mut-through-deref.rs:41:17 | ||
| | ||
LL | fn test_mut_pin(mut s: Pin<&S>) { | ||
| ----^ | ||
| | | ||
| help: remove this `mut` | ||
| | ||
note: the lint level is defined here | ||
--> $DIR/issue-73592-borrow_mut-through-deref.rs:19:9 | ||
| | ||
LL | #![warn(unused_mut)] | ||
| ^^^^^^^^^^ | ||
|
||
warning: variable does not need to be mutable | ||
--> $DIR/issue-73592-borrow_mut-through-deref.rs:46:21 | ||
| | ||
LL | fn test_mut_pin_mut(mut s: Pin<&mut S>) { | ||
| ----^ | ||
| | | ||
| help: remove this `mut` | ||
|
||
warning: 2 warnings emitted | ||
|