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

Add UI test for issue 73592 #73634

Merged
merged 1 commit into from
Jun 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/test/ui/typeck/issue-73592-borrow_mut-through-deref.rs
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 src/test/ui/typeck/issue-73592-borrow_mut-through-deref.stderr
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