Skip to content

Commit 75d9a0a

Browse files
committed
Auto merge of #94061 - matthiaskrgr:rollup-oduekp5, r=matthiaskrgr
Rollup of 10 pull requests Successful merges: - #92366 (Resolve concern of `derive_default_enum`) - #93382 (Add a bit more padding in search box) - #93962 (Make [u8]::cmp implementation branchless) - #94015 (rustdoc --check option documentation) - #94017 (Clarify confusing UB statement in MIR) - #94020 (Support pretty printing of invalid constants) - #94027 (Update browser UI test version) - #94037 (Fix inconsistent symbol mangling with -Zverbose) - #94045 (Update books) - #94054 (:arrow_up: rust-analyzer) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents f90b06d + be858fa commit 75d9a0a

File tree

25 files changed

+177
-68
lines changed

25 files changed

+177
-68
lines changed

compiler/rustc_builtin_macros/src/deriving/default.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,6 @@ fn validate_default_attribute(
222222
"this method must only be called with a variant that has a `#[default]` attribute",
223223
),
224224
[first, rest @ ..] => {
225-
// FIXME(jhpratt) Do we want to perform this check? It doesn't exist
226-
// for `#[inline]`, `#[non_exhaustive]`, and presumably others.
227-
228225
let suggestion_text =
229226
if rest.len() == 1 { "try removing this" } else { "try removing these" };
230227

compiler/rustc_const_eval/src/const_eval/mod.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ use rustc_middle::{
1111
use rustc_span::{source_map::DUMMY_SP, symbol::Symbol};
1212

1313
use crate::interpret::{
14-
intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, MPlaceTy, MemPlaceMeta, Scalar,
14+
intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MPlaceTy,
15+
MemPlaceMeta, Scalar,
1516
};
1617

1718
mod error;
@@ -132,42 +133,39 @@ fn const_to_valtree_inner<'tcx>(
132133
}
133134
}
134135

135-
/// This function uses `unwrap` copiously, because an already validated constant
136-
/// must have valid fields and can thus never fail outside of compiler bugs. However, it is
137-
/// invoked from the pretty printer, where it can receive enums with no variants and e.g.
138-
/// `read_discriminant` needs to be able to handle that.
139-
pub(crate) fn destructure_const<'tcx>(
136+
/// This function should never fail for validated constants. However, it is also invoked from the
137+
/// pretty printer which might attempt to format invalid constants and in that case it might fail.
138+
pub(crate) fn try_destructure_const<'tcx>(
140139
tcx: TyCtxt<'tcx>,
141140
param_env: ty::ParamEnv<'tcx>,
142141
val: ty::Const<'tcx>,
143-
) -> mir::DestructuredConst<'tcx> {
142+
) -> InterpResult<'tcx, mir::DestructuredConst<'tcx>> {
144143
trace!("destructure_const: {:?}", val);
145144
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false);
146-
let op = ecx.const_to_op(val, None).unwrap();
145+
let op = ecx.const_to_op(val, None)?;
147146

148147
// We go to `usize` as we cannot allocate anything bigger anyway.
149148
let (field_count, variant, down) = match val.ty().kind() {
150149
ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op),
151-
ty::Adt(def, _) if def.variants.is_empty() => {
152-
return mir::DestructuredConst { variant: None, fields: &[] };
153-
}
154150
ty::Adt(def, _) => {
155-
let variant = ecx.read_discriminant(&op).unwrap().1;
156-
let down = ecx.operand_downcast(&op, variant).unwrap();
151+
let variant = ecx.read_discriminant(&op)?.1;
152+
let down = ecx.operand_downcast(&op, variant)?;
157153
(def.variants[variant].fields.len(), Some(variant), down)
158154
}
159155
ty::Tuple(substs) => (substs.len(), None, op),
160156
_ => bug!("cannot destructure constant {:?}", val),
161157
};
162158

163-
let fields_iter = (0..field_count).map(|i| {
164-
let field_op = ecx.operand_field(&down, i).unwrap();
165-
let val = op_to_const(&ecx, &field_op);
166-
ty::Const::from_value(tcx, val, field_op.layout.ty)
167-
});
168-
let fields = tcx.arena.alloc_from_iter(fields_iter);
159+
let fields = (0..field_count)
160+
.map(|i| {
161+
let field_op = ecx.operand_field(&down, i)?;
162+
let val = op_to_const(&ecx, &field_op);
163+
Ok(ty::Const::from_value(tcx, val, field_op.layout.ty))
164+
})
165+
.collect::<InterpResult<'tcx, Vec<_>>>()?;
166+
let fields = tcx.arena.alloc_from_iter(fields);
169167

170-
mir::DestructuredConst { variant, fields }
168+
Ok(mir::DestructuredConst { variant, fields })
171169
}
172170

173171
pub(crate) fn deref_const<'tcx>(

compiler/rustc_const_eval/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ pub fn provide(providers: &mut Providers) {
4141
providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
4242
providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
4343
providers.const_caller_location = const_eval::const_caller_location;
44-
providers.destructure_const = |tcx, param_env_and_value| {
44+
providers.try_destructure_const = |tcx, param_env_and_value| {
4545
let (param_env, value) = param_env_and_value.into_parts();
46-
const_eval::destructure_const(tcx, param_env, value)
46+
const_eval::try_destructure_const(tcx, param_env, value).ok()
4747
};
4848
providers.const_to_valtree = |tcx, param_env_and_value| {
4949
let (param_env, raw) = param_env_and_value.into_parts();

compiler/rustc_middle/src/mir/interpret/queries.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,12 @@ impl<'tcx> TyCtxt<'tcx> {
9898
let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?;
9999
Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory())
100100
}
101+
102+
/// Destructure a constant ADT or array into its variant index and its field values.
103+
pub fn destructure_const(
104+
self,
105+
param_env_and_val: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>,
106+
) -> mir::DestructuredConst<'tcx> {
107+
self.try_destructure_const(param_env_and_val).unwrap()
108+
}
101109
}

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2270,11 +2270,13 @@ pub enum BinOp {
22702270
Mul,
22712271
/// The `/` operator (division)
22722272
///
2273-
/// Division by zero is UB.
2273+
/// Division by zero is UB, because the compiler should have inserted checks
2274+
/// prior to this.
22742275
Div,
22752276
/// The `%` operator (modulus)
22762277
///
2277-
/// Using zero as the modulus (second operand) is UB.
2278+
/// Using zero as the modulus (second operand) is UB, because the compiler
2279+
/// should have inserted checks prior to this.
22782280
Rem,
22792281
/// The `^` operator (bitwise xor)
22802282
BitXor,

compiler/rustc_middle/src/query/mod.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -924,10 +924,12 @@ rustc_queries! {
924924
}
925925

926926
/// Destructure a constant ADT or array into its variant index and its
927-
/// field values.
928-
query destructure_const(
927+
/// field values or return `None` if constant is invalid.
928+
///
929+
/// Use infallible `TyCtxt::destructure_const` when you know that constant is valid.
930+
query try_destructure_const(
929931
key: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>
930-
) -> mir::DestructuredConst<'tcx> {
932+
) -> Option<mir::DestructuredConst<'tcx>> {
931933
desc { "destructure constant" }
932934
remap_env_constness
933935
}

compiler/rustc_middle/src/ty/print/mod.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,6 @@ pub trait Printer<'tcx>: Sized {
188188
own_params.start = 1;
189189
}
190190

191-
// If we're in verbose mode, then print default-equal args too
192-
if self.tcx().sess.verbose() {
193-
return &substs[own_params];
194-
}
195-
196191
// Don't print args that are the defaults of their respective parameters.
197192
own_params.end -= generics
198193
.params

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,10 +1459,18 @@ pub trait PrettyPrinter<'tcx>:
14591459
// FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the
14601460
// correct `ty::ParamEnv` to allow printing *all* constant values.
14611461
(_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => {
1462-
let contents =
1463-
self.tcx().destructure_const(ty::ParamEnv::reveal_all().and(
1464-
self.tcx().mk_const(ty::ConstS { val: ty::ConstKind::Value(ct), ty }),
1465-
));
1462+
let Some(contents) = self.tcx().try_destructure_const(
1463+
ty::ParamEnv::reveal_all()
1464+
.and(self.tcx().mk_const(ty::ConstS { val: ty::ConstKind::Value(ct), ty })),
1465+
) else {
1466+
// Fall back to debug pretty printing for invalid constants.
1467+
p!(write("{:?}", ct));
1468+
if print_ty {
1469+
p!(": ", print(ty));
1470+
}
1471+
return Ok(self);
1472+
};
1473+
14661474
let fields = contents.fields.iter().copied();
14671475

14681476
match *ty.kind() {

library/core/src/slice/cmp.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Comparison traits for `[T]`.
22
3-
use crate::cmp;
4-
use crate::cmp::Ordering::{self, Greater, Less};
3+
use crate::cmp::{self, Ordering};
54
use crate::mem;
65

76
use super::from_raw_parts;
@@ -189,18 +188,18 @@ impl<A: Ord> SliceOrd for A {
189188
impl SliceOrd for u8 {
190189
#[inline]
191190
fn compare(left: &[Self], right: &[Self]) -> Ordering {
192-
let order =
193-
// SAFETY: `left` and `right` are references and are thus guaranteed to be valid.
194-
// We use the minimum of both lengths which guarantees that both regions are
195-
// valid for reads in that interval.
196-
unsafe { memcmp(left.as_ptr(), right.as_ptr(), cmp::min(left.len(), right.len())) };
191+
// Since the length of a slice is always less than or equal to isize::MAX, this never underflows.
192+
let diff = left.len() as isize - right.len() as isize;
193+
// This comparison gets optimized away (on x86_64 and ARM) because the subtraction updates flags.
194+
let len = if left.len() < right.len() { left.len() } else { right.len() };
195+
// SAFETY: `left` and `right` are references and are thus guaranteed to be valid.
196+
// We use the minimum of both lengths which guarantees that both regions are
197+
// valid for reads in that interval.
198+
let mut order = unsafe { memcmp(left.as_ptr(), right.as_ptr(), len) as isize };
197199
if order == 0 {
198-
left.len().cmp(&right.len())
199-
} else if order < 0 {
200-
Less
201-
} else {
202-
Greater
200+
order = diff;
203201
}
202+
order.cmp(&0)
204203
}
205204
}
206205

src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}"
7272
# https://github.com/puppeteer/puppeteer/issues/375
7373
#
7474
# We also specify the version in case we need to update it to go around cache limitations.
75-
RUN npm install -g browser-ui-test@0.7.1 --unsafe-perm=true
75+
RUN npm install -g browser-ui-test@0.7.2 --unsafe-perm=true
7676

7777
ENV RUST_CONFIGURE_ARGS \
7878
--build=x86_64-unknown-linux-gnu \

0 commit comments

Comments
 (0)