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

It is possible to call object member function after object had been dropped #12470

Closed
yegor-alexeyev opened this issue Feb 22, 2014 · 10 comments
Closed
Labels
A-typesystem Area: The type system
Milestone

Comments

@yegor-alexeyev
Copy link

Please look at gist https://gist.github.com/yegor-alexeyev/9152969
If execute, "drop" would be printed before the value of memory of dropped object

@huonw
Copy link
Member

huonw commented Feb 22, 2014

Thanks for the report... this is definitely a problem.

I'll reproduce the code here (slightly modified), just so that we're not depending on that gist being permanent:

trait X {
    fn get_i(&self) -> int;
}


struct B {
    i: int
}

impl X for B {
    fn get_i(&self) -> int {
        self.i
    }
}

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

struct A<'r> {
    p: &'r X
}

fn make_a<'r>(p:&'r X) -> A<'r> {
    A{p:p}
}

fn make_make_a() -> A {
    let b: ~B = ~B {i:1};
    let bb: & B = b;
    make_a(bb)
}

fn main() {
    let a = make_make_a();
    println!("{}", a.p.get_i());
}

which prints

drop
0

with the latest master.

Also, this seems very similar to #11374, since any attempt to remove the trait or the trait object makes the code stop compiling.

@alexcrichton
Copy link
Member

Nominating.

@dmski
Copy link
Contributor

dmski commented Mar 12, 2014

I'd like to (try to) fix this.
Also #5723, #11374, #11971 and #12781 all seem related.

@brson
Copy link
Contributor

brson commented Mar 13, 2014

@dmski Go for it!

@pnkfelix
Copy link
Member

Assigning 1.0, P-backcompat-lang.

@pnkfelix pnkfelix added this to the 1.0 milestone Mar 13, 2014
@dmski
Copy link
Contributor

dmski commented Mar 18, 2014

PR #12828 might also be related: it would seem that A is considered bivariant and free region constraint doesn't get added to A{p:p} as a result:
sub.tys(A<>, A<>) super_tys: a_sty=&ty_struct(syntax::ast::DefId{krate: 0u32, node: 81u32}, middle::ty::substs{self_ty: None, tps: std::vec_ng::Vec<middle::ty::t>{len: 0u, cap: 0u, ptr: (0x0 as *mut ())}, regions: NonerasedRegions(Vec(std::vec_ng::Vec<middle::ty::Region>{len: 1u, cap: 1u, ptr: (0x7fd17a54c140 as *mut ())}))}) b_sty=&ty_struct(syntax::ast::DefId{krate: 0u32, node: 81u32}, middle::ty::substs{self_ty: None, tps: std::vec_ng::Vec<middle::ty::t>{len: 0u, cap: 0u, ptr: (0x0 as *mut ())}, regions: NonerasedRegions(Vec(std::vec_ng::Vec<middle::ty::Region>{len: 1u, cap: 1u, ptr: (0x7fd17a54c110 as *mut ())}))}) relate_region_params(item_def_id=syntax::ast::DefId{krate: 0u32, node: 81u32}:A, a_rs=[ReInfer(1)], b_rs=[ReFree(105, BrAnon(0))], region_params=[*]) success

But if A is defined as
struct A<'r> { p: &'r B }
Then A is considered contravariant and region for A{p:p} gets considered free.

@edwardw
Copy link
Contributor

edwardw commented Mar 19, 2014

With the latest #12828, rustc now rejects the code:

...
fn make_make_a() -> A {
    let b: ~B = ~B {i:1};
    let bb: & B = b;  // error: `*b` does not live long enough
    make_a(bb)
}
...

But of course, the fix is meant to implement RFC for tweaked variance inference rules, which itself is still in flux.

@dmski
Copy link
Contributor

dmski commented Mar 19, 2014

Am i right in thinking that the fix for trait contravariance (i.e. edwardw@4c51634) is relatively independent of what RFC and #12828 originally tried to do, and so can be split off? That fix alone corrects this issue (though also leads to an error compiling json.rs).

@edwardw
Copy link
Contributor

edwardw commented Mar 19, 2014

Yes, the fixing ty_trait part is just a bug fix, prelude to the tweaked variance inference RFC if you will.

@nrc
Copy link
Member

nrc commented Jun 13, 2014

I have sort of fixed this in my branch (PR coming soon). My branch forces lifetimes to be invariant, but still allows bounds to be covariant (the latter was to hard to address fix instances of in the compiler, or at least was potentially open-ended enough to put me off trying). I have left a FIXME pointing to this issue in the code for the covariance fix, it would only require removing a small hack. Tidying up afterwards may or may not be an issue.

The test case above gives the following error:

assign.rs:32:19: 32:20 error: `*b` does not live long enough
assign.rs:32     let bb: & B = b;
                               ^
assign.rs:30:23: 34:2 note: reference must be valid for the anonymous lifetime #1 defined on the block at 30:22...
assign.rs:30 fn make_make_a() -> A {
assign.rs:31     let b: Box<B> = box B {i:1};
assign.rs:32     let bb: & B = b;
assign.rs:33     make_a(bb)
assign.rs:34 }
assign.rs:30:23: 34:2 note: ...but borrowed value is only valid for the block at 30:22
assign.rs:30 fn make_make_a() -> A {
assign.rs:31     let b: Box<B> = box B {i:1};
assign.rs:32     let bb: & B = b;
assign.rs:33     make_a(bb)
assign.rs:34 }

We should add a proper test here before this issue can be considered closed.

nrc added a commit to nrc/rust that referenced this issue Jun 17, 2014
Use ty_rptr/ty_uniq(ty_trait) rather than TraitStore to represent trait types.
Also addresses (but doesn't close) rust-lang#12470.
Part of the work towards DST (rust-lang#12938).

[breaking-change] lifetime parameters in `&mut trait` are now invariant. They used to be contravariant.
bors added a commit that referenced this issue Jun 18, 2014
Use ty_rptr/ty_uniq(ty_trait) rather than TraitStore to represent trait types.
Also addresses (but doesn't close) #12470.
Part of the work towards DST (#12938).
edwardw added a commit to edwardw/rust that referenced this issue Jun 23, 2014
The rust-lang#14869 removed `TraitStore` from `ty_trait` and represented trait
reference as regular `ty_rptr`. An old bug of the missing constraint
upon lifetime parameter of trait reference then is fixed as a side
effect. Adds tests for affected bugs and closes them.

Closes rust-lang#12470.
Closes rust-lang#14285.
pcwalton added a commit to pcwalton/rust that referenced this issue Jun 24, 2014
alexcrichton pushed a commit to alexcrichton/rust that referenced this issue Jun 25, 2014
alexcrichton added a commit to alexcrichton/rust that referenced this issue Jun 25, 2014
Closes rust-lang#14482 (std: Bring back half of Add on String)
Closes rust-lang#15026 (librustc: Remove the fallback to `int` from typechecking.)
Closes rust-lang#15119 (Add more description to c_str::unwrap().)
Closes rust-lang#15120 (Add tests for rust-lang#12470 and rust-lang#14285)
Closes rust-lang#15122 (Remove the cheat sheet.)
Closes rust-lang#15126 (rustc: Always include the morestack library)
Closes rust-lang#15127 (Improve ambiguous pronoun.)
Closes rust-lang#15130 (Fix rust-lang#15129)
Closes rust-lang#15131 (Add the Guide, add warning to tutorial.)
Closes rust-lang#15134 (Xfailed tests for hygiene, etc.)
Closes rust-lang#15135 (core: Add stability attributes to Clone)
Closes rust-lang#15136 (Some minor improvements to core::bool)
Closes rust-lang#15137 (std: Add stability attributes to primitive numeric modules)
Closes rust-lang#15141 (Fix grammar in tutorial)
Closes rust-lang#15143 (Remove few FIXMEs)
Closes rust-lang#15145 (Avoid unnecessary temporary on assignments)
Closes rust-lang#15147 (Small improvements for metaprogramming)
Closes rust-lang#15153 (librustc: Check function argument patterns for legality of by-move)
Closes rust-lang#15154 (test: Add a test for regions, traits, and variance.)
Closes rust-lang#15159 (rustc: Don't register syntax crates twice)
Closes rust-lang#13816 (Stabilize version output for rustc and rustdoc)
bors added a commit to rust-lang-ci/rust that referenced this issue Jul 25, 2022
fix: Cleanup output channels when restarting server

Fixes rust-lang/rust-analyzer#12469
matthiaskrgr pushed a commit to matthiaskrgr/rust that referenced this issue Mar 21, 2024
filetime::FileTime::now() is new in 0.2.9

Clippy makes a use of `filetime::FileTime::now()`, which is new in `filetime` 0.2.9.

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-typesystem Area: The type system
Projects
None yet
8 participants