Skip to content

Liveness, borrowck and last use interact badly #2633

Closed
@catamorphism

Description

@catamorphism

This arose from #2584. This code snippet from trans::base::trans_assign_op illustrates the problem:

        ret move_val(bcx, DROP_EXISTING, lhs_res.val,
                     // FIXME: should kind be owned?
                     {bcx: bcx, val: target, kind: owned},
                     dty);

bcx has type block, which is now a newtype-like enum whose LHS is an @ of a class. The bug is exposed by the fact that block doesn't get treated as immediate even though its representation is a box, but that's not the main bug. The main problem is that there's an implicit move because of the second use of bcx as a field in the record literal: it's a last use, implying that bcx gets zeroed at that point. Normally, borrowck would flag a move of something that has a reference to it (the reference gets brought about by the first instance of bcx, as the first argument to move_val). But since the implicit moves due to last-use information aren't visible to borrowck, the code happily compiles, runs, and then segfaults when move_val dereferences its first argument.

@nikomatsakis and I discussed this a bit on IRC and there's not a clear solution (though there is an obvious workaround for #2584). Perhaps the answer is to just remove last-use analysis.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generationA-type-systemArea: Type systemI-crashIssue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions