Skip to content

struct variants define a ctor function as if they were regular variants #18252

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
osa1 opened this issue Oct 23, 2014 · 3 comments · Fixed by #18324
Closed

struct variants define a ctor function as if they were regular variants #18252

osa1 opened this issue Oct 23, 2014 · 3 comments · Fixed by #18324
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.

Comments

@osa1
Copy link
Contributor

osa1 commented Oct 23, 2014

lib.rs:

#![feature(struct_variant)]
pub mod en {
    pub enum MyEnum {
        Variant1(int),
        Variant2{pub name: String}
    }
}

main.rs:

extern crate lib;

use lib::en;

fn main() {
    let enu = en::Variant1(2i);
    let enu2 = en::Variant2("Joe".to_string());
}

error:

main.rs:7:16: 7:28 error: unresolved name `en::Variant2`.
main.rs:7     let enu2 = en::Variant2("Joe".to_string());
                         ^~~~~~~~~~~~
error: aborting due to previous error

But this works:

#![feature(struct_variant)]
pub mod en {
    pub enum MyEnum {
        Variant1(int),
        Variant2{pub name: String}
    }
}

fn main() {
    let enu = en::Variant1(2i);
    let enu2 = en::Variant2("Joe".to_string());
}
@osa1
Copy link
Contributor Author

osa1 commented Oct 23, 2014

Looks similar to #4577.

@sfackler
Copy link
Member

It seems like the bug is that this works within the same crate imo.

@ghost
Copy link

ghost commented Oct 23, 2014

@sfackler Agreed. I sneaked in a fix for that in #18171 but maybe I should split it out.

@ghost ghost added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Oct 23, 2014
@ghost ghost changed the title struct variant constructors doesn't work with function call syntax when used in different crate struct variants define a ctor function as if they were regular variants Oct 24, 2014
lnicola pushed a commit to lnicola/rust that referenced this issue Oct 17, 2024
fix: Do not consider mutable usage of deref to `*mut T` as deref_mut

Fixes rust-lang#15799

We are doing some heuristics for deciding whether the given deref is deref or deref_mut here;

https://github.com/rust-lang/rust-analyzer/blob/5982d9c420d0dc90739171829f0d2e9c80d98979/crates/hir-ty/src/infer/mutability.rs#L182-L200

But this heuristic is erroneous if we are dereferencing to a mut ptr and normally those cases are filtered out here as builtin;

https://github.com/rust-lang/rust-analyzer/blob/5982d9c420d0dc90739171829f0d2e9c80d98979/crates/hir-ty/src/mir/lower/as_place.rs#L165-L177

Howerver, this works not so well if the given dereferencing is double dereferencings like the case in the rust-lang#15799.

```rust
struct WrapPtr(*mut u32);

impl core::ops::Deref for WrapPtr {
    type Target = *mut u32;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

fn main() {
    let mut x = 0u32;
    let wrap = WrapPtr(&mut x);
    unsafe {
        **wrap = 6;
    }
}
```

Here are two - outer and inner - dereferences here, and the outer dereference is marked as deref_mut because there is an assignment operation.
And this deref_mut marking is propagated into the inner dereferencing.
In the later MIR lowering, the outer dereference is filtered out as it's expr type is `*mut u32`, but the expr type in the inner dereference is an ADT, so this false-mutablility is not filtered out.

This PR cuts propagation of this false mutablilty chain if the expr type is mut ptr.
Since this happens before the resolve_all, it may have some limitations when the expr type is determined as mut ptr at the very end of inferencing, but I couldn't find simple fix for it 🤔
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants