Skip to content

Commit e96bb7e

Browse files
committed
Auto merge of #151749 - JonathanBrouwer:rollup-IRCTaVD, r=JonathanBrouwer
Rollup of 4 pull requests Successful merges: - #151161 (std: move time implementations to `sys`) - #151694 (more `proc_macro` bridge cleanups) - #151711 (stdarch subtree update) - #150557 (Don't try to evaluate const blocks during constant promotion)
2 parents 94a0cd1 + 53fb684 commit e96bb7e

File tree

73 files changed

+8091
-7631
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+8091
-7631
lines changed

compiler/rustc_expand/src/proc_macro_server.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,13 +458,11 @@ impl<'a, 'b> Rustc<'a, 'b> {
458458
}
459459
}
460460

461-
impl server::Types for Rustc<'_, '_> {
461+
impl server::Server for Rustc<'_, '_> {
462462
type TokenStream = TokenStream;
463463
type Span = Span;
464464
type Symbol = Symbol;
465-
}
466465

467-
impl server::Server for Rustc<'_, '_> {
468466
fn globals(&mut self) -> ExpnGlobals<Self::Span> {
469467
ExpnGlobals {
470468
def_site: self.def_site,

compiler/rustc_mir_transform/src/promote_consts.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use rustc_const_eval::check_consts::{ConstCx, qualifs};
1818
use rustc_data_structures::assert_matches;
1919
use rustc_data_structures::fx::FxHashSet;
2020
use rustc_hir as hir;
21+
use rustc_hir::def::DefKind;
2122
use rustc_index::{IndexSlice, IndexVec};
2223
use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
2324
use rustc_middle::mir::*;
@@ -329,6 +330,7 @@ impl<'tcx> Validator<'_, 'tcx> {
329330
if let TempState::Defined { location: loc, .. } = self.temps[local]
330331
&& let Left(statement) = self.body.stmt_at(loc)
331332
&& let Some((_, Rvalue::Use(Operand::Constant(c)))) = statement.kind.as_assign()
333+
&& self.should_evaluate_for_promotion_checks(c.const_)
332334
&& let Some(idx) = c.const_.try_eval_target_usize(self.tcx, self.typing_env)
333335
// Determine the type of the thing we are indexing.
334336
&& let ty::Array(_, len) = place_base.ty(self.body, self.tcx).ty.kind()
@@ -484,7 +486,9 @@ impl<'tcx> Validator<'_, 'tcx> {
484486
let sz = lhs_ty.primitive_size(self.tcx);
485487
// Integer division: the RHS must be a non-zero const.
486488
let rhs_val = match rhs {
487-
Operand::Constant(c) => {
489+
Operand::Constant(c)
490+
if self.should_evaluate_for_promotion_checks(c.const_) =>
491+
{
488492
c.const_.try_eval_scalar_int(self.tcx, self.typing_env)
489493
}
490494
_ => None,
@@ -502,9 +506,14 @@ impl<'tcx> Validator<'_, 'tcx> {
502506
// The RHS is -1 or unknown, so we have to be careful.
503507
// But is the LHS int::MIN?
504508
let lhs_val = match lhs {
505-
Operand::Constant(c) => c
506-
.const_
507-
.try_eval_scalar_int(self.tcx, self.typing_env),
509+
Operand::Constant(c)
510+
if self.should_evaluate_for_promotion_checks(
511+
c.const_,
512+
) =>
513+
{
514+
c.const_
515+
.try_eval_scalar_int(self.tcx, self.typing_env)
516+
}
508517
_ => None,
509518
};
510519
let lhs_min = sz.signed_int_min();
@@ -683,6 +692,28 @@ impl<'tcx> Validator<'_, 'tcx> {
683692
// This passed all checks, so let's accept.
684693
Ok(())
685694
}
695+
696+
/// Can we try to evaluate a given constant at this point in compilation? Attempting to evaluate
697+
/// a const block before borrow-checking will result in a query cycle (#150464).
698+
fn should_evaluate_for_promotion_checks(&self, constant: Const<'tcx>) -> bool {
699+
match constant {
700+
// `Const::Ty` is always a `ConstKind::Param` right now and that can never be turned
701+
// into a mir value for promotion
702+
// FIXME(mgca): do we want uses of type_const to be normalized during promotion?
703+
Const::Ty(..) => false,
704+
Const::Val(..) => true,
705+
// Evaluating a MIR constant requires borrow-checking it. For inline consts, as of
706+
// #138499, this means borrow-checking its typeck root. Since borrow-checking the
707+
// typeck root requires promoting its constants, trying to evaluate an inline const here
708+
// will result in a query cycle. To avoid the cycle, we can't evaluate const blocks yet.
709+
// Other kinds of unevaluated's can cause query cycles too when they arise from
710+
// self-reference in user code; e.g. evaluating a constant can require evaluating a
711+
// const function that uses that constant, again requiring evaluation of the constant.
712+
// However, this form of cycle renders both the constant and function unusable in
713+
// general, so we don't need to special-case it here.
714+
Const::Unevaluated(uc, _) => self.tcx.def_kind(uc.def) != DefKind::InlineConst,
715+
}
716+
}
686717
}
687718

688719
fn validate_candidates(

library/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@
182182
#![feature(staged_api)]
183183
#![feature(stmt_expr_attributes)]
184184
#![feature(strict_provenance_lints)]
185+
#![feature(target_feature_inline_always)]
185186
#![feature(trait_alias)]
186187
#![feature(transparent_unions)]
187188
#![feature(try_blocks)]

library/proc_macro/src/bridge/client.rs

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,19 @@ impl Drop for TokenStream {
3030
}
3131

3232
impl<S> Encode<S> for TokenStream {
33-
fn encode(self, w: &mut Writer, s: &mut S) {
33+
fn encode(self, w: &mut Buffer, s: &mut S) {
3434
mem::ManuallyDrop::new(self).handle.encode(w, s);
3535
}
3636
}
3737

3838
impl<S> Encode<S> for &TokenStream {
39-
fn encode(self, w: &mut Writer, s: &mut S) {
39+
fn encode(self, w: &mut Buffer, s: &mut S) {
4040
self.handle.encode(w, s);
4141
}
4242
}
4343

4444
impl<S> Decode<'_, '_, S> for TokenStream {
45-
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
45+
fn decode(r: &mut &[u8], s: &mut S) -> Self {
4646
TokenStream { handle: handle::Handle::decode(r, s) }
4747
}
4848
}
@@ -56,23 +56,17 @@ impl !Send for Span {}
5656
impl !Sync for Span {}
5757

5858
impl<S> Encode<S> for Span {
59-
fn encode(self, w: &mut Writer, s: &mut S) {
59+
fn encode(self, w: &mut Buffer, s: &mut S) {
6060
self.handle.encode(w, s);
6161
}
6262
}
6363

6464
impl<S> Decode<'_, '_, S> for Span {
65-
fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
65+
fn decode(r: &mut &[u8], s: &mut S) -> Self {
6666
Span { handle: handle::Handle::decode(r, s) }
6767
}
6868
}
6969

70-
// FIXME(eddyb) generate these impls by pattern-matching on the
71-
// names of methods - also could use the presence of `fn drop`
72-
// to distinguish between 'owned and 'interned, above.
73-
// Alternatively, special "modes" could be listed of types in with_api
74-
// instead of pattern matching on methods, here and in server decl.
75-
7670
impl Clone for TokenStream {
7771
fn clone(&self) -> Self {
7872
Methods::ts_clone(self)
@@ -104,18 +98,15 @@ pub(crate) use super::symbol::Symbol;
10498

10599
macro_rules! define_client_side {
106100
(
107-
Methods {
108-
$(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
109-
},
110-
$($name:ident),* $(,)?
101+
$(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
111102
) => {
112103
impl Methods {
113104
$(pub(crate) fn $method($($arg: $arg_ty),*) $(-> $ret_ty)? {
114105
Bridge::with(|bridge| {
115106
let mut buf = bridge.cached_buffer.take();
116107

117108
buf.clear();
118-
api_tags::Method::$method.encode(&mut buf, &mut ());
109+
ApiTags::$method.encode(&mut buf, &mut ());
119110
$($arg.encode(&mut buf, &mut ());)*
120111

121112
buf = bridge.dispatch.call(buf);
@@ -130,7 +121,7 @@ macro_rules! define_client_side {
130121
}
131122
}
132123
}
133-
with_api!(self, self, define_client_side);
124+
with_api!(self, define_client_side);
134125

135126
struct Bridge<'a> {
136127
/// Reusable buffer (only `clear`-ed, never shrunk), primarily

0 commit comments

Comments
 (0)