Skip to content

Commit da4a120

Browse files
committed
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.
1 parent 1886d5f commit da4a120

File tree

6 files changed

+44
-1
lines changed

6 files changed

+44
-1
lines changed

src/doc/unstable-book/src/language-features/lang-items.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,3 +311,5 @@ the source code.
311311
- `freeze`: `libcore/marker.rs`
312312
- `debug_trait`: `libcore/fmt/mod.rs`
313313
- `non_zero`: `libcore/nonzero.rs`
314+
- `arc`: `liballoc/sync.rs`
315+
- `rc`: `liballoc/rc.rs`

src/liballoc/rc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ struct RcBox<T: ?Sized> {
282282
/// type `T`.
283283
///
284284
/// [get_mut]: #method.get_mut
285+
#[cfg_attr(all(not(stage0), not(test)), lang = "rc")]
285286
#[stable(feature = "rust1", since = "1.0.0")]
286287
pub struct Rc<T: ?Sized> {
287288
ptr: NonNull<RcBox<T>>,

src/liballoc/sync.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
199199
/// counting in general.
200200
///
201201
/// [rc_examples]: ../../std/rc/index.html#examples
202+
#[cfg_attr(all(not(stage0), not(test)), lang = "arc")]
202203
#[stable(feature = "rust1", since = "1.0.0")]
203204
pub struct Arc<T: ?Sized> {
204205
ptr: NonNull<ArcInner<T>>,

src/librustc/middle/lang_items.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,9 @@ language_item_table! {
362362
AlignOffsetLangItem, "align_offset", align_offset_fn;
363363

364364
TerminationTraitLangItem, "termination", termination;
365+
366+
Arc, "arc", arc;
367+
Rc, "rc", rc;
365368
}
366369

367370
impl<'a, 'tcx, 'gcx> TyCtxt<'a, 'tcx, 'gcx> {

src/librustc/ty/mod.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1694,9 +1694,13 @@ bitflags! {
16941694
const IS_FUNDAMENTAL = 1 << 2;
16951695
const IS_UNION = 1 << 3;
16961696
const IS_BOX = 1 << 4;
1697+
/// Indicates whether the type is an `Arc`.
1698+
const IS_ARC = 1 << 5;
1699+
/// Indicates whether the type is an `Rc`.
1700+
const IS_RC = 1 << 6;
16971701
/// Indicates whether the variant list of this ADT is `#[non_exhaustive]`.
16981702
/// (i.e., this flag is never set unless this ADT is an enum).
1699-
const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 5;
1703+
const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 7;
17001704
}
17011705
}
17021706

@@ -2016,6 +2020,12 @@ impl<'a, 'gcx, 'tcx> AdtDef {
20162020
if Some(did) == tcx.lang_items().owned_box() {
20172021
flags = flags | AdtFlags::IS_BOX;
20182022
}
2023+
if Some(did) == tcx.lang_items().arc() {
2024+
flags = flags | AdtFlags::IS_ARC;
2025+
}
2026+
if Some(did) == tcx.lang_items().rc() {
2027+
flags = flags | AdtFlags::IS_RC;
2028+
}
20192029
if kind == AdtKind::Enum && tcx.has_attr(did, "non_exhaustive") {
20202030
debug!("found non-exhaustive variant list for {:?}", did);
20212031
flags = flags | AdtFlags::IS_VARIANT_LIST_NON_EXHAUSTIVE;
@@ -2094,6 +2104,16 @@ impl<'a, 'gcx, 'tcx> AdtDef {
20942104
self.flags.intersects(AdtFlags::IS_PHANTOM_DATA)
20952105
}
20962106

2107+
/// Returns `true` if this is `Arc<T>`.
2108+
pub fn is_arc(&self) -> bool {
2109+
self.flags.intersects(AdtFlags::IS_ARC)
2110+
}
2111+
2112+
/// Returns `true` if this is `Rc<T>`.
2113+
pub fn is_rc(&self) -> bool {
2114+
self.flags.intersects(AdtFlags::IS_RC)
2115+
}
2116+
20972117
/// Returns true if this is Box<T>.
20982118
#[inline]
20992119
pub fn is_box(&self) -> bool {

src/librustc/ty/sty.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,6 +1598,22 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
15981598
}
15991599
}
16001600

1601+
/// Returns `true` if this type is an `Arc<T>`.
1602+
pub fn is_arc(&self) -> bool {
1603+
match self.sty {
1604+
Adt(def, _) => def.is_arc(),
1605+
_ => false,
1606+
}
1607+
}
1608+
1609+
/// Returns `true` if this type is an `Rc<T>`.
1610+
pub fn is_rc(&self) -> bool {
1611+
match self.sty {
1612+
Adt(def, _) => def.is_rc(),
1613+
_ => false,
1614+
}
1615+
}
1616+
16011617
pub fn is_box(&self) -> bool {
16021618
match self.sty {
16031619
Adt(def, _) => def.is_box(),

0 commit comments

Comments
 (0)