forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#71726 - ldm0:ref2ptr, r=oli-obk
Suggest deref when coercing `ty::Ref` to `ty::RawPtr` with arbitrary mutability Fixes rust-lang#71676 1. Implement dereference suggestion when coercing `ty::Ref` to `ty::RawPtr` with arbitrary mutability. 2. Extract the dereference steps into `deref_steps()`, which removes all the `use` and `pub` noise introduced by last PR rust-lang#71540, and makes the code more readable. 3. Use the `remove_prefix()` closure which makes the prefix removal more readable. 4. Introduce `Applicability` as a return value of `check_ref` to suggest `Applicability::Unspecified` suggestion. **Special**: I found it is not possible to genereate `Applicability::MachineApplicable` suggestion for situation like this: ```rust use std::ops::Deref; use std::ops::DerefMut; struct Bar(u8); struct Foo(Bar); struct Emm(Foo); impl Deref for Bar{ type Target = u8; fn deref(&self) -> &Self::Target { &self.0 } } impl Deref for Foo { type Target = Bar; fn deref(&self) -> &Self::Target { &self.0 } } impl Deref for Emm { type Target = Foo; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for Bar{ fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl DerefMut for Foo { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl DerefMut for Emm { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } fn main() { let a = Emm(Foo(Bar(0))); let _: *mut u8 = &a; //~ ERROR mismatched types } ``` We may suggest `&mut ***a` here, but the `a` is not declared as mutable variable. And also when processing HIR, it's not possible to check if `a` is declared as a mutable variable (currently we do borrow checking with MIR). So we cannot ensure that suggestion when coercing immutable reference to mutable pointer is always machine applicable. Therefore I added a `Applicability` return value in `check_ref()`. And move the `immutable reference -> mutable pointer` situation into a sperate test file without `run-rustfix`. (It seems that `run-rustfix` will also adopt `Applicability::Unspecified` suggestion, which is strange)
- Loading branch information
Showing
10 changed files
with
334 additions
and
47 deletions.
There are no files selected for viewing
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
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
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
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
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
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,53 @@ | ||
// run-rustfix | ||
use std::ops::Deref; | ||
use std::ops::DerefMut; | ||
struct Bar(u8); | ||
struct Foo(Bar); | ||
struct Emm(Foo); | ||
impl Deref for Bar{ | ||
type Target = u8; | ||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} | ||
impl Deref for Foo { | ||
type Target = Bar; | ||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} | ||
impl Deref for Emm { | ||
type Target = Foo; | ||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} | ||
impl DerefMut for Bar{ | ||
fn deref_mut(&mut self) -> &mut Self::Target { | ||
&mut self.0 | ||
} | ||
} | ||
impl DerefMut for Foo { | ||
fn deref_mut(&mut self) -> &mut Self::Target { | ||
&mut self.0 | ||
} | ||
} | ||
impl DerefMut for Emm { | ||
fn deref_mut(&mut self) -> &mut Self::Target { | ||
&mut self.0 | ||
} | ||
} | ||
fn main() { | ||
// Suggest dereference with arbitrary mutability | ||
let a = Emm(Foo(Bar(0))); | ||
let _: *const u8 = &***a; //~ ERROR mismatched types | ||
|
||
let mut a = Emm(Foo(Bar(0))); | ||
let _: *mut u8 = &mut ***a; //~ ERROR mismatched types | ||
|
||
let a = Emm(Foo(Bar(0))); | ||
let _: *const u8 = &***a; //~ ERROR mismatched types | ||
|
||
let mut a = Emm(Foo(Bar(0))); | ||
let _: *mut u8 = &mut ***a; //~ ERROR mismatched types | ||
} |
Oops, something went wrong.