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

Reject specialized Drop impls. #23638

Merged
merged 11 commits into from
Mar 25, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/doc/trpl/unsafe.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,16 @@ use std::ptr;

// Define a wrapper around the handle returned by the foreign code.
// Unique<T> has the same semantics as Box<T>
pub struct Unique<T> {
//
// NB: For simplicity and correctness, we require that T has kind Send
// (owned boxes relax this restriction).
pub struct Unique<T: Send> {
// It contains a single raw, mutable pointer to the object in question.
ptr: *mut T
}

// Implement methods for creating and using the values in the box.

// NB: For simplicity and correctness, we require that T has kind Send
// (owned boxes relax this restriction).
impl<T: Send> Unique<T> {
pub fn new(value: T) -> Unique<T> {
unsafe {
Expand Down Expand Up @@ -239,11 +240,11 @@ impl<T: Send> Unique<T> {
// Unique<T>, making the struct manage the raw pointer: when the
// struct goes out of scope, it will automatically free the raw pointer.
//
// NB: This is an unsafe destructor, because rustc will not normally
// allow destructors to be associated with parameterized types, due to
// bad interaction with managed boxes. (With the Send restriction,
// we don't have this problem.) Note that the `#[unsafe_destructor]`
// feature gate is required to use unsafe destructors.
// NB: This is an unsafe destructor; rustc will not normally allow
// destructors to be associated with parameterized types (due to
// historically failing to check them soundly). Note that the
// `#[unsafe_destructor]` feature gate is currently required to use
// unsafe destructors.
#[unsafe_destructor]
impl<T: Send> Drop for Unique<T> {
fn drop(&mut self) {
Expand Down
6 changes: 3 additions & 3 deletions src/liballoc/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ impl<T: Send + Sync + Clone> Arc<T> {

#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Sync + Send> Drop for Arc<T> {
impl<T> Drop for Arc<T> {
/// Drops the `Arc<T>`.
///
/// This will decrement the strong reference count. If the strong reference
Expand Down Expand Up @@ -388,7 +388,7 @@ impl<T: Sync + Send> Drop for Arc<T> {

#[unstable(feature = "alloc",
reason = "Weak pointers may not belong in this module.")]
impl<T: Sync + Send> Weak<T> {
impl<T> Weak<T> {
/// Upgrades a weak reference to a strong reference.
///
/// Upgrades the `Weak<T>` reference to an `Arc<T>`, if possible.
Expand Down Expand Up @@ -454,7 +454,7 @@ impl<T: Sync + Send> Clone for Weak<T> {

#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Sync + Send> Drop for Weak<T> {
impl<T> Drop for Weak<T> {
/// Drops the `Weak<T>`.
///
/// This will decrement the weak reference count.
Expand Down
58 changes: 58 additions & 0 deletions src/librustc/middle/infer/higher_ranked/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use super::{CombinedSnapshot, cres, InferCtxt, HigherRankedType, SkolemizationMap};
use super::combine::{Combine, Combineable};

use middle::subst;
use middle::ty::{self, Binder};
use middle::ty_fold::{self, TypeFoldable};
use syntax::codemap::Span;
Expand Down Expand Up @@ -455,6 +456,63 @@ impl<'a,'tcx> InferCtxtExt for InferCtxt<'a,'tcx> {
}
}

/// Constructs and returns a substitution that, for a given type
/// scheme parameterized by `generics`, will replace every generic
/// parmeter in the type with a skolemized type/region (which one can
/// think of as a "fresh constant", except at the type/region level of
/// reasoning).
///
/// Since we currently represent bound/free type parameters in the
/// same way, this only has an effect on regions.
///
/// (Note that unlike a substitution from `ty::construct_free_substs`,
/// this inserts skolemized regions rather than free regions; this
/// allows one to use `fn leak_check` to catch attmepts to unify the
/// skolemized regions with e.g. the `'static` lifetime)
pub fn construct_skolemized_substs<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
generics: &ty::Generics<'tcx>,
snapshot: &CombinedSnapshot)
-> (subst::Substs<'tcx>, SkolemizationMap)
{
let mut map = FnvHashMap();

// map T => T
let mut types = subst::VecPerParamSpace::empty();
push_types_from_defs(infcx.tcx, &mut types, generics.types.as_slice());

// map early- or late-bound 'a => fresh 'a
let mut regions = subst::VecPerParamSpace::empty();
push_region_params(infcx, &mut map, &mut regions, generics.regions.as_slice(), snapshot);

let substs = subst::Substs { types: types,
regions: subst::NonerasedRegions(regions) };
return (substs, map);

fn push_region_params<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
map: &mut SkolemizationMap,
regions: &mut subst::VecPerParamSpace<ty::Region>,
region_params: &[ty::RegionParameterDef],
snapshot: &CombinedSnapshot)
{
for r in region_params {
let br = r.to_bound_region();
let skol_var = infcx.region_vars.new_skolemized(br, &snapshot.region_vars_snapshot);
let sanity_check = map.insert(br, skol_var);
assert!(sanity_check.is_none());
regions.push(r.space, skol_var);
}
}

fn push_types_from_defs<'tcx>(tcx: &ty::ctxt<'tcx>,
types: &mut subst::VecPerParamSpace<ty::Ty<'tcx>>,
defs: &[ty::TypeParameterDef<'tcx>]) {
for def in defs {
let ty = ty::mk_param_from_def(tcx, def);
types.push(def.space, ty);
}
}
}

pub fn skolemize_late_bound_regions<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
binder: &ty::Binder<T>,
snapshot: &CombinedSnapshot)
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/middle/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
})
}

pub fn construct_skolemized_subst(&self,
generics: &ty::Generics<'tcx>,
snapshot: &CombinedSnapshot)
-> (subst::Substs<'tcx>, SkolemizationMap) {
/*! See `higher_ranked::construct_skolemized_subst` */

higher_ranked::construct_skolemized_substs(self, generics, snapshot)
}

pub fn skolemize_late_bound_regions<T>(&self,
value: &ty::Binder<T>,
snapshot: &CombinedSnapshot)
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1793,6 +1793,9 @@ impl RegionParameterDef {
pub fn to_early_bound_region(&self) -> ty::Region {
ty::ReEarlyBound(self.def_id.node, self.space, self.index, self.name)
}
pub fn to_bound_region(&self) -> ty::BoundRegion {
ty::BoundRegion::BrNamed(self.def_id, self.name)
}
}

/// Information about the formal type/lifetime parameters associated
Expand Down
Loading