diff options
| author | David Wood <david@davidtw.co> | 2018-09-30 21:19:55 +0200 |
|---|---|---|
| committer | David Wood <david@davidtw.co> | 2018-10-01 13:50:21 +0200 |
| commit | da4a12038bac647b8d07211588c21f1ca07c12e3 (patch) | |
| tree | e739f669e9665a433a53a16f9062e325450cff3f | |
| parent | 1886d5fe1cdd1a016ecea9fc93d68b3052c528c8 (diff) | |
Introduce language items for `Arc` and `Rc`.
This commit introduces language items for `Arc` and `Rc` so that types can later be checked to be `Arc` or `Rc` in the NLL borrow checker. The `lang` attribute is currently limited to `stage1` as it requires a compiler built with knowledge of the expected language items.
| -rw-r--r-- | src/doc/unstable-book/src/language-features/lang-items.md | 2 | ||||
| -rw-r--r-- | src/liballoc/rc.rs | 1 | ||||
| -rw-r--r-- | src/liballoc/sync.rs | 1 | ||||
| -rw-r--r-- | src/librustc/middle/lang_items.rs | 3 | ||||
| -rw-r--r-- | src/librustc/ty/mod.rs | 22 | ||||
| -rw-r--r-- | src/librustc/ty/sty.rs | 16 |
6 files changed, 44 insertions, 1 deletions
diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md index bac619fd4a3..b16739b4743 100644 --- a/src/doc/unstable-book/src/language-features/lang-items.md +++ b/src/doc/unstable-book/src/language-features/lang-items.md @@ -311,3 +311,5 @@ the source code. - `freeze`: `libcore/marker.rs` - `debug_trait`: `libcore/fmt/mod.rs` - `non_zero`: `libcore/nonzero.rs` + - `arc`: `liballoc/sync.rs` + - `rc`: `liballoc/rc.rs` diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 9d951691a34..915b8e7787e 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -282,6 +282,7 @@ struct RcBox<T: ?Sized> { /// type `T`. /// /// [get_mut]: #method.get_mut +#[cfg_attr(all(not(stage0), not(test)), lang = "rc")] #[stable(feature = "rust1", since = "1.0.0")] pub struct Rc<T: ?Sized> { ptr: NonNull<RcBox<T>>, diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 116393bdad1..9e245fbd7bb 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -199,6 +199,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// counting in general. /// /// [rc_examples]: ../../std/rc/index.html#examples +#[cfg_attr(all(not(stage0), not(test)), lang = "arc")] #[stable(feature = "rust1", since = "1.0.0")] pub struct Arc<T: ?Sized> { ptr: NonNull<ArcInner<T>>, diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index bfde4e4a3ae..ef70a4cc45d 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -362,6 +362,9 @@ language_item_table! { AlignOffsetLangItem, "align_offset", align_offset_fn; TerminationTraitLangItem, "termination", termination; + + Arc, "arc", arc; + Rc, "rc", rc; } impl<'a, 'tcx, 'gcx> TyCtxt<'a, 'tcx, 'gcx> { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index b2281691bd6..633551aed18 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1694,9 +1694,13 @@ bitflags! { const IS_FUNDAMENTAL = 1 << 2; const IS_UNION = 1 << 3; const IS_BOX = 1 << 4; + /// Indicates whether the type is an `Arc`. + const IS_ARC = 1 << 5; + /// Indicates whether the type is an `Rc`. + const IS_RC = 1 << 6; /// Indicates whether the variant list of this ADT is `#[non_exhaustive]`. /// (i.e., this flag is never set unless this ADT is an enum). - const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 5; + const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 7; } } @@ -2016,6 +2020,12 @@ impl<'a, 'gcx, 'tcx> AdtDef { if Some(did) == tcx.lang_items().owned_box() { flags = flags | AdtFlags::IS_BOX; } + if Some(did) == tcx.lang_items().arc() { + flags = flags | AdtFlags::IS_ARC; + } + if Some(did) == tcx.lang_items().rc() { + flags = flags | AdtFlags::IS_RC; + } if kind == AdtKind::Enum && tcx.has_attr(did, "non_exhaustive") { debug!("found non-exhaustive variant list for {:?}", did); flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE; @@ -2094,6 +2104,16 @@ impl<'a, 'gcx, 'tcx> AdtDef { self.flags.intersects(AdtFlags::IS_PHANTOM_DATA) } + /// Returns `true` if this is `Arc<T>`. + pub fn is_arc(&self) -> bool { + self.flags.intersects(AdtFlags::IS_ARC) + } + + /// Returns `true` if this is `Rc<T>`. + pub fn is_rc(&self) -> bool { + self.flags.intersects(AdtFlags::IS_RC) + } + /// Returns true if this is Box<T>. #[inline] pub fn is_box(&self) -> bool { diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 6c40dd89239..4f80bf45ab1 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1598,6 +1598,22 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { } } + /// Returns `true` if this type is an `Arc<T>`. + pub fn is_arc(&self) -> bool { + match self.sty { + Adt(def, _) => def.is_arc(), + _ => false, + } + } + + /// Returns `true` if this type is an `Rc<T>`. + pub fn is_rc(&self) -> bool { + match self.sty { + Adt(def, _) => def.is_rc(), + _ => false, + } + } + pub fn is_box(&self) -> bool { match self.sty { Adt(def, _) => def.is_box(), |
