rust icon indicating copy to clipboard operation
rust copied to clipboard

Propagate deref coercion into block

Open ldm0 opened this issue 3 years ago • 41 comments

fn main() {
    // This already compiles
    let _: &i32 = &Box::new(1i32);
    // This doesn't compile until this PR.
    let _: &i32 = & { Box::new(1i32) };
}

Above code doesn't compiles because we apply check_expr_with_expectation() on { Box::new(1i32) } with ExpectHasType(i32). Which is a hard constraint and won't success without deref coercion.

This PR taks the same path as https://github.com/rust-lang/rust/pull/20083 (remove the hard constraint on check_expr_with_expectation when meets a unsized type). When the compiler see a AddrOf(Foo(...))(e.g. &{ Box::new(1i32) }), removes the hard constraint that this Foo have some type.

Fixes #26978 Fixes #57749 Fixes #83783

ldm0 avatar Apr 04 '21 14:04 ldm0

r? @petrochenkov

(rust-highfive has picked a reviewer for you, use r? to override)

rust-highfive avatar Apr 04 '21 14:04 rust-highfive

This is no my area of expertise, and also a language change. r? @nikomatsakis @eddyb (because coercions)

petrochenkov avatar Apr 05 '21 06:04 petrochenkov

Wouldn't this lead to inference errors? I'm surprised we don't have tests that trip. But maybe it's special-cased enough to work. I'll defer to @nikomatsakis either way.

eddyb avatar Apr 30 '21 11:04 eddyb

Sorry @ldm0 ! I'll try to give useful feedback ASAP

nikomatsakis avatar May 13 '21 17:05 nikomatsakis

Wouldn't this lead to inference errors?

Is this something that we can figure out with a crater run?

lambda-fairy avatar Aug 18 '21 06:08 lambda-fairy

Hi @nikomatsakis , do you know when you'll get a chance to look at this?

jyn514 avatar Nov 09 '21 11:11 jyn514

I'm reviewing this now.

nikomatsakis avatar Dec 13 '21 15:12 nikomatsakis

Apologies for the very long delay.

nikomatsakis avatar Dec 13 '21 15:12 nikomatsakis

:umbrella: The latest upstream changes (presumably #92007) made this pull request unmergeable. Please resolve the merge conflicts.

bors avatar Feb 08 '22 03:02 bors

:umbrella: The latest upstream changes (presumably #93148) made this pull request unmergeable. Please resolve the merge conflicts.

bors avatar Feb 15 '22 14:02 bors

Sorry @ldm0, got underwater again, but coming out of it :)

nikomatsakis avatar Feb 15 '22 16:02 nikomatsakis

fn f(_: &[i32]) {}

fn main() {
    f(&Box::new([1, 2]));
}

I guess it's failed because unsized coercion([i32; 2] => [i32]) doesn't happen during autoderef.

It still fails to compile even after this PR. Will add it to tests later.

ldm0 avatar Feb 15 '22 19:02 ldm0

Thanks. I'll take a look at the tests over the next few days! I'm trying to allocate some time every day for reviewing and notifications...

nikomatsakis avatar Feb 16 '22 15:02 nikomatsakis

@ldm0 if you can answer the question in the review above, we can proceed with this

Dylan-DPC avatar Mar 13 '22 14:03 Dylan-DPC

Will this fix #23014?

theemathas avatar Mar 21 '22 13:03 theemathas

Closing this due to inactivity

Dylan-DPC avatar Mar 30 '22 14:03 Dylan-DPC

reopening. ~~Even though the PR author didn't respond to the most recent question (which in hindsight I think was a confusing question, as I responded above),~~ I think that this PR either:

  1. represents a change that we should make, or
  2. represents a change that we shouldn't make, but: The constraints that would lead one to reach that conclusion aren't captured in our test suite currently.

So, as a first step, I propose that we put this through a crater run, in the hopes of identifying cases where this change causes inference failures. (And then we can take those cases and propagate them into the Rust test suite.)

pnkfelix avatar May 26 '22 16:05 pnkfelix

@bors try

pnkfelix avatar May 26 '22 16:05 pnkfelix

:hourglass: Trying commit ee3931b3099ab6c425053f338875e81d623c9cf9 with merge f6d7c613ae2d161ff37dbc63cc5abd809c878597...

bors avatar May 26 '22 16:05 bors

The job x86_64-gnu-llvm-12 failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)
diff of stderr:

2   --> $DIR/coerce-block-tail-83850.rs:5:7
3    |
4 LL |     f(&Box::new([1, 2]));
-    |       ^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found struct `Box`
+    |     - ^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found struct `Box`
+    |     arguments to this function are incorrect
6    |
7    = note: expected reference `&[i32]`
7    = note: expected reference `&[i32]`
8               found reference `&Box<[{integer}; 2]>`
+ note: function defined here
+   --> $DIR/coerce-block-tail-83850.rs:2:4
+    |
+    |
+ LL | fn f(_: &[i32]) {}
+    |    ^ ---------
10 error: aborting due to previous error
11 



Some tests failed in compiletest suite=ui mode=ui host=x86_64-unknown-linux-gnu target=x86_64-unknown-linux-gnu
The actual stderr differed from the expected stderr.
Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/coercion/coerce-block-tail-83850/coerce-block-tail-83850.stderr
To only update this specific test, also pass `--test-args coercion/coerce-block-tail-83850.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
status: exit status: 1
command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/coercion/coerce-block-tail-83850.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/coercion/coerce-block-tail-83850" "-A" "unused" "-Crpath" "-O" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/coercion/coerce-block-tail-83850/auxiliary"
stdout: none
--- stderr -------------------------------
  --> /checkout/src/test/ui/coercion/coerce-block-tail-83850.rs:5:7
   |
   |
LL |     f(&Box::new([1, 2]));
   |     - ^^^^^^^^^^^^^^^^^ expected slice `[i32]`, found struct `Box`
   |     arguments to this function are incorrect
   |
   = note: expected reference `&[i32]`
   = note: expected reference `&[i32]`
              found reference `&Box<[{integer}; 2]>`
  --> /checkout/src/test/ui/coercion/coerce-block-tail-83850.rs:2:4
   |
   |
LL | fn f(_: &[i32]) {}
   |    ^ ---------
error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
------------------------------------------
---
25 error[E0308]: mismatched types
-   --> $DIR/brackets-to-braces-single-element.rs:7:27
+   --> $DIR/brackets-to-braces-single-element.rs:7:23
27    |
28 LL | const C: &&[u32; 1] = &&{ 1 };
-    |                           ^ expected array `[u32; 1]`, found integer
+    |                       ^^^^^^^ expected array `[u32; 1]`, found integer
30    |
+    = note: expected reference `&'static &'static [u32; 1]`
+               found reference `&&{integer}`
31 help: to create an array, use square brackets instead of curly braces
32    |
33 LL | const C: &&[u32; 1] = &&[ 1 ];

The actual stderr differed from the expected stderr.
Actual stderr saved to /checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/did_you_mean/brackets-to-braces-single-element/brackets-to-braces-single-element.stderr
To update references, rerun the tests and pass the `--bless` flag
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args did_you_mean/brackets-to-braces-single-element.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "/checkout/src/test/ui/did_you_mean/brackets-to-braces-single-element.rs" "-Zthreads=1" "--target=x86_64-unknown-linux-gnu" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "--emit" "metadata" "-C" "prefer-dynamic" "--out-dir" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/did_you_mean/brackets-to-braces-single-element" "-A" "unused" "-Crpath" "-O" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers" "-L" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/ui/did_you_mean/brackets-to-braces-single-element/auxiliary"
stdout: none
--- stderr -------------------------------
  --> /checkout/src/test/ui/did_you_mean/brackets-to-braces-single-element.rs:1:24
   |
   |
LL | const A: [&str; 1] = { "hello" };
   |                        ^^^^^^^ expected array `[&'static str; 1]`, found `&str`
   |
help: to create an array, use square brackets instead of curly braces
   |
LL | const A: [&str; 1] = [ "hello" ];

error[E0308]: mismatched types
  --> /checkout/src/test/ui/did_you_mean/brackets-to-braces-single-element.rs:4:19
   |
   |
LL | const B: &[u32] = &{ 1 };
   |                   ^^^^^^ expected slice `[u32]`, found integer
   = note: expected reference `&'static [u32]`
              found reference `&{integer}`
              found reference `&{integer}`
help: to create an array, use square brackets instead of curly braces
   |
LL | const B: &[u32] = &[ 1 ];

error[E0308]: mismatched types
  --> /checkout/src/test/ui/did_you_mean/brackets-to-braces-single-element.rs:7:23
   |
   |
LL | const C: &&[u32; 1] = &&{ 1 };
   |                       ^^^^^^^ expected array `[u32; 1]`, found integer
   |
   = note: expected reference `&'static &'static [u32; 1]`
              found reference `&&{integer}`
help: to create an array, use square brackets instead of curly braces
   |
LL | const C: &&[u32; 1] = &&[ 1 ];

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0308`.

rust-log-analyzer avatar May 26 '22 16:05 rust-log-analyzer

:sunny: Try build successful - checks-actions Build commit: f6d7c613ae2d161ff37dbc63cc5abd809c878597 (f6d7c613ae2d161ff37dbc63cc5abd809c878597)

bors avatar May 26 '22 18:05 bors

@craterbot check f6d7c613ae2d161ff37dbc63cc5abd809c878597

pnkfelix avatar May 31 '22 19:05 pnkfelix

:rotating_light: Error: failed to parse the command

:sos: If you have any trouble with Crater please ping @rust-lang/infra! :information_source: Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

craterbot avatar May 31 '22 19:05 craterbot

@pnkfelix your crater command didn't run, did you intend to do craterbot run <commit> because check doesn't support a commit as an arg

Dylan-DPC avatar Jun 07 '22 16:06 Dylan-DPC

@craterbot run f6d7c613ae2d161ff37dbc63cc5abd809c878597

pnkfelix avatar Jun 09 '22 15:06 pnkfelix

:rotating_light: Error: failed to parse the command

:sos: If you have any trouble with Crater please ping @rust-lang/infra! :information_source: Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

craterbot avatar Jun 09 '22 15:06 craterbot

@craterbot run start=master#1ab98933fa75d72e882b86feac1a0be3a5b02cb0 end=try#f6d7c613ae2d161ff37dbc63cc5abd809c878597 mode=check-only

pnkfelix avatar Jun 09 '22 16:06 pnkfelix

:ok_hand: Experiment pr-83850 created and queued. :mag: You can check out the queue and this experiment's details.

:information_source: Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

craterbot avatar Jun 09 '22 16:06 craterbot

:construction: Experiment pr-83850 is now running

:information_source: Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

craterbot avatar Jun 20 '22 21:06 craterbot

:tada: Experiment pr-83850 is completed! :bar_chart: 4194 regressed and 11 fixed (237111 total) :newspaper: Open the full report.

:warning: If you notice any spurious failure please add them to the blacklist! :information_source: Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

craterbot avatar Jun 22 '22 15:06 craterbot