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 6 pull requests #95481

Closed
wants to merge 17 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
29 changes: 16 additions & 13 deletions compiler/rustc_ast_lowering/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -618,9 +618,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
/// Desugar `<expr>.await` into:
/// ```rust
/// match ::std::future::IntoFuture::into_future(<expr>) {
/// mut pinned => loop {
/// mut __awaitee => loop {
/// match unsafe { ::std::future::Future::poll(
/// <::std::pin::Pin>::new_unchecked(&mut pinned),
/// <::std::pin::Pin>::new_unchecked(&mut __awaitee),
/// ::std::future::get_context(task_context),
/// ) } {
/// ::std::task::Poll::Ready(result) => break result,
Expand Down Expand Up @@ -657,21 +657,24 @@ impl<'hir> LoweringContext<'_, 'hir> {
let expr = self.lower_expr_mut(expr);
let expr_hir_id = expr.hir_id;

let pinned_ident = Ident::with_dummy_span(sym::pinned);
let (pinned_pat, pinned_pat_hid) =
self.pat_ident_binding_mode(span, pinned_ident, hir::BindingAnnotation::Mutable);
// Note that the name of this binding must not be changed to something else because
// debuggers and debugger extensions expect it to be called `__awaitee`. They use
// this name to identify what is being awaited by a suspended async functions.
let awaitee_ident = Ident::with_dummy_span(sym::__awaitee);
let (awaitee_pat, awaitee_pat_hid) =
self.pat_ident_binding_mode(span, awaitee_ident, hir::BindingAnnotation::Mutable);

let task_context_ident = Ident::with_dummy_span(sym::_task_context);

// unsafe {
// ::std::future::Future::poll(
// ::std::pin::Pin::new_unchecked(&mut pinned),
// ::std::pin::Pin::new_unchecked(&mut __awaitee),
// ::std::future::get_context(task_context),
// )
// }
let poll_expr = {
let pinned = self.expr_ident(span, pinned_ident, pinned_pat_hid);
let ref_mut_pinned = self.expr_mut_addr_of(span, pinned);
let awaitee = self.expr_ident(span, awaitee_ident, awaitee_pat_hid);
let ref_mut_awaitee = self.expr_mut_addr_of(span, awaitee);
let task_context = if let Some(task_context_hid) = self.task_context {
self.expr_ident_mut(span, task_context_ident, task_context_hid)
} else {
Expand All @@ -681,7 +684,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let new_unchecked = self.expr_call_lang_item_fn_mut(
span,
hir::LangItem::PinNewUnchecked,
arena_vec![self; ref_mut_pinned],
arena_vec![self; ref_mut_awaitee],
Some(expr_hir_id),
);
let get_context = self.expr_call_lang_item_fn_mut(
Expand Down Expand Up @@ -782,8 +785,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: self.lower_span(span),
});

// mut pinned => loop { ... }
let pinned_arm = self.arm(pinned_pat, loop_expr);
// mut __awaitee => loop { ... }
let awaitee_arm = self.arm(awaitee_pat, loop_expr);

// `match ::std::future::IntoFuture::into_future(<expr>) { ... }`
let into_future_span = self.mark_span_with_reason(
Expand All @@ -799,11 +802,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
);

// match <into_future_expr> {
// mut pinned => loop { .. }
// mut __awaitee => loop { .. }
// }
hir::ExprKind::Match(
into_future_expr,
arena_vec![self; pinned_arm],
arena_vec![self; awaitee_arm],
hir::MatchSource::AwaitDesugar,
)
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,8 @@ declare_features! (
(active, generic_arg_infer, "1.55.0", Some(85077), None),
/// Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598).
(active, generic_associated_types, "1.23.0", Some(44265), None),
/// An extension to the `generic_associated_types` feature, allowing incomplete features.
(incomplete, generic_associated_types_extended, "1.61.0", Some(95451), None),
/// Allows non-trivial generic constants which have to have wfness manually propagated to callers
(incomplete, generic_const_exprs, "1.56.0", Some(76560), None),
/// Allows using `..X`, `..=X`, `...X`, and `X..` as a pattern.
Expand Down
47 changes: 47 additions & 0 deletions compiler/rustc_middle/src/ty/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1379,3 +1379,50 @@ impl<'tcx> TypeVisitor<'tcx> for LateBoundRegionsCollector {
ControlFlow::CONTINUE
}
}

/// Finds the max universe present
pub struct MaxUniverse {
max_universe: ty::UniverseIndex,
}

impl MaxUniverse {
pub fn new() -> Self {
MaxUniverse { max_universe: ty::UniverseIndex::ROOT }
}

pub fn max_universe(self) -> ty::UniverseIndex {
self.max_universe
}
}

impl<'tcx> TypeVisitor<'tcx> for MaxUniverse {
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::Placeholder(placeholder) = t.kind() {
self.max_universe = ty::UniverseIndex::from_u32(
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
);
}

t.super_visit_with(self)
}

fn visit_const(&mut self, c: ty::consts::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Placeholder(placeholder) = c.val() {
self.max_universe = ty::UniverseIndex::from_u32(
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
);
}

c.super_visit_with(self)
}

fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
if let ty::RePlaceholder(placeholder) = *r {
self.max_universe = ty::UniverseIndex::from_u32(
self.max_universe.as_u32().max(placeholder.universe.as_u32()),
);
}

ControlFlow::CONTINUE
}
}
3 changes: 2 additions & 1 deletion compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ symbols! {
__D,
__H,
__S,
__awaitee,
__try_var,
_d,
_e,
Expand Down Expand Up @@ -722,6 +723,7 @@ symbols! {
generators,
generic_arg_infer,
generic_associated_types,
generic_associated_types_extended,
generic_const_exprs,
generic_param_attrs,
get_context,
Expand Down Expand Up @@ -1018,7 +1020,6 @@ symbols! {
pattern_parentheses,
phantom_data,
pin,
pinned,
platform_intrinsics,
plugin,
plugin_registrar,
Expand Down
23 changes: 7 additions & 16 deletions compiler/rustc_target/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,30 +279,16 @@ impl ToJson for Endian {
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Encodable, Decodable)]
#[derive(HashStable_Generic)]
pub struct Size {
// The top 3 bits are ALWAYS zero.
raw: u64,
}

impl Size {
pub const ZERO: Size = Size { raw: 0 };

/// Rounds `bits` up to the next-higher byte boundary, if `bits` is
/// is not aligned.
/// not a multiple of 8.
pub fn from_bits(bits: impl TryInto<u64>) -> Size {
let bits = bits.try_into().ok().unwrap();

#[cold]
fn overflow(bits: u64) -> ! {
panic!("Size::from_bits({}) has overflowed", bits);
}

// This is the largest value of `bits` that does not cause overflow
// during rounding, and guarantees that the resulting number of bytes
// cannot cause overflow when multiplied by 8.
if bits > 0xffff_ffff_ffff_fff8 {
overflow(bits);
}

// Avoid potential overflow from `bits + 7`.
Size { raw: bits / 8 + ((bits % 8) + 7) / 8 }
}
Expand All @@ -325,7 +311,12 @@ impl Size {

#[inline]
pub fn bits(self) -> u64 {
self.raw << 3
#[cold]
fn overflow(bytes: u64) -> ! {
panic!("Size::bits: {} bytes in bits doesn't fit in u64", bytes)
}

self.bytes().checked_mul(8).unwrap_or_else(|| overflow(self.bytes()))
}

#[inline]
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_trait_selection/src/traits/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use super::*;

use crate::infer::region_constraints::{Constraint, RegionConstraintData};
use crate::infer::InferCtxt;
use crate::traits::project::ProjectAndUnifyResult;
use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::{Region, RegionVid, Term};

Expand Down Expand Up @@ -751,19 +752,19 @@ impl<'tcx> AutoTraitFinder<'tcx> {
debug!("Projecting and unifying projection predicate {:?}", predicate);

match project::poly_project_and_unify_type(select, &obligation.with(p)) {
Err(e) => {
ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
debug!(
"evaluate_nested_obligations: Unable to unify predicate \
'{:?}' '{:?}', bailing out",
ty, e
);
return false;
}
Ok(Err(project::InProgress)) => {
ProjectAndUnifyResult::Recursive => {
debug!("evaluate_nested_obligations: recursive projection predicate");
return false;
}
Ok(Ok(Some(v))) => {
ProjectAndUnifyResult::Holds(v) => {
// We only care about sub-obligations
// when we started out trying to unify
// some inference variables. See the comment above
Expand All @@ -782,7 +783,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
}
}
}
Ok(Ok(None)) => {
ProjectAndUnifyResult::FailedNormalization => {
// It's ok not to make progress when have no inference variables -
// in that case, we were only performing unification to check if an
// error occurred (which would indicate that it's impossible for our
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_trait_selection/src/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::ty::{self, Binder, Const, Ty, TypeFoldable};
use std::marker::PhantomData;

use super::const_evaluatable;
use super::project;
use super::project::{self, ProjectAndUnifyResult};
use super::select::SelectionContext;
use super::wf;
use super::CodeAmbiguity;
Expand Down Expand Up @@ -753,8 +753,8 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
}

match project::poly_project_and_unify_type(self.selcx, &project_obligation) {
Ok(Ok(Some(os))) => ProcessResult::Changed(mk_pending(os)),
Ok(Ok(None)) => {
ProjectAndUnifyResult::Holds(os) => ProcessResult::Changed(mk_pending(os)),
ProjectAndUnifyResult::FailedNormalization => {
stalled_on.clear();
stalled_on.extend(substs_infer_vars(
self.selcx,
Expand All @@ -763,10 +763,12 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
ProcessResult::Unchanged
}
// Let the caller handle the recursion
Ok(Err(project::InProgress)) => ProcessResult::Changed(mk_pending(vec![
ProjectAndUnifyResult::Recursive => ProcessResult::Changed(mk_pending(vec![
project_obligation.with(project_obligation.predicate.to_predicate(tcx)),
])),
Err(e) => ProcessResult::Error(CodeProjectionError(e)),
ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
ProcessResult::Error(CodeProjectionError(e))
}
}
}
}
Expand Down
Loading