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

drop not always behaving since nightly-2016-08-03-x86_64-unknown-linux-gnu #35737

Closed
mikedilger opened this issue Aug 16, 2016 · 9 comments · Fixed by #35751
Closed

drop not always behaving since nightly-2016-08-03-x86_64-unknown-linux-gnu #35737

mikedilger opened this issue Aug 16, 2016 · 9 comments · Fixed by #35751
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html regression-from-stable-to-beta Performance or correctness regression from stable to beta. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@mikedilger
Copy link
Contributor

This was discovered in database connection pooling where connections were not returned to the pool properly, and reported under sfackler/r2d2#25

Unfortunately I do not have example code small enough to share at this point.

I narrowed down the rust-nightly version that introduced the bug to nightly-2016-08-03-x86_64-unknown-linux-gnu

@sfackler

@mikedilger
Copy link
Contributor Author

when compiled with RUSTFLAGS="-Zorbit=off" the issue does not appear, so yes it is the MIR as suspected.

@nagisa
Copy link
Member

nagisa commented Aug 16, 2016

The compiler not running drop glue is not considered unsafe behaviour (i.e. it is allowed to happen), but it is still weird this happens.

cc @arielb1 could be your drop elaboration not catching this (&*Doop) case?

@mikedilger Something that we could run without having postgresql installed would be ideal test case, even if it depended on other crates for now.

@nagisa
Copy link
Member

nagisa commented Aug 16, 2016

Minimal reproduction:

enum Error {
    Error
}

struct ConnWrap(Conn);
impl ::std::ops::Deref for ConnWrap {
    type Target=Conn;
    fn deref(&self) -> &Conn { &self.0 }
}

struct App;
impl App {
    fn conn(&self) -> Result<ConnWrap, Error> { Ok(ConnWrap(Conn)) }
}

struct Conn;
impl Drop for  Conn {
    fn drop(&mut self) { println!("drop") }
}

fn accessible_sites(app: &App) -> Result<Vec<i32>, Error>
{
    let conn = &*try!(app.conn());
    return Ok(vec![]);
}

fn main() {
    accessible_sites(&App);
}

@brson brson added regression-from-stable-to-beta Performance or correctness regression from stable to beta. A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 16, 2016
@nagisa
Copy link
Member

nagisa commented Aug 17, 2016

More minimal:

#![feature(core_intrinsics)]
struct ConnWrap(Conn);
impl ::std::ops::Deref for ConnWrap {
    type Target=Conn;
    fn deref(&self) -> &Conn { &self.0 }
}

struct Conn;
impl Drop for  Conn {
    fn drop(&mut self) { unsafe { ::std::intrinsics::abort() } }
}

fn main() {
    let conn = &*match Some(ConnWrap(Conn)) {
        Some(val) => val,
        None => return,
    };
    return
}

Removing either of early returns in the function makes the issue go away. Seems like a scoping issue.

@Stebalien
Copy link
Contributor

@brson regression-from-stable-to-nightly (for a two more days at least).

@brson
Copy link
Contributor

brson commented Aug 17, 2016

Yeah I jumped the gun on the tag, but the beta is building right now.

@nikomatsakis
Copy link
Contributor

@nagisa I saw your commit -- I feel like the extent should be unique for the cleanup scope. That is, we should push a given extent only once -- but perhaps I am wrong about this? It'd be good to add an assertion (or warning) for when we push cleanup scopes with the same extent more than once so we can see what it happens.

@nikomatsakis
Copy link
Contributor

Ah, but reading IRC chatter I see that the problem is that the extent of the "outermost scope" changed and thus the extent_of_return_scope helper is out of date? That seems pretty plausible.

@nagisa
Copy link
Member

nagisa commented Aug 17, 2016

As pointed out on the IRC the commit linked above is a shot in the dark and is not a fix.

nagisa added a commit to nagisa/rust that referenced this issue Aug 17, 2016
eddyb added a commit to eddyb/rust that referenced this issue Aug 18, 2016
Fix the invalidation of the MIR early exit cache

~~The rust-lang#34307 introduced a cache for early exits in order to help with O(n*m) explosion of cleanup blocks but the cache is invalidated incorrectly and I can’t seem to figure out why (caching is hard!)~~

~~Remove the cache for now to fix the immediate correctness issue and worry about the performance later.~~

Cache invalidation got fixed.

Fixes rust-lang#35737

r? @nikomatsakis
alexcrichton pushed a commit to alexcrichton/rust that referenced this issue Aug 23, 2016
pmatos pushed a commit to LinkiTools/rust that referenced this issue Sep 27, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html regression-from-stable-to-beta Performance or correctness regression from stable to beta. 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.

5 participants