diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2017-04-17 21:18:56 +0300 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2017-04-20 14:39:31 +0300 |
| commit | 6563374ed2e518ea5fec2b7411dc4331772c46d2 (patch) | |
| tree | 6211971da9ad119e25d1b2c2e13960c65611a29d /src/librustc | |
| parent | 3f5c311dc1dcb5bfe65d6eecd0dfda04d77c7594 (diff) | |
| download | rust-6563374ed2e518ea5fec2b7411dc4331772c46d2.tar.gz rust-6563374ed2e518ea5fec2b7411dc4331772c46d2.zip | |
rustc: replace interior_unsafe with a Freeze trait.
Diffstat (limited to 'src/librustc')
| -rw-r--r-- | src/librustc/middle/lang_items.rs | 1 | ||||
| -rw-r--r-- | src/librustc/ty/contents.rs | 14 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 8 | ||||
| -rw-r--r-- | src/librustc/ty/util.rs | 44 |
4 files changed, 55 insertions, 12 deletions
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 5989fa9007c..32dfb63d615 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -274,6 +274,7 @@ language_item_table! { UnsizeTraitLangItem, "unsize", unsize_trait; CopyTraitLangItem, "copy", copy_trait; SyncTraitLangItem, "sync", sync_trait; + FreezeTraitLangItem, "freeze", freeze_trait; DropTraitLangItem, "drop", drop_trait; diff --git a/src/librustc/ty/contents.rs b/src/librustc/ty/contents.rs index c690795b342..a1cb848213a 100644 --- a/src/librustc/ty/contents.rs +++ b/src/librustc/ty/contents.rs @@ -24,8 +24,7 @@ bitflags! { /// easier for me (nmatsakis) to think about what is contained within /// a type than to think about what is *not* contained within a type. flags TypeContents: u8 { - const INTERIOR_UNSAFE = 0b01, - const OWNS_DTOR = 0b10, + const OWNS_DTOR = 0b1, } } @@ -34,10 +33,6 @@ impl TypeContents { if cond {*self} else {TypeContents::empty()} } - pub fn interior_unsafe(&self) -> bool { - self.intersects(TypeContents::INTERIOR_UNSAFE) - } - pub fn needs_drop(&self, _: TyCtxt) -> bool { self.intersects(TypeContents::OWNS_DTOR) } @@ -124,17 +119,12 @@ impl<'a, 'tcx> ty::TyS<'tcx> { // unions don't have destructors regardless of the child types - TypeContents::OWNS_DTOR.when(def.is_union()) | TypeContents::OWNS_DTOR.when(def.has_dtor(tcx)) - | TypeContents::INTERIOR_UNSAFE.when( - Some(def.did) == tcx.lang_items.unsafe_cell_type()) } - ty::TyDynamic(..) | ty::TyProjection(..) | ty::TyParam(_) | - ty::TyAnon(..) => { - TypeContents::INTERIOR_UNSAFE | TypeContents::OWNS_DTOR - } + ty::TyAnon(..) => TypeContents::OWNS_DTOR, ty::TyInfer(_) | ty::TyError => { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 78d3885bb98..7325235ca7b 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -425,6 +425,8 @@ bitflags! { const IS_SIZED = 1 << 17, const MOVENESS_CACHED = 1 << 18, const MOVES_BY_DEFAULT = 1 << 19, + const FREEZENESS_CACHED = 1 << 20, + const IS_FREEZE = 1 << 21, } } @@ -1181,6 +1183,9 @@ pub struct ParameterEnvironment<'tcx> { /// A cache for `type_is_sized` pub is_sized_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>, + + /// A cache for `type_is_freeze` + pub is_freeze_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>, } impl<'a, 'tcx> ParameterEnvironment<'tcx> { @@ -1195,6 +1200,7 @@ impl<'a, 'tcx> ParameterEnvironment<'tcx> { free_id_outlive: self.free_id_outlive, is_copy_cache: RefCell::new(FxHashMap()), is_sized_cache: RefCell::new(FxHashMap()), + is_freeze_cache: RefCell::new(FxHashMap()), } } @@ -2531,6 +2537,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { free_id_outlive: free_id_outlive, is_copy_cache: RefCell::new(FxHashMap()), is_sized_cache: RefCell::new(FxHashMap()), + is_freeze_cache: RefCell::new(FxHashMap()), } } @@ -2603,6 +2610,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { free_id_outlive: free_id_outlive, is_copy_cache: RefCell::new(FxHashMap()), is_sized_cache: RefCell::new(FxHashMap()), + is_freeze_cache: RefCell::new(FxHashMap()), }; let cause = traits::ObligationCause::misc(span, free_id_outlive.node_id(&self.region_maps)); diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 5334ee2835d..d43d570397b 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -655,6 +655,50 @@ impl<'a, 'tcx> ty::TyS<'tcx> { result } + /// Returns `true` if and only if there are no `UnsafeCell`s + /// nested within the type (ignoring `PhantomData` or pointers). + #[inline] + pub fn is_freeze(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, + param_env: &ParameterEnvironment<'tcx>, + span: Span) -> bool + { + if self.flags.get().intersects(TypeFlags::FREEZENESS_CACHED) { + return self.flags.get().intersects(TypeFlags::IS_FREEZE); + } + + self.is_freeze_uncached(tcx, param_env, span) + } + + fn is_freeze_uncached(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, + param_env: &ParameterEnvironment<'tcx>, + span: Span) -> bool { + assert!(!self.needs_infer()); + + // Fast-path for primitive types + let result = match self.sty { + TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | + TyRawPtr(..) | TyRef(..) | TyFnDef(..) | TyFnPtr(_) | + TyStr | TyNever => Some(true), + + TyArray(..) | TySlice(_) | + TyTuple(..) | TyClosure(..) | TyAdt(..) | + TyDynamic(..) | TyProjection(..) | TyParam(..) | + TyInfer(..) | TyAnon(..) | TyError => None + }.unwrap_or_else(|| { + self.impls_bound(tcx, param_env, tcx.require_lang_item(lang_items::FreezeTraitLangItem), + ¶m_env.is_freeze_cache, span) }); + + if !self.has_param_types() && !self.has_self_ty() { + self.flags.set(self.flags.get() | if result { + TypeFlags::FREEZENESS_CACHED | TypeFlags::IS_FREEZE + } else { + TypeFlags::FREEZENESS_CACHED + }); + } + + result + } + #[inline] pub fn layout<'lcx>(&'tcx self, infcx: &InferCtxt<'a, 'tcx, 'lcx>) -> Result<&'tcx Layout, LayoutError<'tcx>> { |
