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

Suggest deref when coercing ty::Ref to ty::RawPtr with arbitrary mutability #71726

Merged
merged 4 commits into from
May 3, 2020

Conversation

ldm0
Copy link
Contributor

@ldm0 ldm0 commented May 1, 2020

Fixes #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 Suggest deref when coercing ty::Ref to ty::RawPtr #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:

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)

@rust-highfive
Copy link
Collaborator

r? @cramertj

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 1, 2020
@ldm0
Copy link
Contributor Author

ldm0 commented May 1, 2020

r? @oli-obk
Since #71540

@rust-highfive rust-highfive assigned oli-obk and unassigned cramertj May 1, 2020
@@ -470,7 +474,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let sugg_expr = if needs_parens { format!("({})", src) } else { src };

if let Some(sugg) = self.can_use_as_ref(expr) {
return Some(sugg);
return Some((
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're reaching the point where this function should probably return a struct with named fields ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I think for consistency that would requires a lot of irrelevant changes. If that's really need would changing them in a seperate PR be better? :-P

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yea, this was mainly a drive by comment, feel free to address it or not or in a different PR

@oli-obk
Copy link
Contributor

oli-obk commented May 1, 2020

@bors r+

@bors
Copy link
Contributor

bors commented May 1, 2020

📌 Commit a74a048cb7e61f7038f2a48c39cc3d8af37fc354 has been approved by oli-obk

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels May 1, 2020
bors added a commit to rust-lang-ci/rust that referenced this pull request May 2, 2020
Rollup of 5 pull requests

Successful merges:

 - rust-lang#71018 (handle ConstValue::ByRef in relate)
 - rust-lang#71758 (Remove leftover chalk types)
 - rust-lang#71760 (Document unsafety for `*const T` and `*mut T`)
 - rust-lang#71761 (doc: reference does not exist, probably a typo)
 - rust-lang#71762 (doc: this resulted in a link pointing to a non-existent target)

Failed merges:

 - rust-lang#71726 (Suggest deref when coercing `ty::Ref` to `ty::RawPtr` with arbitrary mutability)

r? @ghost
@bors
Copy link
Contributor

bors commented May 2, 2020

☔ The latest upstream changes (presumably #71776) made this pull request unmergeable. Please resolve the merge conflicts.

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 2, 2020
@ldm0
Copy link
Contributor Author

ldm0 commented May 2, 2020

Rebase done.

@oli-obk
Copy link
Contributor

oli-obk commented May 2, 2020

@bors r+

@bors
Copy link
Contributor

bors commented May 2, 2020

📌 Commit 9a212c1 has been approved by oli-obk

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 2, 2020
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request May 2, 2020
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)
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request May 3, 2020
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)
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request May 3, 2020
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)
bors added a commit to rust-lang-ci/rust that referenced this pull request May 3, 2020
Rollup of 4 pull requests

Successful merges:

 - rust-lang#71398 (Add `RefCell::take`)
 - rust-lang#71663 (Fix exceeding bitshifts not emitting for assoc. consts (properly this time, I swear!))
 - rust-lang#71726 (Suggest deref when coercing `ty::Ref` to `ty::RawPtr` with arbitrary mutability)
 - rust-lang#71808 (Add long error explanation for E0539)

Failed merges:

r? @ghost
@bors bors merged commit 44e678b into rust-lang:master May 3, 2020
@ldm0 ldm0 deleted the ref2ptr branch May 4, 2020 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Suggest deref when coercing mutable ty::Ref to ty::RawPtr
5 participants