Skip to content

Wrapping value in noop function call changes evaluation order #15384

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
huonw opened this issue Jul 3, 2014 · 5 comments
Closed

Wrapping value in noop function call changes evaluation order #15384

huonw opened this issue Jul 3, 2014 · 5 comments

Comments

@huonw
Copy link
Member

huonw commented Jul 3, 2014

Breaking out of #15300. These two differ in evaluation order, even though the only difference is the introduction of the noop foo((), ...) around the a on the LHS:

fn foo(_: (), x: int) -> int { x }

fn main() {
    let mut a = 2i;
    println!("{}", a * foo(a = 5, a)); // 25
    a = 2i;
    println!("{}", foo((), a) * foo(a = 5, a)); // 10
}

http://is.gd/zVdDoh

@pnkfelix
Copy link
Member

pnkfelix commented Jul 3, 2014

cc me

@steveklabnik
Copy link
Member

Triage: still a bug.

@Aatch
Copy link
Contributor

Aatch commented May 29, 2015

So having been linked #15300, I looked at this briefly. There's an argument to be made that the second behaviour is correct and the first not. What we do for non-overloaded binops is translate the LHS, then the RHS then translate the operation. Makes sense, right? Well a identifier expression is translated to an "lvalue datum", which is just a pointer to the on-stack location of the value the variable contains. We don't actually load the value from the lvalue until after translating both sides, meaning any changes to a will be visible.

It'd be a simple fix to load the value a little earlier, but it does change visible behaviour (though you could argue that this is buggy behaviour).

@bltavares
Copy link
Contributor

Triage: I could not reproduce the bug.

I had to change the int types to compile it.

fn foo(_: (), x: isize) -> isize { x }

fn main() {
    let mut a = 2isize;
    println!("{}", a * foo(a = 5, a)); // 10
    a = 2isize;
    println!("{}", foo((), a) * foo(a = 5, a)); // 10
}

http://is.gd/EiOduV

@arielb1
Copy link
Contributor

arielb1 commented Nov 15, 2015

I fixed it.

@arielb1 arielb1 closed this as completed Nov 15, 2015
bors added a commit to rust-lang-ci/rust that referenced this issue Dec 11, 2023
feat: Prioritize import suggestions based on the expected type

Hi, this is a draft PR to solve rust-lang#15384. `Adt` types work and now I have a few questions :)

1. What other types make sense in this context? Looking at [ModuleDef](https://github.com/rust-lang/rust-analyzer/blob/05666441bafd6010787a4097a6bd44266ad21018/crates/hir/src/lib.rs#L275) I am thinking everything except Modules.
2. Is there an existing way of converting between `ModeuleDef` and `hir::Type` in the rustanalyzer code base?
3. Does this approach seem sound to you?

Ups: Upon writing this I just realised that the enum test is invalided as there are no enum variants and this no variant is passed as a function argument.
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants