mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Auto merge of #111671 - Dylan-DPC:rollup-1jy5r16, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #110145 (Share slice of bytes) - #111043 (Stabilize feature `cstr_is_empty`) - #111648 (Remove `LangItems::require`) - #111649 (Add derive for `core::marker::ConstParamTy`) - #111654 (Add a conversion from `&mut T` to `&mut UnsafeCell<T>`) - #111661 (Erase regions of type in `offset_of!`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c2ccc855e7
@ -27,3 +27,26 @@ pub fn expand_deriving_copy(
|
||||
|
||||
trait_def.expand(cx, mitem, item, push);
|
||||
}
|
||||
|
||||
pub fn expand_deriving_const_param_ty(
|
||||
cx: &mut ExtCtxt<'_>,
|
||||
span: Span,
|
||||
mitem: &MetaItem,
|
||||
item: &Annotatable,
|
||||
push: &mut dyn FnMut(Annotatable),
|
||||
is_const: bool,
|
||||
) {
|
||||
let trait_def = TraitDef {
|
||||
span,
|
||||
path: path_std!(marker::ConstParamTy),
|
||||
skip_path_as_bound: false,
|
||||
needs_copy_as_bound_if_packed: false,
|
||||
additional_bounds: Vec::new(),
|
||||
supports_unions: false,
|
||||
methods: Vec::new(),
|
||||
associated_types: Vec::new(),
|
||||
is_const,
|
||||
};
|
||||
|
||||
trait_def.expand(cx, mitem, item, push);
|
||||
}
|
||||
|
@ -115,6 +115,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
|
||||
register_derive! {
|
||||
Clone: clone::expand_deriving_clone,
|
||||
Copy: bounds::expand_deriving_copy,
|
||||
ConstParamTy: bounds::expand_deriving_const_param_ty,
|
||||
Debug: debug::expand_deriving_debug,
|
||||
Default: default::expand_deriving_default,
|
||||
Eq: eq::expand_deriving_eq,
|
||||
|
@ -966,11 +966,7 @@ fn codegen_panic_inner<'tcx>(
|
||||
args: &[Value],
|
||||
span: Span,
|
||||
) {
|
||||
let def_id = fx
|
||||
.tcx
|
||||
.lang_items()
|
||||
.require(lang_item)
|
||||
.unwrap_or_else(|e| fx.tcx.sess.span_fatal(span, e.to_string()));
|
||||
let def_id = fx.tcx.require_lang_item(lang_item, Some(span));
|
||||
|
||||
let instance = Instance::mono(fx.tcx, def_id).polymorphize(fx.tcx);
|
||||
let symbol_name = fx.tcx.symbol_name(instance).name;
|
||||
|
@ -14,8 +14,7 @@ use snap::write::FrameEncoder;
|
||||
|
||||
use object::elf::NT_GNU_PROPERTY_TYPE_0;
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_data_structures::owned_slice::try_slice_owned;
|
||||
use rustc_data_structures::sync::MetadataRef;
|
||||
use rustc_data_structures::owned_slice::{try_slice_owned, OwnedSlice};
|
||||
use rustc_metadata::fs::METADATA_FILENAME;
|
||||
use rustc_metadata::EncodedMetadata;
|
||||
use rustc_session::cstore::MetadataLoader;
|
||||
@ -39,7 +38,7 @@ pub struct DefaultMetadataLoader;
|
||||
fn load_metadata_with(
|
||||
path: &Path,
|
||||
f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>,
|
||||
) -> Result<MetadataRef, String> {
|
||||
) -> Result<OwnedSlice, String> {
|
||||
let file =
|
||||
File::open(path).map_err(|e| format!("failed to open file '{}': {}", path.display(), e))?;
|
||||
|
||||
@ -49,7 +48,7 @@ fn load_metadata_with(
|
||||
}
|
||||
|
||||
impl MetadataLoader for DefaultMetadataLoader {
|
||||
fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> {
|
||||
fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result<OwnedSlice, String> {
|
||||
load_metadata_with(path, |data| {
|
||||
let archive = object::read::archive::ArchiveFile::parse(&*data)
|
||||
.map_err(|e| format!("failed to parse rlib '{}': {}", path.display(), e))?;
|
||||
@ -69,7 +68,7 @@ impl MetadataLoader for DefaultMetadataLoader {
|
||||
})
|
||||
}
|
||||
|
||||
fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> {
|
||||
fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<OwnedSlice, String> {
|
||||
load_metadata_with(path, |data| search_for_section(path, data, ".rustc"))
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::any::Any;
|
||||
|
||||
use super::write::WriteBackendMethods;
|
||||
use super::CodegenObject;
|
||||
use crate::back::write::TargetMachineFactoryFn;
|
||||
@ -5,6 +7,7 @@ use crate::{CodegenResults, ModuleCodegen};
|
||||
|
||||
use rustc_ast::expand::allocator::AllocatorKind;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync::{DynSend, DynSync};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_metadata::EncodedMetadata;
|
||||
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
|
||||
@ -20,11 +23,6 @@ use rustc_span::symbol::Symbol;
|
||||
use rustc_target::abi::call::FnAbi;
|
||||
use rustc_target::spec::Target;
|
||||
|
||||
pub use rustc_data_structures::sync::MetadataRef;
|
||||
|
||||
use rustc_data_structures::sync::{DynSend, DynSync};
|
||||
use std::any::Any;
|
||||
|
||||
pub trait BackendTypes {
|
||||
type Value: CodegenObject;
|
||||
type Function: CodegenObject;
|
||||
|
@ -1,5 +1,6 @@
|
||||
use std::{borrow::Borrow, ops::Deref};
|
||||
|
||||
use crate::sync::Lrc;
|
||||
// Use our fake Send/Sync traits when on not parallel compiler,
|
||||
// so that `OwnedSlice` only implements/requires Send/Sync
|
||||
// for parallel compiler builds.
|
||||
@ -7,7 +8,7 @@ use crate::sync::{Send, Sync};
|
||||
|
||||
/// An owned slice.
|
||||
///
|
||||
/// This is similar to `Box<[u8]>` but allows slicing and using anything as the
|
||||
/// This is similar to `Lrc<[u8]>` but allows slicing and using anything as the
|
||||
/// backing buffer.
|
||||
///
|
||||
/// See [`slice_owned`] for `OwnedSlice` construction and examples.
|
||||
@ -16,6 +17,7 @@ use crate::sync::{Send, Sync};
|
||||
///
|
||||
/// This is essentially a replacement for `owning_ref` which is a lot simpler
|
||||
/// and even sound! 🌸
|
||||
#[derive(Clone)]
|
||||
pub struct OwnedSlice {
|
||||
/// This is conceptually a `&'self.owner [u8]`.
|
||||
bytes: *const [u8],
|
||||
@ -31,7 +33,7 @@ pub struct OwnedSlice {
|
||||
// \/
|
||||
// ⊂(´・◡・⊂ )∘˚˳° (I am the phantom remnant of #97770)
|
||||
#[expect(dead_code)]
|
||||
owner: Box<dyn Send + Sync>,
|
||||
owner: Lrc<dyn Send + Sync>,
|
||||
}
|
||||
|
||||
/// Makes an [`OwnedSlice`] out of an `owner` and a `slicer` function.
|
||||
@ -72,10 +74,10 @@ where
|
||||
O: Send + Sync + 'static,
|
||||
F: FnOnce(&O) -> Result<&[u8], E>,
|
||||
{
|
||||
// We box the owner of the bytes, so it doesn't move.
|
||||
// We wrap the owner of the bytes in, so it doesn't move.
|
||||
//
|
||||
// Since the owner does not move and we don't access it in any way
|
||||
// before drop, there is nothing that can invalidate the bytes pointer.
|
||||
// before dropping, there is nothing that can invalidate the bytes pointer.
|
||||
//
|
||||
// Thus, "extending" the lifetime of the reference returned from `F` is fine.
|
||||
// We pretend that we pass it a reference that lives as long as the returned slice.
|
||||
@ -83,12 +85,39 @@ where
|
||||
// N.B. the HRTB on the `slicer` is important — without it the caller could provide
|
||||
// a short lived slice, unrelated to the owner.
|
||||
|
||||
let owner = Box::new(owner);
|
||||
let owner = Lrc::new(owner);
|
||||
let bytes = slicer(&*owner)?;
|
||||
|
||||
Ok(OwnedSlice { bytes, owner })
|
||||
}
|
||||
|
||||
impl OwnedSlice {
|
||||
/// Slice this slice by `slicer`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned};
|
||||
/// let vec = vec![1, 2, 3, 4];
|
||||
///
|
||||
/// // Identical to slicing via `&v[1..3]` but produces an owned slice
|
||||
/// let slice: OwnedSlice = slice_owned(vec, |v| &v[..]);
|
||||
/// assert_eq!(&*slice, [1, 2, 3, 4]);
|
||||
///
|
||||
/// let slice = slice.slice(|slice| &slice[1..][..2]);
|
||||
/// assert_eq!(&*slice, [2, 3]);
|
||||
/// ```
|
||||
///
|
||||
pub fn slice(self, slicer: impl FnOnce(&[u8]) -> &[u8]) -> OwnedSlice {
|
||||
// This is basically identical to `try_slice_owned`,
|
||||
// `slicer` can only return slices of its argument or some static data,
|
||||
// both of which are valid while `owner` is alive.
|
||||
|
||||
let bytes = slicer(&self);
|
||||
OwnedSlice { bytes, ..self }
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for OwnedSlice {
|
||||
type Target = [u8];
|
||||
|
||||
@ -108,11 +137,11 @@ impl Borrow<[u8]> for OwnedSlice {
|
||||
}
|
||||
}
|
||||
|
||||
// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Box<dyn Send + Sync>)`, which is `Send`
|
||||
// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Arc<dyn Send + Sync>)`, which is `Send`
|
||||
#[cfg(parallel_compiler)]
|
||||
unsafe impl Send for OwnedSlice {}
|
||||
|
||||
// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Box<dyn Send + Sync>)`, which is `Sync`
|
||||
// Safety: `OwnedSlice` is conceptually `(&'self.1 [u8], Arc<dyn Send + Sync>)`, which is `Sync`
|
||||
#[cfg(parallel_compiler)]
|
||||
unsafe impl Sync for OwnedSlice {}
|
||||
|
||||
|
@ -26,7 +26,7 @@ fn static_storage() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slice_the_slice() {
|
||||
fn slice_owned_the_slice() {
|
||||
let slice = slice_owned(vec![1, 2, 3, 4, 5, 6], Vec::as_slice);
|
||||
let slice = slice_owned(slice, |s| &s[1..][..4]);
|
||||
let slice = slice_owned(slice, |s| s);
|
||||
@ -35,6 +35,16 @@ fn slice_the_slice() {
|
||||
assert_eq!(&*slice, &[1, 2, 3, 4, 5, 6][1..][..4][1..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slice_the_slice() {
|
||||
let slice = slice_owned(vec![1, 2, 3, 4, 5, 6], Vec::as_slice)
|
||||
.slice(|s| &s[1..][..4])
|
||||
.slice(|s| s)
|
||||
.slice(|s| &s[1..]);
|
||||
|
||||
assert_eq!(&*slice, &[1, 2, 3, 4, 5, 6][1..][..4][1..]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_and_fail() {
|
||||
let res = try_slice_owned(vec![0], |v| v.get(12..).ok_or(()));
|
||||
|
@ -40,7 +40,6 @@
|
||||
//! [^2] `MTLockRef` is a typedef.
|
||||
|
||||
pub use crate::marker::*;
|
||||
use crate::owned_slice::OwnedSlice;
|
||||
use std::collections::HashMap;
|
||||
use std::hash::{BuildHasher, Hash};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
@ -92,6 +91,7 @@ mod mode {
|
||||
}
|
||||
|
||||
pub use mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode};
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(not(parallel_compiler))] {
|
||||
pub unsafe auto trait Send {}
|
||||
@ -244,8 +244,6 @@ cfg_if! {
|
||||
r
|
||||
}
|
||||
|
||||
pub type MetadataRef = OwnedSlice;
|
||||
|
||||
pub use std::rc::Rc as Lrc;
|
||||
pub use std::rc::Weak as Weak;
|
||||
pub use std::cell::Ref as ReadGuard;
|
||||
@ -517,8 +515,6 @@ cfg_if! {
|
||||
}
|
||||
}
|
||||
|
||||
pub type MetadataRef = OwnedSlice;
|
||||
|
||||
/// This makes locks panic if they are already held.
|
||||
/// It is only useful when you are running in a single thread
|
||||
const ERROR_CHECKING: bool = false;
|
||||
|
@ -1,10 +0,0 @@
|
||||
use crate::LangItem;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
|
||||
pub struct LangItemError(pub LangItem);
|
||||
|
||||
impl ToString for LangItemError {
|
||||
fn to_string(&self) -> String {
|
||||
format!("requires `{}` lang_item", self.0.name())
|
||||
}
|
||||
}
|
@ -8,7 +8,6 @@
|
||||
//! * Functions called by the compiler itself.
|
||||
|
||||
use crate::def_id::DefId;
|
||||
use crate::errors::LangItemError;
|
||||
use crate::{MethodKind, Target};
|
||||
|
||||
use rustc_ast as ast;
|
||||
@ -42,13 +41,6 @@ impl LanguageItems {
|
||||
self.items[item as usize] = Some(def_id);
|
||||
}
|
||||
|
||||
/// Requires that a given `LangItem` was bound and returns the corresponding `DefId`.
|
||||
/// If it wasn't bound, e.g. due to a missing `#[lang = "<it.name()>"]`,
|
||||
/// returns an error encapsulating the `LangItem`.
|
||||
pub fn require(&self, it: LangItem) -> Result<DefId, LangItemError> {
|
||||
self.get(it).ok_or_else(|| LangItemError(it))
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = (LangItem, DefId)> + '_ {
|
||||
self.items
|
||||
.iter()
|
||||
|
@ -30,7 +30,6 @@ pub mod def;
|
||||
pub mod def_path_hash_map;
|
||||
pub mod definitions;
|
||||
pub mod diagnostic_items;
|
||||
pub mod errors;
|
||||
pub use rustc_span::def_id;
|
||||
mod hir;
|
||||
pub mod hir_id;
|
||||
|
@ -298,9 +298,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
|
||||
|
||||
let coerce_unsized_trait = tcx.require_lang_item(LangItem::CoerceUnsized, Some(span));
|
||||
|
||||
let unsize_trait = tcx.lang_items().require(LangItem::Unsize).unwrap_or_else(|err| {
|
||||
tcx.sess.fatal(format!("`CoerceUnsized` implementation {}", err.to_string()));
|
||||
});
|
||||
let unsize_trait = tcx.require_lang_item(LangItem::Unsize, Some(span));
|
||||
|
||||
let source = tcx.type_of(impl_did).subst_identity();
|
||||
let trait_ref = tcx.impl_trait_ref(impl_did).unwrap().subst_identity();
|
||||
|
@ -220,7 +220,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::memmap::Mmap;
|
||||
use rustc_data_structures::owned_slice::slice_owned;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::MetadataRef;
|
||||
use rustc_errors::{DiagnosticArgValue, FatalError, IntoDiagnosticArg};
|
||||
use rustc_fs_util::try_canonicalize;
|
||||
use rustc_session::config::{self, CrateType};
|
||||
@ -782,7 +781,7 @@ fn get_metadata_section<'p>(
|
||||
if !filename.exists() {
|
||||
return Err(MetadataError::NotPresent(filename));
|
||||
}
|
||||
let raw_bytes: MetadataRef = match flavor {
|
||||
let raw_bytes = match flavor {
|
||||
CrateFlavor::Rlib => {
|
||||
loader.get_rlib_metadata(target, filename).map_err(MetadataError::LoadFailure)?
|
||||
}
|
||||
@ -843,7 +842,7 @@ fn get_metadata_section<'p>(
|
||||
slice_owned(mmap, Deref::deref)
|
||||
}
|
||||
};
|
||||
let blob = MetadataBlob::new(raw_bytes);
|
||||
let blob = MetadataBlob(raw_bytes);
|
||||
if blob.is_compatible() {
|
||||
Ok(blob)
|
||||
} else {
|
||||
|
@ -7,6 +7,7 @@ use crate::rmeta::*;
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::owned_slice::OwnedSlice;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc, OnceCell};
|
||||
use rustc_data_structures::unhash::UnhashMap;
|
||||
@ -50,7 +51,7 @@ mod cstore_impl;
|
||||
/// A `MetadataBlob` internally is just a reference counted pointer to
|
||||
/// the actual data, so cloning it is cheap.
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct MetadataBlob(Lrc<MetadataRef>);
|
||||
pub(crate) struct MetadataBlob(pub(crate) OwnedSlice);
|
||||
|
||||
impl std::ops::Deref for MetadataBlob {
|
||||
type Target = [u8];
|
||||
@ -660,10 +661,6 @@ impl<'a, 'tcx, I: Idx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyTable<I, T>
|
||||
implement_ty_decoder!(DecodeContext<'a, 'tcx>);
|
||||
|
||||
impl MetadataBlob {
|
||||
pub(crate) fn new(metadata_ref: MetadataRef) -> MetadataBlob {
|
||||
MetadataBlob(Lrc::new(metadata_ref))
|
||||
}
|
||||
|
||||
pub(crate) fn is_compatible(&self) -> bool {
|
||||
self.blob().starts_with(METADATA_HEADER)
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
use crate::rmeta::DecodeContext;
|
||||
use crate::rmeta::EncodeContext;
|
||||
use rustc_data_structures::owned_slice::slice_owned;
|
||||
use rustc_data_structures::owned_slice::OwnedSlice;
|
||||
use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap};
|
||||
use rustc_middle::parameterized_over_tcx;
|
||||
@ -47,7 +46,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefPathHashMapRef<'static>
|
||||
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefPathHashMapRef<'static> {
|
||||
let len = d.read_usize();
|
||||
let pos = d.position();
|
||||
let o = slice_owned(d.blob().clone(), |blob| &blob[pos..pos + len]);
|
||||
let o = d.blob().clone().0.slice(|blob| &blob[pos..pos + len]);
|
||||
|
||||
// Although we already have the data we need via the `OwnedSlice`, we still need
|
||||
// to advance the `DecodeContext`'s position so it's in a valid state after
|
||||
|
@ -7,7 +7,6 @@ use table::TableBuilder;
|
||||
use rustc_ast as ast;
|
||||
use rustc_attr as attr;
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::MetadataRef;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, DefKind, DocLinkResMap};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId};
|
||||
|
@ -39,5 +39,7 @@ middle_strict_coherence_needs_negative_coherence =
|
||||
to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
|
||||
.label = due to this attribute
|
||||
|
||||
middle_requires_lang_item = requires `{$name}` lang_item
|
||||
|
||||
middle_const_not_used_in_type_alias =
|
||||
const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias
|
||||
|
@ -1,5 +1,5 @@
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
use crate::ty::Ty;
|
||||
|
||||
@ -73,6 +73,14 @@ pub(crate) struct StrictCoherenceNeedsNegativeCoherence {
|
||||
pub attr_span: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(middle_requires_lang_item)]
|
||||
pub(crate) struct RequiresLangItem {
|
||||
#[primary_span]
|
||||
pub span: Option<Span>,
|
||||
pub name: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(middle_const_not_used_in_type_alias)]
|
||||
pub(super) struct ConstNotUsedTraitAlias {
|
||||
|
@ -18,12 +18,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
/// Returns the `DefId` for a given `LangItem`.
|
||||
/// If not found, fatally aborts compilation.
|
||||
pub fn require_lang_item(self, lang_item: LangItem, span: Option<Span>) -> DefId {
|
||||
self.lang_items().require(lang_item).unwrap_or_else(|err| {
|
||||
if let Some(span) = span {
|
||||
self.sess.span_fatal(span, err.to_string())
|
||||
} else {
|
||||
self.sess.fatal(err.to_string())
|
||||
}
|
||||
self.lang_items().get(lang_item).unwrap_or_else(|| {
|
||||
self.sess.emit_fatal(crate::error::RequiresLangItem { span, name: lang_item.name() });
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -481,9 +481,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
}))))
|
||||
}
|
||||
|
||||
ExprKind::OffsetOf { container, fields } => {
|
||||
block.and(Rvalue::NullaryOp(NullOp::OffsetOf(fields), container))
|
||||
}
|
||||
ExprKind::OffsetOf { container, fields } => block.and(Rvalue::NullaryOp(
|
||||
NullOp::OffsetOf(fields),
|
||||
this.tcx.erase_regions(container),
|
||||
)),
|
||||
|
||||
ExprKind::Literal { .. }
|
||||
| ExprKind::NamedConst { .. }
|
||||
|
@ -6,7 +6,8 @@ use crate::search_paths::PathKind;
|
||||
use crate::utils::NativeLibKind;
|
||||
use crate::Session;
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::sync::{self, AppendOnlyIndexVec, MetadataRef, RwLock};
|
||||
use rustc_data_structures::owned_slice::OwnedSlice;
|
||||
use rustc_data_structures::sync::{self, AppendOnlyIndexVec, RwLock};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, StableCrateId, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions};
|
||||
use rustc_span::hygiene::{ExpnHash, ExpnId};
|
||||
@ -203,8 +204,8 @@ pub enum ExternCrateSource {
|
||||
/// metadata in library -- this trait just serves to decouple rustc_metadata from
|
||||
/// the archive reader, which depends on LLVM.
|
||||
pub trait MetadataLoader: std::fmt::Debug {
|
||||
fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String>;
|
||||
fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<MetadataRef, String>;
|
||||
fn get_rlib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>;
|
||||
fn get_dylib_metadata(&self, target: &Target, filename: &Path) -> Result<OwnedSlice, String>;
|
||||
}
|
||||
|
||||
pub type MetadataLoaderDyn = dyn MetadataLoader + Send + Sync + sync::DynSend + sync::DynSync;
|
||||
|
@ -164,6 +164,7 @@ symbols! {
|
||||
Capture,
|
||||
Center,
|
||||
Clone,
|
||||
ConstParamTy,
|
||||
Context,
|
||||
Continue,
|
||||
Copy,
|
||||
@ -1583,6 +1584,7 @@ symbols! {
|
||||
unrestricted_attribute_tokens,
|
||||
unsafe_block_in_unsafe_fn,
|
||||
unsafe_cell,
|
||||
unsafe_cell_from_mut,
|
||||
unsafe_no_drop_flag,
|
||||
unsafe_pin_internals,
|
||||
unsize,
|
||||
|
@ -2030,6 +2030,27 @@ impl<T> UnsafeCell<T> {
|
||||
}
|
||||
|
||||
impl<T: ?Sized> UnsafeCell<T> {
|
||||
/// Converts from `&mut T` to `&mut UnsafeCell<T>`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(unsafe_cell_from_mut)]
|
||||
/// use std::cell::UnsafeCell;
|
||||
///
|
||||
/// let mut val = 42;
|
||||
/// let uc = UnsafeCell::from_mut(&mut val);
|
||||
///
|
||||
/// *uc.get_mut() -= 1;
|
||||
/// assert_eq!(*uc.get_mut(), 41);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
#[unstable(feature = "unsafe_cell_from_mut", issue = "111645")]
|
||||
pub const fn from_mut(value: &mut T) -> &mut UnsafeCell<T> {
|
||||
// SAFETY: `UnsafeCell<T>` has the same memory layout as `T` due to #[repr(transparent)].
|
||||
unsafe { &mut *(value as *mut T as *mut UnsafeCell<T>) }
|
||||
}
|
||||
|
||||
/// Gets a mutable pointer to the wrapped value.
|
||||
///
|
||||
/// This can be cast to a pointer of any kind.
|
||||
|
@ -517,8 +517,6 @@ impl CStr {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(cstr_is_empty)]
|
||||
///
|
||||
/// use std::ffi::CStr;
|
||||
/// # use std::ffi::FromBytesWithNulError;
|
||||
///
|
||||
@ -533,7 +531,8 @@ impl CStr {
|
||||
/// # }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "cstr_is_empty", issue = "102444")]
|
||||
#[stable(feature = "cstr_is_empty", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "cstr_is_empty", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn is_empty(&self) -> bool {
|
||||
// SAFETY: We know there is at least one byte; for empty strings it
|
||||
// is the NUL terminator.
|
||||
|
@ -986,6 +986,14 @@ pub trait PointerLike {}
|
||||
#[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")]
|
||||
pub trait ConstParamTy: StructuralEq {}
|
||||
|
||||
/// Derive macro generating an impl of the trait `Copy`.
|
||||
#[rustc_builtin_macro]
|
||||
#[unstable(feature = "adt_const_params", issue = "95174")]
|
||||
#[cfg(not(bootstrap))]
|
||||
pub macro ConstParamTy($item:item) {
|
||||
/* compiler built-in */
|
||||
}
|
||||
|
||||
// FIXME(generic_const_parameter_types): handle `ty::FnDef`/`ty::Closure`
|
||||
// FIXME(generic_const_parameter_types): handle `ty::Tuple`
|
||||
marker_impls! {
|
||||
|
@ -289,10 +289,11 @@ fn is_pat_variant(cx: &LateContext<'_>, pat: &Pat<'_>, path: &QPath<'_>, expecte
|
||||
let Some(id) = cx.typeck_results().qpath_res(path, pat.hir_id).opt_def_id() else { return false };
|
||||
|
||||
match expected_item {
|
||||
Item::Lang(expected_lang_item) => {
|
||||
let expected_id = cx.tcx.lang_items().require(expected_lang_item).unwrap();
|
||||
cx.tcx.parent(id) == expected_id
|
||||
},
|
||||
Item::Lang(expected_lang_item) => cx
|
||||
.tcx
|
||||
.lang_items()
|
||||
.get(expected_lang_item)
|
||||
.map_or(false, |expected_id| cx.tcx.parent(id) == expected_id),
|
||||
Item::Diag(expected_ty, expected_variant) => {
|
||||
let ty = cx.typeck_results().pat_ty(pat);
|
||||
|
||||
|
@ -11,6 +11,13 @@ struct S<T> {
|
||||
|
||||
impl<T: ConstParamTy> ConstParamTy for S<T> {}
|
||||
|
||||
#[derive(PartialEq, Eq, ConstParamTy)]
|
||||
struct D<T> {
|
||||
field: u8,
|
||||
gen: T,
|
||||
}
|
||||
|
||||
|
||||
fn check<T: ConstParamTy + ?Sized>() {}
|
||||
|
||||
fn main() {
|
||||
@ -39,5 +46,8 @@ fn main() {
|
||||
check::<S<u8>>();
|
||||
check::<S<[&[bool]; 8]>>();
|
||||
|
||||
check::<D<u8>>();
|
||||
check::<D<[&[bool]; 8]>>();
|
||||
|
||||
// FIXME: test tuples
|
||||
}
|
||||
|
@ -10,4 +10,8 @@ struct CantParam(NotParam);
|
||||
impl std::marker::ConstParamTy for CantParam {}
|
||||
//~^ error: the trait `ConstParamTy` cannot be implemented for this type
|
||||
|
||||
#[derive(std::marker::ConstParamTy, Eq, PartialEq)]
|
||||
//~^ error: the trait `ConstParamTy` cannot be implemented for this type
|
||||
struct CantParamDerive(NotParam);
|
||||
|
||||
fn main() {}
|
||||
|
@ -7,6 +7,17 @@ LL |
|
||||
LL | impl std::marker::ConstParamTy for CantParam {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0204]: the trait `ConstParamTy` cannot be implemented for this type
|
||||
--> $DIR/const_param_ty_impl_bad_field.rs:13:10
|
||||
|
|
||||
LL | #[derive(std::marker::ConstParamTy, Eq, PartialEq)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
LL |
|
||||
LL | struct CantParamDerive(NotParam);
|
||||
| -------- this field does not implement `ConstParamTy`
|
||||
|
|
||||
= note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0204`.
|
||||
|
@ -10,6 +10,10 @@ struct CantParam(ImplementsConstParamTy);
|
||||
impl std::marker::ConstParamTy for CantParam {}
|
||||
//~^ error: the type `CantParam` does not `#[derive(Eq)]`
|
||||
|
||||
#[derive(std::marker::ConstParamTy)]
|
||||
//~^ error: the type `CantParamDerive` does not `#[derive(Eq)]`
|
||||
struct CantParamDerive(ImplementsConstParamTy);
|
||||
|
||||
fn check<T: std::marker::ConstParamTy>() {}
|
||||
|
||||
fn main() {
|
||||
|
@ -7,6 +7,16 @@ LL | impl std::marker::ConstParamTy for CantParam {}
|
||||
note: required by a bound in `ConstParamTy`
|
||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0277]: the type `CantParamDerive` does not `#[derive(Eq)]`
|
||||
--> $DIR/const_param_ty_impl_no_structural_eq.rs:13:10
|
||||
|
|
||||
LL | #[derive(std::marker::ConstParamTy)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralEq` is not implemented for `CantParamDerive`
|
||||
|
|
||||
note: required by a bound in `ConstParamTy`
|
||||
--> $SRC_DIR/core/src/marker.rs:LL:COL
|
||||
= note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -0,0 +1,33 @@
|
||||
#![allow(incomplete_features)]
|
||||
#![feature(adt_const_params, structural_match)]
|
||||
|
||||
union Union {
|
||||
a: u8,
|
||||
}
|
||||
|
||||
impl PartialEq for Union {
|
||||
fn eq(&self, other: &Union) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
impl Eq for Union {}
|
||||
impl std::marker::StructuralEq for Union {}
|
||||
|
||||
impl std::marker::ConstParamTy for Union {}
|
||||
|
||||
#[derive(std::marker::ConstParamTy)]
|
||||
//~^ ERROR this trait cannot be derived for unions
|
||||
union UnionDerive {
|
||||
a: u8,
|
||||
}
|
||||
|
||||
impl PartialEq for UnionDerive {
|
||||
fn eq(&self, other: &UnionDerive) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
impl Eq for UnionDerive {}
|
||||
impl std::marker::StructuralEq for UnionDerive {}
|
||||
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,8 @@
|
||||
error: this trait cannot be derived for unions
|
||||
--> $DIR/const_param_ty_impl_union.rs:18:10
|
||||
|
|
||||
LL | #[derive(std::marker::ConstParamTy)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -12,6 +12,11 @@ fn main() {
|
||||
offset_of!(S, f.,); //~ ERROR expected identifier
|
||||
offset_of!(S, f..); //~ ERROR no rules expected the token
|
||||
offset_of!(S, f..,); //~ ERROR no rules expected the token
|
||||
offset_of!(Lt<'static>, bar); // issue #111657
|
||||
|
||||
}
|
||||
|
||||
struct S { f: u8, }
|
||||
struct Lt<'a> {
|
||||
bar: &'a (),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user