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

dropck and new scoping rules for safe destruction #21972

Merged
merged 9 commits into from
Feb 11, 2015

Conversation

pnkfelix
Copy link
Member

@pnkfelix pnkfelix commented Feb 5, 2015

This is a resurrection and heavy revision/expansion of a PR that pcwalton did to resolve #8861.

The most relevant, user-visible semantic change is this: if a type expression for some value has a destructor, then any lifetimes referenced within that type expression must strictly outlive the scope of the value.

See discussion on rust-lang/rfcs#769, especially for the discussion of the meaning of "strictly outlive."


A previous version of this pull request also removed the #[unsafe_destructor] attribute, as well as the analysis that would reject generic Drop impls that were not annotated with that attribute. For the short term, however, we are landing just the new, stricter, believed-to-be sound analysis; there is still work remaining on #8861 before we could be comfortable removing the #[unsafe_destructor] attribute.

[breaking-change]

@rust-highfive
Copy link
Collaborator

r? @huonw

(rust_highfive has picked a reviewer for you, use r? to override)

@nikomatsakis
Copy link
Contributor

r? @nikomatsakis

@rust-highfive rust-highfive assigned nikomatsakis and unassigned huonw Feb 5, 2015
@pnkfelix
Copy link
Member Author

pnkfelix commented Feb 5, 2015

This PR is for @nikomatsakis to look at.

It is marked "no checkin" because it includes a marker::OwnsInstancesOf<T> change that is a local recreation of the (planned?) marker::PhantomData<T>. So landing this will require coordinating those two efforts, perhaps by landing marker::PhantomData<T> on its own ahead of time.

@pnkfelix
Copy link
Member Author

pnkfelix commented Feb 5, 2015

(also, I would not object if someone wants me to separate out the removal of #[unsafe_destructor] from the other changes. i.e. if we want to take some time to let this bake before we declare Sound Generic Drop to be complete.)

@nikomatsakis
Copy link
Contributor

modulo that nit, the parametricity commit looks good to me. I had some doubts for a bit but assuaged them by building and thinking about it. I think the key point is that when the "type has dtor of interest" flag is false, we are basically inlining what the default drop glue will do, since we have decided that the actions of the destructor itself are immaterial. One key point that worried me for a bit is that any type which carries borrowed data explicitly must have a region parameter, and hence is always a "dtor of interest" with the stricter rules.

@pnkfelix pnkfelix force-pushed the new-dtor-semantics-6 branch 3 times, most recently from c84b47e to 509a378 Compare February 11, 2015 07:29
(My fix to for-loops (21984) did not deal with similar problems in
if-let expressions, so those binding shifts stay.)
immediately surrounding a node that is a terminating_scope
(e.g. statements, looping forms) during which the destructors run (the
destructors for temporaries from the execution of that node, that is).

Introduced DestructionScopeData newtype wrapper around ast::NodeId, to
preserve invariant that FreeRegion and ScopeChain::BlockScope carry
destruction scopes (rather than arbitrary CodeExtents).

Insert DestructionScope and block Remainder into enclosing CodeExtents
hierarchy.

Add more doc for DestructionScope, complete with ASCII art.

Switch to constructing DestructionScope rather than Misc in a number
of places, mostly related to `ty::ReFree` creation, and use
destruction-scopes of node-ids at various calls to
liberate_late_bound_regions.

middle::resolve_lifetime: Map BlockScope to DestructionScope in `fn resolve_free_lifetime`.

Add the InnermostDeclaringBlock and InnermostEnclosingExpr enums that
are my attempt to clarify the region::Context structure, and that
later commmts build upon.

Improve the debug output for `CodeExtent` attached to `ty::Region::ReScope`.

Loosened an assertion in `rustc_trans::trans::cleanup` to account for
`DestructionScope`.  (Perhaps this should just be switched entirely
over to `DestructionScope`, rather than allowing for either `Misc` or
`DestructionScope`.)

----

Even though the DestructionScope is new, this particular commit should
not actually change the semantics of any current code.
Largely adapted from pcwalton's original branch, with following
notable modifications:

Use `regionck::type_must_outlive` to generate `SafeDestructor`
constraints.  (this plugged some soundness holes in the analysis).

Avoid exponential time blowup on compile-fail/huge-struct.rs by
keeping the breadcrumbs until end of traversal.

Avoid premature return from regionck::visit_expr.

Factored drop-checking code out into dropck module.

Added `SafeDestructor` to enum `SubregionOrigin` (for error reporting).

----

Since this imposes restrictions on the lifetimes used in types with
destructors, this is a (wait for it)

[breaking-change]
@pnkfelix pnkfelix force-pushed the new-dtor-semantics-6 branch 9 times, most recently from 85627d5 to 1a2954b Compare February 11, 2015 08:08
let &ty::ParamBounds {
ref region_bounds, builtin_bounds, ref trait_bounds,
ref projection_bounds,
} = &t.bounds;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to establish context (post rebasing) for his note above, nikomatsakis had a note here (in the original commit), as follows:

the bounds are reflected in the predicates already, so you don't have to look at them.

@pnkfelix
Copy link
Member Author

@bors: r=nikomatsakis 2c9d81b p=1

@bors
Copy link
Contributor

bors commented Feb 11, 2015

⌛ Testing commit 2c9d81b with merge fc6123d...

@bors
Copy link
Contributor

bors commented Feb 11, 2015

💔 Test failed - auto-win-32-nopt-t

@pnkfelix
Copy link
Member Author

@bors: retry

@bors
Copy link
Contributor

bors commented Feb 11, 2015

⌛ Testing commit 2c9d81b with merge e29f420...

bors added a commit that referenced this pull request Feb 11, 2015
This is a resurrection and heavy revision/expansion of a PR that pcwalton did to resolve #8861.

The most relevant, user-visible semantic change is this: #[unsafe_destructor] is gone. Instead, if a type expression for some value has a destructor, then any lifetimes referenced within that type expression must strictly outlive the scope of the value.

See discussion on rust-lang/rfcs#769
@pnkfelix
Copy link
Member Author

Argh, bors, you used my old description for your merge message!

@pnkfelix
Copy link
Member Author

Argh, bors, you used my old description for your merge message!

Hey @barosl is this related to barosl/homu#51 , or is it a distinct issue that deserves a separate ticket?

(My old description said "... #[unsafe_destructor] is gone ..." But then over development of the PR, we decided to take out that bit. It is unfortunate that the commit history is likely to end up claiming that its gone, due to the use of the old description.)


(Having said that, fixing the commit message is not worth cancelling the build. But if this build fails, then I will open a fresh PR to work around these issues with bors.)

@aturon aturon mentioned this pull request Feb 11, 2015
38 tasks
@brson
Copy link
Contributor

brson commented Feb 17, 2015

This is a big deal! 🚀

@brson
Copy link
Contributor

brson commented Feb 17, 2015

Beautiful tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

New destructor semantics
6 participants