/// type `T`.
///
/// [get_mut]: #method.get_mut
-#[cfg_attr(not(test), lang = "rc")]
+#[cfg_attr(all(bootstrap, not(test)), lang = "rc")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "Rc")]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Rc<T: ?Sized> {
ptr: NonNull<RcBox<T>>,
/// counting in general.
///
/// [rc_examples]: ../../std/rc/index.html#examples
-#[cfg_attr(not(test), lang = "arc")]
+#[cfg_attr(all(bootstrap, not(test)), lang = "arc")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "Arc")]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Arc<T: ?Sized> {
ptr: NonNull<ArcInner<T>>,
```compile_fail,E0152
#![feature(lang_items)]
-#[lang = "arc"]
-struct Foo; // error: duplicate lang item found: `arc`
+#[lang = "owned_box"]
+struct Foo; // error: duplicate lang item found: `owned_box`
```
Lang items are already implemented in the standard library. Unless you are
```compile_fail,E0718
#![feature(lang_items)]
-#[lang = "arc"]
+#[lang = "owned_box"]
static X: u32 = 42;
```
AlignOffsetLangItem, "align_offset", align_offset_fn, Target::Fn;
TerminationTraitLangItem, "termination", termination, Target::Trait;
-
- Arc, "arc", arc, Target::Struct;
- Rc, "rc", rc, Target::Struct;
}
Some(self.mk_generic_adt(def_id, ty))
}
+ #[inline]
+ pub fn mk_diagnostic_item(self, ty: Ty<'tcx>, name: Symbol) -> Option<Ty<'tcx>> {
+ let def_id = self.get_diagnostic_item(name)?;
+ Some(self.mk_generic_adt(def_id, ty))
+ }
+
#[inline]
pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> {
let def_id = self.require_lang_item(lang_items::MaybeUninitLangItem, None);
const IS_BOX = 1 << 6;
/// Indicates whether the type is `ManuallyDrop`.
const IS_MANUALLY_DROP = 1 << 7;
- // FIXME(matthewjasper) replace these with diagnostic items
- /// Indicates whether the type is an `Arc`.
- const IS_ARC = 1 << 8;
- /// Indicates whether the type is an `Rc`.
- const IS_RC = 1 << 9;
/// 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 << 10;
+ const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 8;
}
}
if Some(did) == tcx.lang_items().manually_drop() {
flags |= AdtFlags::IS_MANUALLY_DROP;
}
- if Some(did) == tcx.lang_items().arc() {
- flags |= AdtFlags::IS_ARC;
- }
- if Some(did) == tcx.lang_items().rc() {
- flags |= AdtFlags::IS_RC;
- }
AdtDef { did, variants, flags, repr }
}
self.flags.contains(AdtFlags::IS_PHANTOM_DATA)
}
- /// Returns `true` if this is `Arc<T>`.
- pub fn is_arc(&self) -> bool {
- self.flags.contains(AdtFlags::IS_ARC)
- }
-
- /// Returns `true` if this is `Rc<T>`.
- pub fn is_rc(&self) -> bool {
- self.flags.contains(AdtFlags::IS_RC)
- }
-
/// Returns `true` if this is Box<T>.
#[inline]
pub fn is_box(&self) -> bool {
self.is_region_ptr() || self.is_unsafe_ptr() || self.is_fn_ptr()
}
- /// Returns `true` if this type is an `Arc<T>`.
- #[inline]
- pub fn is_arc(&self) -> bool {
- match self.kind {
- Adt(def, _) => def.is_arc(),
- _ => false,
- }
- }
-
- /// Returns `true` if this type is an `Rc<T>`.
- #[inline]
- pub fn is_rc(&self) -> bool {
- match self.kind {
- Adt(def, _) => def.is_rc(),
- _ => false,
- }
- }
-
#[inline]
pub fn is_box(&self) -> bool {
match self.kind {
};
use rustc_middle::ty::print::Print;
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt};
-use rustc_span::Span;
+use rustc_span::{symbol::sym, Span};
use rustc_target::abi::VariantIdx;
use super::borrow_set::BorrowData;
}
impl BorrowedContentSource<'tcx> {
- pub(super) fn describe_for_unnamed_place(&self) -> String {
+ pub(super) fn describe_for_unnamed_place(&self, tcx: TyCtxt<'_>) -> String {
match *self {
BorrowedContentSource::DerefRawPointer => "a raw pointer".to_string(),
BorrowedContentSource::DerefSharedRef => "a shared reference".to_string(),
BorrowedContentSource::DerefMutableRef => "a mutable reference".to_string(),
- BorrowedContentSource::OverloadedDeref(ty) => {
- if ty.is_rc() {
+ BorrowedContentSource::OverloadedDeref(ty) => match ty.kind {
+ ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Rc, def.did) => {
"an `Rc`".to_string()
- } else if ty.is_arc() {
+ }
+ ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Arc, def.did) => {
"an `Arc`".to_string()
- } else {
- format!("dereference of `{}`", ty)
}
- }
+ _ => format!("dereference of `{}`", ty),
+ },
BorrowedContentSource::OverloadedIndex(ty) => format!("index of `{}`", ty),
}
}
}
}
- pub(super) fn describe_for_immutable_place(&self) -> String {
+ pub(super) fn describe_for_immutable_place(&self, tcx: TyCtxt<'_>) -> String {
match *self {
BorrowedContentSource::DerefRawPointer => "a `*const` pointer".to_string(),
BorrowedContentSource::DerefSharedRef => "a `&` reference".to_string(),
BorrowedContentSource::DerefMutableRef => {
bug!("describe_for_immutable_place: DerefMutableRef isn't immutable")
}
- BorrowedContentSource::OverloadedDeref(ty) => {
- if ty.is_rc() {
+ BorrowedContentSource::OverloadedDeref(ty) => match ty.kind {
+ ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Rc, def.did) => {
"an `Rc`".to_string()
- } else if ty.is_arc() {
+ }
+ ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Arc, def.did) => {
"an `Arc`".to_string()
- } else {
- format!("a dereference of `{}`", ty)
}
- }
+ _ => format!("a dereference of `{}`", ty),
+ },
BorrowedContentSource::OverloadedIndex(ty) => format!("an index of `{}`", ty),
}
}
span,
&format!("`{}` which is behind a {}", place_desc, source_desc),
),
- (_, _) => self.cannot_move_out_of(span, &source.describe_for_unnamed_place()),
+ (_, _) => self.cannot_move_out_of(
+ span,
+ &source.describe_for_unnamed_place(self.infcx.tcx),
+ ),
}
}
};
local: the_place_err.local,
projection: proj_base,
});
- let pointer_type = source.describe_for_immutable_place();
+ let pointer_type = source.describe_for_immutable_place(self.infcx.tcx);
opt_source = Some(source);
if let Some(desc) = access_place_desc {
item_msg = format!("`{}`", desc);
any,
arbitrary_enum_discriminant,
arbitrary_self_types,
+ Arc,
Arguments,
ArgumentV1,
arm_target_feature,
raw_dylib,
raw_identifiers,
raw_ref_op,
+ Rc,
Ready,
reason,
recursion_limit,
error: MethodError<'tcx>,
) {
let rcvr = &args[0];
- let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, rcvr_t, lang_item| {
- if let Some(new_rcvr_t) = self.tcx.mk_lang_item(rcvr_t, lang_item) {
+ let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| {
+ if let Some(new_rcvr_t) = new_rcvr_t {
if let Ok(pick) = self.lookup_probe(
span,
segment.ident,
// Try alternative arbitrary self types that could fulfill this call.
// FIXME: probe for all types that *could* be arbitrary self-types, not
// just this whitelist.
- try_alt_rcvr(&mut err, rcvr_t, lang_items::OwnedBoxLangItem);
- try_alt_rcvr(&mut err, rcvr_t, lang_items::PinTypeLangItem);
- try_alt_rcvr(&mut err, rcvr_t, lang_items::Arc);
- try_alt_rcvr(&mut err, rcvr_t, lang_items::Rc);
+ try_alt_rcvr(&mut err, self.tcx.mk_lang_item(rcvr_t, lang_items::OwnedBoxLangItem));
+ try_alt_rcvr(&mut err, self.tcx.mk_lang_item(rcvr_t, lang_items::PinTypeLangItem));
+ try_alt_rcvr(&mut err, self.tcx.mk_diagnostic_item(rcvr_t, sym::Arc));
+ try_alt_rcvr(&mut err, self.tcx.mk_diagnostic_item(rcvr_t, sym::Rc));
}
err.emit();
}
#![feature(lang_items)]
-#[lang = "arc"]
+#[lang = "owned_box"]
struct Foo; //~ ERROR E0152
fn main() {
-error[E0152]: found duplicate lang item `arc`
+error[E0152]: found duplicate lang item `owned_box`
--> $DIR/E0152.rs:4:1
|
LL | struct Foo;
#![feature(lang_items)]
-// Arc is expected to be a struct, so this will error.
-#[lang = "arc"] //~ ERROR language item must be applied to a struct
+// Box is expected to be a struct, so this will error.
+#[lang = "owned_box"] //~ ERROR language item must be applied to a struct
static X: u32 = 42;
fn main() {}
-error[E0718]: `arc` language item must be applied to a struct
+error[E0718]: `owned_box` language item must be applied to a struct
--> $DIR/E0718.rs:4:1
|
-LL | #[lang = "arc"]
- | ^^^^^^^^^^^^^^^ attribute should be applied to a struct, not a static item
+LL | #[lang = "owned_box"]
+ | ^^^^^^^^^^^^^^^^^^^^^ attribute should be applied to a struct, not a static item
error: aborting due to previous error