Auto merge of #91418 - matthiaskrgr:rollup-vn9f9w3, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #87160 (When recovering from a `:` in a pattern, use adequate AST pattern)
 - #90985 (Use `get_diagnostic_name` more)
 - #91087 (Remove all migrate.nll.stderr files)
 - #91207 (Add support for LLVM coverage mapping format versions 5 and 6)
 - #91298 (Improve error message for `E0659` if the source is not available)
 - #91346 (Add `Option::inspect` and `Result::{inspect, inspect_err}`)
 - #91404 (Fix bad `NodeId` limit checking.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-12-01 09:51:00 +00:00
commit 26b45573be
53 changed files with 618 additions and 459 deletions

View File

@ -738,15 +738,13 @@ impl BorrowedContentSource<'tcx> {
BorrowedContentSource::DerefRawPointer => "a raw pointer".to_string(),
BorrowedContentSource::DerefSharedRef => "a shared reference".to_string(),
BorrowedContentSource::DerefMutableRef => "a mutable reference".to_string(),
BorrowedContentSource::OverloadedDeref(ty) => match ty.kind() {
ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Rc, def.did) => {
"an `Rc`".to_string()
}
ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Arc, def.did) => {
"an `Arc`".to_string()
}
_ => format!("dereference of `{}`", ty),
},
BorrowedContentSource::OverloadedDeref(ty) => ty
.ty_adt_def()
.and_then(|adt| match tcx.get_diagnostic_name(adt.did)? {
name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
_ => None,
})
.unwrap_or_else(|| format!("dereference of `{}`", ty)),
BorrowedContentSource::OverloadedIndex(ty) => format!("index of `{}`", ty),
}
}
@ -770,15 +768,13 @@ impl BorrowedContentSource<'tcx> {
BorrowedContentSource::DerefMutableRef => {
bug!("describe_for_immutable_place: DerefMutableRef isn't immutable")
}
BorrowedContentSource::OverloadedDeref(ty) => match ty.kind() {
ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Rc, def.did) => {
"an `Rc`".to_string()
}
ty::Adt(def, _) if tcx.is_diagnostic_item(sym::Arc, def.did) => {
"an `Arc`".to_string()
}
_ => format!("a dereference of `{}`", ty),
},
BorrowedContentSource::OverloadedDeref(ty) => ty
.ty_adt_def()
.and_then(|adt| match tcx.get_diagnostic_name(adt.did)? {
name @ (sym::Rc | sym::Arc) => Some(format!("an `{}`", name)),
_ => None,
})
.unwrap_or_else(|| format!("dereference of `{}`", ty)),
BorrowedContentSource::OverloadedIndex(ty) => format!("an index of `{}`", ty),
}
}
@ -960,8 +956,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
_ => None,
});
let is_option_or_result = parent_self_ty.map_or(false, |def_id| {
tcx.is_diagnostic_item(sym::Option, def_id)
|| tcx.is_diagnostic_item(sym::Result, def_id)
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
});
FnSelfUseKind::Normal { self_arg, implicit_into_iter, is_option_or_result }
});

View File

@ -9,6 +9,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
use rustc_hir::def_id::{DefId, DefIdSet};
use rustc_llvm::RustString;
use rustc_middle::mir::coverage::CodeRegion;
use rustc_middle::ty::TyCtxt;
use rustc_span::Symbol;
use std::ffi::CString;
@ -17,10 +18,11 @@ use tracing::debug;
/// Generates and exports the Coverage Map.
///
/// This Coverage Map complies with Coverage Mapping Format version 4 (zero-based encoded as 3),
/// as defined at [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format)
/// and published in Rust's November 2020 fork of LLVM. This version is supported by the LLVM
/// coverage tools (`llvm-profdata` and `llvm-cov`) bundled with Rust's fork of LLVM.
/// Rust Coverage Map generation supports LLVM Coverage Mapping Format versions
/// 5 (LLVM 12, only) and 6 (zero-based encoded as 4 and 5, respectively), as defined at
/// [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format).
/// These versions are supported by the LLVM coverage tools (`llvm-profdata` and `llvm-cov`)
/// bundled with Rust's fork of LLVM.
///
/// Consequently, Rust's bundled version of Clang also generates Coverage Maps compliant with
/// the same version. Clang's implementation of Coverage Map generation was referenced when
@ -30,11 +32,12 @@ use tracing::debug;
pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
let tcx = cx.tcx;
// Ensure LLVM supports Coverage Map Version 4 (encoded as a zero-based value: 3).
// If not, the LLVM Version must be less than 11.
// Ensure the installed version of LLVM supports at least Coverage Map
// Version 5 (encoded as a zero-based value: 4), which was introduced with
// LLVM 12.
let version = coverageinfo::mapping_version();
if version != 3 {
tcx.sess.fatal("rustc option `-Z instrument-coverage` requires LLVM 11 or higher.");
if version < 4 {
tcx.sess.fatal("rustc option `-Z instrument-coverage` requires LLVM 12 or higher.");
}
debug!("Generating coverage map for CodegenUnit: `{}`", cx.codegen_unit.name());
@ -57,7 +60,7 @@ pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) {
return;
}
let mut mapgen = CoverageMapGenerator::new();
let mut mapgen = CoverageMapGenerator::new(tcx, version);
// Encode coverage mappings and generate function records
let mut function_data = Vec::new();
@ -112,8 +115,26 @@ struct CoverageMapGenerator {
}
impl CoverageMapGenerator {
fn new() -> Self {
Self { filenames: FxIndexSet::default() }
fn new(tcx: TyCtxt<'_>, version: u32) -> Self {
let mut filenames = FxIndexSet::default();
if version >= 5 {
// LLVM Coverage Mapping Format version 6 (zero-based encoded as 5)
// requires setting the first filename to the compilation directory.
// Since rustc generates coverage maps with relative paths, the
// compilation directory can be combined with the the relative paths
// to get absolute paths, if needed.
let working_dir = tcx
.sess
.opts
.working_dir
.remapped_path_if_available()
.to_string_lossy()
.to_string();
let c_filename =
CString::new(working_dir).expect("null error converting filename to C string");
filenames.insert(c_filename);
}
Self { filenames }
}
/// Using the `expressions` and `counter_regions` collected for the current function, generate

View File

@ -685,7 +685,7 @@ pub type InlineAsmDiagHandlerTy = unsafe extern "C" fn(&SMDiagnostic, *const c_v
pub mod coverageinfo {
use super::coverage_map;
/// Aligns with [llvm::coverage::CounterMappingRegion::RegionKind](https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L206-L222)
/// Aligns with [llvm::coverage::CounterMappingRegion::RegionKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L209-L230)
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum RegionKind {
@ -704,11 +704,16 @@ pub mod coverageinfo {
/// A GapRegion is like a CodeRegion, but its count is only set as the
/// line execution count when its the only region in the line.
GapRegion = 3,
/// A BranchRegion represents leaf-level boolean expressions and is
/// associated with two counters, each representing the number of times the
/// expression evaluates to true or false.
BranchRegion = 4,
}
/// This struct provides LLVM's representation of a "CoverageMappingRegion", encoded into the
/// coverage map, in accordance with the
/// [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format).
/// [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format).
/// The struct composes fields representing the `Counter` type and value(s) (injected counter
/// ID, or expression type and operands), the source file (an indirect index into a "filenames
/// array", encoded separately), and source location (start and end positions of the represented
@ -721,6 +726,10 @@ pub mod coverageinfo {
/// The counter type and type-dependent counter data, if any.
counter: coverage_map::Counter,
/// If the `RegionKind` is a `BranchRegion`, this represents the counter
/// for the false branch of the region.
false_counter: coverage_map::Counter,
/// An indirect reference to the source filename. In the LLVM Coverage Mapping Format, the
/// file_id is an index into a function-specific `virtual_file_mapping` array of indexes
/// that, in turn, are used to look up the filename for this region.
@ -758,6 +767,7 @@ pub mod coverageinfo {
) -> Self {
Self {
counter,
false_counter: coverage_map::Counter::zero(),
file_id,
expanded_file_id: 0,
start_line,
@ -768,6 +778,31 @@ pub mod coverageinfo {
}
}
// This function might be used in the future; the LLVM API is still evolving, as is coverage
// support.
#[allow(dead_code)]
crate fn branch_region(
counter: coverage_map::Counter,
false_counter: coverage_map::Counter,
file_id: u32,
start_line: u32,
start_col: u32,
end_line: u32,
end_col: u32,
) -> Self {
Self {
counter,
false_counter,
file_id,
expanded_file_id: 0,
start_line,
start_col,
end_line,
end_col,
kind: RegionKind::BranchRegion,
}
}
// This function might be used in the future; the LLVM API is still evolving, as is coverage
// support.
#[allow(dead_code)]
@ -781,6 +816,7 @@ pub mod coverageinfo {
) -> Self {
Self {
counter: coverage_map::Counter::zero(),
false_counter: coverage_map::Counter::zero(),
file_id,
expanded_file_id,
start_line,
@ -803,6 +839,7 @@ pub mod coverageinfo {
) -> Self {
Self {
counter: coverage_map::Counter::zero(),
false_counter: coverage_map::Counter::zero(),
file_id,
expanded_file_id: 0,
start_line,
@ -826,6 +863,7 @@ pub mod coverageinfo {
) -> Self {
Self {
counter,
false_counter: coverage_map::Counter::zero(),
file_id,
expanded_file_id: 0,
start_line,

View File

@ -1,6 +1,6 @@
use rustc_middle::mir::coverage::{CounterValueReference, MappedExpressionIndex};
/// Aligns with [llvm::coverage::Counter::CounterKind](https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L206-L222)
/// Aligns with [llvm::coverage::Counter::CounterKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L95)
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum CounterKind {
@ -17,7 +17,7 @@ pub enum CounterKind {
/// `instrprof.increment()`)
/// * For `CounterKind::Expression`, `id` is the index into the coverage map's array of
/// counter expressions.
/// Aligns with [llvm::coverage::Counter](https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L99-L100)
/// Aligns with [llvm::coverage::Counter](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L102-L103)
/// Important: The Rust struct layout (order and types of fields) must match its C++ counterpart.
#[derive(Copy, Clone, Debug)]
#[repr(C)]
@ -59,7 +59,7 @@ impl Counter {
}
}
/// Aligns with [llvm::coverage::CounterExpression::ExprKind](https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L147)
/// Aligns with [llvm::coverage::CounterExpression::ExprKind](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L150)
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub enum ExprKind {
@ -67,7 +67,7 @@ pub enum ExprKind {
Add = 1,
}
/// Aligns with [llvm::coverage::CounterExpression](https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L148-L149)
/// Aligns with [llvm::coverage::CounterExpression](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L151-L152)
/// Important: The Rust struct layout (order and types of fields) must match its C++
/// counterpart.
#[derive(Copy, Clone, Debug)]

View File

@ -91,16 +91,14 @@ fn enforce_mem_variant_count(cx: &LateContext<'_>, func_expr: &hir::Expr<'_>, sp
impl<'tcx> LateLintPass<'tcx> for EnumIntrinsicsNonEnums {
fn check_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
if let hir::ExprKind::Call(ref func, ref args) = expr.kind {
if let hir::ExprKind::Path(ref qpath) = func.kind {
if let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id() {
if cx.tcx.is_diagnostic_item(sym::mem_discriminant, def_id) {
enforce_mem_discriminant(cx, func, expr.span, args[0].span);
} else if cx.tcx.is_diagnostic_item(sym::mem_variant_count, def_id) {
enforce_mem_variant_count(cx, func, expr.span);
}
}
}
let hir::ExprKind::Call(func, args) = &expr.kind else { return };
let hir::ExprKind::Path(qpath) = &func.kind else { return };
let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id() else { return };
let Some(name) = cx.tcx.get_diagnostic_name(def_id) else { return };
match name {
sym::mem_discriminant => enforce_mem_discriminant(cx, func, expr.span, args[0].span),
sym::mem_variant_count => enforce_mem_variant_count(cx, func, expr.span),
_ => {}
}
}
}

View File

@ -33,6 +33,7 @@
#![cfg_attr(bootstrap, feature(format_args_capture))]
#![feature(iter_order_by)]
#![feature(iter_zip)]
#![feature(let_else)]
#![feature(never_type)]
#![feature(nll)]
#![feature(control_flow_enum)]

View File

@ -309,14 +309,21 @@ fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span,
// Unwrap more levels of macro expansion, as panic_2015!()
// was likely expanded from panic!() and possibly from
// [debug_]assert!().
for &i in
&[sym::std_panic_macro, sym::core_panic_macro, sym::assert_macro, sym::debug_assert_macro]
{
loop {
let parent = expn.call_site.ctxt().outer_expn_data();
if parent.macro_def_id.map_or(false, |id| cx.tcx.is_diagnostic_item(i, id)) {
expn = parent;
panic_macro = i;
let Some(id) = parent.macro_def_id else { break };
let Some(name) = cx.tcx.get_diagnostic_name(id) else { break };
if !matches!(
name,
sym::core_panic_macro
| sym::std_panic_macro
| sym::assert_macro
| sym::debug_assert_macro
) {
break;
}
expn = parent;
panic_macro = name;
}
let macro_symbol =

View File

@ -75,38 +75,36 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
_ => return,
};
// (Re)check that it implements the noop diagnostic.
for s in [sym::noop_method_clone, sym::noop_method_deref, sym::noop_method_borrow].iter() {
if cx.tcx.is_diagnostic_item(*s, i.def_id()) {
let method = &call.ident.name;
let receiver = &elements[0];
let receiver_ty = cx.typeck_results().expr_ty(receiver);
let expr_ty = cx.typeck_results().expr_ty_adjusted(expr);
if receiver_ty != expr_ty {
// This lint will only trigger if the receiver type and resulting expression \
// type are the same, implying that the method call is unnecessary.
return;
}
let expr_span = expr.span;
let note = format!(
"the type `{:?}` which `{}` is being called on is the same as \
the type returned from `{}`, so the method call does not do \
anything and can be removed",
receiver_ty, method, method,
);
let span = expr_span.with_lo(receiver.span.hi());
cx.struct_span_lint(NOOP_METHOD_CALL, span, |lint| {
let method = &call.ident.name;
let message = format!(
"call to `.{}()` on a reference in this situation does nothing",
&method,
);
lint.build(&message)
.span_label(span, "unnecessary method call")
.note(&note)
.emit()
});
}
let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return };
if !matches!(
name,
sym::noop_method_borrow | sym::noop_method_clone | sym::noop_method_deref
) {
return;
}
let method = &call.ident.name;
let receiver = &elements[0];
let receiver_ty = cx.typeck_results().expr_ty(receiver);
let expr_ty = cx.typeck_results().expr_ty_adjusted(expr);
if receiver_ty != expr_ty {
// This lint will only trigger if the receiver type and resulting expression \
// type are the same, implying that the method call is unnecessary.
return;
}
let expr_span = expr.span;
let note = format!(
"the type `{:?}` which `{}` is being called on is the same as \
the type returned from `{}`, so the method call does not do \
anything and can be removed",
receiver_ty, method, method,
);
let span = expr_span.with_lo(receiver.span.hi());
cx.struct_span_lint(NOOP_METHOD_CALL, span, |lint| {
let method = &call.ident.name;
let message =
format!("call to `.{}()` on a reference in this situation does nothing", &method,);
lint.build(&message).span_label(span, "unnecessary method call").note(&note).emit()
});
}
}

View File

@ -10,6 +10,7 @@ using namespace llvm;
struct LLVMRustCounterMappingRegion {
coverage::Counter Count;
coverage::Counter FalseCount;
uint32_t FileID;
uint32_t ExpandedFileID;
uint32_t LineStart;
@ -53,7 +54,7 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
MappingRegions.reserve(NumMappingRegions);
for (const auto &Region : makeArrayRef(RustMappingRegions, NumMappingRegions)) {
MappingRegions.emplace_back(
Region.Count, Region.FileID, Region.ExpandedFileID,
Region.Count, Region.FalseCount, Region.FileID, Region.ExpandedFileID,
Region.LineStart, Region.ColumnStart, Region.LineEnd, Region.ColumnEnd,
Region.Kind);
}
@ -108,5 +109,9 @@ extern "C" void LLVMRustCoverageWriteMappingVarNameToString(RustStringRef Str) {
}
extern "C" uint32_t LLVMRustCoverageMappingVersion() {
return coverage::CovMapVersion::Version4;
#if LLVM_VERSION_GE(13, 0)
return coverage::CovMapVersion::Version6;
#else
return coverage::CovMapVersion::Version5;
#endif
}

View File

@ -21,9 +21,9 @@ rustc_index::newtype_index! {
impl ExpressionOperandId {
/// An expression operand for a "zero counter", as described in the following references:
///
/// * <https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/docs/CoverageMappingFormat.rst#counter>
/// * <https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/docs/CoverageMappingFormat.rst#tag>
/// * <https://github.com/rust-lang/llvm-project/blob/rustc/11.0-2020-10-12/llvm/docs/CoverageMappingFormat.rst#counter-expressions>
/// * <https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#counter>
/// * <https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#tag>
/// * <https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#counter-expressions>
///
/// This operand can be used to count two or more separate code regions with a single counter,
/// if they run sequentially with no branches, by injecting the `Counter` in a `BasicBlock` for

View File

@ -1,6 +1,9 @@
use super::pat::Expected;
use super::ty::AllowPlus;
use super::TokenType;
use super::{BlockMode, Parser, PathStyle, Restrictions, SemiColonMode, SeqSep, TokenExpectType};
use super::{
BlockMode, Parser, PathStyle, RecoverColon, RecoverComma, Restrictions, SemiColonMode, SeqSep,
TokenExpectType, TokenType,
};
use rustc_ast as ast;
use rustc_ast::ptr::P;
@ -19,6 +22,8 @@ use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{MultiSpan, Span, SpanSnippetError, DUMMY_SP};
use std::mem::take;
use tracing::{debug, trace};
const TURBOFISH_SUGGESTION_STR: &str =
@ -2075,4 +2080,177 @@ impl<'a> Parser<'a> {
);
err
}
/// Some special error handling for the "top-level" patterns in a match arm,
/// `for` loop, `let`, &c. (in contrast to subpatterns within such).
crate fn maybe_recover_colon_colon_in_pat_typo(
&mut self,
mut first_pat: P<Pat>,
ra: RecoverColon,
expected: Expected,
) -> P<Pat> {
if RecoverColon::Yes != ra || token::Colon != self.token.kind {
return first_pat;
}
if !matches!(first_pat.kind, PatKind::Ident(_, _, None) | PatKind::Path(..))
|| !self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident())
{
return first_pat;
}
// The pattern looks like it might be a path with a `::` -> `:` typo:
// `match foo { bar:baz => {} }`
let span = self.token.span;
// We only emit "unexpected `:`" error here if we can successfully parse the
// whole pattern correctly in that case.
let snapshot = self.clone();
// Create error for "unexpected `:`".
match self.expected_one_of_not_found(&[], &[]) {
Err(mut err) => {
self.bump(); // Skip the `:`.
match self.parse_pat_no_top_alt(expected) {
Err(mut inner_err) => {
// Carry on as if we had not done anything, callers will emit a
// reasonable error.
inner_err.cancel();
err.cancel();
*self = snapshot;
}
Ok(mut pat) => {
// We've parsed the rest of the pattern.
let new_span = first_pat.span.to(pat.span);
let mut show_sugg = false;
// Try to construct a recovered pattern.
match &mut pat.kind {
PatKind::Struct(qself @ None, path, ..)
| PatKind::TupleStruct(qself @ None, path, _)
| PatKind::Path(qself @ None, path) => match &first_pat.kind {
PatKind::Ident(_, ident, _) => {
path.segments.insert(0, PathSegment::from_ident(ident.clone()));
path.span = new_span;
show_sugg = true;
first_pat = pat;
}
PatKind::Path(old_qself, old_path) => {
path.segments = old_path
.segments
.iter()
.cloned()
.chain(take(&mut path.segments))
.collect();
path.span = new_span;
*qself = old_qself.clone();
first_pat = pat;
show_sugg = true;
}
_ => {}
},
PatKind::Ident(BindingMode::ByValue(Mutability::Not), ident, None) => {
match &first_pat.kind {
PatKind::Ident(_, old_ident, _) => {
let path = PatKind::Path(
None,
Path {
span: new_span,
segments: vec![
PathSegment::from_ident(old_ident.clone()),
PathSegment::from_ident(ident.clone()),
],
tokens: None,
},
);
first_pat = self.mk_pat(new_span, path);
show_sugg = true;
}
PatKind::Path(old_qself, old_path) => {
let mut segments = old_path.segments.clone();
segments.push(PathSegment::from_ident(ident.clone()));
let path = PatKind::Path(
old_qself.clone(),
Path { span: new_span, segments, tokens: None },
);
first_pat = self.mk_pat(new_span, path);
show_sugg = true;
}
_ => {}
}
}
_ => {}
}
if show_sugg {
err.span_suggestion(
span,
"maybe write a path separator here",
"::".to_string(),
Applicability::MaybeIncorrect,
);
} else {
first_pat = self.mk_pat(new_span, PatKind::Wild);
}
err.emit();
}
}
}
_ => {
// Carry on as if we had not done anything. This should be unreachable.
*self = snapshot;
}
};
first_pat
}
/// Some special error handling for the "top-level" patterns in a match arm,
/// `for` loop, `let`, &c. (in contrast to subpatterns within such).
crate fn maybe_recover_unexpected_comma(
&mut self,
lo: Span,
rc: RecoverComma,
) -> PResult<'a, ()> {
if rc == RecoverComma::No || self.token != token::Comma {
return Ok(());
}
// An unexpected comma after a top-level pattern is a clue that the
// user (perhaps more accustomed to some other language) forgot the
// parentheses in what should have been a tuple pattern; return a
// suggestion-enhanced error here rather than choking on the comma later.
let comma_span = self.token.span;
self.bump();
if let Err(mut err) = self.skip_pat_list() {
// We didn't expect this to work anyway; we just wanted to advance to the
// end of the comma-sequence so we know the span to suggest parenthesizing.
err.cancel();
}
let seq_span = lo.to(self.prev_token.span);
let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern");
if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
const MSG: &str = "try adding parentheses to match on a tuple...";
err.span_suggestion(
seq_span,
MSG,
format!("({})", seq_snippet),
Applicability::MachineApplicable,
);
err.span_suggestion(
seq_span,
"...or a vertical bar to match on multiple alternatives",
seq_snippet.replace(",", " |"),
Applicability::MachineApplicable,
);
}
Err(err)
}
/// Parse and throw away a parenthesized comma separated
/// sequence of patterns until `)` is reached.
fn skip_pat_list(&mut self) -> PResult<'a, ()> {
while !self.check(&token::CloseDelim(token::Paren)) {
self.parse_pat_no_top_alt(None)?;
if !self.eat(&token::Comma) {
return Ok(());
}
}
Ok(())
}
}

View File

@ -3,14 +3,16 @@ use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor};
use rustc_ast::ptr::P;
use rustc_ast::token;
use rustc_ast::{self as ast, AttrVec, Attribute, MacCall, Pat, PatField, PatKind, RangeEnd};
use rustc_ast::{BindingMode, Expr, ExprKind, Mutability, Path, QSelf, RangeSyntax};
use rustc_ast::{
self as ast, AttrVec, Attribute, BindingMode, Expr, ExprKind, MacCall, Mutability, Pat,
PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
};
use rustc_ast_pretty::pprust;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, PResult};
use rustc_span::source_map::{respan, Span, Spanned};
use rustc_span::symbol::{kw, sym, Ident};
type Expected = Option<&'static str>;
pub(super) type Expected = Option<&'static str>;
/// `Expected` for function and lambda parameter patterns.
pub(super) const PARAM_EXPECTED: Expected = Some("parameter name");
@ -98,55 +100,9 @@ impl<'a> Parser<'a> {
// If we parsed a leading `|` which should be gated,
// then we should really gate the leading `|`.
// This complicated procedure is done purely for diagnostics UX.
let mut first_pat = first_pat;
if let (RecoverColon::Yes, token::Colon) = (ra, &self.token.kind) {
if matches!(
first_pat.kind,
PatKind::Ident(BindingMode::ByValue(Mutability::Not), _, None)
| PatKind::Path(..)
) && self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident())
{
// The pattern looks like it might be a path with a `::` -> `:` typo:
// `match foo { bar:baz => {} }`
let span = self.token.span;
// We only emit "unexpected `:`" error here if we can successfully parse the
// whole pattern correctly in that case.
let snapshot = self.clone();
// Create error for "unexpected `:`".
match self.expected_one_of_not_found(&[], &[]) {
Err(mut err) => {
self.bump(); // Skip the `:`.
match self.parse_pat_no_top_alt(expected) {
Err(mut inner_err) => {
// Carry on as if we had not done anything, callers will emit a
// reasonable error.
inner_err.cancel();
err.cancel();
*self = snapshot;
}
Ok(pat) => {
// We've parsed the rest of the pattern.
err.span_suggestion(
span,
"maybe write a path separator here",
"::".to_string(),
Applicability::MachineApplicable,
);
err.emit();
first_pat =
self.mk_pat(first_pat.span.to(pat.span), PatKind::Wild);
}
}
}
_ => {
// Carry on as if we had not done anything. This should be unreachable.
*self = snapshot;
}
};
}
}
// Check if the user wrote `foo:bar` instead of `foo::bar`.
let first_pat = self.maybe_recover_colon_colon_in_pat_typo(first_pat, ra, expected);
if let Some(leading_vert_span) = leading_vert_span {
// If there was a leading vert, treat this as an or-pattern. This improves
@ -321,57 +277,6 @@ impl<'a> Parser<'a> {
err.emit();
}
/// Some special error handling for the "top-level" patterns in a match arm,
/// `for` loop, `let`, &c. (in contrast to subpatterns within such).
fn maybe_recover_unexpected_comma(&mut self, lo: Span, rc: RecoverComma) -> PResult<'a, ()> {
if rc == RecoverComma::No || self.token != token::Comma {
return Ok(());
}
// An unexpected comma after a top-level pattern is a clue that the
// user (perhaps more accustomed to some other language) forgot the
// parentheses in what should have been a tuple pattern; return a
// suggestion-enhanced error here rather than choking on the comma later.
let comma_span = self.token.span;
self.bump();
if let Err(mut err) = self.skip_pat_list() {
// We didn't expect this to work anyway; we just wanted to advance to the
// end of the comma-sequence so we know the span to suggest parenthesizing.
err.cancel();
}
let seq_span = lo.to(self.prev_token.span);
let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern");
if let Ok(seq_snippet) = self.span_to_snippet(seq_span) {
const MSG: &str = "try adding parentheses to match on a tuple...";
err.span_suggestion(
seq_span,
MSG,
format!("({})", seq_snippet),
Applicability::MachineApplicable,
);
err.span_suggestion(
seq_span,
"...or a vertical bar to match on multiple alternatives",
seq_snippet.replace(",", " |"),
Applicability::MachineApplicable,
);
}
Err(err)
}
/// Parse and throw away a parenthesized comma separated
/// sequence of patterns until `)` is reached.
fn skip_pat_list(&mut self) -> PResult<'a, ()> {
while !self.check(&token::CloseDelim(token::Paren)) {
self.parse_pat_no_top_alt(None)?;
if !self.eat(&token::Comma) {
return Ok(());
}
}
Ok(())
}
/// A `|` or possibly `||` token shouldn't be here. Ban it.
fn ban_illegal_vert(&mut self, lo: Option<Span>, pos: &str, ctx: &str) {
let span = self.token.span;
@ -1168,7 +1073,7 @@ impl<'a> Parser<'a> {
self.mk_pat(span, PatKind::Ident(bm, ident, None))
}
fn mk_pat(&self, span: Span, kind: PatKind) -> P<Pat> {
pub(super) fn mk_pat(&self, span: Span, kind: PatKind) -> P<Pat> {
P(Pat { kind, span, id: ast::DUMMY_NODE_ID, tokens: None })
}
}

View File

@ -1178,7 +1178,7 @@ impl<'a> Resolver<'a> {
fn binding_description(&self, b: &NameBinding<'_>, ident: Ident, from_prelude: bool) -> String {
let res = b.res();
if b.span.is_dummy() {
if b.span.is_dummy() || self.session.source_map().span_to_snippet(b.span).is_err() {
// These already contain the "built-in" prefix or look bad with it.
let add_built_in =
!matches!(b.res(), Res::NonMacroAttr(..) | Res::PrimTy(..) | Res::ToolMod);

View File

@ -1430,12 +1430,9 @@ impl<'a> Resolver<'a> {
}
pub fn next_node_id(&mut self) -> NodeId {
let next = self
.next_node_id
.as_usize()
.checked_add(1)
.expect("input too large; ran out of NodeIds");
self.next_node_id = ast::NodeId::from_usize(next);
let next =
self.next_node_id.as_u32().checked_add(1).expect("input too large; ran out of NodeIds");
self.next_node_id = ast::NodeId::from_u32(next);
self.next_node_id
}

View File

@ -539,11 +539,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// is otherwise overwhelming and unhelpful (see #85844 for an
// example).
let trait_is_debug =
self.tcx.is_diagnostic_item(sym::Debug, trait_ref.def_id());
let trait_is_display =
self.tcx.is_diagnostic_item(sym::Display, trait_ref.def_id());
let in_std_macro =
match obligation.cause.span.ctxt().outer_expn_data().macro_def_id {
Some(macro_def_id) => {
@ -553,7 +548,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
None => false,
};
if in_std_macro && (trait_is_debug || trait_is_display) {
if in_std_macro
&& matches!(
self.tcx.get_diagnostic_name(trait_ref.def_id()),
Some(sym::Debug | sym::Display)
)
{
err.emit();
return;
}

View File

@ -848,6 +848,31 @@ impl<T> Option<T> {
}
}
/// Calls the provided closure with a reference to the contained value (if [`Some`]).
///
/// # Examples
///
/// ```
/// #![feature(result_option_inspect)]
///
/// let v = vec![1, 2, 3, 4, 5];
///
/// // prints "got: 4"
/// let x: Option<&usize> = v.get(3).inspect(|x| println!("got: {}", x));
///
/// // prints nothing
/// let x: Option<&usize> = v.get(5).inspect(|x| println!("got: {}", x));
/// ```
#[inline]
#[unstable(feature = "result_option_inspect", issue = "91345")]
pub fn inspect<F: FnOnce(&T)>(self, f: F) -> Self {
if let Some(ref x) = self {
f(x);
}
self
}
/// Returns the provided default result (if none),
/// or applies a function to the contained value (if any).
///

View File

@ -854,6 +854,53 @@ impl<T, E> Result<T, E> {
}
}
/// Calls the provided closure with a reference to the contained value (if [`Ok`]).
///
/// # Examples
///
/// ```
/// #![feature(result_option_inspect)]
///
/// let x: u8 = "4"
/// .parse::<u8>()
/// .inspect(|x| println!("original: {}", x))
/// .map(|x| x.pow(3))
/// .expect("failed to parse number");
/// ```
#[inline]
#[unstable(feature = "result_option_inspect", issue = "91345")]
pub fn inspect<F: FnOnce(&T)>(self, f: F) -> Self {
if let Ok(ref t) = self {
f(t);
}
self
}
/// Calls the provided closure with a reference to the contained error (if [`Err`]).
///
/// # Examples
///
/// ```
/// #![feature(result_option_inspect)]
///
/// use std::{fs, io};
///
/// fn read() -> io::Result<String> {
/// fs::read_to_string("address.txt")
/// .inspect_err(|e| eprintln!("failed to read file: {}", e))
/// }
/// ```
#[inline]
#[unstable(feature = "result_option_inspect", issue = "91345")]
pub fn inspect_err<F: FnOnce(&E)>(self, f: F) -> Self {
if let Err(ref e) = self {
f(e);
}
self
}
/////////////////////////////////////////////////////////////////////////
// Iterator constructors
/////////////////////////////////////////////////////////////////////////

View File

@ -20,7 +20,7 @@ This document describes how to enable and use the LLVM instrumentation-based cov
When `-Z instrument-coverage` is enabled, the Rust compiler enhances rust-based libraries and binaries by:
- Automatically injecting calls to an LLVM intrinsic ([`llvm.instrprof.increment`]), at functions and branches in compiled code, to increment counters when conditional sections of code are executed.
- Embedding additional information in the data section of each library and binary (using the [LLVM Code Coverage Mapping Format] _Version 4_, supported _only_ in LLVM 11 and up), to define the code regions (start and end positions in the source code) being counted.
- Embedding additional information in the data section of each library and binary (using the [LLVM Code Coverage Mapping Format] _Version 5_, if compiling with LLVM 12, or _Version 6_, if compiling with LLVM 13 or higher), to define the code regions (start and end positions in the source code) being counted.
When running a coverage-instrumented program, the counter values are written to a `profraw` file at program termination. LLVM bundles tools that read the counter results, combine those results with the coverage map (embedded in the program binary), and generate coverage reports in multiple formats.
@ -123,7 +123,7 @@ If `LLVM_PROFILE_FILE` contains a path to a non-existent directory, the missing
## Installing LLVM coverage tools
LLVM's supplies two tools—`llvm-profdata` and `llvm-cov`—that process coverage data and generate reports. There are several ways to find and/or install these tools, but note that the coverage mapping data generated by the Rust compiler requires LLVM version 11 or higher. (`llvm-cov --version` typically shows the tool's LLVM version number.):
LLVM's supplies two tools—`llvm-profdata` and `llvm-cov`—that process coverage data and generate reports. There are several ways to find and/or install these tools, but note that the coverage mapping data generated by the Rust compiler requires LLVM version 12 or higher. (`llvm-cov --version` typically shows the tool's LLVM version number.):
- The LLVM tools may be installed (or installable) directly to your OS (such as via `apt-get`, for Linux).
- If you are building the Rust compiler from source, you can optionally use the bundled LLVM tools, built from source. Those tool binaries can typically be found in your build platform directory at something like: `rust/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-*`.

View File

@ -1,5 +1,11 @@
# needs-profiler-support
# Rust coverage maps support LLVM Coverage Mapping Format versions 5 and 6,
# corresponding with LLVM versions 12 and 13, respectively.
# When upgrading LLVM versions, consider whether to enforce a minimum LLVM
# version during testing, with an additional directive at the top of this file
# that sets, for example: `min-llvm-version: 12.0`
-include ../coverage/coverage_tools.mk
BASEDIR=../coverage-llvmir

View File

@ -1,6 +1,12 @@
# needs-profiler-support
# ignore-windows-gnu
# Rust coverage maps support LLVM Coverage Mapping Format versions 5 and 6,
# corresponding with LLVM versions 12 and 13, respectively.
# When upgrading LLVM versions, consider whether to enforce a minimum LLVM
# version during testing, with an additional directive at the top of this file
# that sets, for example: `min-llvm-version: 12.0`
# FIXME(mati865): MinGW GCC miscompiles compiler-rt profiling library but with Clang it works
# properly. Since we only have GCC on the CI ignore the test for now.
@ -115,6 +121,7 @@ endif
"$(LLVM_BIN_DIR)"/llvm-cov show \
$(DEBUG_FLAG) \
$(LLVM_COV_IGNORE_FILES) \
--compilation-dir=. \
--Xdemangler="$(RUST_DEMANGLER)" \
--show-line-counts-or-regions \
--instr-profile="$(TMPDIR)"/$@.profdata \

View File

@ -1,5 +1,5 @@
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:19:46
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:17:46
|
LL | pub fn e(x: &'static mut isize) {
| - help: consider changing this to be mutable: `mut x`
@ -8,7 +8,7 @@ LL | let mut c1 = |y: &'static mut isize| x = y;
| ^^^^^ cannot assign
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:30:50
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:28:50
|
LL | pub fn ee(x: &'static mut isize) {
| - help: consider changing this to be mutable: `mut x`
@ -17,7 +17,7 @@ LL | let mut c2 = |y: &'static mut isize| x = y;
| ^^^^^ cannot assign
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:42:14
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:40:14
|
LL | pub fn capture_assign_whole(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
@ -25,7 +25,7 @@ LL | || { x = (1,); };
| ^^^^^^^^ cannot assign
error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:47:14
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:45:14
|
LL | pub fn capture_assign_part(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
@ -33,7 +33,7 @@ LL | || { x.0 = 1; };
| ^^^^^^^ cannot assign
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:52:14
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:50:14
|
LL | pub fn capture_reborrow_whole(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
@ -41,7 +41,7 @@ LL | || { &mut x; };
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:57:14
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:55:14
|
LL | pub fn capture_reborrow_part(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`

View File

@ -1,5 +1,5 @@
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:19:46
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:17:46
|
LL | pub fn e(x: &'static mut isize) {
| - help: consider changing this to be mutable: `mut x`
@ -8,7 +8,7 @@ LL | let mut c1 = |y: &'static mut isize| x = y;
| ^^^^^ cannot assign
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:30:50
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:28:50
|
LL | pub fn ee(x: &'static mut isize) {
| - help: consider changing this to be mutable: `mut x`
@ -17,7 +17,7 @@ LL | let mut c2 = |y: &'static mut isize| x = y;
| ^^^^^ cannot assign
error[E0594]: cannot assign to `x`, as it is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:42:14
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:40:14
|
LL | pub fn capture_assign_whole(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
@ -25,7 +25,7 @@ LL | || { x = (1,); };
| ^^^^^^^^ cannot assign
error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:47:14
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:45:14
|
LL | pub fn capture_assign_part(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
@ -33,7 +33,7 @@ LL | || { x.0 = 1; };
| ^^^^^^^ cannot assign
error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:52:14
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:50:14
|
LL | pub fn capture_reborrow_whole(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`
@ -41,7 +41,7 @@ LL | || { &mut x; };
| ^^^^^^ cannot borrow as mutable
error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:57:14
--> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:55:14
|
LL | pub fn capture_reborrow_part(x: (i32,)) {
| - help: consider changing this to be mutable: `mut x`

View File

@ -3,15 +3,13 @@
// looks at some parent.
// revisions: migrate nll
//[nll]compile-flags: -Z borrowck=mir
// Since we are testing nll (and migration) explicitly as a separate
// revisions, don't worry about the --compare-mode=nll on this test.
// ignore-compare-mode-nll
//[nll]compile-flags: -Z borrowck=mir
// transcribed from borrowck-closures-unique.rs
mod borrowck_closures_unique {
pub fn e(x: &'static mut isize) {

View File

@ -1,32 +0,0 @@
error[E0506]: cannot assign to `greeting` because it is borrowed
--> $DIR/issue-58776-borrowck-scans-children.rs:11:5
|
LL | let res = (|| (|| &greeting)())();
| -- -------- borrow occurs due to use in closure
| |
| borrow of `greeting` occurs here
LL |
LL | greeting = "DEALLOCATED".to_string();
| ^^^^^^^^ assignment to borrowed `greeting` occurs here
...
LL | println!("thread result: {:?}", res);
| --- borrow later used here
error[E0505]: cannot move out of `greeting` because it is borrowed
--> $DIR/issue-58776-borrowck-scans-children.rs:14:10
|
LL | let res = (|| (|| &greeting)())();
| -- -------- borrow occurs due to use in closure
| |
| borrow of `greeting` occurs here
...
LL | drop(greeting);
| ^^^^^^^^ move out of `greeting` occurs here
...
LL | println!("thread result: {:?}", res);
| --- borrow later used here
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0505, E0506.
For more information about an error, try `rustc --explain E0505`.

View File

@ -1,5 +1,5 @@
error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
--> $DIR/E0161.rs:29:5
--> $DIR/E0161.rs:32:5
|
LL | x.f();
| ^^^^^

View File

@ -1,5 +1,5 @@
error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
--> $DIR/E0161.rs:29:5
--> $DIR/E0161.rs:32:5
|
LL | x.f();
| ^^^^^

View File

@ -1,5 +1,5 @@
error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
--> $DIR/E0161.rs:29:5
--> $DIR/E0161.rs:32:5
|
LL | x.f();
| ^^^^^

View File

@ -1,5 +1,3 @@
// ignore-compare-mode-nll
// Check that E0161 is a hard error in all possible configurations that might
// affect it.
@ -13,6 +11,11 @@
//[zflagsul] check-pass
//[editionul] check-pass
// Since we are testing nll (and migration) explicitly as a separate
// revisions, don't worry about the --compare-mode=nll on this test.
// ignore-compare-mode-nll
#![allow(incomplete_features)]
#![cfg_attr(nll, feature(nll))]
#![cfg_attr(nllul, feature(nll))]

View File

@ -1,5 +1,5 @@
error[E0161]: cannot move a value of type dyn Bar: the size of dyn Bar cannot be statically determined
--> $DIR/E0161.rs:29:5
--> $DIR/E0161.rs:32:5
|
LL | x.f();
| ^^^^^

View File

@ -1,5 +1,5 @@
error: implementation of `Parser` is not general enough
--> $DIR/issue-71955.rs:52:5
--> $DIR/issue-71955.rs:57:5
|
LL | foo(bar, "string", |s| s.len() == 5);
| ^^^ implementation of `Parser` is not general enough
@ -8,7 +8,7 @@ LL | foo(bar, "string", |s| s.len() == 5);
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
error: implementation of `Parser` is not general enough
--> $DIR/issue-71955.rs:52:5
--> $DIR/issue-71955.rs:57:5
|
LL | foo(bar, "string", |s| s.len() == 5);
| ^^^ implementation of `Parser` is not general enough
@ -17,7 +17,7 @@ LL | foo(bar, "string", |s| s.len() == 5);
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
error: implementation of `Parser` is not general enough
--> $DIR/issue-71955.rs:52:5
--> $DIR/issue-71955.rs:57:5
|
LL | foo(bar, "string", |s| s.len() == 5);
| ^^^ implementation of `Parser` is not general enough
@ -26,7 +26,7 @@ LL | foo(bar, "string", |s| s.len() == 5);
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
error: implementation of `Parser` is not general enough
--> $DIR/issue-71955.rs:52:5
--> $DIR/issue-71955.rs:57:5
|
LL | foo(bar, "string", |s| s.len() == 5);
| ^^^ implementation of `Parser` is not general enough
@ -35,7 +35,7 @@ LL | foo(bar, "string", |s| s.len() == 5);
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
error: implementation of `Parser` is not general enough
--> $DIR/issue-71955.rs:52:5
--> $DIR/issue-71955.rs:57:5
|
LL | foo(bar, "string", |s| s.len() == 5);
| ^^^ implementation of `Parser` is not general enough
@ -44,7 +44,7 @@ LL | foo(bar, "string", |s| s.len() == 5);
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
error: implementation of `Parser` is not general enough
--> $DIR/issue-71955.rs:58:5
--> $DIR/issue-71955.rs:63:5
|
LL | foo(baz, "string", |s| s.0.len() == 5);
| ^^^ implementation of `Parser` is not general enough
@ -53,7 +53,7 @@ LL | foo(baz, "string", |s| s.0.len() == 5);
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
error: implementation of `Parser` is not general enough
--> $DIR/issue-71955.rs:58:5
--> $DIR/issue-71955.rs:63:5
|
LL | foo(baz, "string", |s| s.0.len() == 5);
| ^^^ implementation of `Parser` is not general enough
@ -62,7 +62,7 @@ LL | foo(baz, "string", |s| s.0.len() == 5);
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
error: implementation of `Parser` is not general enough
--> $DIR/issue-71955.rs:58:5
--> $DIR/issue-71955.rs:63:5
|
LL | foo(baz, "string", |s| s.0.len() == 5);
| ^^^ implementation of `Parser` is not general enough
@ -71,7 +71,7 @@ LL | foo(baz, "string", |s| s.0.len() == 5);
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
error: implementation of `Parser` is not general enough
--> $DIR/issue-71955.rs:58:5
--> $DIR/issue-71955.rs:63:5
|
LL | foo(baz, "string", |s| s.0.len() == 5);
| ^^^ implementation of `Parser` is not general enough
@ -80,7 +80,7 @@ LL | foo(baz, "string", |s| s.0.len() == 5);
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
error: implementation of `Parser` is not general enough
--> $DIR/issue-71955.rs:58:5
--> $DIR/issue-71955.rs:63:5
|
LL | foo(baz, "string", |s| s.0.len() == 5);
| ^^^ implementation of `Parser` is not general enough

View File

@ -1,5 +1,5 @@
error: fatal error triggered by #[rustc_error]
--> $DIR/issue-71955.rs:42:1
--> $DIR/issue-71955.rs:47:1
|
LL | fn main() {
| ^^^^^^^^^

View File

@ -3,6 +3,11 @@
// [nll]compile-flags: -Zborrowck=mir
// check-fail
// Since we are testing nll (and migration) explicitly as a separate
// revisions, don't worry about the --compare-mode=nll on this test.
// ignore-compare-mode-nll
#![feature(rustc_attrs)]
trait Parser<'s> {

View File

@ -1,5 +1,5 @@
error[E0599]: the method `filterx` exists for struct `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>`, but its trait bounds were not satisfied
--> $DIR/issue-30786.rs:128:22
error[E0599]: the method `filterx` exists for struct `Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>`, but its trait bounds were not satisfied
--> $DIR/issue-30786.rs:127:22
|
LL | pub struct Map<S, F> {
| --------------------
@ -8,19 +8,19 @@ LL | pub struct Map<S, F> {
| doesn't satisfy `_: StreamExt`
...
LL | let filter = map.filterx(|x: &_| true);
| ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>` due to unsatisfied trait bounds
| ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>` due to unsatisfied trait bounds
|
note: the following trait bounds were not satisfied because of the requirements of the implementation of `StreamExt` for `_`:
`&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
`&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
`&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
--> $DIR/issue-30786.rs:106:9
`&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
`&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
`&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
--> $DIR/issue-30786.rs:105:9
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
| ^^^^^^^^^ ^
error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>`, but its trait bounds were not satisfied
--> $DIR/issue-30786.rs:141:24
error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>`, but its trait bounds were not satisfied
--> $DIR/issue-30786.rs:140:24
|
LL | pub struct Filter<S, F> {
| -----------------------
@ -29,13 +29,13 @@ LL | pub struct Filter<S, F> {
| doesn't satisfy `_: StreamExt`
...
LL | let count = filter.countx();
| ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>` due to unsatisfied trait bounds
| ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>` due to unsatisfied trait bounds
|
note: the following trait bounds were not satisfied because of the requirements of the implementation of `StreamExt` for `_`:
`&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
`&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
`&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
--> $DIR/issue-30786.rs:106:9
`&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
`&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
`&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
--> $DIR/issue-30786.rs:105:9
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
| ^^^^^^^^^ ^

View File

@ -1,5 +1,5 @@
error[E0599]: the method `filterx` exists for struct `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>`, but its trait bounds were not satisfied
--> $DIR/issue-30786.rs:128:22
error[E0599]: the method `filterx` exists for struct `Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>`, but its trait bounds were not satisfied
--> $DIR/issue-30786.rs:127:22
|
LL | pub struct Map<S, F> {
| --------------------
@ -8,19 +8,19 @@ LL | pub struct Map<S, F> {
| doesn't satisfy `_: StreamExt`
...
LL | let filter = map.filterx(|x: &_| true);
| ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>` due to unsatisfied trait bounds
| ^^^^^^^ method cannot be called on `Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>` due to unsatisfied trait bounds
|
note: the following trait bounds were not satisfied because of the requirements of the implementation of `StreamExt` for `_`:
`&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
`&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
`&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:127:27: 127:36]>: Stream`
--> $DIR/issue-30786.rs:106:9
`&'a mut Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
`&'a mut &Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
`&'a mut &mut Map<Repeat, [closure@$DIR/issue-30786.rs:126:27: 126:36]>: Stream`
--> $DIR/issue-30786.rs:105:9
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
| ^^^^^^^^^ ^
error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>`, but its trait bounds were not satisfied
--> $DIR/issue-30786.rs:141:24
error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>`, but its trait bounds were not satisfied
--> $DIR/issue-30786.rs:140:24
|
LL | pub struct Filter<S, F> {
| -----------------------
@ -29,13 +29,13 @@ LL | pub struct Filter<S, F> {
| doesn't satisfy `_: StreamExt`
...
LL | let count = filter.countx();
| ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>` due to unsatisfied trait bounds
| ^^^^^^ method cannot be called on `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>` due to unsatisfied trait bounds
|
note: the following trait bounds were not satisfied because of the requirements of the implementation of `StreamExt` for `_`:
`&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
`&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
`&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:140:30: 140:42]>: Stream`
--> $DIR/issue-30786.rs:106:9
`&'a mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
`&'a mut &Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
`&'a mut &mut Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>: Stream`
--> $DIR/issue-30786.rs:105:9
|
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
| ^^^^^^^^^ ^

View File

@ -7,6 +7,7 @@
// through again.
// revisions: migrate nll
//[nll]compile-flags: -Z borrowck=mir
// Since we are testing nll (and migration) explicitly as a separate
// revisions, don't worry about the --compare-mode=nll on this test.
@ -14,8 +15,6 @@
// ignore-compare-mode-nll
// ignore-compare-mode-polonius
//[nll]compile-flags: -Z borrowck=mir
pub trait Stream {
type Item;
fn next(self) -> Option<Self::Item>;

View File

@ -1,11 +1,15 @@
// Tests that a suggestion is issued if the user wrote a colon instead of
// a path separator in a match arm.
enum Foo {
Bar,
Baz,
mod qux {
pub enum Foo {
Bar,
Baz,
}
}
use qux::Foo;
fn f() -> Foo { Foo::Bar }
fn g1() {
@ -16,24 +20,24 @@ fn g1() {
_ => {}
}
match f() {
Foo::Bar:Baz => {}
qux::Foo:Bar => {}
//~^ ERROR: expected one of
//~| HELP: maybe write a path separator here
_ => {}
}
match f() {
Foo:Bar::Baz => {}
qux:Foo::Baz => {}
//~^ ERROR: expected one of
//~| HELP: maybe write a path separator here
_ => {}
}
match f() {
Foo: Bar::Baz if true => {}
qux: Foo::Baz if true => {}
//~^ ERROR: expected one of
//~| HELP: maybe write a path separator here
_ => {}
}
if let Bar:Baz = f() {
if let Foo:Bar = f() {
//~^ ERROR: expected one of
//~| HELP: maybe write a path separator here
}
@ -41,16 +45,18 @@ fn g1() {
fn g1_neg() {
match f() {
ref Foo: Bar::Baz => {}
ref qux: Foo::Baz => {}
//~^ ERROR: expected one of
//~| HELP: maybe write a path separator here
_ => {}
}
}
fn g2_neg() {
match f() {
mut Foo: Bar::Baz => {}
mut qux: Foo::Baz => {}
//~^ ERROR: expected one of
//~| HELP: maybe write a path separator here
_ => {}
}
}
@ -62,5 +68,12 @@ fn main() {
Foo:Bar::Baz => {}
//~^ ERROR: expected one of
//~| HELP: maybe write a path separator here
//~| ERROR: failed to resolve: `Bar` is a variant, not a module
}
match myfoo {
Foo::Bar => {}
Foo:Bar => {}
//~^ ERROR: expected one of
//~| HELP: maybe write a path separator here
}
}

View File

@ -1,5 +1,5 @@
error: expected one of `@` or `|`, found `:`
--> $DIR/issue-87086-colon-path-sep.rs:13:12
--> $DIR/issue-87086-colon-path-sep.rs:17:12
|
LL | Foo:Bar => {}
| ^
@ -8,55 +8,61 @@ LL | Foo:Bar => {}
| help: maybe write a path separator here: `::`
error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `{`, or `|`, found `:`
--> $DIR/issue-87086-colon-path-sep.rs:19:17
--> $DIR/issue-87086-colon-path-sep.rs:23:17
|
LL | Foo::Bar:Baz => {}
LL | qux::Foo:Bar => {}
| ^
| |
| expected one of 8 possible tokens
| help: maybe write a path separator here: `::`
error: expected one of `@` or `|`, found `:`
--> $DIR/issue-87086-colon-path-sep.rs:25:12
--> $DIR/issue-87086-colon-path-sep.rs:29:12
|
LL | Foo:Bar::Baz => {}
LL | qux:Foo::Baz => {}
| ^
| |
| expected one of `@` or `|`
| help: maybe write a path separator here: `::`
error: expected one of `@` or `|`, found `:`
--> $DIR/issue-87086-colon-path-sep.rs:31:12
--> $DIR/issue-87086-colon-path-sep.rs:35:12
|
LL | Foo: Bar::Baz if true => {}
LL | qux: Foo::Baz if true => {}
| ^
| |
| expected one of `@` or `|`
| help: maybe write a path separator here: `::`
error: expected one of `@` or `|`, found `:`
--> $DIR/issue-87086-colon-path-sep.rs:36:15
--> $DIR/issue-87086-colon-path-sep.rs:40:15
|
LL | if let Bar:Baz = f() {
LL | if let Foo:Bar = f() {
| ^
| |
| expected one of `@` or `|`
| help: maybe write a path separator here: `::`
error: expected one of `=>`, `@`, `if`, or `|`, found `:`
--> $DIR/issue-87086-colon-path-sep.rs:44:16
error: expected one of `@` or `|`, found `:`
--> $DIR/issue-87086-colon-path-sep.rs:48:16
|
LL | ref Foo: Bar::Baz => {}
| ^ expected one of `=>`, `@`, `if`, or `|`
error: expected one of `=>`, `@`, `if`, or `|`, found `:`
--> $DIR/issue-87086-colon-path-sep.rs:52:16
|
LL | mut Foo: Bar::Baz => {}
| ^ expected one of `=>`, `@`, `if`, or `|`
LL | ref qux: Foo::Baz => {}
| ^
| |
| expected one of `@` or `|`
| help: maybe write a path separator here: `::`
error: expected one of `@` or `|`, found `:`
--> $DIR/issue-87086-colon-path-sep.rs:62:12
--> $DIR/issue-87086-colon-path-sep.rs:57:16
|
LL | mut qux: Foo::Baz => {}
| ^
| |
| expected one of `@` or `|`
| help: maybe write a path separator here: `::`
error: expected one of `@` or `|`, found `:`
--> $DIR/issue-87086-colon-path-sep.rs:68:12
|
LL | Foo:Bar::Baz => {}
| ^
@ -64,5 +70,21 @@ LL | Foo:Bar::Baz => {}
| expected one of `@` or `|`
| help: maybe write a path separator here: `::`
error: aborting due to 8 previous errors
error: expected one of `@` or `|`, found `:`
--> $DIR/issue-87086-colon-path-sep.rs:75:12
|
LL | Foo:Bar => {}
| ^
| |
| expected one of `@` or `|`
| help: maybe write a path separator here: `::`
error[E0433]: failed to resolve: `Bar` is a variant, not a module
--> $DIR/issue-87086-colon-path-sep.rs:68:13
|
LL | Foo:Bar::Baz => {}
| ^^^ `Bar` is a variant, not a module
error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0433`.

View File

@ -1,15 +0,0 @@
error: lifetime may not live long enough
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:39:12
|
LL | fn with_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
error: aborting due to previous error

View File

@ -1,16 +1,16 @@
error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:39:12
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:44:12
|
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the pointer is valid for the lifetime `'a` as defined here
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:33:15
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:38:15
|
LL | fn with_assoc<'a,'b>() {
| ^^
note: but the referenced data is only valid for the lifetime `'b` as defined here
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:33:18
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:38:18
|
LL | fn with_assoc<'a,'b>() {
| ^^

View File

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:39:12
--> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:44:12
|
LL | fn with_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here

View File

@ -6,6 +6,11 @@
// revisions: migrate nll
//[nll]compile-flags: -Z borrowck=mir
// Since we are testing nll (and migration) explicitly as a separate
// revisions, don't worry about the --compare-mode=nll on this test.
// ignore-compare-mode-nll
#![allow(dead_code)]
pub trait TheTrait {

View File

@ -1,39 +0,0 @@
error: lifetime may not live long enough
--> $DIR/regions-free-region-ordering-caller.rs:11:12
|
LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | let z: Option<&'b &'a usize> = None;
| ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
|
= help: consider adding the following bound: `'a: 'b`
error: lifetime may not live long enough
--> $DIR/regions-free-region-ordering-caller.rs:17:12
|
LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | let y: Paramd<'a> = Paramd { x: a };
LL | let z: Option<&'b Paramd<'a>> = None;
| ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'b`
|
= help: consider adding the following bound: `'a: 'b`
error: lifetime may not live long enough
--> $DIR/regions-free-region-ordering-caller.rs:22:12
|
LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | let z: Option<&'a &'b usize> = None;
| ^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
error: aborting due to 3 previous errors

View File

@ -1,50 +1,50 @@
error[E0491]: in type `&'b &'a usize`, reference has a longer lifetime than the data it references
--> $DIR/regions-free-region-ordering-caller.rs:11:12
--> $DIR/regions-free-region-ordering-caller.rs:16:12
|
LL | let z: Option<&'b &'a usize> = None;
| ^^^^^^^^^^^^^^^^^^^^^
|
note: the pointer is valid for the lifetime `'b` as defined here
--> $DIR/regions-free-region-ordering-caller.rs:10:14
--> $DIR/regions-free-region-ordering-caller.rs:15:14
|
LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
| ^^
note: but the referenced data is only valid for the lifetime `'a` as defined here
--> $DIR/regions-free-region-ordering-caller.rs:10:10
--> $DIR/regions-free-region-ordering-caller.rs:15:10
|
LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
| ^^
error[E0491]: in type `&'b Paramd<'a>`, reference has a longer lifetime than the data it references
--> $DIR/regions-free-region-ordering-caller.rs:17:12
--> $DIR/regions-free-region-ordering-caller.rs:22:12
|
LL | let z: Option<&'b Paramd<'a>> = None;
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: the pointer is valid for the lifetime `'b` as defined here
--> $DIR/regions-free-region-ordering-caller.rs:15:14
--> $DIR/regions-free-region-ordering-caller.rs:20:14
|
LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
| ^^
note: but the referenced data is only valid for the lifetime `'a` as defined here
--> $DIR/regions-free-region-ordering-caller.rs:15:10
--> $DIR/regions-free-region-ordering-caller.rs:20:10
|
LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
| ^^
error[E0491]: in type `&'a &'b usize`, reference has a longer lifetime than the data it references
--> $DIR/regions-free-region-ordering-caller.rs:22:12
--> $DIR/regions-free-region-ordering-caller.rs:27:12
|
LL | let z: Option<&'a &'b usize> = None;
| ^^^^^^^^^^^^^^^^^^^^^
|
note: the pointer is valid for the lifetime `'a` as defined here
--> $DIR/regions-free-region-ordering-caller.rs:21:10
--> $DIR/regions-free-region-ordering-caller.rs:26:10
|
LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
| ^^
note: but the referenced data is only valid for the lifetime `'b` as defined here
--> $DIR/regions-free-region-ordering-caller.rs:21:14
--> $DIR/regions-free-region-ordering-caller.rs:26:14
|
LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
| ^^

View File

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/regions-free-region-ordering-caller.rs:11:12
--> $DIR/regions-free-region-ordering-caller.rs:16:12
|
LL | fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {
| -- -- lifetime `'b` defined here
@ -11,7 +11,7 @@ LL | let z: Option<&'b &'a usize> = None;
= help: consider adding the following bound: `'a: 'b`
error: lifetime may not live long enough
--> $DIR/regions-free-region-ordering-caller.rs:17:12
--> $DIR/regions-free-region-ordering-caller.rs:22:12
|
LL | fn call3<'a, 'b>(a: &'a usize, b: &'b usize) {
| -- -- lifetime `'b` defined here
@ -24,7 +24,7 @@ LL | let z: Option<&'b Paramd<'a>> = None;
= help: consider adding the following bound: `'a: 'b`
error: lifetime may not live long enough
--> $DIR/regions-free-region-ordering-caller.rs:22:12
--> $DIR/regions-free-region-ordering-caller.rs:27:12
|
LL | fn call4<'a, 'b>(a: &'a usize, b: &'b usize) {
| -- -- lifetime `'b` defined here

View File

@ -5,6 +5,11 @@
// revisions: migrate nll
//[nll]compile-flags: -Z borrowck=mir
// Since we are testing nll (and migration) explicitly as a separate
// revisions, don't worry about the --compare-mode=nll on this test.
// ignore-compare-mode-nll
struct Paramd<'a> { x: &'a usize }
fn call2<'a, 'b>(a: &'a usize, b: &'b usize) {

View File

@ -1,28 +0,0 @@
error: lifetime may not live long enough
--> $DIR/regions-outlives-projection-container-hrtb.rs:30:12
|
LL | fn with_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | let _: &'a WithHrAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
error: lifetime may not live long enough
--> $DIR/regions-outlives-projection-container-hrtb.rs:50:12
|
LL | fn with_assoc_sub<'a,'b>() {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | let _: &'a WithHrAssocSub<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
error: aborting due to 2 previous errors

View File

@ -1,33 +1,33 @@
error[E0491]: in type `&'a WithHrAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
--> $DIR/regions-outlives-projection-container-hrtb.rs:30:12
--> $DIR/regions-outlives-projection-container-hrtb.rs:35:12
|
LL | let _: &'a WithHrAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the pointer is valid for the lifetime `'a` as defined here
--> $DIR/regions-outlives-projection-container-hrtb.rs:27:15
--> $DIR/regions-outlives-projection-container-hrtb.rs:32:15
|
LL | fn with_assoc<'a,'b>() {
| ^^
note: but the referenced data is only valid for the lifetime `'b` as defined here
--> $DIR/regions-outlives-projection-container-hrtb.rs:27:18
--> $DIR/regions-outlives-projection-container-hrtb.rs:32:18
|
LL | fn with_assoc<'a,'b>() {
| ^^
error[E0491]: in type `&'a WithHrAssocSub<TheType<'b>>`, reference has a longer lifetime than the data it references
--> $DIR/regions-outlives-projection-container-hrtb.rs:50:12
--> $DIR/regions-outlives-projection-container-hrtb.rs:55:12
|
LL | let _: &'a WithHrAssocSub<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the pointer is valid for the lifetime `'a` as defined here
--> $DIR/regions-outlives-projection-container-hrtb.rs:46:19
--> $DIR/regions-outlives-projection-container-hrtb.rs:51:19
|
LL | fn with_assoc_sub<'a,'b>() {
| ^^
note: but the referenced data is only valid for the lifetime `'b` as defined here
--> $DIR/regions-outlives-projection-container-hrtb.rs:46:22
--> $DIR/regions-outlives-projection-container-hrtb.rs:51:22
|
LL | fn with_assoc_sub<'a,'b>() {
| ^^

View File

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/regions-outlives-projection-container-hrtb.rs:30:12
--> $DIR/regions-outlives-projection-container-hrtb.rs:35:12
|
LL | fn with_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here
@ -12,7 +12,7 @@ LL | let _: &'a WithHrAssoc<TheType<'b>> = loop { };
= help: consider adding the following bound: `'b: 'a`
error: lifetime may not live long enough
--> $DIR/regions-outlives-projection-container-hrtb.rs:50:12
--> $DIR/regions-outlives-projection-container-hrtb.rs:55:12
|
LL | fn with_assoc_sub<'a,'b>() {
| -- -- lifetime `'b` defined here

View File

@ -4,6 +4,11 @@
// revisions: migrate nll
//[nll]compile-flags: -Z borrowck=mir
// Since we are testing nll (and migration) explicitly as a separate
// revisions, don't worry about the --compare-mode=nll on this test.
// ignore-compare-mode-nll
#![allow(dead_code)]
pub trait TheTrait<'b> {

View File

@ -1,15 +0,0 @@
error: lifetime may not live long enough
--> $DIR/regions-outlives-projection-container-wc.rs:33:12
|
LL | fn with_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
error: aborting due to previous error

View File

@ -1,16 +1,16 @@
error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references
--> $DIR/regions-outlives-projection-container-wc.rs:33:12
--> $DIR/regions-outlives-projection-container-wc.rs:38:12
|
LL | let _: &'a WithAssoc<TheType<'b>> = loop { };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: the pointer is valid for the lifetime `'a` as defined here
--> $DIR/regions-outlives-projection-container-wc.rs:27:15
--> $DIR/regions-outlives-projection-container-wc.rs:32:15
|
LL | fn with_assoc<'a,'b>() {
| ^^
note: but the referenced data is only valid for the lifetime `'b` as defined here
--> $DIR/regions-outlives-projection-container-wc.rs:27:18
--> $DIR/regions-outlives-projection-container-wc.rs:32:18
|
LL | fn with_assoc<'a,'b>() {
| ^^

View File

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/regions-outlives-projection-container-wc.rs:33:12
--> $DIR/regions-outlives-projection-container-wc.rs:38:12
|
LL | fn with_assoc<'a,'b>() {
| -- -- lifetime `'b` defined here

View File

@ -6,6 +6,11 @@
// revisions: migrate nll
//[nll]compile-flags: -Z borrowck=mir
// Since we are testing nll (and migration) explicitly as a separate
// revisions, don't worry about the --compare-mode=nll on this test.
// ignore-compare-mode-nll
#![allow(dead_code)]
pub trait TheTrait {