Skip to content

Rollup of 9 pull requests #64932

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

Merged
merged 25 commits into from
Oct 1, 2019
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ce60da4
Fix `vec![x; n]` with null raw fat pointer zeroing the pointer metadata
SimonSapin Sep 29, 2019
6c01c0e
Zero-initialize `vec![None; n]` for `Option<&T>`, `Option<&mut T>` an…
SimonSapin Sep 29, 2019
2185710
Use https for curl when building for linux
tmandry Sep 28, 2019
6c6d27d
Fixed a misleading documentation issue #64844
hman523 Sep 30, 2019
cc9db52
Add long error explanation for E0493
GuillaumeGomez Sep 11, 2019
9f978b7
update tests
GuillaumeGomez Sep 12, 2019
67eabe1
Add long error explanation for E0550
GuillaumeGomez Sep 27, 2019
e67ae0e
update ui tests
GuillaumeGomez Sep 27, 2019
5bf4397
Add test for issue-64662
JohnTitor Sep 30, 2019
cdf1852
Add missing links for mem::needs_drop
tesuji Sep 30, 2019
f33d94d
Fix typo in docs
ecstatic-morse Sep 26, 2019
3e88aa2
Allow `ResultsCursor` to borrow the underlying `Results`
ecstatic-morse Sep 26, 2019
d37c318
Add graphviz debug output for generic dataflow
ecstatic-morse Sep 26, 2019
cd24cd4
Update consumers of `generic::Engine` API
ecstatic-morse Sep 30, 2019
cf5f5c5
Use separate files for debugging `Qualif` dataflow results
ecstatic-morse Sep 30, 2019
2b8e023
Stop printing `Qualif` results in debug logs
ecstatic-morse Sep 30, 2019
30ba6fd
Rollup merge of #64377 - GuillaumeGomez:E0493, r=estebank
tmandry Sep 30, 2019
fb8f9b4
Rollup merge of #64786 - tmandry:patch-1, r=alexcrichton
tmandry Sep 30, 2019
686ad4d
Rollup merge of #64828 - ecstatic-morse:generic-dataflow-graphviz, r=…
tmandry Sep 30, 2019
3add979
Rollup merge of #64838 - GuillaumeGomez:long-err-explanation-e0550, r…
tmandry Sep 30, 2019
1cd9b4b
Rollup merge of #64891 - SimonSapin:vec-of-fat-raw-ptr, r=sfackler
tmandry Sep 30, 2019
a8ed9bf
Rollup merge of #64893 - SimonSapin:vec-of-option-box, r=sfackler
tmandry Sep 30, 2019
5560f8c
Rollup merge of #64911 - hman523:64844, r=Dylan-DPC
tmandry Sep 30, 2019
e9d2879
Rollup merge of #64921 - JohnTitor:add-test-enum, r=varkor
tmandry Sep 30, 2019
913c095
Rollup merge of #64923 - lzutao:improve-doc-needs_drop, r=jonas-schie…
tmandry Sep 30, 2019
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
6 changes: 4 additions & 2 deletions src/ci/docker/dist-x86_64-linux/build-curl.sh
Original file line number Diff line number Diff line change
@@ -3,9 +3,11 @@
set -ex
source shared.sh

VERSION=7.51.0
VERSION=7.66.0

curl http://cool.haxx.se/download/curl-$VERSION.tar.bz2 | tar xjf -
curl https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc/curl-$VERSION.tar.xz \
| xz --decompress \
| tar xf -

mkdir curl-build
cd curl-build
48 changes: 48 additions & 0 deletions src/liballoc/tests/vec.rs
Original file line number Diff line number Diff line change
@@ -1281,3 +1281,51 @@ fn test_stable_push_pop() {
v.pop().unwrap();
assert_eq!(*v0, 13);
}

// https://github.com/rust-lang/rust/pull/49496 introduced specialization based on:
//
// ```
// unsafe impl<T: ?Sized> IsZero for *mut T {
// fn is_zero(&self) -> bool {
// (*self).is_null()
// }
// }
// ```
//
// … to call `RawVec::with_capacity_zeroed` for creating `Vec<*mut T>`,
// which is incorrect for fat pointers since `<*mut T>::is_null` only looks at the data component.
// That is, a fat pointer can be “null” without being made entirely of zero bits.
#[test]
fn vec_macro_repeating_null_raw_fat_pointer() {
let raw_dyn = &mut (|| ()) as &mut dyn Fn() as *mut dyn Fn();
let vtable = dbg!(ptr_metadata(raw_dyn));
let null_raw_dyn = ptr_from_raw_parts(std::ptr::null_mut(), vtable);
assert!(null_raw_dyn.is_null());

let vec = vec![null_raw_dyn; 1];
dbg!(ptr_metadata(vec[0]));
assert!(vec[0] == null_raw_dyn);

// Polyfill for https://github.com/rust-lang/rfcs/pull/2580

fn ptr_metadata(ptr: *mut dyn Fn()) -> *mut () {
unsafe {
std::mem::transmute::<*mut dyn Fn(), DynRepr>(ptr).vtable
}
}

fn ptr_from_raw_parts(data: *mut (), vtable: *mut()) -> *mut dyn Fn() {
unsafe {
std::mem::transmute::<DynRepr, *mut dyn Fn()>(DynRepr {
data,
vtable
})
}
}

#[repr(C)]
struct DynRepr {
data: *mut (),
vtable: *mut (),
}
}
29 changes: 27 additions & 2 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
@@ -1734,20 +1734,45 @@ impl_is_zero!(char, |x| x == '\0');
impl_is_zero!(f32, |x: f32| x.to_bits() == 0);
impl_is_zero!(f64, |x: f64| x.to_bits() == 0);

unsafe impl<T: ?Sized> IsZero for *const T {
unsafe impl<T> IsZero for *const T {
#[inline]
fn is_zero(&self) -> bool {
(*self).is_null()
}
}

unsafe impl<T: ?Sized> IsZero for *mut T {
unsafe impl<T> IsZero for *mut T {
#[inline]
fn is_zero(&self) -> bool {
(*self).is_null()
}
}

// `Option<&T>`, `Option<&mut T>` and `Option<Box<T>>` are guaranteed to represent `None` as null.
// For fat pointers, the bytes that would be the pointer metadata in the `Some` variant
// are padding in the `None` variant, so ignoring them and zero-initializing instead is ok.

unsafe impl<T: ?Sized> IsZero for Option<&T> {
#[inline]
fn is_zero(&self) -> bool {
self.is_none()
}
}

unsafe impl<T: ?Sized> IsZero for Option<&mut T> {
#[inline]
fn is_zero(&self) -> bool {
self.is_none()
}
}

unsafe impl<T: ?Sized> IsZero for Option<Box<T>> {
#[inline]
fn is_zero(&self) -> bool {
self.is_none()
}
}


////////////////////////////////////////////////////////////////////////////////
// Common trait implementations for Vec
10 changes: 6 additions & 4 deletions src/libcore/mem/mod.rs
Original file line number Diff line number Diff line change
@@ -368,15 +368,17 @@ pub fn align_of_val<T: ?Sized>(val: &T) -> usize {
/// make a difference in release builds (where a loop that has no side-effects
/// is easily detected and eliminated), but is often a big win for debug builds.
///
/// Note that `ptr::drop_in_place` already performs this check, so if your workload
/// can be reduced to some small number of drop_in_place calls, using this is
/// unnecessary. In particular note that you can drop_in_place a slice, and that
/// Note that [`drop_in_place`] already performs this check, so if your workload
/// can be reduced to some small number of [`drop_in_place`] calls, using this is
/// unnecessary. In particular note that you can [`drop_in_place`] a slice, and that
/// will do a single needs_drop check for all the values.
///
/// Types like Vec therefore just `drop_in_place(&mut self[..])` without using
/// needs_drop explicitly. Types like `HashMap`, on the other hand, have to drop
/// `needs_drop` explicitly. Types like [`HashMap`], on the other hand, have to drop
/// values one at a time and should use this API.
///
/// [`drop_in_place`]: ../ptr/fn.drop_in_place.html
/// [`HashMap`]: ../../std/collections/struct.HashMap.html
///
/// # Examples
///
2 changes: 1 addition & 1 deletion src/libcore/option.rs
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@
//! # Options and pointers ("nullable" pointers)
//!
//! Rust's pointer types must always point to a valid location; there are
//! no "null" pointers. Instead, Rust has *optional* pointers, like
//! no "null" references. Instead, Rust has *optional* pointers, like
//! the optional owned box, [`Option`]`<`[`Box<T>`]`>`.
//!
//! The following example uses [`Option`] to create an optional box of
129 changes: 115 additions & 14 deletions src/librustc_mir/dataflow/generic.rs
Original file line number Diff line number Diff line change
@@ -16,16 +16,24 @@
//! [gk]: https://en.wikipedia.org/wiki/Data-flow_analysis#Bit_vector_problems
//! [#64566]: https://github.com/rust-lang/rust/pull/64566
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::ops;
use std::ffi::OsString;
use std::path::{Path, PathBuf};
use std::{fs, io, ops};

use rustc::hir::def_id::DefId;
use rustc::mir::{self, traversal, BasicBlock, Location};
use rustc::ty::{self, TyCtxt};
use rustc_data_structures::work_queue::WorkQueue;
use rustc_index::bit_set::BitSet;
use rustc_index::vec::{Idx, IndexVec};
use rustc_data_structures::work_queue::WorkQueue;
use syntax::symbol::sym;

use crate::dataflow::BottomValue;

mod graphviz;

/// A specific kind of dataflow analysis.
///
/// To run a dataflow analysis, one must set the initial state of the `START_BLOCK` via
@@ -62,6 +70,13 @@ pub trait Analysis<'tcx>: BottomValue {
/// and try to keep it short.
const NAME: &'static str;

/// How each element of your dataflow state will be displayed during debugging.
///
/// By default, this is the `fmt::Debug` representation of `Self::Idx`.
fn pretty_print_idx(&self, w: &mut impl io::Write, idx: Self::Idx) -> io::Result<()> {
write!(w, "{:?}", idx)
}

/// The size of each bitvector allocated for each block.
fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize;

@@ -77,7 +92,7 @@ pub trait Analysis<'tcx>: BottomValue {
location: Location,
);

/// Updates the current dataflow state with the effect of evaluating a statement.
/// Updates the current dataflow state with the effect of evaluating a terminator.
///
/// Note that the effect of a successful return from a `Call` terminator should **not** be
/// acounted for in this function. That should go in `apply_call_return_effect`. For example,
@@ -180,17 +195,20 @@ impl CursorPosition {
}
}

type ResultsRefCursor<'a, 'mir, 'tcx, A> =
ResultsCursor<'mir, 'tcx, A, &'a Results<'tcx, A>>;

/// Inspect the results of dataflow analysis.
///
/// This cursor has linear performance when visiting statements in a block in order. Visiting
/// statements within a block in reverse order is `O(n^2)`, where `n` is the number of statements
/// in that block.
pub struct ResultsCursor<'mir, 'tcx, A>
pub struct ResultsCursor<'mir, 'tcx, A, R = Results<'tcx, A>>
where
A: Analysis<'tcx>,
{
body: &'mir mir::Body<'tcx>,
results: Results<'tcx, A>,
results: R,
state: BitSet<A::Idx>,

pos: CursorPosition,
@@ -202,24 +220,29 @@ where
is_call_return_effect_applied: bool,
}

impl<'mir, 'tcx, A> ResultsCursor<'mir, 'tcx, A>
impl<'mir, 'tcx, A, R> ResultsCursor<'mir, 'tcx, A, R>
where
A: Analysis<'tcx>,
R: Borrow<Results<'tcx, A>>,
{
/// Returns a new cursor for `results` that points to the start of the `START_BLOCK`.
pub fn new(body: &'mir mir::Body<'tcx>, results: Results<'tcx, A>) -> Self {
pub fn new(body: &'mir mir::Body<'tcx>, results: R) -> Self {
ResultsCursor {
body,
pos: CursorPosition::AtBlockStart(mir::START_BLOCK),
is_call_return_effect_applied: false,
state: results.entry_sets[mir::START_BLOCK].clone(),
state: results.borrow().entry_sets[mir::START_BLOCK].clone(),
results,
}
}

pub fn analysis(&self) -> &A {
&self.results.borrow().analysis
}

/// Resets the cursor to the start of the given `block`.
pub fn seek_to_block_start(&mut self, block: BasicBlock) {
self.state.overwrite(&self.results.entry_sets[block]);
self.state.overwrite(&self.results.borrow().entry_sets[block]);
self.pos = CursorPosition::AtBlockStart(block);
self.is_call_return_effect_applied = false;
}
@@ -275,7 +298,7 @@ where
} = &term.kind {
if !self.is_call_return_effect_applied {
self.is_call_return_effect_applied = true;
self.results.analysis.apply_call_return_effect(
self.results.borrow().analysis.apply_call_return_effect(
&mut self.state,
target.block,
func,
@@ -316,7 +339,7 @@ where
};

let block_data = &self.body.basic_blocks()[target_block];
self.results.analysis.apply_partial_block_effect(
self.results.borrow().analysis.apply_partial_block_effect(
&mut self.state,
target_block,
block_data,
@@ -349,7 +372,9 @@ where
{
analysis: A,
bits_per_block: usize,
tcx: TyCtxt<'tcx>,
body: &'a mir::Body<'tcx>,
def_id: DefId,
dead_unwinds: &'a BitSet<BasicBlock>,
entry_sets: IndexVec<BasicBlock, BitSet<A::Idx>>,
}
@@ -359,7 +384,9 @@ where
A: Analysis<'tcx>,
{
pub fn new(
tcx: TyCtxt<'tcx>,
body: &'a mir::Body<'tcx>,
def_id: DefId,
dead_unwinds: &'a BitSet<BasicBlock>,
analysis: A,
) -> Self {
@@ -377,7 +404,9 @@ where
Engine {
analysis,
bits_per_block,
tcx,
body,
def_id,
dead_unwinds,
entry_sets,
}
@@ -413,10 +442,26 @@ where
);
}

Results {
analysis: self.analysis,
entry_sets: self.entry_sets,
let Engine {
tcx,
body,
def_id,
analysis,
entry_sets,
..
} = self;

let results = Results { analysis, entry_sets };

let attrs = tcx.get_attrs(def_id);
if let Some(path) = get_dataflow_graphviz_output_path(tcx, attrs, A::NAME) {
let result = write_dataflow_graphviz_results(body, def_id, &path, &results);
if let Err(e) = result {
warn!("Failed to write dataflow results to {}: {}", path.display(), e);
}
}

results
}

fn propagate_bits_into_graph_successors_of(
@@ -510,3 +555,59 @@ where
}
}
}

/// Looks for attributes like `#[rustc_mir(borrowck_graphviz_postflow="./path/to/suffix.dot")]` and
/// extracts the path with the given analysis name prepended to the suffix.
///
/// Returns `None` if no such attribute exists.
fn get_dataflow_graphviz_output_path(
tcx: TyCtxt<'tcx>,
attrs: ty::Attributes<'tcx>,
analysis: &str,
) -> Option<PathBuf> {
let mut rustc_mir_attrs = attrs
.into_iter()
.filter(|attr| attr.check_name(sym::rustc_mir))
.flat_map(|attr| attr.meta_item_list().into_iter().flat_map(|v| v.into_iter()));

let borrowck_graphviz_postflow = rustc_mir_attrs
.find(|attr| attr.check_name(sym::borrowck_graphviz_postflow))?;

let path_and_suffix = match borrowck_graphviz_postflow.value_str() {
Some(p) => p,
None => {
tcx.sess.span_err(
borrowck_graphviz_postflow.span(),
"borrowck_graphviz_postflow requires a path",
);

return None;
}
};

// Change "path/suffix.dot" to "path/analysis_name_suffix.dot"
let mut ret = PathBuf::from(path_and_suffix.to_string());
let suffix = ret.file_name().unwrap();

let mut file_name: OsString = analysis.into();
file_name.push("_");
file_name.push(suffix);
ret.set_file_name(file_name);

Some(ret)
}

fn write_dataflow_graphviz_results<A: Analysis<'tcx>>(
body: &mir::Body<'tcx>,
def_id: DefId,
path: &Path,
results: &Results<'tcx, A>
) -> io::Result<()> {
debug!("printing dataflow results for {:?} to {}", def_id, path.display());

let mut buf = Vec::new();
let graphviz = graphviz::Formatter::new(body, def_id, results);

dot::render(&graphviz, &mut buf)?;
fs::write(path, buf)
}
412 changes: 412 additions & 0 deletions src/librustc_mir/dataflow/generic/graphviz.rs

Large diffs are not rendered by default.

46 changes: 45 additions & 1 deletion src/librustc_mir/error_codes.rs
Original file line number Diff line number Diff line change
@@ -1128,6 +1128,51 @@ Remember this solution is unsafe! You will have to ensure that accesses to the
cell are synchronized.
"##,

E0493: r##"
A type with a `Drop` implementation was destructured when trying to initialize
a static item.
Erroneous code example:
```compile_fail,E0493
enum DropType {
A,
}
impl Drop for DropType {
fn drop(&mut self) {}
}
struct Foo {
field1: DropType,
}
static FOO: Foo = Foo { ..Foo { field1: DropType::A } }; // error!
```
The problem here is that if the given type or one of its fields implements the
`Drop` trait, this `Drop` implementation cannot be called during the static
type initialization which might cause a memory leak. To prevent this issue,
you need to instantiate all the static type's fields by hand.
```
enum DropType {
A,
}
impl Drop for DropType {
fn drop(&mut self) {}
}
struct Foo {
field1: DropType,
}
static FOO: Foo = Foo { field1: DropType::A }; // We initialize all fields
// by hand.
```
"##,

E0499: r##"
A variable was borrowed as mutable more than once. Erroneous code example:
@@ -2454,7 +2499,6 @@ There are some known bugs that trigger this message.
// E0299, // mismatched types between arms
// E0471, // constant evaluation error (in pattern)
// E0385, // {} in an aliasable location
E0493, // destructors cannot be evaluated at compile-time
E0521, // borrowed data escapes outside of closure
E0526, // shuffle indices are not constant
E0594, // cannot assign to {}
5 changes: 5 additions & 0 deletions src/librustc_mir/transform/check_consts/qualifs.rs
Original file line number Diff line number Diff line change
@@ -27,6 +27,9 @@ impl QualifSet {
pub trait Qualif {
const IDX: usize;

/// The name of the file used to debug the dataflow analysis that computes this qualif.
const ANALYSIS_NAME: &'static str;

/// Whether this `Qualif` is cleared when a local is moved from.
const IS_CLEARED_ON_MOVE: bool = false;

@@ -207,6 +210,7 @@ pub struct HasMutInterior;

impl Qualif for HasMutInterior {
const IDX: usize = 0;
const ANALYSIS_NAME: &'static str = "flow_has_mut_interior";

fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
!ty.is_freeze(cx.tcx, cx.param_env, DUMMY_SP)
@@ -264,6 +268,7 @@ pub struct NeedsDrop;

impl Qualif for NeedsDrop {
const IDX: usize = 1;
const ANALYSIS_NAME: &'static str = "flow_needs_drop";
const IS_CLEARED_ON_MOVE: bool = true;

fn in_any_value_of_ty(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
5 changes: 3 additions & 2 deletions src/librustc_mir/transform/check_consts/resolver.rs
Original file line number Diff line number Diff line change
@@ -208,7 +208,8 @@ where
_qualif: PhantomData,
};
let results =
dataflow::Engine::new(item.body, dead_unwinds, analysis).iterate_to_fixpoint();
dataflow::Engine::new(item.tcx, item.body, item.def_id, dead_unwinds, analysis)
.iterate_to_fixpoint();
let cursor = dataflow::ResultsCursor::new(item.body, results);

let mut qualifs_in_any_value_of_ty = BitSet::new_empty(item.body.local_decls.len());
@@ -308,7 +309,7 @@ where
{
type Idx = Local;

const NAME: &'static str = "flow_sensitive_qualif";
const NAME: &'static str = Q::ANALYSIS_NAME;

fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize {
body.local_decls.len()
4 changes: 0 additions & 4 deletions src/librustc_mir/transform/check_consts/validation.rs
Original file line number Diff line number Diff line change
@@ -467,8 +467,6 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {

self.qualifs.needs_drop.visit_statement(statement, location);
self.qualifs.has_mut_interior.visit_statement(statement, location);
debug!("needs_drop: {:?}", self.qualifs.needs_drop.get());
debug!("has_mut_interior: {:?}", self.qualifs.has_mut_interior.get());

match statement.kind {
StatementKind::Assign(..) => {
@@ -494,8 +492,6 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {

self.qualifs.needs_drop.visit_terminator(terminator, location);
self.qualifs.has_mut_interior.visit_terminator(terminator, location);
debug!("needs_drop: {:?}", self.qualifs.needs_drop.get());
debug!("has_mut_interior: {:?}", self.qualifs.has_mut_interior.get());

self.super_terminator(terminator, location);
}
20 changes: 19 additions & 1 deletion src/libsyntax/error_codes.rs
Original file line number Diff line number Diff line change
@@ -144,6 +144,25 @@ fn deprecated_function() {}
```
"##,

E0550: r##"
More than one `deprecated` attribute has been put on an item.
Erroneous code example:
```compile_fail,E0550
#[deprecated(note = "because why not?")]
#[deprecated(note = "right?")] // error!
fn the_banished() {}
```
The `deprecated` attribute can only be present **once** on an item.
```
#[deprecated(note = "because why not, right?")]
fn the_banished() {} // ok!
```
"##,

E0552: r##"
A unrecognized representation attribute was used.
@@ -435,7 +454,6 @@ features in the `-Z allow_features` flag.
// rustc_deprecated attribute must be paired with either stable or unstable
// attribute
E0549,
E0550, // multiple deprecated attributes
E0551, // incorrect meta item
E0553, // multiple rustc_const_unstable attributes
// E0555, // replaced with a generic attribute input check
2 changes: 1 addition & 1 deletion src/test/ui/check-static-values-constraints.stderr
Original file line number Diff line number Diff line change
@@ -108,5 +108,5 @@ LL | let y = { static x: Box<isize> = box 3; x };

error: aborting due to 17 previous errors

Some errors have detailed explanations: E0010, E0015, E0019, E0507.
Some errors have detailed explanations: E0010, E0015, E0019, E0493, E0507.
For more information about an error, try `rustc --explain E0010`.
1 change: 1 addition & 0 deletions src/test/ui/consts/const-eval/const_let.stderr
Original file line number Diff line number Diff line change
@@ -24,3 +24,4 @@ LL | const Z2: () = { let mut x; x = None; x = Some(FakeNeedsDrop); };

error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0493`.
10 changes: 10 additions & 0 deletions src/test/ui/consts/issue-64662.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
enum Foo {
A = foo(), //~ ERROR: type annotations needed
B = foo(), //~ ERROR: type annotations needed
}

const fn foo<T>() -> isize {
0
}

fn main() {}
15 changes: 15 additions & 0 deletions src/test/ui/consts/issue-64662.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0282]: type annotations needed
--> $DIR/issue-64662.rs:2:9
|
LL | A = foo(),
| ^^^ cannot infer type for `T`

error[E0282]: type annotations needed
--> $DIR/issue-64662.rs:3:9
|
LL | B = foo(),
| ^^^ cannot infer type for `T`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0282`.
4 changes: 2 additions & 2 deletions src/test/ui/consts/min_const_fn/min_const_fn.stderr
Original file line number Diff line number Diff line change
@@ -324,5 +324,5 @@ LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }

error: aborting due to 37 previous errors

Some errors have detailed explanations: E0515, E0723.
For more information about an error, try `rustc --explain E0515`.
Some errors have detailed explanations: E0493, E0515, E0723.
For more information about an error, try `rustc --explain E0493`.
Original file line number Diff line number Diff line change
@@ -6,3 +6,4 @@ LL | const F: u32 = (U::X, 42).1;

error: aborting due to previous error

For more information about this error, try `rustc --explain E0493`.
2 changes: 1 addition & 1 deletion src/test/ui/deprecation/deprecation-sanity.stderr
Original file line number Diff line number Diff line change
@@ -54,5 +54,5 @@ LL | #[deprecated(since = "a", since = "b", note = "c")]

error: aborting due to 9 previous errors

Some errors have detailed explanations: E0538, E0541, E0565.
Some errors have detailed explanations: E0538, E0541, E0550, E0565.
For more information about an error, try `rustc --explain E0538`.
1 change: 1 addition & 0 deletions src/test/ui/span/E0493.stderr
Original file line number Diff line number Diff line change
@@ -6,3 +6,4 @@ LL | const F : Foo = (Foo { a : 0 }, Foo { a : 1 }).1;

error: aborting due to previous error

For more information about this error, try `rustc --explain E0493`.
3 changes: 2 additions & 1 deletion src/test/ui/static/static-drop-scope.stderr
Original file line number Diff line number Diff line change
@@ -68,4 +68,5 @@ LL | const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;

error: aborting due to 10 previous errors

For more information about this error, try `rustc --explain E0716`.
Some errors have detailed explanations: E0493, E0716.
For more information about an error, try `rustc --explain E0493`.