Auto merge of #71509 - Dylan-DPC:rollup-n8s37rm, r=Dylan-DPC

Rollup of 5 pull requests

Successful merges:

 - #71235 (Tweak `'static` suggestion code)
 - #71318 (miri-unleash tests: ensure they fire even with 'allow(const_err)')
 - #71428 (Let compiletest recognize gdb 10.x)
 - #71475 (Miri Frame: use mir::Location to represent position in function)
 - #71476 (more compact way to adjust test sizes for Miri)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-04-24 12:28:44 +00:00
commit 0612568358
55 changed files with 830 additions and 499 deletions

View File

@ -386,10 +386,8 @@ fn test_vec_from_vecdeque() {
assert!(vec.into_iter().eq(vd));
}
#[cfg(not(miri))] // Miri is too slow
let max_pwr = 7;
#[cfg(miri)]
let max_pwr = 5;
// Miri is too slow
let max_pwr = if cfg!(miri) { 5 } else { 7 };
for cap_pwr in 0..max_pwr {
// Make capacity as a (2^x)-1, so that the ring size is 2^x

View File

@ -409,16 +409,14 @@ fn panic_safe() {
}
let mut rng = thread_rng();
const DATASZ: usize = 32;
#[cfg(not(miri))] // Miri is too slow
const NTEST: usize = 10;
#[cfg(miri)]
const NTEST: usize = 1;
// Miri is too slow
let ntest = if cfg!(miri) { 1 } else { 10 };
// don't use 0 in the data -- we want to catch the zeroed-out case.
let data = (1..=DATASZ).collect::<Vec<_>>();
// since it's a fuzzy test, run several tries.
for _ in 0..NTEST {
for _ in 0..ntest {
for i in 1..=DATASZ {
DROP_COUNTER.store(0, Ordering::SeqCst);

View File

@ -28,10 +28,8 @@ const MIN_INSERTS_HEIGHT_2: usize = NODE_CAPACITY + (NODE_CAPACITY + 1) * NODE_C
#[test]
fn test_basic_large() {
let mut map = BTreeMap::new();
#[cfg(not(miri))] // Miri is too slow
let size = 10000;
#[cfg(miri)]
let size = MIN_INSERTS_HEIGHT_2;
// Miri is too slow
let size = if cfg!(miri) { MIN_INSERTS_HEIGHT_2 } else { 10000 };
assert_eq!(map.len(), 0);
for i in 0..size {
@ -155,10 +153,8 @@ fn test_basic_small() {
#[test]
fn test_iter() {
#[cfg(not(miri))] // Miri is too slow
let size = 10000;
#[cfg(miri)]
let size = 200;
// Miri is too slow
let size = if cfg!(miri) { 200 } else { 10000 };
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
@ -180,10 +176,8 @@ fn test_iter() {
#[test]
fn test_iter_rev() {
#[cfg(not(miri))] // Miri is too slow
let size = 10000;
#[cfg(miri)]
let size = 200;
// Miri is too slow
let size = if cfg!(miri) { 200 } else { 10000 };
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
@ -289,10 +283,8 @@ fn test_values_mut() {
#[test]
fn test_iter_mixed() {
#[cfg(not(miri))] // Miri is too slow
let size = 10000;
#[cfg(miri)]
let size = 200;
// Miri is too slow
let size = if cfg!(miri) { 200 } else { 10000 };
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
@ -525,10 +517,8 @@ fn test_range_backwards_4() {
#[test]
fn test_range_1000() {
#[cfg(not(miri))] // Miri is too slow
let size = 1000;
#[cfg(miri)]
let size = MIN_INSERTS_HEIGHT_2 as u32;
// Miri is too slow
let size = if cfg!(miri) { MIN_INSERTS_HEIGHT_2 as u32 } else { 1000 };
let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
fn test(map: &BTreeMap<u32, u32>, size: u32, min: Bound<&u32>, max: Bound<&u32>) {
@ -566,10 +556,8 @@ fn test_range_borrowed_key() {
#[test]
fn test_range() {
let size = 200;
#[cfg(not(miri))] // Miri is too slow
let step = 1;
#[cfg(miri)]
let step = 66;
// Miri is too slow
let step = if cfg!(miri) { 66 } else { 1 };
let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
for i in (0..size).step_by(step) {
@ -589,10 +577,8 @@ fn test_range() {
#[test]
fn test_range_mut() {
let size = 200;
#[cfg(not(miri))] // Miri is too slow
let step = 1;
#[cfg(miri)]
let step = 66;
// Miri is too slow
let step = if cfg!(miri) { 66 } else { 1 };
let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect();
for i in (0..size).step_by(step) {
@ -1263,10 +1249,8 @@ fn test_split_off_empty_left() {
#[test]
fn test_split_off_large_random_sorted() {
#[cfg(not(miri))] // Miri is too slow
let mut data = rand_data(1529);
#[cfg(miri)]
let mut data = rand_data(529);
// Miri is too slow
let mut data = if cfg!(miri) { rand_data(529) } else { rand_data(1529) };
// special case with maximum height.
data.sort();

View File

@ -621,10 +621,8 @@ fn test_split_off_empty_left() {
#[test]
fn test_split_off_large_random_sorted() {
#[cfg(not(miri))] // Miri is too slow
let mut data = rand_data(1529);
#[cfg(miri)]
let mut data = rand_data(529);
// Miri is too slow
let mut data = if cfg!(miri) { rand_data(529) } else { rand_data(1529) };
// special case with maximum height.
data.sort();

View File

@ -463,15 +463,9 @@ fn test_sort() {
#[test]
fn test_sort_stability() {
#[cfg(not(miri))] // Miri is too slow
let large_range = 500..510;
#[cfg(not(miri))] // Miri is too slow
let rounds = 10;
#[cfg(miri)]
let large_range = 0..0; // empty range
#[cfg(miri)]
let rounds = 1;
// Miri is too slow
let large_range = if cfg!(miri) { 0..0 } else { 500..510 };
let rounds = if cfg!(miri) { 1 } else { 10 };
for len in (2..25).chain(large_range) {
for _ in 0..rounds {
@ -1727,15 +1721,9 @@ fn panic_safe() {
let mut rng = thread_rng();
#[cfg(not(miri))] // Miri is too slow
let lens = (1..20).chain(70..MAX_LEN);
#[cfg(not(miri))] // Miri is too slow
let moduli = &[5, 20, 50];
#[cfg(miri)]
let lens = 1..10;
#[cfg(miri)]
let moduli = &[5];
// Miri is too slow
let lens = if cfg!(miri) { (1..10).chain(20..21) } else { (1..20).chain(70..MAX_LEN) };
let moduli: &[u32] = if cfg!(miri) { &[5] } else { &[5, 20, 50] };
for len in lens {
for &modulus in moduli {

View File

@ -954,16 +954,14 @@ fn test_append_permutations() {
out
}
#[cfg(not(miri))] // Miri is too slow
const MAX: usize = 5;
#[cfg(miri)]
const MAX: usize = 3;
// Miri is too slow
let max = if cfg!(miri) { 3 } else { 5 };
// Many different permutations of both the `VecDeque` getting appended to
// and the one getting appended are generated to check `append`.
// This ensures all 6 code paths of `append` are tested.
for src_push_back in 0..MAX {
for src_push_front in 0..MAX {
for src_push_back in 0..max {
for src_push_front in 0..max {
// doesn't pop more values than are pushed
for src_pop_back in 0..(src_push_back + src_push_front) {
for src_pop_front in 0..(src_push_back + src_push_front - src_pop_back) {
@ -974,8 +972,8 @@ fn test_append_permutations() {
src_pop_front,
);
for dst_push_back in 0..MAX {
for dst_push_front in 0..MAX {
for dst_push_back in 0..max {
for dst_push_front in 0..max {
for dst_pop_back in 0..(dst_push_back + dst_push_front) {
for dst_pop_front in
0..(dst_push_back + dst_push_front - dst_pop_back)

View File

@ -52,12 +52,10 @@ fn test_estimate_scaling_factor() {
assert_almost_eq!(estimate_scaling_factor(1, -1074), -323);
assert_almost_eq!(estimate_scaling_factor(0x1fffffffffffff, 971), 309);
#[cfg(not(miri))] // Miri is too slow
let iter = -1074..972;
#[cfg(miri)]
let iter = (-1074..972).step_by(37);
// Miri is too slow
let step = if cfg!(miri) { 37 } else { 1 };
for i in iter {
for i in (-1074..972).step_by(step) {
let expected = super::ldexp_f64(1.0, i).log10().ceil();
assert_almost_eq!(estimate_scaling_factor(1, i as i16), expected as i16);
}

View File

@ -138,13 +138,11 @@ where
#[test]
fn shortest_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_shortest as fallback;
#[cfg(not(miri))] // Miri is too slow
const N: usize = 10_000;
#[cfg(miri)]
const N: usize = 10;
// Miri is too slow
let n = if cfg!(miri) { 10 } else { 10_000 };
f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, N);
f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, N);
f64_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, n);
f32_random_equivalence_test(format_shortest_opt, fallback, MAX_SIG_DIGITS, n);
}
#[test]
@ -173,17 +171,15 @@ fn shortest_f64_hard_random_equivalence_test() {
#[test]
fn exact_f32_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_exact as fallback;
#[cfg(not(miri))] // Miri is too slow
const N: usize = 1_000;
#[cfg(miri)]
const N: usize = 3;
// Miri is too slow
let n = if cfg!(miri) { 3 } else { 1_000 };
for k in 1..21 {
f32_random_equivalence_test(
|d, buf| format_exact_opt(d, buf, i16::MIN),
|d, buf| fallback(d, buf, i16::MIN),
k,
N,
n,
);
}
}
@ -191,17 +187,15 @@ fn exact_f32_random_equivalence_test() {
#[test]
fn exact_f64_random_equivalence_test() {
use core::num::flt2dec::strategy::dragon::format_exact as fallback;
#[cfg(not(miri))] // Miri is too slow
const N: usize = 1_000;
#[cfg(miri)]
const N: usize = 3;
// Miri is too slow
let n = if cfg!(miri) { 3 } else { 1_000 };
for k in 1..21 {
f64_random_equivalence_test(
|d, buf| format_exact_opt(d, buf, i16::MIN),
|d, buf| fallback(d, buf, i16::MIN),
k,
N,
n,
);
}
}

View File

@ -1227,15 +1227,9 @@ fn sort_unstable() {
use core::slice::heapsort;
use rand::{rngs::StdRng, seq::SliceRandom, Rng, SeedableRng};
#[cfg(not(miri))] // Miri is too slow
let large_range = 500..510;
#[cfg(not(miri))] // Miri is too slow
let rounds = 100;
#[cfg(miri)]
let large_range = 0..0; // empty range
#[cfg(miri)]
let rounds = 1;
// Miri is too slow
let large_range = if cfg!(miri) { 0..0 } else { 500..510 };
let rounds = if cfg!(miri) { 1 } else { 100 };
let mut v = [0; 600];
let mut tmp = [0; 600];

View File

@ -273,7 +273,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
.next();
if !generic_args.parenthesized && !has_lifetimes {
generic_args.args = self
.elided_path_lifetimes(path_span, expected_lifetimes)
.elided_path_lifetimes(
first_generic_span.map(|s| s.shrink_to_lo()).unwrap_or(segment.ident.span),
expected_lifetimes,
)
.map(GenericArg::Lifetime)
.chain(generic_args.args.into_iter())
.collect();

View File

@ -81,14 +81,9 @@ pub struct Frame<'mir, 'tcx, Tag = (), Extra = ()> {
////////////////////////////////////////////////////////////////////////////////
// Current position within the function
////////////////////////////////////////////////////////////////////////////////
/// The block that is currently executed (or will be executed after the above call stacks
/// return).
/// If this is `None`, we are unwinding and this function doesn't need any clean-up.
/// Just continue the same as with `Resume`.
pub block: Option<mir::BasicBlock>,
/// The index of the currently evaluated statement.
pub stmt: usize,
pub loc: Option<mir::Location>,
}
#[derive(Clone, Eq, PartialEq, Debug, HashStable)] // Miri debug-prints these
@ -168,8 +163,7 @@ impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> {
return_to_block: self.return_to_block,
return_place: self.return_place,
locals: self.locals,
block: self.block,
stmt: self.stmt,
loc: self.loc,
extra,
}
}
@ -178,10 +172,10 @@ impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> {
impl<'mir, 'tcx, Tag, Extra> Frame<'mir, 'tcx, Tag, Extra> {
/// Return the `SourceInfo` of the current instruction.
pub fn current_source_info(&self) -> Option<mir::SourceInfo> {
self.block.map(|block| {
let block = &self.body.basic_blocks()[block];
if self.stmt < block.statements.len() {
block.statements[self.stmt].source_info
self.loc.map(|loc| {
let block = &self.body.basic_blocks()[loc.block];
if loc.statement_index < block.statements.len() {
block.statements[loc.statement_index].source_info
} else {
block.terminator().source_info
}
@ -615,14 +609,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// first push a stack frame so we have access to the local substs
let pre_frame = Frame {
body,
block: Some(mir::START_BLOCK),
loc: Some(mir::Location::START),
return_to_block,
return_place,
// empty local array, we fill it in below, after we are inside the stack frame and
// all methods actually know about the frame
locals: IndexVec::new(),
instance,
stmt: 0,
extra: (),
};
let frame = M::init_frame_extra(self, pre_frame)?;
@ -666,9 +659,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Jump to the given block.
#[inline]
pub fn go_to_block(&mut self, target: mir::BasicBlock) {
let frame = self.frame_mut();
frame.block = Some(target);
frame.stmt = 0;
self.frame_mut().loc = Some(mir::Location { block: target, statement_index: 0 });
}
/// *Return* to the given `target` basic block.
@ -690,9 +681,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// If `target` is `None`, that indicates the function does not need cleanup during
/// unwinding, and we will just keep propagating that upwards.
pub fn unwind_to_block(&mut self, target: Option<mir::BasicBlock>) {
let frame = self.frame_mut();
frame.block = target;
frame.stmt = 0;
self.frame_mut().loc = target.map(|block| mir::Location { block, statement_index: 0 });
}
/// Pops the current frame from the stack, deallocating the
@ -719,9 +708,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Sanity check `unwinding`.
assert_eq!(
unwinding,
match self.frame().block {
match self.frame().loc {
None => true,
Some(block) => self.body().basic_blocks()[block].is_cleanup,
Some(loc) => self.body().basic_blocks()[loc.block].is_cleanup,
}
);
@ -973,13 +962,14 @@ where
Tag: HashStable<StableHashingContext<'ctx>>,
{
fn hash_stable(&self, hcx: &mut StableHashingContext<'ctx>, hasher: &mut StableHasher) {
self.body.hash_stable(hcx, hasher);
self.instance.hash_stable(hcx, hasher);
self.return_to_block.hash_stable(hcx, hasher);
self.return_place.as_ref().map(|r| &**r).hash_stable(hcx, hasher);
self.locals.hash_stable(hcx, hasher);
self.block.hash_stable(hcx, hasher);
self.stmt.hash_stable(hcx, hasher);
self.extra.hash_stable(hcx, hasher);
// Exhaustive match on fields to make sure we forget no field.
let Frame { body, instance, return_to_block, return_place, locals, loc, extra } = self;
body.hash_stable(hcx, hasher);
instance.hash_stable(hcx, hasher);
return_to_block.hash_stable(hcx, hasher);
return_place.as_ref().map(|r| &**r).hash_stable(hcx, hasher);
locals.hash_stable(hcx, hasher);
loc.hash_stable(hcx, hasher);
extra.hash_stable(hcx, hasher);
}
}

View File

@ -46,8 +46,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
return Ok(false);
}
let block = match self.frame().block {
Some(block) => block,
let loc = match self.frame().loc {
Some(loc) => loc,
None => {
// We are unwinding and this fn has no cleanup code.
// Just go on unwinding.
@ -56,13 +56,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
return Ok(true);
}
};
let stmt_id = self.frame().stmt;
let body = self.body();
let basic_block = &body.basic_blocks()[block];
let basic_block = &self.body().basic_blocks()[loc.block];
let old_frames = self.frame_idx();
if let Some(stmt) = basic_block.statements.get(stmt_id) {
if let Some(stmt) = basic_block.statements.get(loc.statement_index) {
assert_eq!(old_frames, self.frame_idx());
self.statement(stmt)?;
return Ok(true);
@ -126,7 +124,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
LlvmInlineAsm { .. } => throw_unsup_format!("inline assembly is not supported"),
}
self.stack_mut()[frame_idx].stmt += 1;
self.stack_mut()[frame_idx].loc.as_mut().unwrap().statement_index += 1;
Ok(())
}
@ -279,8 +277,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.eval_terminator(terminator)?;
if !self.stack().is_empty() {
if let Some(block) = self.frame().block {
info!("// executing {:?}", block);
if let Some(loc) = self.frame().loc {
info!("// executing {:?}", loc.block);
}
}
Ok(())

View File

@ -52,7 +52,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Call { ref func, ref args, destination, ref cleanup, .. } => {
let old_stack = self.frame_idx();
let old_bb = self.frame().block;
let old_loc = self.frame().loc;
let func = self.eval_operand(func, None)?;
let (fn_val, abi) = match func.layout.ty.kind {
ty::FnPtr(sig) => {
@ -79,7 +79,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.eval_fn_call(fn_val, abi, &args[..], ret, *cleanup)?;
// Sanity-check that `eval_fn_call` either pushed a new frame or
// did a jump to another block.
if self.frame_idx() == old_stack && self.frame().block == old_bb {
if self.frame_idx() == old_stack && self.frame().loc == old_loc {
span_bug!(terminator.source_info.span, "evaluating this call made no progress");
}
}

View File

@ -1034,101 +1034,125 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
lifetime_names: &FxHashSet<ast::Ident>,
params: &[ElisionFailureInfo],
) {
if count > 1 {
err.span_label(span, format!("expected {} lifetime parameters", count));
} else {
let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok();
let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| {
err.span_suggestion(
span,
"consider using the named lifetime",
sugg,
Applicability::MaybeIncorrect,
);
};
let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg: &str| {
err.span_label(span, "expected named lifetime parameter");
let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok();
for missing in self.missing_named_lifetime_spots.iter().rev() {
let mut introduce_suggestion = vec![];
let msg;
let should_break;
introduce_suggestion.push(match missing {
MissingLifetimeSpot::Generics(generics) => {
msg = "consider introducing a named lifetime parameter".to_string();
should_break = true;
if let Some(param) = generics.params.iter().find(|p| match p.kind {
hir::GenericParamKind::Type {
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
..
} => false,
_ => true,
}) {
(param.span.shrink_to_lo(), "'a, ".to_string())
} else {
(generics.span, "<'a>".to_string())
}
}
MissingLifetimeSpot::HigherRanked { span, span_type } => {
msg = format!(
"consider making the {} lifetime-generic with a new `'a` lifetime",
span_type.descr(),
);
should_break = false;
err.note(
"for more information on higher-ranked polymorphism, visit \
https://doc.rust-lang.org/nomicon/hrtb.html",
);
(*span, span_type.suggestion("'a"))
}
});
for param in params {
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span)
{
if snippet.starts_with('&') && !snippet.starts_with("&'") {
introduce_suggestion
.push((param.span, format!("&'a {}", &snippet[1..])));
} else if snippet.starts_with("&'_ ") {
introduce_suggestion
.push((param.span, format!("&'a {}", &snippet[4..])));
}
err.span_label(
span,
&format!(
"expected {} lifetime parameter{}",
if count == 1 { "named".to_string() } else { count.to_string() },
pluralize!(count)
),
);
let suggest_existing = |err: &mut DiagnosticBuilder<'_>, sugg| {
err.span_suggestion_verbose(
span,
&format!("consider using the `{}` lifetime", lifetime_names.iter().next().unwrap()),
sugg,
Applicability::MaybeIncorrect,
);
};
let suggest_new = |err: &mut DiagnosticBuilder<'_>, sugg: &str| {
for missing in self.missing_named_lifetime_spots.iter().rev() {
let mut introduce_suggestion = vec![];
let msg;
let should_break;
introduce_suggestion.push(match missing {
MissingLifetimeSpot::Generics(generics) => {
msg = "consider introducing a named lifetime parameter".to_string();
should_break = true;
if let Some(param) = generics.params.iter().find(|p| match p.kind {
hir::GenericParamKind::Type {
synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
..
} => false,
_ => true,
}) {
(param.span.shrink_to_lo(), "'a, ".to_string())
} else {
(generics.span, "<'a>".to_string())
}
}
introduce_suggestion.push((span, sugg.to_string()));
err.multipart_suggestion(
&msg,
introduce_suggestion,
Applicability::MaybeIncorrect,
);
if should_break {
break;
MissingLifetimeSpot::HigherRanked { span, span_type } => {
msg = format!(
"consider making the {} lifetime-generic with a new `'a` lifetime",
span_type.descr(),
);
should_break = false;
err.note(
"for more information on higher-ranked polymorphism, visit \
https://doc.rust-lang.org/nomicon/hrtb.html",
);
(*span, span_type.suggestion("'a"))
}
});
for param in params {
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(param.span) {
if snippet.starts_with('&') && !snippet.starts_with("&'") {
introduce_suggestion
.push((param.span, format!("&'a {}", &snippet[1..])));
} else if snippet.starts_with("&'_ ") {
introduce_suggestion
.push((param.span, format!("&'a {}", &snippet[4..])));
}
}
}
};
match (lifetime_names.len(), lifetime_names.iter().next(), snippet.as_deref()) {
(1, Some(name), Some("&")) => {
suggest_existing(err, format!("&{} ", name));
}
(1, Some(name), Some("'_")) => {
suggest_existing(err, name.to_string());
}
(1, Some(name), Some(snippet)) if !snippet.ends_with('>') => {
suggest_existing(err, format!("{}<{}>", snippet, name));
}
(0, _, Some("&")) => {
suggest_new(err, "&'a ");
}
(0, _, Some("'_")) => {
suggest_new(err, "'a");
}
(0, _, Some(snippet)) if !snippet.ends_with('>') => {
suggest_new(err, &format!("{}<'a>", snippet));
}
_ => {
err.span_label(span, "expected lifetime parameter");
introduce_suggestion.push((span, sugg.to_string()));
err.multipart_suggestion(&msg, introduce_suggestion, Applicability::MaybeIncorrect);
if should_break {
break;
}
}
};
match (lifetime_names.len(), lifetime_names.iter().next(), snippet.as_deref()) {
(1, Some(name), Some("&")) => {
suggest_existing(err, format!("&{} ", name));
}
(1, Some(name), Some("'_")) => {
suggest_existing(err, name.to_string());
}
(1, Some(name), Some("")) => {
suggest_existing(err, format!("{}, ", name).repeat(count));
}
(1, Some(name), Some(snippet)) if !snippet.ends_with('>') => {
suggest_existing(
err,
format!(
"{}<{}>",
snippet,
std::iter::repeat(name.to_string())
.take(count)
.collect::<Vec<_>>()
.join(", ")
),
);
}
(0, _, Some("&")) if count == 1 => {
suggest_new(err, "&'a ");
}
(0, _, Some("'_")) if count == 1 => {
suggest_new(err, "'a");
}
(0, _, Some(snippet)) if !snippet.ends_with('>') && count == 1 => {
suggest_new(err, &format!("{}<'a>", snippet));
}
(n, ..) if n > 1 => {
let spans: Vec<Span> = lifetime_names.iter().map(|lt| lt.span).collect();
err.span_note(spans, "these named lifetimes are available to use");
if Some("") == snippet.as_deref() {
// This happens when we have `Foo<T>` where we point at the space before `T`,
// but this can be confusing so we give a suggestion with placeholders.
err.span_suggestion_verbose(
span,
"consider using one of the available lifetimes here",
"'lifetime, ".repeat(count),
Applicability::HasPlaceholders,
);
}
}
_ => {}
}
}
}

View File

@ -2393,52 +2393,28 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
};
let mut err = self.report_missing_lifetime_specifiers(span, lifetime_refs.len());
let mut add_label = true;
if let Some(params) = error {
if lifetime_refs.len() == 1 {
add_label = add_label && self.report_elision_failure(&mut err, params, span);
// If there's no lifetime available, suggest `'static`.
if self.report_elision_failure(&mut err, params) && lifetime_names.is_empty() {
lifetime_names.insert(ast::Ident::from_str("'static"));
}
}
if add_label {
self.add_missing_lifetime_specifiers_label(
&mut err,
span,
lifetime_refs.len(),
&lifetime_names,
error.map(|p| &p[..]).unwrap_or(&[]),
);
}
self.add_missing_lifetime_specifiers_label(
&mut err,
span,
lifetime_refs.len(),
&lifetime_names,
error.map(|p| &p[..]).unwrap_or(&[]),
);
err.emit();
}
fn suggest_lifetime(&self, db: &mut DiagnosticBuilder<'_>, span: Span, msg: &str) -> bool {
match self.tcx.sess.source_map().span_to_snippet(span) {
Ok(ref snippet) => {
let (sugg, applicability) = if snippet == "&" {
("&'static ".to_owned(), Applicability::MachineApplicable)
} else if snippet == "'_" {
("'static".to_owned(), Applicability::MachineApplicable)
} else {
(format!("{} + 'static", snippet), Applicability::MaybeIncorrect)
};
db.span_suggestion(span, msg, sugg, applicability);
false
}
Err(_) => {
db.help(msg);
true
}
}
}
fn report_elision_failure(
&mut self,
db: &mut DiagnosticBuilder<'_>,
params: &[ElisionFailureInfo],
span: Span,
) -> bool {
) -> bool /* add `'static` lifetime to lifetime list */ {
let mut m = String::new();
let len = params.len();
@ -2487,29 +2463,28 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
"this function's return type contains a borrowed value, \
but there is no value for it to be borrowed from",
);
self.suggest_lifetime(db, span, "consider giving it a 'static lifetime")
true
} else if elided_len == 0 {
db.help(
"this function's return type contains a borrowed value with \
an elided lifetime, but the lifetime cannot be derived from \
the arguments",
);
let msg = "consider giving it an explicit bounded or 'static lifetime";
self.suggest_lifetime(db, span, msg)
true
} else if elided_len == 1 {
db.help(&format!(
"this function's return type contains a borrowed value, \
but the signature does not say which {} it is borrowed from",
m
));
true
false
} else {
db.help(&format!(
"this function's return type contains a borrowed value, \
but the signature does not say whether it is borrowed from {}",
m
));
true
false
}
}

View File

@ -657,7 +657,8 @@ impl MultiSpan {
MultiSpan { primary_spans: vec![primary_span], span_labels: vec![] }
}
pub fn from_spans(vec: Vec<Span>) -> MultiSpan {
pub fn from_spans(mut vec: Vec<Span>) -> MultiSpan {
vec.sort();
MultiSpan { primary_spans: vec, span_labels: vec![] }
}

View File

@ -1017,18 +1017,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
let path_span = if let [segment] = &trait_ref.path.segments[..] {
// FIXME: `trait_ref.path.span` can point to a full path with multiple
// segments, even though `trait_ref.path.segments` is of length `1`. Work
// around that bug here, even though it should be fixed elsewhere.
// This would otherwise cause an invalid suggestion. For an example, look at
// `src/test/ui/issues/issue-28344.rs`.
segment.ident.span
} else {
trait_ref.path.span
};
let (substs, assoc_bindings, arg_count_correct) = self.create_substs_for_ast_trait_ref(
path_span,
trait_ref.path.span,
trait_def_id,
self_ty,
trait_ref.path.segments.last().unwrap(),
@ -1729,6 +1719,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.ast_region_to_region(lifetime, None)
} else {
self.re_infer(None, span).unwrap_or_else(|| {
// FIXME: these can be redundant with E0106, but not always.
struct_span_err!(
tcx.sess,
span,

View File

@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
--> $DIR/bound-lifetime-in-binding-only.rs:52:23
|
LL | fn elision<T: Fn() -> &i32>() {
| ^ help: consider giving it a 'static lifetime: `&'static`
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | fn elision<T: Fn() -> &'static i32>() {
| ^^^^^^^^
error: aborting due to previous error

View File

@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
--> $DIR/bound-lifetime-in-return-only.rs:34:23
|
LL | fn elision(_: fn() -> &i32) {
| ^ help: consider giving it a 'static lifetime: `&'static`
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | fn elision(_: fn() -> &'static i32) {
| ^^^^^^^^
error: aborting due to previous error

View File

@ -4,9 +4,13 @@ error[E0106]: missing lifetime specifier
LL | foo: &dyn Foo, bar: &'a dyn Foo
| -------- -----------
LL | ) -> &dyn Foo
| ^ help: consider using the named lifetime: `&'a`
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar`
help: consider using the `'a` lifetime
|
LL | ) -> &'a dyn Foo
| ^^^
error: aborting due to previous error

View File

@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
--> $DIR/variadic-ffi-6.rs:7:6
|
LL | ) -> &usize {
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
help: consider using the `'static` lifetime
|
LL | ) -> &'static usize {
| ^^^^^^^^
error: aborting due to previous error

View File

@ -2,15 +2,20 @@
// compile-flags: -Z unleash-the-miri-inside-of-you
#![feature(const_extern_fn)]
#![allow(const_err)]
const extern "C" fn c_fn() {}
const fn call_rust_fn(my_fn: extern "Rust" fn()) {
my_fn(); //~ ERROR any use of this value will cause an error
my_fn();
//~^ WARN skipping const checks
//~| ERROR could not evaluate static initializer
//~| NOTE calling a function with ABI C using caller ABI Rust
//~| NOTE inside `call_rust_fn`
}
const VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
//~^ WARN skipping const checks
//~| NOTE inside `VAL`
fn main() {}

View File

@ -1,29 +1,27 @@
warning: skipping const checks
--> $DIR/abi-mismatch.rs:9:5
--> $DIR/abi-mismatch.rs:10:5
|
LL | my_fn();
| ^^^^^^^
warning: skipping const checks
--> $DIR/abi-mismatch.rs:13:39
--> $DIR/abi-mismatch.rs:17:40
|
LL | const VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: any use of this value will cause an error
--> $DIR/abi-mismatch.rs:9:5
error[E0080]: could not evaluate static initializer
--> $DIR/abi-mismatch.rs:10:5
|
LL | my_fn();
| ^^^^^^^
| |
| calling a function with ABI C using caller ABI Rust
| inside `call_rust_fn` at $DIR/abi-mismatch.rs:9:5
| inside `VAL` at $DIR/abi-mismatch.rs:13:17
| inside `call_rust_fn` at $DIR/abi-mismatch.rs:10:5
...
LL | const VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
| --------------------------------------------------------------------------------------
|
= note: `#[deny(const_err)]` on by default
LL | static VAL: () = call_rust_fn(unsafe { std::mem::transmute(c_fn as extern "C" fn()) });
| --------------------------------------------------------------------- inside `VAL` at $DIR/abi-mismatch.rs:17:18
error: aborting due to previous error; 2 warnings emitted
For more information about this error, try `rustc --explain E0080`.

View File

@ -1,6 +1,6 @@
// compile-flags: -Zunleash-the-miri-inside-of-you
#![feature(const_mut_refs, box_syntax)]
#![deny(const_err)]
#![allow(const_err)]
use std::mem::ManuallyDrop;

View File

@ -1,39 +1,37 @@
// build-fail
// compile-flags: -Zunleash-the-miri-inside-of-you
#![warn(const_err)]
#![allow(const_err)]
#![feature(const_raw_ptr_deref)]
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
const REF_INTERIOR_MUT: &usize = { //~ ERROR undefined behavior to use this value
static FOO: AtomicUsize = AtomicUsize::new(0);
unsafe { &*(&FOO as *const _ as *const usize) }
//~^ WARN skipping const checks
};
// These tests only cause an error when *using* the const.
const MUTATE_INTERIOR_MUT: usize = {
static FOO: AtomicUsize = AtomicUsize::new(0);
FOO.fetch_add(1, Ordering::Relaxed) //~ WARN any use of this value will cause an error
FOO.fetch_add(1, Ordering::Relaxed)
//~^ WARN skipping const checks
//~| WARN skipping const checks
};
const READ_INTERIOR_MUT: usize = {
static FOO: AtomicUsize = AtomicUsize::new(0);
unsafe { *(&FOO as *const _ as *const usize) } //~ WARN any use of this value will cause an err
unsafe { *(&FOO as *const _ as *const usize) }
//~^ WARN skipping const checks
};
static mut MUTABLE: u32 = 0;
const READ_MUT: u32 = unsafe { MUTABLE }; //~ WARN any use of this value will cause an error
const READ_MUT: u32 = unsafe { MUTABLE };
//~^ WARN skipping const checks
//~| WARN skipping const checks
// ok some day perhaps
const READ_IMMUT: &usize = { //~ ERROR it is undefined behavior to use this value
static FOO: usize = 0;
&FOO
//~^ WARN skipping const checks
};
fn main() {}
fn main() {
MUTATE_INTERIOR_MUT;
//~^ ERROR: erroneous constant used
READ_INTERIOR_MUT;
//~^ ERROR: erroneous constant used
READ_MUT;
//~^ ERROR: erroneous constant used
}

View File

@ -1,106 +1,51 @@
warning: skipping const checks
--> $DIR/const_refers_to_static.rs:11:18
|
LL | unsafe { &*(&FOO as *const _ as *const usize) }
| ^^^
warning: skipping const checks
--> $DIR/const_refers_to_static.rs:17:5
--> $DIR/const_refers_to_static.rs:14:5
|
LL | FOO.fetch_add(1, Ordering::Relaxed)
| ^^^
warning: skipping const checks
--> $DIR/const_refers_to_static.rs:17:5
--> $DIR/const_refers_to_static.rs:14:5
|
LL | FOO.fetch_add(1, Ordering::Relaxed)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: skipping const checks
--> $DIR/const_refers_to_static.rs:24:17
--> $DIR/const_refers_to_static.rs:21:17
|
LL | unsafe { *(&FOO as *const _ as *const usize) }
| ^^^
warning: skipping const checks
--> $DIR/const_refers_to_static.rs:29:32
--> $DIR/const_refers_to_static.rs:26:32
|
LL | const READ_MUT: u32 = unsafe { MUTABLE };
| ^^^^^^^
warning: skipping const checks
--> $DIR/const_refers_to_static.rs:29:32
--> $DIR/const_refers_to_static.rs:26:32
|
LL | const READ_MUT: u32 = unsafe { MUTABLE };
| ^^^^^^^
warning: skipping const checks
--> $DIR/const_refers_to_static.rs:36:6
error[E0080]: erroneous constant used
--> $DIR/const_refers_to_static.rs:31:5
|
LL | &FOO
| ^^^
LL | MUTATE_INTERIOR_MUT;
| ^^^^^^^^^^^^^^^^^^^ referenced constant has errors
error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static.rs:9:1
error[E0080]: erroneous constant used
--> $DIR/const_refers_to_static.rs:33:5
|
LL | / const REF_INTERIOR_MUT: &usize = {
LL | | static FOO: AtomicUsize = AtomicUsize::new(0);
LL | | unsafe { &*(&FOO as *const _ as *const usize) }
LL | |
LL | | };
| |__^ type validation failed: encountered a reference pointing to a static variable
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
LL | READ_INTERIOR_MUT;
| ^^^^^^^^^^^^^^^^^ referenced constant has errors
warning: any use of this value will cause an error
--> $DIR/const_refers_to_static.rs:17:5
error[E0080]: erroneous constant used
--> $DIR/const_refers_to_static.rs:35:5
|
LL | / const MUTATE_INTERIOR_MUT: usize = {
LL | | static FOO: AtomicUsize = AtomicUsize::new(0);
LL | | FOO.fetch_add(1, Ordering::Relaxed)
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling non-const function `std::sync::atomic::AtomicUsize::fetch_add`
LL | |
LL | |
LL | | };
| |__-
|
note: the lint level is defined here
--> $DIR/const_refers_to_static.rs:2:9
|
LL | #![warn(const_err)]
| ^^^^^^^^^
LL | READ_MUT;
| ^^^^^^^^ referenced constant has errors
warning: any use of this value will cause an error
--> $DIR/const_refers_to_static.rs:24:14
|
LL | / const READ_INTERIOR_MUT: usize = {
LL | | static FOO: AtomicUsize = AtomicUsize::new(0);
LL | | unsafe { *(&FOO as *const _ as *const usize) }
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static
LL | |
LL | | };
| |__-
warning: any use of this value will cause an error
--> $DIR/const_refers_to_static.rs:29:32
|
LL | const READ_MUT: u32 = unsafe { MUTABLE };
| -------------------------------^^^^^^^---
| |
| constant accesses static
error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static.rs:34:1
|
LL | / const READ_IMMUT: &usize = {
LL | | static FOO: usize = 0;
LL | | &FOO
LL | |
LL | | };
| |__^ type validation failed: encountered a reference pointing to a static variable
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
error: aborting due to 2 previous errors; 10 warnings emitted
error: aborting due to 3 previous errors; 5 warnings emitted
For more information about this error, try `rustc --explain E0080`.

View File

@ -0,0 +1,24 @@
// compile-flags: -Zunleash-the-miri-inside-of-you
#![allow(const_err)]
#![feature(const_raw_ptr_deref)]
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
// These tests cause immediate error when *defining* the const.
const REF_INTERIOR_MUT: &usize = { //~ ERROR undefined behavior to use this value
static FOO: AtomicUsize = AtomicUsize::new(0);
unsafe { &*(&FOO as *const _ as *const usize) }
//~^ WARN skipping const checks
};
// ok some day perhaps
const READ_IMMUT: &usize = { //~ ERROR it is undefined behavior to use this value
static FOO: usize = 0;
&FOO
//~^ WARN skipping const checks
};
fn main() {}

View File

@ -0,0 +1,39 @@
warning: skipping const checks
--> $DIR/const_refers_to_static2.rs:13:18
|
LL | unsafe { &*(&FOO as *const _ as *const usize) }
| ^^^
warning: skipping const checks
--> $DIR/const_refers_to_static2.rs:20:6
|
LL | &FOO
| ^^^
error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static2.rs:11:1
|
LL | / const REF_INTERIOR_MUT: &usize = {
LL | | static FOO: AtomicUsize = AtomicUsize::new(0);
LL | | unsafe { &*(&FOO as *const _ as *const usize) }
LL | |
LL | | };
| |__^ type validation failed: encountered a reference pointing to a static variable
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
error[E0080]: it is undefined behavior to use this value
--> $DIR/const_refers_to_static2.rs:18:1
|
LL | / const READ_IMMUT: &usize = {
LL | | static FOO: usize = 0;
LL | | &FOO
LL | |
LL | | };
| |__^ type validation failed: encountered a reference pointing to a static variable
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
error: aborting due to 2 previous errors; 2 warnings emitted
For more information about this error, try `rustc --explain E0080`.

View File

@ -1,6 +1,6 @@
// compile-flags: -Zunleash-the-miri-inside-of-you
// error-pattern: calling non-const function `<std::vec::Vec<i32> as std::ops::Drop>::drop`
#![deny(const_err)]
#![allow(const_err)]
use std::mem::ManuallyDrop;

View File

@ -1,8 +1,13 @@
// compile-flags: -Zunleash-the-miri-inside-of-you
// normalize-stderr-test "alloc[0-9]+" -> "allocN"
#![feature(const_raw_ptr_deref)]
#![feature(const_mut_refs)]
#![deny(const_err)]
#![deny(const_err)] // The `allow` variant is tested by `mutable_const2`.
//~^ NOTE lint level
// Here we check that even though `MUTABLE_BEHIND_RAW` is created from a mutable
// allocation, we intern that allocation as *immutable* and reject writes to it.
// We avoid the `delay_span_bug` ICE by having compilation fail via the `deny` above.
use std::cell::UnsafeCell;
@ -10,10 +15,13 @@ use std::cell::UnsafeCell;
const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
//~^ WARN: skipping const checks
const MUTATING_BEHIND_RAW: () = {
const MUTATING_BEHIND_RAW: () = { //~ NOTE
// Test that `MUTABLE_BEHIND_RAW` is actually immutable, by doing this at const time.
unsafe {
*MUTABLE_BEHIND_RAW = 99 //~ ERROR any use of this value will cause an error
//~^ NOTE: which is read-only
// FIXME would be good to match more of the error message here, but looks like we
// normalize *after* checking the annoations here.
}
};

View File

@ -1,25 +1,26 @@
warning: skipping const checks
--> $DIR/mutable_const.rs:10:38
--> $DIR/mutable_const.rs:15:38
|
LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _;
| ^^^^^^^^^^^^^^^^^^^^
error: any use of this value will cause an error
--> $DIR/mutable_const.rs:16:9
--> $DIR/mutable_const.rs:21:9
|
LL | / const MUTATING_BEHIND_RAW: () = {
LL | | // Test that `MUTABLE_BEHIND_RAW` is actually immutable, by doing this at const time.
LL | | unsafe {
LL | | *MUTABLE_BEHIND_RAW = 99
| | ^^^^^^^^^^^^^^^^^^^^^^^^ writing to alloc2 which is read-only
| | ^^^^^^^^^^^^^^^^^^^^^^^^ writing to allocN which is read-only
... |
LL | | }
LL | | };
| |__-
|
note: the lint level is defined here
--> $DIR/mutable_const.rs:5:9
--> $DIR/mutable_const.rs:6:9
|
LL | #![deny(const_err)]
LL | #![deny(const_err)] // The `allow` variant is tested by `mutable_const2`.
| ^^^^^^^^^
error: aborting due to previous error; 1 warning emitted

View File

@ -3,11 +3,11 @@
// rustc-env:RUST_BACKTRACE=0
// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET"
// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS"
// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC"
// normalize-stderr-test "interpret/intern.rs:[0-9]+:[0-9]+" -> "interpret/intern.rs:LL:CC"
#![feature(const_raw_ptr_deref)]
#![feature(const_mut_refs)]
#![deny(const_err)]
#![allow(const_err)]
use std::cell::UnsafeCell;

View File

@ -3,7 +3,7 @@
// rustc-env:RUST_BACKTRACE=0
// normalize-stderr-test "note: rustc 1.* running on .*" -> "note: rustc VERSION running on TARGET"
// normalize-stderr-test "note: compiler flags: .*" -> "note: compiler flags: FLAGS"
// normalize-stderr-test "interpret/intern.rs:[0-9]*:[0-9]*" -> "interpret/intern.rs:LL:CC"
// normalize-stderr-test "interpret/intern.rs:[0-9]+:[0-9]+" -> "interpret/intern.rs:LL:CC"
#![allow(const_err)]

View File

@ -1,14 +1,15 @@
// compile-flags: -Zunleash-the-miri-inside-of-you
#![allow(const_err)]
// Make sure we cannot mutate globals.
static mut GLOBAL: i32 = 0;
const MUTATING_GLOBAL: () = {
static MUTATING_GLOBAL: () = {
unsafe {
GLOBAL = 99 //~ ERROR any use of this value will cause an error
//~^ WARN skipping const checks
//~| WARN skipping const checks
GLOBAL = 99
//~^ ERROR could not evaluate static initializer
//~| NOTE modifying a static's initial value
}
};

View File

@ -1,29 +1,9 @@
warning: skipping const checks
--> $DIR/mutating_global.rs:9:9
error[E0080]: could not evaluate static initializer
--> $DIR/mutating_global.rs:10:9
|
LL | GLOBAL = 99
| ^^^^^^
| ^^^^^^^^^^^ modifying a static's initial value from another static's initializer
warning: skipping const checks
--> $DIR/mutating_global.rs:9:9
|
LL | GLOBAL = 99
| ^^^^^^
error: any use of this value will cause an error
--> $DIR/mutating_global.rs:9:9
|
LL | / const MUTATING_GLOBAL: () = {
LL | | unsafe {
LL | | GLOBAL = 99
| | ^^^^^^^^^^^ modifying a static's initial value from another static's initializer
LL | |
LL | |
LL | | }
LL | | };
| |__-
|
= note: `#[deny(const_err)]` on by default
error: aborting due to previous error; 2 warnings emitted
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.

View File

@ -1,17 +1,13 @@
// build-fail
// compile-flags: -Zunleash-the-miri-inside-of-you
#![warn(const_err)]
#![allow(const_err)]
// A test demonstrating that we prevent calling non-const fn during CTFE.
fn foo() {}
const C: () = foo(); //~ WARN: skipping const checks
//~^ WARN any use of this value will cause an error
static C: () = foo(); //~ WARN: skipping const checks
//~^ ERROR could not evaluate static initializer
//~| NOTE calling non-const function `foo`
fn main() {
println!("{:?}", C);
//~^ ERROR: evaluation of constant expression failed
//~| WARN: erroneous constant used [const_err]
}
fn main() {}

View File

@ -1,35 +1,15 @@
warning: skipping const checks
--> $DIR/non_const_fn.rs:10:15
--> $DIR/non_const_fn.rs:9:16
|
LL | const C: () = foo();
| ^^^^^
LL | static C: () = foo();
| ^^^^^
warning: any use of this value will cause an error
--> $DIR/non_const_fn.rs:10:15
error[E0080]: could not evaluate static initializer
--> $DIR/non_const_fn.rs:9:16
|
LL | const C: () = foo();
| --------------^^^^^-
| |
| calling non-const function `foo`
|
note: the lint level is defined here
--> $DIR/non_const_fn.rs:4:9
|
LL | #![warn(const_err)]
| ^^^^^^^^^
LL | static C: () = foo();
| ^^^^^ calling non-const function `foo`
error[E0080]: evaluation of constant expression failed
--> $DIR/non_const_fn.rs:14:22
|
LL | println!("{:?}", C);
| ^ referenced constant has errors
warning: erroneous constant used
--> $DIR/non_const_fn.rs:14:22
|
LL | println!("{:?}", C);
| ^ referenced constant has errors
error: aborting due to previous error; 3 warnings emitted
error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0080`.

View File

@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
--> $DIR/foreign-fn-return-lifetime.rs:5:19
|
LL | pub fn f() -> &u8;
| ^ help: consider giving it a 'static lifetime: `&'static`
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | pub fn f() -> &'static u8;
| ^^^^^^^^
error: aborting due to previous error

View File

@ -5,16 +5,33 @@ LL | fn should_error<T>() where T : Into<&u32> {}
| ^ explicit lifetime name needed here
error[E0106]: missing lifetime specifier
--> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:9:19
--> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:9:21
|
LL | fn foo<'b, L: X<&'b Nested<K>>>();
| ^^^^^^^^^^^^^^^^ expected lifetime parameter
| ^ expected named lifetime parameter
|
note: these named lifetimes are available to use
--> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:8:9
|
LL | trait X<'a, K: 'a> {
| ^^
LL | fn foo<'b, L: X<&'b Nested<K>>>();
| ^^
help: consider using one of the available lifetimes here
|
LL | fn foo<'b, L: X<'lifetime, &'b Nested<K>>>();
| ^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:13:15
--> $DIR/issue-65285-incorrect-explicit-lifetime-name-needed.rs:13:17
|
LL | fn bar<'b, L: X<&'b Nested<i32>>>(){}
| ^^^^^^^^^^^^^^^^^^ expected lifetime parameter
| ^ expected named lifetime parameter
|
help: consider using the `'b` lifetime
|
LL | fn bar<'b, L: X<'b, &'b Nested<i32>>>(){}
| ^^^
error: aborting due to 3 previous errors

View File

@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
--> $DIR/issue-13497.rs:2:5
|
LL | &str
| ^ help: consider giving it a 'static lifetime: `&'static`
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | &'static str
| ^^^^^^^^
error: aborting due to previous error

View File

@ -14,17 +14,25 @@ error[E0106]: missing lifetime specifier
--> $DIR/issue-26638.rs:4:40
|
LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
help: consider using the `'static` lifetime
|
LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &'static str { iter() }
| ^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/issue-26638.rs:7:22
|
LL | fn parse_type_3() -> &str { unimplemented!() }
| ^ help: consider giving it a 'static lifetime: `&'static`
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | fn parse_type_3() -> &'static str { unimplemented!() }
| ^^^^^^^^
error: aborting due to 3 previous errors

View File

@ -2,9 +2,13 @@ error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:2:11
|
LL | fn f() -> &isize {
| ^ help: consider giving it a 'static lifetime: `&'static`
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | fn f() -> &'static isize {
| ^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:33
@ -34,25 +38,37 @@ error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:21:20
|
LL | fn i(_x: isize) -> &isize {
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
help: consider using the `'static` lifetime
|
LL | fn i(_x: isize) -> &'static isize {
| ^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:34:24
|
LL | fn j(_x: StaticStr) -> &isize {
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
help: consider using the `'static` lifetime
|
LL | fn j(_x: StaticStr) -> &'static isize {
| ^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:40:49
|
LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize {
| ^ help: consider giving it an explicit bounded or 'static lifetime: `&'static`
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
help: consider using the `'a` lifetime
|
LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &'a isize {
| ^^^
error: aborting due to 6 previous errors

View File

@ -25,13 +25,13 @@ LL | default impl !Send for Z {}
| default because of this
error[E0750]: negative impls cannot be default impls
--> $DIR/validation.rs:10:14
--> $DIR/validation.rs:10:1
|
LL | default impl !Send for Z {}
| ^^^^^^^ ^
error[E0750]: negative impls cannot be default impls
--> $DIR/validation.rs:14:14
--> $DIR/validation.rs:14:1
|
LL | default impl !Tr for S {}
| ^^^^^^^ ^

View File

@ -0,0 +1,65 @@
#![allow(bare_trait_objects)]
use std::collections::HashMap;
use std::cell::RefCell;
pub union Foo<'t, 'k> {
i: &'t i64,
f: &'k f64,
}
trait Bar<'t, 'k> {}
pub union Qux<'t, 'k, I> {
i: &'t I,
f: &'k I,
}
trait Tar<'t, 'k, I> {}
thread_local! {
static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
//~^ ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
}
thread_local! {
static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
//~^ ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR the lifetime bound for this object type cannot be deduced from context
//~| ERROR the lifetime bound for this object type cannot be deduced from context
}
thread_local! {
static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
//~^ ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
}
thread_local! {
static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
//~^ ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR the lifetime bound for this object type cannot be deduced from context
//~| ERROR the lifetime bound for this object type cannot be deduced from context
}
thread_local! {
static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
//~^ ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
}
thread_local! {
static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
//~^ ERROR the lifetime bound for this object type cannot be deduced from context
//~| ERROR the lifetime bound for this object type cannot be deduced from context
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
}
fn main() {}

View File

@ -0,0 +1,256 @@
error[E0106]: missing lifetime specifiers
--> $DIR/missing-lifetime-specifier.rs:18:44
|
LL | static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
| ^^^ expected 2 lifetime parameters
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static a: RefCell<HashMap<i32, Vec<Vec<Foo<'static, 'static>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifiers
--> $DIR/missing-lifetime-specifier.rs:18:44
|
LL | static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
| ^^^ expected 2 lifetime parameters
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static a: RefCell<HashMap<i32, Vec<Vec<Foo<'static, 'static>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-specifier.rs:23:44
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&'static Bar>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
error[E0106]: missing lifetime specifiers
--> $DIR/missing-lifetime-specifier.rs:23:45
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
| ^^^ expected 2 lifetime parameters
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar<'static, 'static>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-specifier.rs:23:44
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&'static Bar>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
error[E0106]: missing lifetime specifiers
--> $DIR/missing-lifetime-specifier.rs:23:45
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
| ^^^ expected 2 lifetime parameters
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar<'static, 'static>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifiers
--> $DIR/missing-lifetime-specifier.rs:32:48
|
LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
| ^ expected 2 lifetime parameters
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifiers
--> $DIR/missing-lifetime-specifier.rs:32:48
|
LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
| ^ expected 2 lifetime parameters
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-specifier.rs:37:44
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
error[E0106]: missing lifetime specifiers
--> $DIR/missing-lifetime-specifier.rs:37:49
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^ expected 2 lifetime parameters
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-specifier.rs:37:44
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
error[E0106]: missing lifetime specifiers
--> $DIR/missing-lifetime-specifier.rs:37:49
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^ expected 2 lifetime parameters
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-specifier.rs:54:44
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/missing-lifetime-specifier.rs:54:44
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:23:45
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
| ^^^
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:23:45
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
| ^^^
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:37:45
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:37:45
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:47:44
|
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:47:44
|
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:47:44
|
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:47:44
|
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:54:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:54:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:54:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:54:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:54:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
--> $DIR/missing-lifetime-specifier.rs:54:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
error: aborting due to 28 previous errors
Some errors have detailed explanations: E0106, E0107.
For more information about an error, try `rustc --explain E0106`.

View File

@ -2,23 +2,36 @@ error[E0106]: missing lifetime specifier
--> $DIR/return-without-lifetime.rs:2:16
|
LL | struct Foo<'a>(&usize);
| ^ help: consider using the named lifetime: `&'a`
| ^ expected named lifetime parameter
|
help: consider using the `'a` lifetime
|
LL | struct Foo<'a>(&'a usize);
| ^^^
error[E0106]: missing lifetime specifier
--> $DIR/return-without-lifetime.rs:5:34
|
LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() }
| --------- ^ help: consider using the named lifetime: `&'a`
| --------- ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from
help: consider using the `'a` lifetime
|
LL | fn func1<'a>(_arg: &'a Thing) -> &'a () { unimplemented!() }
| ^^^
error[E0106]: missing lifetime specifier
--> $DIR/return-without-lifetime.rs:7:35
|
LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() }
| ---------- ^ help: consider using the named lifetime: `&'a`
| ---------- ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from
help: consider using the `'a` lifetime
|
LL | fn func2<'a>(_arg: &Thing<'a>) -> &'a () { unimplemented!() }
| ^^^
error: aborting due to 3 previous errors

View File

@ -1,5 +1,5 @@
error[E0750]: negative impls cannot be default impls
--> $DIR/negative-default-impls.rs:8:14
--> $DIR/negative-default-impls.rs:8:1
|
LL | default impl !MyTrait for u32 {}
| ^^^^^^^ ^

View File

@ -2,7 +2,7 @@ error[E0658]: parenthetical notation is only stable when used with `Fn`-family t
--> $DIR/unboxed-closure-feature-gate.rs:13:20
|
LL | let x: Box<dyn Foo(isize)>;
| ^^^
| ^^^^^^^^^^
|
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable

View File

@ -2,7 +2,7 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
--> $DIR/unboxed-closure-sugar-not-used-on-fn.rs:3:17
|
LL | fn bar1(x: &dyn Fn<(), Output=()>) {
| ^^ help: use parenthetical notation instead: `Fn() -> ()`
| ^^^^^^^^^^^^^^^^^ help: use parenthetical notation instead: `Fn() -> ()`
|
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
@ -11,7 +11,7 @@ error[E0658]: the precise format of `Fn`-family traits' type parameters is subje
--> $DIR/unboxed-closure-sugar-not-used-on-fn.rs:7:28
|
LL | fn bar2<T>(x: &T) where T: Fn<()> {
| ^^ help: use parenthetical notation instead: `Fn() -> ()`
| ^^^^^^ help: use parenthetical notation instead: `Fn() -> ()`
|
= note: see issue #29625 <https://github.com/rust-lang/rust/issues/29625> for more information
= help: add `#![feature(unboxed_closures)]` to the crate attributes to enable

View File

@ -2,7 +2,7 @@ error[E0107]: wrong number of lifetime arguments: expected 1, found 0
--> $DIR/unboxed-closure-sugar-region.rs:30:51
|
LL | fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) {
| ^^^ expected 1 lifetime argument
| ^^^^^^^^^^ expected 1 lifetime argument
error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error[E0107]: wrong number of type arguments: expected 3, found 1
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs:5:16
|
LL | fn foo(_: &dyn Three())
| ^^^^^ expected 3 type arguments
| ^^^^^^^ expected 3 type arguments
error[E0220]: associated type `Output` not found for `Three<(), [type error], [type error]>`
--> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs:5:16

View File

@ -14,15 +14,24 @@ error[E0106]: missing lifetime specifier
--> $DIR/underscore-lifetime-binders.rs:2:17
|
LL | struct Baz<'a>(&'_ &'a u8);
| ^^ help: consider using the named lifetime: `'a`
| ^^ expected named lifetime parameter
|
help: consider using the `'a` lifetime
|
LL | struct Baz<'a>(&'a &'a u8);
| ^^
error[E0106]: missing lifetime specifier
--> $DIR/underscore-lifetime-binders.rs:10:33
|
LL | fn meh() -> Box<dyn for<'_> Meh<'_>>
| ^^ help: consider giving it a 'static lifetime: `'static`
| ^^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
LL | fn meh() -> Box<dyn for<'_> Meh<'static>>
| ^^^^^^^
error[E0106]: missing lifetime specifier
--> $DIR/underscore-lifetime-binders.rs:16:35

View File

@ -31,7 +31,7 @@ LL | | }
| |_- type parameter `A` must be specified for this
...
LL | let e = Bar::<usize>::lol();
| ^^^ missing reference to `A`
| ^^^^^^^^^^^^^^^^^ missing reference to `A`
|
= note: because of the default `Self` reference, type parameters must be specified on object types

View File

@ -831,12 +831,28 @@ fn extract_gdb_version(full_version_line: &str) -> Option<u32> {
// GDB versions look like this: "major.minor.patch?.yyyymmdd?", with both
// of the ? sections being optional
// We will parse up to 3 digits for minor and patch, ignoring the date
// We limit major to 1 digit, otherwise, on openSUSE, we parse the openSUSE version
// We will parse up to 3 digits for each component, ignoring the date
// We skip text in parentheses. This avoids accidentally parsing
// the openSUSE version, which looks like:
// GNU gdb (GDB; openSUSE Leap 15.0) 8.1
// This particular form is documented in the GNU coding standards:
// https://www.gnu.org/prep/standards/html_node/_002d_002dversion.html#g_t_002d_002dversion
// don't start parsing in the middle of a number
let mut prev_was_digit = false;
let mut in_parens = false;
for (pos, c) in full_version_line.char_indices() {
if in_parens {
if c == ')' {
in_parens = false;
}
continue;
} else if c == '(' {
in_parens = true;
continue;
}
if prev_was_digit || !c.is_digit(10) {
prev_was_digit = c.is_digit(10);
continue;
@ -876,7 +892,7 @@ fn extract_gdb_version(full_version_line: &str) -> Option<u32> {
None => (line, None),
};
if major.len() != 1 || minor.is_empty() {
if minor.is_empty() {
continue;
}

View File

@ -7,9 +7,9 @@ fn test_extract_gdb_version() {
)*}}}
test! {
7000001: "GNU gdb (GDB) CentOS (7.0.1-45.el5.centos)",
7000001: "GNU gdb (GDB) CentOS 7.0.1-45.el5.centos",
7002000: "GNU gdb (GDB) Red Hat Enterprise Linux (7.2-90.el6)",
7002000: "GNU gdb (GDB) Red Hat Enterprise Linux 7.2-90.el6",
7004000: "GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04",
7004001: "GNU gdb (GDB) 7.4.1-debian",