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 10 pull requests #94061

Merged
merged 22 commits into from
Feb 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
969fee6
Remove FIXME
jhpratt Dec 28, 2021
b12d926
Add a bit more padding on search padding and reduce its font size
GuillaumeGomez Jan 27, 2022
3960ce6
Make [u8]::cmp implementation branchless
joboet Feb 13, 2022
41a0f8c
Clean up rustdoc command line args doc
GuillaumeGomez Feb 15, 2022
7fa87f2
Clarify confusing UB statement in MIR
fee1-dead Feb 15, 2022
6763cb9
Update browser-ui-test version
GuillaumeGomez Feb 15, 2022
0d2ff61
Fix GUI test
GuillaumeGomez Feb 15, 2022
590ca7e
Add documentation for rustdoc --check option
GuillaumeGomez Feb 15, 2022
92d20c4
Support pretty printing of invalid constants
tmiasko Feb 15, 2022
3158372
Fix inconsistent symbol mangling with -Zverbose
tmiasko Feb 16, 2022
2b75594
Update books
ehuss Feb 16, 2022
ef88c3f
:arrow_up: rust-analyzer
lnicola Feb 16, 2022
6930b66
Rollup merge of #92366 - jhpratt:derive-default-enum, r=Mark-Simulacrum
matthiaskrgr Feb 16, 2022
01f0da2
Rollup merge of #93382 - GuillaumeGomez:search-input-padding, r=jsha
matthiaskrgr Feb 16, 2022
9a42121
Rollup merge of #93962 - joboet:branchless_slice_ord, r=Mark-Simulacrum
matthiaskrgr Feb 16, 2022
75a631d
Rollup merge of #94015 - GuillaumeGomez:check-option, r=notriddle
matthiaskrgr Feb 16, 2022
a5a1ffb
Rollup merge of #94017 - fee1-dead:unub, r=bjorn3
matthiaskrgr Feb 16, 2022
bc4f117
Rollup merge of #94020 - tmiasko:pp, r=oli-obk
matthiaskrgr Feb 16, 2022
847ac55
Rollup merge of #94027 - GuillaumeGomez:update-browser-ui-test, r=not…
matthiaskrgr Feb 16, 2022
237f16d
Rollup merge of #94037 - tmiasko:verbose, r=Mark-Simulacrum
matthiaskrgr Feb 16, 2022
5394714
Rollup merge of #94045 - ehuss:update-books, r=ehuss
matthiaskrgr Feb 16, 2022
be858fa
Rollup merge of #94054 - lnicola:rust-analyzer-2022-02-16, r=lnicola
matthiaskrgr Feb 16, 2022
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
3 changes: 0 additions & 3 deletions compiler/rustc_builtin_macros/src/deriving/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,6 @@ fn validate_default_attribute(
"this method must only be called with a variant that has a `#[default]` attribute",
),
[first, rest @ ..] => {
// FIXME(jhpratt) Do we want to perform this check? It doesn't exist
// for `#[inline]`, `#[non_exhaustive]`, and presumably others.

let suggestion_text =
if rest.len() == 1 { "try removing this" } else { "try removing these" };

Expand Down
38 changes: 18 additions & 20 deletions compiler/rustc_const_eval/src/const_eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use rustc_middle::{
use rustc_span::{source_map::DUMMY_SP, symbol::Symbol};

use crate::interpret::{
intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, MPlaceTy, MemPlaceMeta, Scalar,
intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MPlaceTy,
MemPlaceMeta, Scalar,
};

mod error;
Expand Down Expand Up @@ -132,42 +133,39 @@ fn const_to_valtree_inner<'tcx>(
}
}

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

// We go to `usize` as we cannot allocate anything bigger anyway.
let (field_count, variant, down) = match val.ty().kind() {
ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op),
ty::Adt(def, _) if def.variants.is_empty() => {
return mir::DestructuredConst { variant: None, fields: &[] };
}
ty::Adt(def, _) => {
let variant = ecx.read_discriminant(&op).unwrap().1;
let down = ecx.operand_downcast(&op, variant).unwrap();
let variant = ecx.read_discriminant(&op)?.1;
let down = ecx.operand_downcast(&op, variant)?;
(def.variants[variant].fields.len(), Some(variant), down)
}
ty::Tuple(substs) => (substs.len(), None, op),
_ => bug!("cannot destructure constant {:?}", val),
};

let fields_iter = (0..field_count).map(|i| {
let field_op = ecx.operand_field(&down, i).unwrap();
let val = op_to_const(&ecx, &field_op);
ty::Const::from_value(tcx, val, field_op.layout.ty)
});
let fields = tcx.arena.alloc_from_iter(fields_iter);
let fields = (0..field_count)
.map(|i| {
let field_op = ecx.operand_field(&down, i)?;
let val = op_to_const(&ecx, &field_op);
Ok(ty::Const::from_value(tcx, val, field_op.layout.ty))
})
.collect::<InterpResult<'tcx, Vec<_>>>()?;
let fields = tcx.arena.alloc_from_iter(fields);

mir::DestructuredConst { variant, fields }
Ok(mir::DestructuredConst { variant, fields })
}

pub(crate) fn deref_const<'tcx>(
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ pub fn provide(providers: &mut Providers) {
providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
providers.const_caller_location = const_eval::const_caller_location;
providers.destructure_const = |tcx, param_env_and_value| {
providers.try_destructure_const = |tcx, param_env_and_value| {
let (param_env, value) = param_env_and_value.into_parts();
const_eval::destructure_const(tcx, param_env, value)
const_eval::try_destructure_const(tcx, param_env, value).ok()
};
providers.const_to_valtree = |tcx, param_env_and_value| {
let (param_env, raw) = param_env_and_value.into_parts();
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,12 @@ impl<'tcx> TyCtxt<'tcx> {
let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?;
Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory())
}

/// Destructure a constant ADT or array into its variant index and its field values.
pub fn destructure_const(
self,
param_env_and_val: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>,
) -> mir::DestructuredConst<'tcx> {
self.try_destructure_const(param_env_and_val).unwrap()
}
}
6 changes: 4 additions & 2 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2270,11 +2270,13 @@ pub enum BinOp {
Mul,
/// The `/` operator (division)
///
/// Division by zero is UB.
/// Division by zero is UB, because the compiler should have inserted checks
/// prior to this.
Div,
/// The `%` operator (modulus)
///
/// Using zero as the modulus (second operand) is UB.
/// Using zero as the modulus (second operand) is UB, because the compiler
/// should have inserted checks prior to this.
Rem,
/// The `^` operator (bitwise xor)
BitXor,
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -924,10 +924,12 @@ rustc_queries! {
}

/// Destructure a constant ADT or array into its variant index and its
/// field values.
query destructure_const(
/// field values or return `None` if constant is invalid.
///
/// Use infallible `TyCtxt::destructure_const` when you know that constant is valid.
query try_destructure_const(
key: ty::ParamEnvAnd<'tcx, ty::Const<'tcx>>
) -> mir::DestructuredConst<'tcx> {
) -> Option<mir::DestructuredConst<'tcx>> {
desc { "destructure constant" }
remap_env_constness
}
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_middle/src/ty/print/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,6 @@ pub trait Printer<'tcx>: Sized {
own_params.start = 1;
}

// If we're in verbose mode, then print default-equal args too
if self.tcx().sess.verbose() {
return &substs[own_params];
}

// Don't print args that are the defaults of their respective parameters.
own_params.end -= generics
.params
Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1459,10 +1459,18 @@ pub trait PrettyPrinter<'tcx>:
// FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the
// correct `ty::ParamEnv` to allow printing *all* constant values.
(_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => {
let contents =
self.tcx().destructure_const(ty::ParamEnv::reveal_all().and(
self.tcx().mk_const(ty::ConstS { val: ty::ConstKind::Value(ct), ty }),
));
let Some(contents) = self.tcx().try_destructure_const(
ty::ParamEnv::reveal_all()
.and(self.tcx().mk_const(ty::ConstS { val: ty::ConstKind::Value(ct), ty })),
) else {
// Fall back to debug pretty printing for invalid constants.
p!(write("{:?}", ct));
if print_ty {
p!(": ", print(ty));
}
return Ok(self);
};

let fields = contents.fields.iter().copied();

match *ty.kind() {
Expand Down
23 changes: 11 additions & 12 deletions library/core/src/slice/cmp.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Comparison traits for `[T]`.

use crate::cmp;
use crate::cmp::Ordering::{self, Greater, Less};
use crate::cmp::{self, Ordering};
use crate::mem;

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

Expand Down
2 changes: 1 addition & 1 deletion src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ ENV PATH="/node-v14.4.0-linux-x64/bin:${PATH}"
# https://github.com/puppeteer/puppeteer/issues/375
#
# We also specify the version in case we need to update it to go around cache limitations.
RUN npm install -g [email protected].1 --unsafe-perm=true
RUN npm install -g [email protected].2 --unsafe-perm=true

ENV RUST_CONFIGURE_ARGS \
--build=x86_64-unknown-linux-gnu \
Expand Down
2 changes: 1 addition & 1 deletion src/doc/nomicon
15 changes: 14 additions & 1 deletion src/doc/rustdoc/src/command-line-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ the same CSS rules as the official `light` theme.
`--check-theme` flag, it discards all other flags and only performs the CSS rule
comparison operation.

### `--crate-version`: control the crate version
## `--crate-version`: control the crate version

Using this flag looks like this:

Expand Down Expand Up @@ -418,9 +418,22 @@ Rustdoc only supports Rust source code and Markdown input formats. If the
file ends in `.md` or `.markdown`, `rustdoc` treats it as a Markdown file.
Otherwise, it assumes that the input file is Rust.

# Unstable command line arguments

## `--nocapture`

When this flag is used with `--test`, the output (stdout and stderr) of your tests won't be
captured by rustdoc. Instead, the output will be directed to your terminal,
as if you had run the test executable manually. This is especially useful
for debugging your tests!

## `--check`

When this flag is supplied, rustdoc will type check and lint your code, but will not generate any
documentation or run your doctests.

Using this flag looks like:

```bash
rustdoc -Z unstable-options --check src/lib.rs
```
2 changes: 1 addition & 1 deletion src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -933,7 +933,7 @@ table,
outline: none;
border: 1px solid;
border-radius: 2px;
padding: 5px 8px;
padding: 8px;
font-size: 1rem;
transition: border-color 300ms ease;
width: 100%;
Expand Down
55 changes: 55 additions & 0 deletions src/test/mir-opt/const_prop/invalid_constant.main.ConstProp.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
- // MIR for `main` before ConstProp
+ // MIR for `main` after ConstProp

fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/invalid_constant.rs:15:11: 15:11
let _1: std::option::Option<()>; // in scope 0 at $DIR/invalid_constant.rs:16:5: 16:12
let mut _2: std::option::Option<std::option::Option<()>>; // in scope 0 at $DIR/invalid_constant.rs:16:7: 16:11
scope 1 (inlined f) { // at $DIR/invalid_constant.rs:16:5: 16:12
debug x => _2; // in scope 1 at $DIR/invalid_constant.rs:16:5: 16:12
let mut _3: isize; // in scope 1 at $DIR/invalid_constant.rs:16:5: 16:12
let _4: std::option::Option<()>; // in scope 1 at $DIR/invalid_constant.rs:16:5: 16:12
scope 2 {
debug y => _4; // in scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
}
}

bb0: {
discriminant(_2) = 0; // scope 0 at $DIR/invalid_constant.rs:16:7: 16:11
- _3 = discriminant(_2); // scope 1 at $DIR/invalid_constant.rs:16:5: 16:12
- switchInt(move _3) -> [0_isize: bb3, otherwise: bb2]; // scope 1 at $DIR/invalid_constant.rs:16:5: 16:12
+ _3 = const 0_isize; // scope 1 at $DIR/invalid_constant.rs:16:5: 16:12
+ switchInt(const 0_isize) -> [0_isize: bb3, otherwise: bb2]; // scope 1 at $DIR/invalid_constant.rs:16:5: 16:12
}

bb1: {
nop; // scope 0 at $DIR/invalid_constant.rs:15:11: 17:2
return; // scope 0 at $DIR/invalid_constant.rs:17:2: 17:2
}

bb2: {
- _4 = ((_2 as Some).0: std::option::Option<()>); // scope 1 at $DIR/invalid_constant.rs:16:5: 16:12
- _1 = _4; // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
+ _4 = const Scalar(0x02): Option::<()>; // scope 1 at $DIR/invalid_constant.rs:16:5: 16:12
+ // ty::Const
+ // + ty: std::option::Option<()>
+ // + val: Value(Scalar(0x02))
+ // mir::Constant
+ // + span: $DIR/invalid_constant.rs:16:5: 16:12
+ // + literal: Const { ty: std::option::Option<()>, val: Value(Scalar(0x02)) }
+ _1 = const Scalar(0x02): Option::<()>; // scope 2 at $DIR/invalid_constant.rs:16:5: 16:12
+ // ty::Const
+ // + ty: std::option::Option<()>
+ // + val: Value(Scalar(0x02))
+ // mir::Constant
+ // + span: $DIR/invalid_constant.rs:16:5: 16:12
+ // + literal: Const { ty: std::option::Option<()>, val: Value(Scalar(0x02)) }
goto -> bb1; // scope 0 at $DIR/invalid_constant.rs:10:20: 10:21
}

bb3: {
discriminant(_1) = 0; // scope 1 at $DIR/invalid_constant.rs:16:5: 16:12
goto -> bb1; // scope 0 at $DIR/invalid_constant.rs:9:17: 9:21
}
}

17 changes: 17 additions & 0 deletions src/test/mir-opt/const_prop/invalid_constant.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Verify that we can pretty print invalid constant introduced
// by constant propagation. Regression test for issue #93688.
//
// compile-flags: -Copt-level=0 -Zinline-mir

#[inline(always)]
pub fn f(x: Option<Option<()>>) -> Option<()> {
match x {
None => None,
Some(y) => y,
}
}

// EMIT_MIR invalid_constant.main.ConstProp.diff
fn main() {
f(None);
}
2 changes: 1 addition & 1 deletion src/test/rustdoc-gui/item-info-width.goml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ goto: file://|DOC_PATH|/lib2/struct.Foo.html
size: (1100, 800)
// We check that ".item-info" is bigger than its content.
assert-css: (".item-info", {"width": "790px"})
assert-css: (".item-info .stab", {"width": "339.562px"})
assert-css: (".item-info .stab", {"width": "340px"})
assert-position: (".item-info .stab", {"x": 295})
2 changes: 1 addition & 1 deletion src/test/ui/associated-types/substs-ppaux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn foo<'z>() where &'z (): Sized {
let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
//[verbose]~^ ERROR mismatched types
//[verbose]~| expected unit type `()`
//[verbose]~| found fn item `fn() {<i8 as Foo<ReStatic, ReStatic, u32>>::bar::<ReStatic, char>}`
//[verbose]~| found fn item `fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>}`
//[normal]~^^^^ ERROR mismatched types
//[normal]~| expected unit type `()`
//[normal]~| found fn item `fn() {<i8 as Foo<'static, 'static>>::bar::<'static, char>}`
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/associated-types/substs-ppaux.verbose.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ error[E0308]: mismatched types
--> $DIR/substs-ppaux.rs:25:17
|
LL | fn bar<'a, T>() where T: 'a {}
| --------------------------- fn() {<i8 as Foo<ReStatic, ReStatic, u32>>::bar::<ReStatic, char>} defined here
| --------------------------- fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>} defined here
...
LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>;
| -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found fn item
| |
| expected due to this
|
= note: expected unit type `()`
found fn item `fn() {<i8 as Foo<ReStatic, ReStatic, u32>>::bar::<ReStatic, char>}`
found fn item `fn() {<i8 as Foo<ReStatic, ReStatic>>::bar::<ReStatic, char>}`
help: use parentheses to call this function
|
LL | let x: () = <i8 as Foo<'static, 'static, u32>>::bar::<'static, char>();
Expand Down
Loading