Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #136111

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1095,9 +1095,9 @@ dependencies = [

[[package]]
name = "elsa"
version = "1.7.1"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "848fe615fbb0a74d9ae68dcaa510106d32e37d9416207bbea4bd008bd89c47ed"
checksum = "d98e71ae4df57d214182a2e5cb90230c0192c6ddfcaa05c36453d46a54713e10"
dependencies = [
"stable_deref_trait",
]
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub struct Path {
impl PartialEq<Symbol> for Path {
#[inline]
fn eq(&self, symbol: &Symbol) -> bool {
self.segments.len() == 1 && { self.segments[0].ident.name == *symbol }
matches!(&self.segments[..], [segment] if segment.ident.name == *symbol)
}
}

Expand All @@ -121,13 +121,13 @@ impl Path {
}

pub fn is_global(&self) -> bool {
!self.segments.is_empty() && self.segments[0].ident.name == kw::PathRoot
self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
}

/// If this path is a single identifier with no arguments, does not ensure
/// that the path resolves to a const param, the caller should check this.
pub fn is_potential_trivial_const_arg(&self) -> bool {
self.segments.len() == 1 && self.segments[0].args.is_none()
matches!(self.segments[..], [PathSegment { args: None, .. }])
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast/src/attr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ impl AttrItem {
impl MetaItem {
/// For a single-segment meta item, returns its name; otherwise, returns `None`.
pub fn ident(&self) -> Option<Ident> {
if self.path.segments.len() == 1 { Some(self.path.segments[0].ident) } else { None }
if let [PathSegment { ident, .. }] = self.path.segments[..] { Some(ident) } else { None }
}

pub fn name_or_empty(&self) -> Symbol {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_ast/src/mut_visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1813,10 +1813,10 @@ pub fn walk_flat_map_stmt<T: MutVisitor>(
.into_iter()
.map(|kind| Stmt { id, kind, span })
.collect();
match stmts.len() {
0 => {}
1 => vis.visit_span(&mut stmts[0].span),
2.. => panic!(
match &mut stmts[..] {
[] => {}
[stmt] => vis.visit_span(&mut stmt.span),
_ => panic!(
"cloning statement `NodeId`s is prohibited by default, \
the visitor should implement custom statement visiting"
),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_ast/src/util/comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol {
let mut i = 0;
let mut j = lines.len();
// first line of all-stars should be omitted
if !lines.is_empty() && lines[0].chars().all(|c| c == '*') {
if lines.first().is_some_and(|line| line.chars().all(|c| c == '*')) {
i += 1;
}

Expand Down Expand Up @@ -97,7 +97,7 @@ pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol {
return None;
}
}
if lines.is_empty() { None } else { Some(lines[0][..i].into()) }
Some(lines.first()?[..i].to_string())
}

let data_s = data.as_str();
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_data_structures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ edition = "2021"
arrayvec = { version = "0.7", default-features = false }
bitflags = "2.4.1"
either = "1.0"
elsa = "=1.7.1"
elsa = "1.10.0"
ena = "0.14.3"
indexmap = { version = "2.4.0", features = ["rustc-rayon"] }
jobserver_crate = { version = "0.1.28", package = "jobserver" }
Expand Down
7 changes: 7 additions & 0 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

#![stable(feature = "rust1", since = "1.0.0")]

mod variance;

#[unstable(feature = "phantom_variance_markers", issue = "135806")]
pub use self::variance::{
PhantomContravariant, PhantomContravariantLifetime, PhantomCovariant, PhantomCovariantLifetime,
PhantomInvariant, PhantomInvariantLifetime, Variance, variance,
};
use crate::cell::UnsafeCell;
use crate::cmp;
use crate::fmt::Debug;
Expand Down
260 changes: 260 additions & 0 deletions library/core/src/marker/variance.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
#![unstable(feature = "phantom_variance_markers", issue = "135806")]

use super::PhantomData;
use crate::any::type_name;
use crate::cmp::Ordering;
use crate::fmt;
use crate::hash::{Hash, Hasher};

macro_rules! first_token {
($first:tt $($rest:tt)*) => {
$first
};
}

macro_rules! phantom_type {
($(
$(#[$attr:meta])*
pub struct $name:ident <$t:ident> ($($inner:tt)*);
)*) => {$(
$(#[$attr])*
pub struct $name<$t>($($inner)*) where T: ?Sized;

impl<T> $name<T>
where T: ?Sized
{
/// Constructs a new instance of the variance marker.
pub const fn new() -> Self {
Self(PhantomData)
}
}

impl<T> self::sealed::Sealed for $name<T> where T: ?Sized {
const VALUE: Self = Self::new();
}
impl<T> Variance for $name<T> where T: ?Sized {}

impl<T> Default for $name<T>
where T: ?Sized
{
fn default() -> Self {
Self(PhantomData)
}
}

impl<T> fmt::Debug for $name<T>
where T: ?Sized
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}<{}>", stringify!($name), type_name::<T>())
}
}

impl<T> Clone for $name<T>
where T: ?Sized
{
fn clone(&self) -> Self {
*self
}
}

impl<T> Copy for $name<T> where T: ?Sized {}

impl<T> PartialEq for $name<T>
where T: ?Sized
{
fn eq(&self, _: &Self) -> bool {
true
}
}

impl<T> Eq for $name<T> where T: ?Sized {}

impl<T> PartialOrd for $name<T>
where T: ?Sized
{
fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
Some(Ordering::Equal)
}
}

impl<T> Ord for $name<T>
where T: ?Sized
{
fn cmp(&self, _: &Self) -> Ordering {
Ordering::Equal
}
}

impl<T> Hash for $name<T>
where T: ?Sized
{
fn hash<H: Hasher>(&self, _: &mut H) {}
}
)*};
}

macro_rules! phantom_lifetime {
($(
$(#[$attr:meta])*
pub struct $name:ident <$lt:lifetime> ($($inner:tt)*);
)*) => {$(
$(#[$attr])*
#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct $name<$lt>($($inner)*);

impl $name<'_> {
/// Constructs a new instance of the variance marker.
pub const fn new() -> Self {
Self(first_token!($($inner)*)(PhantomData))
}
}

impl self::sealed::Sealed for $name<'_> {
const VALUE: Self = Self::new();
}
impl Variance for $name<'_> {}

impl fmt::Debug for $name<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", stringify!($name))
}
}
)*};
}

phantom_lifetime! {
/// Zero-sized type used to mark a lifetime as covariant.
///
/// Covariant lifetimes must live at least as long as declared. See [the reference][1] for more
/// information.
///
/// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance
///
/// ## Layout
///
/// For all `'a`, the following are guaranteed:
/// * `size_of::<PhantomCovariantLifetime<'a>>() == 0`
/// * `align_of::<PhantomCovariantLifetime<'a>>() == 1`
pub struct PhantomCovariantLifetime<'a>(PhantomCovariant<&'a ()>);
/// Zero-sized type used to mark a lifetime as contravariant.
///
/// Contravariant lifetimes must live at most as long as declared. See [the reference][1] for
/// more information.
///
/// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance
///
/// ## Layout
///
/// For all `'a`, the following are guaranteed:
/// * `size_of::<PhantomContravariantLifetime<'a>>() == 0`
/// * `align_of::<PhantomContravariantLifetime<'a>>() == 1`
pub struct PhantomContravariantLifetime<'a>(PhantomContravariant<&'a ()>);
/// Zero-sized type used to mark a lifetime as invariant.
///
/// Invariant lifetimes must be live for the exact length declared, neither shorter nor longer.
/// See [the reference][1] for more information.
///
/// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance
///
/// ## Layout
///
/// For all `'a`, the following are guaranteed:
/// * `size_of::<PhantomInvariantLifetime<'a>>() == 0`
/// * `align_of::<PhantomInvariantLifetime<'a>>() == 1`
pub struct PhantomInvariantLifetime<'a>(PhantomInvariant<&'a ()>);
}

phantom_type! {
/// Zero-sized type used to mark a type parameter as covariant.
///
/// Types used as part of the return value from a function are covariant. If the type is _also_
/// passed as a parameter then it is [invariant][PhantomInvariant]. See [the reference][1] for
/// more information.
///
/// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance
///
/// ## Layout
///
/// For all `T`, the following are guaranteed:
/// * `size_of::<PhantomCovariant<T>>() == 0`
/// * `align_of::<PhantomCovariant<T>>() == 1`
pub struct PhantomCovariant<T>(PhantomData<fn() -> T>);
/// Zero-sized type used to mark a type parameter as contravariant.
///
/// Types passed as arguments to a function are contravariant. If the type is _also_ part of the
/// return value from a function then it is [invariant][PhantomInvariant]. See [the
/// reference][1] for more information.
///
/// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance
///
/// ## Layout
///
/// For all `T`, the following are guaranteed:
/// * `size_of::<PhantomContravariant<T>>() == 0`
/// * `align_of::<PhantomContravariant<T>>() == 1`
pub struct PhantomContravariant<T>(PhantomData<fn(T)>);
/// Zero-sized type used to mark a type parameter as invariant.
///
/// Types that are both passed as an argument _and_ used as part of the return value from a
/// function are invariant. See [the reference][1] for more information.
///
/// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance
///
/// ## Layout
///
/// For all `T`, the following are guaranteed:
/// * `size_of::<PhantomInvariant<T>>() == 0`
/// * `align_of::<PhantomInvariant<T>>() == 1`
pub struct PhantomInvariant<T>(PhantomData<fn(T) -> T>);
}

mod sealed {
pub trait Sealed {
const VALUE: Self;
}
}

/// A marker trait for phantom variance types.
pub trait Variance: sealed::Sealed + Default {}

/// Construct a variance marker; equivalent to [`Default::default`].
///
/// This type can be any of the following. You generally should not need to explicitly name the
/// type, however.
///
/// - [`PhantomCovariant`]
/// - [`PhantomContravariant`]
/// - [`PhantomInvariant`]
/// - [`PhantomCovariantLifetime`]
/// - [`PhantomContravariantLifetime`]
/// - [`PhantomInvariantLifetime`]
///
/// # Example
///
/// ```rust
/// #![feature(phantom_variance_markers)]
///
/// use core::marker::{PhantomCovariant, variance};
///
/// struct BoundFn<F, P, R>
/// where
/// F: Fn(P) -> R,
/// {
/// function: F,
/// parameter: P,
/// return_value: PhantomCovariant<R>,
/// }
///
/// let bound_fn = BoundFn {
/// function: core::convert::identity,
/// parameter: 5u8,
/// return_value: variance(),
/// };
/// ```
pub const fn variance<T>() -> T
where
T: Variance,
{
T::VALUE
}
Loading
Loading