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

Closed
barosl opened this Issue Jul 11, 2015 · 12 comments

Comments

Projects
None yet
9 participants
@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.

@Gankro

This comment has been minimized.

Copy link
Contributor

Gankro commented Jul 11, 2015

CC @nrc

@Gankro Gankro added the A-typesystem label Jul 11, 2015

@bluss

This comment has been minimized.

Copy link
Contributor

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

This comment has been minimized.

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-

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Copy link
Contributor

llogiq commented Sep 19, 2015

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

@nrc

This comment has been minimized.

Copy link
Member

nrc commented Sep 21, 2015

triage: I-nominated

@nrc

This comment has been minimized.

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 label Sep 21, 2015

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Oct 1, 2015

cc @eddyb

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

nikomatsakis commented Oct 1, 2015

triage: P-medium

@rust-highfive rust-highfive added P-medium and removed I-nominated labels Oct 1, 2015

@eddyb

This comment has been minimized.

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

This comment has been minimized.

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

Auto merge of #31651 - eddyb:fix-26978, r=arielb1
Handles `str` being an expression's expected type, which was missing from #20083.
Fixes #26978.

@bors bors closed this in #31651 Feb 14, 2016

gifnksm added a commit to gifnksm/power-assert-rs that referenced this issue Mar 17, 2016

Merge pull request #15 from ivan/master
Uncomment issue4 power_assert! now that rust-lang/rust#26978 is fixed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.