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

[nll] compilation error from mozjs-0.1.10 #47722

Closed
nikomatsakis opened this issue Jan 24, 2018 · 3 comments · Fixed by #47873
Closed

[nll] compilation error from mozjs-0.1.10 #47722

nikomatsakis opened this issue Jan 24, 2018 · 3 comments · Fixed by #47873
Assignees
Labels
A-NLL Area: Non Lexical Lifetimes (NLL) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Jan 24, 2018

In #47596, @SimonSapin reported several NLL errors in dependencies of the servo crate. @lqd later minimized one of those errors into this example:

#![feature(nll)]

struct AutoGCRooter {
    stackTop: *mut *mut AutoGCRooter,
}

impl AutoGCRooter {
    unsafe fn add_to_root_stack(&mut self) {
        *self.stackTop = self;
    }
}

fn main() {}

which yields:

error[E0506]: cannot assign to `*self.stackTop` because it is borrowed
 --> src/main.rs:9:9
  |
9 |         *self.stackTop = self;
  |         ^^^^^^^^^^^^^^^^^----
  |         |                |
  |         |                borrow of `*self.stackTop` occurs here
  |         assignment to borrowed `*self.stackTop` occurs here

error: aborting due to previous error

Removing feature(nll) makes the code work, so probably this is an NLL bug.

@nikomatsakis nikomatsakis added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-compiler-nll labels Jan 24, 2018
@nikomatsakis nikomatsakis added this to the NLL: Valid code works milestone Jan 24, 2018
@nikomatsakis nikomatsakis added the A-NLL Area: Non Lexical Lifetimes (NLL) label Jan 24, 2018
@Aaron1011
Copy link
Member

I'd like to take a look at this.

@Aaron1011
Copy link
Member

Explicitly casting self to *mut AutoGCRooter fixes the issue: https://play.rust-lang.org/?gist=15c060db3de0a3212c3ab2b2a3d32b30&version=nightly

#![feature(nll)]

struct AutoGCRooter {
    stackTop: *mut *mut AutoGCRooter,
}

impl AutoGCRooter {
    unsafe fn add_to_root_stack(&mut self) {
        *self.stackTop = self as *mut AutoGCRooter;
    }
}

fn main() {}

My guess is that there's an issue with the automatic coercion from &mut self to *mut self. I'll investigate further.

@Aaron1011
Copy link
Member

It turns out you can remove one layer of indirection and still get the same error:

#![feature(nll)]

struct AutoGCRooter {
    stackTop: *mut AutoGCRooter,
}

impl AutoGCRooter {
    unsafe fn add_to_root_stack(&mut self) {
        self.stackTop = self;
    }
}

fn main() {}

Aaron1011 added a commit to Aaron1011/rust that referenced this issue Jan 30, 2018
Implicit coercions from references to pointers were lowered to slightly
different Mir than explicit casts (e.g. 'foo as *mut T'). This resulted
in certain uses of self-referential structs compiling correctly when an
explicit cast was used, but not when the implicit coercion was used.

To fix this, this commit adds an outer 'Use' expr when applying a
raw-ptr-borrow adjustment. This makes the lowered Mir for coercions
identical to that of explicit coercions, allowing the original code to
compile regardless of how the raw ptr cast occurs.

Fixes rust-lang#47722
Aaron1011 added a commit to Aaron1011/rust that referenced this issue Jan 30, 2018
Implicit coercions from references to pointers were lowered to slightly
different Mir than explicit casts (e.g. 'foo as *mut T'). This resulted
in certain uses of self-referential structs compiling correctly when an
explicit cast was used, but not when the implicit coercion was used.

To fix this, this commit adds an outer 'Use' expr when applying a
raw-ptr-borrow adjustment. This makes the lowered Mir for coercions
identical to that of explicit coercions, allowing the original code to
compile regardless of how the raw ptr cast occurs.

Fixes rust-lang#47722
bors added a commit that referenced this issue Feb 5, 2018
Fix ref-to-ptr coercions not working with NLL in certain cases

Implicit coercions from references to pointers were lowered to slightly
different Mir than explicit casts (e.g. 'foo as *mut T'). This resulted
in certain uses of self-referential structs compiling correctly when an
explicit cast was used, but not when the implicit coercion was used.

To fix this, this commit adds an outer 'Use' expr when applying a
raw-ptr-borrow adjustment. This makes the lowered Mir for coercions
identical to that of explicit coercions, allowing the original code to
compile regardless of how the raw ptr cast occurs.

Fixes #47722
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-NLL Area: Non Lexical Lifetimes (NLL) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants