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.
This commit is contained in:
parent
1886d5fe1c
commit
da4a12038b
6 changed files with 44 additions and 1 deletions
|
|
@ -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`
|
||||
|
|
|
|||
|
|
@ -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>>,
|
||||
|
|
|
|||
|
|
@ -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>>,
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue