rust/compiler
bors 8eef79ca9a Auto merge of #84968 - FabianWolff:master, r=estebank
Fix incorrect suggestions for E0605

Fixes #84598. Here is a simplified version of the problem presented in issue #84598:

```Rust
#![allow(unused_variables)]
#![allow(dead_code)]

trait T { fn t(&self) -> i32; }

unsafe fn foo(t: *mut dyn T) {
    (t as &dyn T).t();
}

fn main() {}
```

The current output is:
```
error[E0605]: non-primitive cast: `*mut (dyn T + 'static)` as `&dyn T`
 --> src/main.rs:7:5
  |
7 |     (t as &dyn T).t();
  |     ^^^^^^^^^^^^^ invalid cast
  |
help: borrow the value for the cast to be valid
  |
7 |     (&t as &dyn T).t();
  |      ^
```

This is incorrect, though: The cast will _not_ be valid when writing `&t` instead of `t`:
```
error[E0277]: the trait bound `*mut (dyn T + 'static): T` is not satisfied
 --> t4.rs:7:6
  |
7 |     (&t as &dyn T).t();
  |      ^^ the trait `T` is not implemented for `*mut (dyn T + 'static)`
  |
  = note: required for the cast to the object type `dyn T`
```

The correct suggestion is `&*t`, which I have implemented in this pull request. Of course, this suggestion will always require an unsafe block, but arguably, that's what the user really wants if they're trying to cast a pointer to a reference.

In any case, claiming that the cast will be valid after implementing the suggestion is overly optimistic, as the coercion logic doesn't seem to resolve all nested obligations, i.e. the cast may still be invalid after implementing the suggestion. I have therefore rephrased the suggestion slightly ("consider borrowing the value" instead of "borrow the value for the cast to be valid").

Additionally, I have fixed another incorrect suggestion not mentioned in #84598, which relates to casting immutable references to mutable ones:

```rust
fn main() {
    let mut x = 0;
    let m = &x as &mut i32;
}
```
currently leads to
```
error[E0605]: non-primitive cast: `&i32` as `&mut i32`
 --> t5.rs:3:13
  |
3 |     let m = &x as &mut i32;
  |             ^^^^^^^^^^^^^^ invalid cast
  |
help: borrow the value for the cast to be valid
  |
3 |     let m = &mut &x as &mut i32;
  |             ^^^^
```
which is obviously incorrect:
```
error[E0596]: cannot borrow data in a `&` reference as mutable
 --> t5.rs:3:13
  |
3 |     let m = &mut &x as &mut i32;
  |             ^^^^^^^ cannot borrow as mutable
```
I've changed the suggestion to a note explaining the problem:
```
error[E0605]: non-primitive cast: `&i32` as `&mut i32`
 --> t5.rs:3:13
  |
3 |     let m = &x as &mut i32;
  |             ^^^^^^^^^^^^^^ invalid cast
  |
note: this reference is immutable
 --> t5.rs:3:13
  |
3 |     let m = &x as &mut i32;
  |             ^^
note: trying to cast to a mutable reference type
 --> t5.rs:3:19
  |
3 |     let m = &x as &mut i32;
  |                   ^^^^^^^^
```
In this example, it would have been even nicer to suggest replacing `&x` with `&mut x`, but this would be much more complex because we would have to take apart the expression to be cast (currently, we only look at its type), and `&x` could be stored in a variable, where such a suggestion would not even be directly applicable:
```rust
fn main() {
    let mut x = 0;
    let r = &x;
    let m = r as &mut i32;
}
```
My solution covers this case, too.
2021-05-28 03:38:28 +00:00
..
rustc use jemallocator in rustc/rustdoc 2021-04-04 14:10:26 -07:00
rustc_apfloat remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_arena Remove (lots of) dead code 2021-03-27 22:16:33 -04:00
rustc_ast remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_ast_lowering remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_ast_passes Stabilize extended_key_value_attributes 2021-05-18 01:01:36 -04:00
rustc_ast_pretty remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_attr remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_builtin_macros remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_codegen_cranelift Merge commit '40dd3e2b70' into sync_cg_clif-2021-05-27 2021-05-27 13:08:14 +02:00
rustc_codegen_llvm remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_codegen_ssa Rollup merge of #85649 - ChrisDenton:update-cc, r=matthewjasper 2021-05-27 03:02:09 +02:00
rustc_data_structures Only compute Obligation cache_key once in register_obligation_at 2021-05-04 11:57:53 -07:00
rustc_driver Auto merge of #83842 - LeSeulArtichaut:thir-vec, r=nikomatsakis 2021-05-19 18:41:23 +00:00
rustc_error_codes swap function order for better read flow 2021-05-13 13:22:24 +02:00
rustc_errors Stabilize extended_key_value_attributes 2021-05-18 01:01:36 -04:00
rustc_expand remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_feature stabilize member constraints 2021-05-26 06:01:53 -04:00
rustc_fs_util Optimize away a fs::metadata call. 2021-01-06 08:33:15 -08:00
rustc_graphviz Remove (lots of) dead code 2021-03-27 22:16:33 -04:00
rustc_hir remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_hir_pretty remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_incremental Get rid of PreviousDepGraph. 2021-05-22 14:14:23 +02:00
rustc_index Change bitwise operator to more easily keep data in vector registers 2021-05-04 11:55:18 -04:00
rustc_infer remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_interface Make thir_check_unsafety itself responsible for checking gate 2021-05-24 15:09:33 +02:00
rustc_lexer Fix outdated crate names in compiler docs 2021-04-08 11:12:14 -05:00
rustc_lint Lint against non-camelCase trait alias names 2021-05-26 19:55:27 -04:00
rustc_lint_defs Add additional migrations to handle auto-traits and clone traits 2021-05-06 14:17:59 -04:00
rustc_llvm Update cc 2021-05-24 23:34:12 +01:00
rustc_macros Use iter::zip in compiler/ 2021-03-26 09:32:31 -07:00
rustc_metadata remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_middle Auto merge of #85729 - LeSeulArtichaut:thir-no-hash, r=nikomatsakis 2021-05-27 15:46:48 +00:00
rustc_mir Rollup merge of #85725 - Smittyvb:rm-24159-workaround, r=RalfJung 2021-05-27 03:02:12 +02:00
rustc_mir_build Rollup merge of #85564 - pnkfelix:issue-85435-readd-capture-disjoint-fields-gate, r=nikomatsakis 2021-05-27 03:02:08 +02:00
rustc_parse remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_parse_format remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_passes remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_plugin_impl Use () for plugin_registrar_fn. 2021-05-12 13:58:43 +02:00
rustc_privacy remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_query_impl Use () in dependency_formats. 2021-05-12 13:58:41 +02:00
rustc_query_system Get rid of PreviousDepGraph. 2021-05-22 14:14:23 +02:00
rustc_resolve Rollup merge of #85478 - FabianWolff:issue-85348, r=petrochenkov 2021-05-26 13:32:05 +02:00
rustc_save_analysis remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_serialize Auto merge of #83465 - michaelwoerister:safe-read_raw_bytes, r=cjgillot 2021-03-26 01:28:59 +00:00
rustc_session Rollup merge of #85361 - bjorn3:rustdoc_target_json_path_canonicalize, r=jyn514 2021-05-25 13:05:09 +02:00
rustc_span Rollup merge of #85439 - mgacek8:add_diagnostic_item_to_CStr_type, r=davidtwco 2021-05-20 00:19:07 +02:00
rustc_symbol_mangling remove cfg(bootstrap) 2021-05-24 11:07:48 -04:00
rustc_target Remove linker_is_gnu: true cases as that is now the default. 2021-05-20 23:36:04 -07:00
rustc_trait_selection stabilize member constraints 2021-05-26 06:01:53 -04:00
rustc_traits Auto merge of #83207 - oli-obk:valtree2, r=lcnr 2021-04-02 10:28:12 +00:00
rustc_ty_utils add new attribute rustc_insignificant_dtor and a query to check if a type has a significant drop 2021-05-14 22:57:33 -04:00
rustc_type_ir Make TypeFoldable::is_global() false when fresh tys/consts are present 2021-05-01 16:58:33 -04:00
rustc_typeck Auto merge of #84968 - FabianWolff:master, r=estebank 2021-05-28 03:38:28 +00:00