rust
rust copied to clipboard
Propagate deref coercion into block
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
r? @petrochenkov
(rust-highfive has picked a reviewer for you, use r? to override)
This is no my area of expertise, and also a language change. r? @nikomatsakis @eddyb (because coercions)
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.
Sorry @ldm0 ! I'll try to give useful feedback ASAP
Wouldn't this lead to inference errors?
Is this something that we can figure out with a crater run?
Hi @nikomatsakis , do you know when you'll get a chance to look at this?
I'm reviewing this now.
Apologies for the very long delay.
:umbrella: The latest upstream changes (presumably #92007) made this pull request unmergeable. Please resolve the merge conflicts.
:umbrella: The latest upstream changes (presumably #93148) made this pull request unmergeable. Please resolve the merge conflicts.
Sorry @ldm0, got underwater again, but coming out of it :)
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.
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...
@ldm0 if you can answer the question in the review above, we can proceed with this
Will this fix #23014?
Closing this due to inactivity
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:
- represents a change that we should make, or
- 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.)
@bors try
:hourglass: Trying commit ee3931b3099ab6c425053f338875e81d623c9cf9 with merge f6d7c613ae2d161ff37dbc63cc5abd809c878597...
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`.
:sunny: Try build successful - checks-actions
Build commit: f6d7c613ae2d161ff37dbc63cc5abd809c878597 (f6d7c613ae2d161ff37dbc63cc5abd809c878597
)
@craterbot check f6d7c613ae2d161ff37dbc63cc5abd809c878597
: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
@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
@craterbot run f6d7c613ae2d161ff37dbc63cc5abd809c878597
: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 run start=master#1ab98933fa75d72e882b86feac1a0be3a5b02cb0 end=try#f6d7c613ae2d161ff37dbc63cc5abd809c878597 mode=check-only
: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
:construction: Experiment pr-83850
is now running
:information_source: Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more
: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