Skip to content

Commit

Permalink
Auto merge of rust-lang#136111 - jhpratt:rollup-p9wdze6, r=jhpratt
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - rust-lang#135807 (Implement phantom variance markers)
 - rust-lang#136091 (Add some tracing to core bootstrap logic)
 - rust-lang#136094 (Upgrade elsa to the newest version.)
 - rust-lang#136097 (rustc_ast: replace some len-checks + indexing with slice patterns etc.)
 - rust-lang#136101 (triagebot: set myself on vacation)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jan 27, 2025
2 parents 0df0662 + a953137 commit d21b9c2
Show file tree
Hide file tree
Showing 15 changed files with 447 additions and 64 deletions.
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

0 comments on commit d21b9c2

Please sign in to comment.