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

Deref coercions do not work with blocks #26978

Open
barosl opened this issue Jul 11, 2015 · 14 comments
Open

Deref coercions do not work with blocks #26978

barosl opened this issue Jul 11, 2015 · 14 comments
Labels
A-type-system Area: Type system P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@barosl
Copy link
Contributor

barosl commented Jul 11, 2015

It seems that the compiler handles a block differently when coercing a value.

fn f(_: &str) {}

fn main() {
    let x = "Akemi Homura".to_owned();

    f(&x); // OK
    f(&(x)); // OK
    f(&{x}); // Error
}

RFC 401 says that a block with type U is also a target for coercion, so I think this behavior is a bug.

blocks, if a block has type U, then the last expression in the block (if it
is not semicolon-terminated) is a coercion site to U. This includes blocks
which are part of control flow statements, such as if/else, if the block
has a known type.

Also, the compiler seems to be able to coerce blocks using some "trivial" rules (e.g. &mut T -> &T).

fn f(_: &i32) {}

fn main() {
    let x = &mut 42;

    f(x); // OK
    f((x)); // OK
    f({x}); // OK
}

So I guess this is more likely a problem of auto-deref.

@Gankra
Copy link
Contributor

Gankra commented Jul 11, 2015

CC @nrc

@Gankra Gankra added the A-type-system Area: Type system label Jul 11, 2015
@bluss
Copy link
Member

bluss commented Jul 12, 2015

As some users have discovered, {x}.item can be used to force a x: &mut X to move instead of reborrow. Is that related? We might not be allowed to break that.

@nrc nrc changed the title Auto-deref does not work with blocks Deref coercions do not work with blocks Jul 12, 2015
@nrc
Copy link
Member

nrc commented Jul 12, 2015

I suspect this is something specific to deref coercions. I think it is 'just a bug', but I don't know how easy it is to fix.

@tbu-
Copy link
Contributor

tbu- commented Aug 20, 2015

This blocks usage of try! together with deref coercions if I understand this bug correctly:

let _: &Path = &try!(env::current_dir()); fails to compile.

@barosl
Copy link
Contributor Author

barosl commented Aug 21, 2015

@tbu- Yup, actually this issue was found by a Stack Overflow question that tried the same thing.

@llogiq
Copy link
Contributor

llogiq commented Sep 19, 2015

There is also this rust-users thread with a very similar problem.

@nrc
Copy link
Member

nrc commented Sep 21, 2015

triage: I-nominated

@nrc
Copy link
Member

nrc commented Sep 21, 2015

triaged because it is such an annoying bug. Recommend p-medium.

@nrc nrc added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Sep 21, 2015
@nikomatsakis
Copy link
Contributor

cc @eddyb

@nikomatsakis
Copy link
Contributor

triage: P-medium

@rust-highfive rust-highfive added P-medium Medium priority and removed I-nominated labels Oct 1, 2015
@eddyb
Copy link
Member

eddyb commented Oct 3, 2015

It would be very helpful to point out the error, which is:

<anon>:8:9: 8:10 error: mismatched types:
 expected `str`,
    found `collections::string::String`
(expected str,
    found struct `collections::string::String`) [E0308]
<anon>:8     f(&{x}); // Error
                 ^

So the problem could be that str propagated through the block to x, despite being unsized.
As blocks are always rvalues, maybe the "expected type" propagation doesn't deal with unsized values being mere hints in the block case?

@eddyb
Copy link
Member

eddyb commented Feb 14, 2016

Update: That was dumb of me: I did not realize this only ever happens with str.
Of course it does, because I never implemented it.

bors added a commit that referenced this issue Feb 14, 2016
Handles `str` being an expression's expected type, which was missing from #20083.
Fixes #26978.
gifnksm added a commit to gifnksm/power-assert-rs that referenced this issue Mar 17, 2016
Uncomment issue4 power_assert! now that rust-lang/rust#26978 is fixed
@ldm0
Copy link
Contributor

ldm0 commented Apr 4, 2021

This issue should be reopened:

fn f(_: &i32) {}

fn main() {
    let x = Box::new(1i32);

    f(&x); // OK
    f(&(x)); // OK
    f(&{x}); // Error
}

@eddyb
Copy link
Member

eddyb commented Apr 30, 2021

I should've renamed the title of this issue, I believe (based on my comments in this thread) that this issue was specifically about str not working the same was [T].

I doubt your example ever worked, because the block gets i32 as the expected type and that is Sized, so there's no way to rule it out as the type of the block.

@fmease fmease added the T-types Relevant to the types team, which will review and decide on the PR/issue. label Dec 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.