Skip to content
Merged
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
10 changes: 10 additions & 0 deletions compiler/rustc_abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2450,12 +2450,22 @@ pub enum AbiFromStrErr {
NoExplicitUnwind,
}

/// The layout information for a variant.
///
/// For items with multiple variants ([`Variants::Multiple`]), the layout information of each
/// variant largely matches that of the overall item. So, instead of giving each one a new [`LayoutData`],
/// we use this struct, which stores only the information that differs between the variants.
///
/// See <https://github.com/rust-lang/rust/issues/113988> for more context.
// NOTE: This struct is generic over the FieldIdx for rust-analyzer usage.
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
#[cfg_attr(feature = "nightly", derive(StableHash))]
pub struct VariantLayout<FieldIdx: Idx> {
// FIXME: ideally we'd remove these as variants should not have their own
// size or backend_repr.
pub size: Size,
pub backend_repr: BackendRepr,

pub field_offsets: IndexVec<FieldIdx, Size>,
fields_in_memory_order: IndexVec<u32, FieldIdx>,
largest_niche: Option<Niche>,
Expand Down
60 changes: 11 additions & 49 deletions compiler/rustc_hir_typeck/src/upvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
//! then mean that all later passes would have to check for these figments
//! and report an error, and it just seems like more mess in the end.)

use std::iter;
use std::{cmp, iter};

use rustc_abi::FIRST_VARIANT;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
Expand Down Expand Up @@ -2608,56 +2608,18 @@ fn determine_capture_info(
capture_info_a: ty::CaptureInfo,
capture_info_b: ty::CaptureInfo,
) -> ty::CaptureInfo {
// If the capture kind is equivalent then, we don't need to escalate and can compare the
// expressions.
let eq_capture_kind = match (capture_info_a.capture_kind, capture_info_b.capture_kind) {
(ty::UpvarCapture::ByValue, ty::UpvarCapture::ByValue) => true,
(ty::UpvarCapture::ByUse, ty::UpvarCapture::ByUse) => true,
(ty::UpvarCapture::ByRef(ref_a), ty::UpvarCapture::ByRef(ref_b)) => ref_a == ref_b,
(ty::UpvarCapture::ByValue, _)
| (ty::UpvarCapture::ByUse, _)
| (ty::UpvarCapture::ByRef(_), _) => false,
};

if eq_capture_kind {
match (capture_info_a.capture_kind_expr_id, capture_info_b.capture_kind_expr_id) {
(Some(_), _) | (None, None) => capture_info_a,
(None, Some(_)) => capture_info_b,
}
} else {
// We select the CaptureKind which ranks higher based the following priority order:
// (ByUse | ByValue) > MutBorrow > UniqueImmBorrow > ImmBorrow
match (capture_info_a.capture_kind, capture_info_b.capture_kind) {
(ty::UpvarCapture::ByUse, ty::UpvarCapture::ByValue)
| (ty::UpvarCapture::ByValue, ty::UpvarCapture::ByUse) => {
bug!("Same capture can't be ByUse and ByValue at the same time")
}
(ty::UpvarCapture::ByValue, ty::UpvarCapture::ByValue)
| (ty::UpvarCapture::ByUse, ty::UpvarCapture::ByUse)
| (ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse, ty::UpvarCapture::ByRef(_)) => {
capture_info_a
}
(ty::UpvarCapture::ByRef(_), ty::UpvarCapture::ByValue | ty::UpvarCapture::ByUse) => {
capture_info_b
}
(ty::UpvarCapture::ByRef(ref_a), ty::UpvarCapture::ByRef(ref_b)) => {
match (ref_a, ref_b) {
// Take LHS:
(BorrowKind::UniqueImmutable | BorrowKind::Mutable, BorrowKind::Immutable)
| (BorrowKind::Mutable, BorrowKind::UniqueImmutable) => capture_info_a,

// Take RHS:
(BorrowKind::Immutable, BorrowKind::UniqueImmutable | BorrowKind::Mutable)
| (BorrowKind::UniqueImmutable, BorrowKind::Mutable) => capture_info_b,

(BorrowKind::Immutable, BorrowKind::Immutable)
| (BorrowKind::UniqueImmutable, BorrowKind::UniqueImmutable)
| (BorrowKind::Mutable, BorrowKind::Mutable) => {
bug!("Expected unequal capture kinds");
}
}
// We select the CaptureKind which ranks higher based the following priority order:
// (ByUse | ByValue) > MutBorrow > UniqueImmBorrow > ImmBorrow
match capture_info_a.capture_kind.partial_cmp(&capture_info_b.capture_kind) {
Some(cmp::Ordering::Equal) => {
match (capture_info_a.capture_kind_expr_id, capture_info_b.capture_kind_expr_id) {
(Some(_), _) | (None, None) => capture_info_a,
(None, Some(_)) => capture_info_b,
}
}
Some(cmp::Ordering::Greater) => capture_info_a,
Some(cmp::Ordering::Less) => capture_info_b,
None => bug!("Same capture can't be ByUse and ByValue at the same time"),
}
}

Expand Down
44 changes: 37 additions & 7 deletions compiler/rustc_middle/src/ty/closure.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::cmp;
use std::fmt::Write;

use rustc_data_structures::fx::FxIndexMap;
Expand Down Expand Up @@ -46,16 +47,32 @@ impl UpvarId {
#[derive(Eq, PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, StableHash, Hash)]
#[derive(TypeFoldable, TypeVisitable)]
pub enum UpvarCapture {
/// Upvar is captured by reference.
ByRef(BorrowKind),

/// Upvar is captured by use. This is true when the closure is labeled `use`.
ByUse,

/// Upvar is captured by value. This is always true when the
/// closure is labeled `move`, but can also be true in other cases
/// depending on inference.
ByValue,
}

/// Upvar is captured by use. This is true when the closure is labeled `use`.
ByUse,

/// Upvar is captured by reference.
ByRef(BorrowKind),
// Used in rustc_hir_typeck::upvar::determine_capture_info
impl PartialOrd for UpvarCapture {
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
match (self, other) {
(Self::ByValue, Self::ByValue) | (Self::ByUse, Self::ByUse) => {
Some(cmp::Ordering::Equal)
}
(Self::ByValue | Self::ByUse, Self::ByRef(_)) => Some(cmp::Ordering::Greater),
(Self::ByRef(_), Self::ByValue | Self::ByUse) => Some(cmp::Ordering::Less),
(Self::ByRef(left), Self::ByRef(right)) => Some(left.cmp(&right)),
(Self::ByUse, Self::ByValue) | (Self::ByValue, Self::ByUse) => None,
}
}
}

/// Given the closure DefId this map provides a map of root variables to minimum
Expand Down Expand Up @@ -339,8 +356,21 @@ pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tc
curr_string
}

#[derive(Eq, Clone, PartialEq, Debug, TyEncodable, TyDecodable, Copy, StableHash, Hash)]
#[derive(TypeFoldable, TypeVisitable)]
#[derive(
Clone,
Copy,
Debug,
PartialEq,
Eq,
Hash,
PartialOrd, // Order of variants is load-bearing
Ord,
TyEncodable,
TyDecodable,
StableHash,
TypeFoldable,
TypeVisitable
)]
pub enum BorrowKind {
/// Data must be immutable and is aliasable.
Immutable,
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1202,9 +1202,9 @@ impl<T> Option<T> {
/// Returns the provided default result (if none),
/// or applies a function to the contained value (if any).
///
/// Arguments passed to `map_or` are eagerly evaluated; if you are passing
/// The `default` argument passed to `map_or` is eagerly evaluated; if you are passing
/// the result of a function call, it is recommended to use [`map_or_else`],
/// which is lazily evaluated.
/// which lazily evaluates `default`.
///
/// [`map_or_else`]: Option::map_or_else
///
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -842,9 +842,9 @@ impl<T, E> Result<T, E> {
/// Returns the provided default (if [`Err`]), or
/// applies a function to the contained value (if [`Ok`]).
///
/// Arguments passed to `map_or` are eagerly evaluated; if you are passing
/// The `default` argument passed to `map_or` is eagerly evaluated; if you are passing
/// the result of a function call, it is recommended to use [`map_or_else`],
/// which is lazily evaluated.
/// which lazily evaluates `default`.
///
/// [`map_or_else`]: Result::map_or_else
///
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

pub mod atomic;
mod sync_view;
#[unstable(feature = "exclusive_wrapper", issue = "98407")]
#[stable(feature = "exclusive_wrapper", since = "CURRENT_RUSTC_VERSION")]
pub use sync_view::SyncView;
Loading
Loading