Auto merge of #96369 - matthiaskrgr:rollup-q18w4v2, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - #95395 (Better error message for `_` in function signature in `impl Trait for Ty`)
 - #96090 (Implement MIR opt unit tests)
 - #96107 ([test] Add test cases for untested functions for VecDeque)
 - #96212 (Use revisions instead of nll compare mode for `/regions/` ui tests)
 - #96215 (Drop support for legacy PM with LLVM 15)
 - #96366 (bootstrap: Remove dead code in rustdoc shim)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-04-24 22:20:56 +00:00
commit 1f631e8e93
206 changed files with 1602 additions and 621 deletions

View file

@ -625,7 +625,7 @@ pub(crate) fn run_pass_manager(
if thin {
llvm::LLVMRustPassManagerBuilderPopulateThinLTOPassManager(b, pm);
} else {
llvm::LLVMPassManagerBuilderPopulateLTOPassManager(
llvm::LLVMRustPassManagerBuilderPopulateLTOPassManager(
b, pm, /* Internalize = */ False, /* RunInliner = */ True,
);
}

View file

@ -523,6 +523,12 @@ pub(crate) unsafe fn optimize(
let module_name = module.name.clone();
let module_name = Some(&module_name[..]);
if let Some(false) = config.new_llvm_pass_manager && llvm_util::get_version() >= (15, 0, 0) {
diag_handler.warn(
"ignoring `-Z new-llvm-pass-manager=no`, which is no longer supported with LLVM 15",
);
}
if config.emit_no_opt_bc {
let out = cgcx.output_filenames.temp_path_ext("no-opt.bc", module_name);
let out = path_to_c_string(&out);
@ -628,8 +634,8 @@ pub(crate) unsafe fn optimize(
extra_passes.as_ptr(),
extra_passes.len() as size_t,
);
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm);
llvm::LLVMRustPassManagerBuilderPopulateFunctionPassManager(b, fpm);
llvm::LLVMRustPassManagerBuilderPopulateModulePassManager(b, mpm);
});
have_name_anon_globals_pass = have_name_anon_globals_pass || prepare_for_thin_lto;
@ -1085,7 +1091,7 @@ pub unsafe fn with_llvm_pmb(
// Create the PassManagerBuilder for LLVM. We configure it with
// reasonable defaults and prepare it to actually populate the pass
// manager.
let builder = llvm::LLVMPassManagerBuilderCreate();
let builder = llvm::LLVMRustPassManagerBuilderCreate();
let opt_size = config.opt_size.map_or(llvm::CodeGenOptSizeNone, |x| to_llvm_opt_settings(x).1);
let inline_threshold = config.inline_threshold;
let pgo_gen_path = get_pgo_gen_path(config);
@ -1102,14 +1108,9 @@ pub unsafe fn with_llvm_pmb(
pgo_gen_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()),
pgo_use_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()),
pgo_sample_use_path.as_ref().map_or(ptr::null(), |s| s.as_ptr()),
opt_size as c_int,
);
llvm::LLVMPassManagerBuilderSetSizeLevel(builder, opt_size as u32);
if opt_size != llvm::CodeGenOptSizeNone {
llvm::LLVMPassManagerBuilderSetDisableUnrollLoops(builder, 1);
}
llvm::LLVMRustAddBuilderLibraryInfo(builder, llmod, config.no_builtins);
// Here we match what clang does (kinda). For O0 we only inline
@ -1118,16 +1119,16 @@ pub unsafe fn with_llvm_pmb(
// thresholds copied from clang.
match (opt_level, opt_size, inline_threshold) {
(.., Some(t)) => {
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, t);
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, t);
}
(llvm::CodeGenOptLevel::Aggressive, ..) => {
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 275);
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 275);
}
(_, llvm::CodeGenOptSizeDefault, _) => {
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 75);
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 75);
}
(_, llvm::CodeGenOptSizeAggressive, _) => {
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 25);
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 25);
}
(llvm::CodeGenOptLevel::None, ..) => {
llvm::LLVMRustAddAlwaysInlinePass(builder, config.emit_lifetime_markers);
@ -1136,12 +1137,12 @@ pub unsafe fn with_llvm_pmb(
llvm::LLVMRustAddAlwaysInlinePass(builder, config.emit_lifetime_markers);
}
(llvm::CodeGenOptLevel::Default, ..) => {
llvm::LLVMPassManagerBuilderUseInlinerWithThreshold(builder, 225);
llvm::LLVMRustPassManagerBuilderUseInlinerWithThreshold(builder, 225);
}
}
f(builder);
llvm::LLVMPassManagerBuilderDispose(builder);
llvm::LLVMRustPassManagerBuilderDispose(builder);
}
// Create a `__imp_<symbol> = &symbol` global for every public static `symbol`.

View file

@ -1825,24 +1825,22 @@ extern "C" {
pub fn LLVMAddAnalysisPasses<'a>(T: &'a TargetMachine, PM: &PassManager<'a>);
pub fn LLVMPassManagerBuilderCreate() -> &'static mut PassManagerBuilder;
pub fn LLVMPassManagerBuilderDispose(PMB: &'static mut PassManagerBuilder);
pub fn LLVMPassManagerBuilderSetSizeLevel(PMB: &PassManagerBuilder, Value: Bool);
pub fn LLVMPassManagerBuilderSetDisableUnrollLoops(PMB: &PassManagerBuilder, Value: Bool);
pub fn LLVMPassManagerBuilderUseInlinerWithThreshold(
pub fn LLVMRustPassManagerBuilderCreate() -> &'static mut PassManagerBuilder;
pub fn LLVMRustPassManagerBuilderDispose(PMB: &'static mut PassManagerBuilder);
pub fn LLVMRustPassManagerBuilderUseInlinerWithThreshold(
PMB: &PassManagerBuilder,
threshold: c_uint,
);
pub fn LLVMPassManagerBuilderPopulateModulePassManager(
pub fn LLVMRustPassManagerBuilderPopulateModulePassManager(
PMB: &PassManagerBuilder,
PM: &PassManager<'_>,
);
pub fn LLVMPassManagerBuilderPopulateFunctionPassManager(
pub fn LLVMRustPassManagerBuilderPopulateFunctionPassManager(
PMB: &PassManagerBuilder,
PM: &PassManager<'_>,
);
pub fn LLVMPassManagerBuilderPopulateLTOPassManager(
pub fn LLVMRustPassManagerBuilderPopulateLTOPassManager(
PMB: &PassManagerBuilder,
PM: &PassManager<'_>,
Internalize: Bool,
@ -2308,6 +2306,7 @@ extern "C" {
PGOGenPath: *const c_char,
PGOUsePath: *const c_char,
PGOSampleUsePath: *const c_char,
SizeLevel: c_int,
);
pub fn LLVMRustAddLibraryInfo<'a>(
PM: &PassManager<'a>,

View file

@ -542,6 +542,11 @@ pub(crate) fn should_use_new_llvm_pass_manager(user_opt: &Option<bool>, target_a
// The new pass manager is enabled by default for LLVM >= 13.
// This matches Clang, which also enables it since Clang 13.
// Since LLVM 15, the legacy pass manager is no longer supported.
if llvm_util::get_version() >= (15, 0, 0) {
return true;
}
// There are some perf issues with the new pass manager when targeting
// s390x with LLVM 13, so enable the new pass manager only with LLVM 14.
// See https://github.com/rust-lang/rust/issues/89609.

View file

@ -752,6 +752,7 @@ fn test_debugging_options_tracking_hash() {
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
tracked!(merge_functions, Some(MergeFunctions::Disabled));
tracked!(mir_emit_retag, true);
tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]);
tracked!(mir_opt_level, Some(4));
tracked!(move_size_limit, Some(4096));
tracked!(mutable_noalias, Some(true));

View file

@ -107,6 +107,7 @@ static LLVMRustPassKind toRust(PassKind Kind) {
}
extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) {
#if LLVM_VERSION_LT(15, 0)
StringRef SR(PassName);
PassRegistry *PR = PassRegistry::getPassRegistry();
@ -115,36 +116,59 @@ extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) {
return wrap(PI->createPass());
}
return nullptr;
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMPassRef LLVMRustCreateAddressSanitizerFunctionPass(bool Recover) {
#if LLVM_VERSION_LT(15, 0)
const bool CompileKernel = false;
const bool UseAfterScope = true;
return wrap(createAddressSanitizerFunctionPass(CompileKernel, Recover, UseAfterScope));
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMPassRef LLVMRustCreateModuleAddressSanitizerPass(bool Recover) {
#if LLVM_VERSION_LT(15, 0)
const bool CompileKernel = false;
return wrap(createModuleAddressSanitizerLegacyPassPass(CompileKernel, Recover));
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool Recover) {
#if LLVM_VERSION_LT(15, 0)
const bool CompileKernel = false;
return wrap(createMemorySanitizerLegacyPassPass(
MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() {
#if LLVM_VERSION_LT(15, 0)
return wrap(createThreadSanitizerLegacyPassPass());
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMPassRef LLVMRustCreateHWAddressSanitizerPass(bool Recover) {
#if LLVM_VERSION_LT(15, 0)
const bool CompileKernel = false;
return wrap(createHWAddressSanitizerLegacyPassPass(CompileKernel, Recover));
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) {
@ -154,10 +178,57 @@ extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) {
}
extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR, LLVMPassRef RustPass) {
#if LLVM_VERSION_LT(15, 0)
assert(RustPass);
Pass *Pass = unwrap(RustPass);
PassManagerBase *PMB = unwrap(PMR);
PMB->add(Pass);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" LLVMPassManagerBuilderRef LLVMRustPassManagerBuilderCreate() {
#if LLVM_VERSION_LT(15, 0)
return LLVMPassManagerBuilderCreate();
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" void LLVMRustPassManagerBuilderDispose(LLVMPassManagerBuilderRef PMB) {
#if LLVM_VERSION_LT(15, 0)
LLVMPassManagerBuilderDispose(PMB);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" void LLVMRustPassManagerBuilderPopulateFunctionPassManager(
LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM) {
#if LLVM_VERSION_LT(15, 0)
LLVMPassManagerBuilderPopulateFunctionPassManager(PMB, PM);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" void LLVMRustPassManagerBuilderPopulateModulePassManager(
LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM) {
#if LLVM_VERSION_LT(15, 0)
LLVMPassManagerBuilderPopulateModulePassManager(PMB, PM);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" void LLVMRustPassManagerBuilderPopulateLTOPassManager(
LLVMPassManagerBuilderRef PMB, LLVMPassManagerRef PM, bool Internalize, bool RunInliner) {
#if LLVM_VERSION_LT(15, 0)
LLVMPassManagerBuilderPopulateLTOPassManager(PMB, PM, Internalize, RunInliner);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C"
@ -165,12 +236,26 @@ void LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
LLVMPassManagerBuilderRef PMBR,
LLVMPassManagerRef PMR
) {
#if LLVM_VERSION_LT(15, 0)
unwrap(PMBR)->populateThinLTOPassManager(*unwrap(PMR));
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C" void LLVMRustPassManagerBuilderUseInlinerWithThreshold(
LLVMPassManagerBuilderRef PMB, unsigned Threshold) {
#if LLVM_VERSION_LT(15, 0)
LLVMPassManagerBuilderUseInlinerWithThreshold(PMB, Threshold);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
extern "C"
void LLVMRustAddLastExtensionPasses(
LLVMPassManagerBuilderRef PMBR, LLVMPassRef *Passes, size_t NumPasses) {
#if LLVM_VERSION_LT(15, 0)
auto AddExtensionPasses = [Passes, NumPasses](
const PassManagerBuilder &Builder, PassManagerBase &PM) {
for (size_t I = 0; I < NumPasses; I++) {
@ -183,6 +268,9 @@ void LLVMRustAddLastExtensionPasses(
AddExtensionPasses);
unwrap(PMBR)->addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
AddExtensionPasses);
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
#ifdef LLVM_COMPONENT_X86
@ -533,12 +621,16 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
extern "C" void LLVMRustConfigurePassManagerBuilder(
LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
const char* PGOGenPath, const char* PGOUsePath, const char* PGOSampleUsePath) {
const char* PGOGenPath, const char* PGOUsePath, const char* PGOSampleUsePath,
int SizeLevel) {
#if LLVM_VERSION_LT(15, 0)
unwrap(PMBR)->MergeFunctions = MergeFunctions;
unwrap(PMBR)->SLPVectorize = SLPVectorize;
unwrap(PMBR)->OptLevel = fromRust(OptLevel);
unwrap(PMBR)->LoopVectorize = LoopVectorize;
unwrap(PMBR)->PrepareForThinLTO = PrepareForThinLTO;
unwrap(PMBR)->SizeLevel = SizeLevel;
unwrap(PMBR)->DisableUnrollLoops = SizeLevel != 0;
if (PGOGenPath) {
assert(!PGOUsePath && !PGOSampleUsePath);
@ -550,6 +642,9 @@ extern "C" void LLVMRustConfigurePassManagerBuilder(
} else if (PGOSampleUsePath) {
unwrap(PMBR)->PGOSampleUse = PGOSampleUsePath;
}
#else
report_fatal_error("Legacy PM not supported with LLVM 15");
#endif
}
// Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`

View file

@ -6,6 +6,7 @@
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Mangler.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFFImportFile.h"
#include "llvm/Object/ObjectFile.h"

View file

@ -77,17 +77,30 @@ pub fn run_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, passes: &[&dyn
let mut cnt = 0;
let validate = tcx.sess.opts.debugging_opts.validate_mir;
let overridden_passes = &tcx.sess.opts.debugging_opts.mir_enable_passes;
trace!(?overridden_passes);
if validate {
validate_body(tcx, body, format!("start of phase transition from {:?}", start_phase));
}
for pass in passes {
if !pass.is_enabled(&tcx.sess) {
continue;
}
let name = pass.name();
if let Some((_, polarity)) = overridden_passes.iter().rev().find(|(s, _)| s == &*name) {
trace!(
pass = %name,
"{} as requested by flag",
if *polarity { "Running" } else { "Not running" },
);
if !polarity {
continue;
}
} else {
if !pass.is_enabled(&tcx.sess) {
continue;
}
}
let dump_enabled = pass.is_mir_dump_enabled();
if dump_enabled {

View file

@ -368,6 +368,8 @@ mod desc {
pub const parse_opt_langid: &str = "a language identifier";
pub const parse_opt_pathbuf: &str = "a path";
pub const parse_list: &str = "a space-separated list of strings";
pub const parse_list_with_polarity: &str =
"a comma-separated list of strings, with elements beginning with + or -";
pub const parse_opt_comma_list: &str = "a comma-separated list of strings";
pub const parse_number: &str = "a number";
pub const parse_opt_number: &str = parse_number;
@ -529,6 +531,19 @@ mod parse {
}
}
crate fn parse_list_with_polarity(slot: &mut Vec<(String, bool)>, v: Option<&str>) -> bool {
match v {
Some(s) => {
for s in s.split(",") {
let Some(pass_name) = s.strip_prefix(&['+', '-'][..]) else { return false };
slot.push((pass_name.to_string(), &s[..1] == "+"));
}
true
}
None => false,
}
}
crate fn parse_location_detail(ld: &mut LocationDetail, v: Option<&str>) -> bool {
if let Some(v) = v {
ld.line = false;
@ -1318,6 +1333,10 @@ options! {
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
(default: no)"),
mir_enable_passes: Vec<(String, bool)> = (Vec::new(), parse_list_with_polarity, [TRACKED],
"use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be \
enabled, overriding all other checks. Passes that are not specified are enabled or \
disabled by other flags as usual."),
mir_opt_level: Option<usize> = (None, parse_opt_number, [TRACKED],
"MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds)"),
move_size_limit: Option<usize> = (None, parse_opt_number, [TRACKED],

View file

@ -2563,40 +2563,77 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// We proactively collect all the inferred type params to emit a single error per fn def.
let mut visitor = HirPlaceholderCollector::default();
for ty in decl.inputs {
visitor.visit_ty(ty);
}
let mut infer_replacements = vec![];
walk_generics(&mut visitor, generics);
let input_tys = decl.inputs.iter().map(|a| self.ty_of_arg(a, None));
let input_tys: Vec<_> = decl
.inputs
.iter()
.enumerate()
.map(|(i, a)| {
if let hir::TyKind::Infer = a.kind && !self.allow_ty_infer() {
if let Some(suggested_ty) =
self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
{
infer_replacements.push((a.span, suggested_ty.to_string()));
return suggested_ty;
}
}
// Only visit the type looking for `_` if we didn't fix the type above
visitor.visit_ty(a);
self.ty_of_arg(a, None)
})
.collect();
let output_ty = match decl.output {
hir::FnRetTy::Return(output) => {
visitor.visit_ty(output);
self.ast_ty_to_ty(output)
if let hir::TyKind::Infer = output.kind
&& !self.allow_ty_infer()
&& let Some(suggested_ty) =
self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None)
{
infer_replacements.push((output.span, suggested_ty.to_string()));
suggested_ty
} else {
visitor.visit_ty(output);
self.ast_ty_to_ty(output)
}
}
hir::FnRetTy::DefaultReturn(..) => tcx.mk_unit(),
};
debug!("ty_of_fn: output_ty={:?}", output_ty);
let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi);
let fn_ty = tcx.mk_fn_sig(input_tys.into_iter(), output_ty, decl.c_variadic, unsafety, abi);
let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
if !self.allow_ty_infer() {
if !self.allow_ty_infer() && !(visitor.0.is_empty() && infer_replacements.is_empty()) {
// We always collect the spans for placeholder types when evaluating `fn`s, but we
// only want to emit an error complaining about them if infer types (`_`) are not
// allowed. `allow_ty_infer` gates this behavior. We check for the presence of
// `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
crate::collect::placeholder_type_error(
let mut diag = crate::collect::placeholder_type_error_diag(
tcx,
ident_span.map(|sp| sp.shrink_to_hi()),
generics.params,
visitor.0,
infer_replacements.iter().map(|(s, _)| *s).collect(),
true,
hir_ty,
"function",
);
if !infer_replacements.is_empty() {
diag.multipart_suggestion(&format!(
"try replacing `_` with the type{} in the corresponding trait method signature",
rustc_errors::pluralize!(infer_replacements.len()),
), infer_replacements, Applicability::MachineApplicable);
}
diag.emit();
}
// Find any late-bound regions declared in return type that do
@ -2624,6 +2661,43 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
bare_fn_ty
}
/// Given a fn_hir_id for a impl function, suggest the type that is found on the
/// corresponding function in the trait that the impl implements, if it exists.
/// If arg_idx is Some, then it corresponds to an input type index, otherwise it
/// corresponds to the return type.
fn suggest_trait_fn_ty_for_impl_fn_infer(
&self,
fn_hir_id: hir::HirId,
arg_idx: Option<usize>,
) -> Option<Ty<'tcx>> {
let tcx = self.tcx();
let hir = tcx.hir();
let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
hir.get(fn_hir_id) else { return None };
let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(i), .. }) =
hir.get(hir.get_parent_node(fn_hir_id)) else { bug!("ImplItem should have Impl parent") };
let trait_ref =
self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty));
let x: &ty::AssocItem = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
tcx,
*ident,
ty::AssocKind::Fn,
trait_ref.def_id,
)?;
let fn_sig = tcx.fn_sig(x.def_id).subst(
tcx,
trait_ref.substs.extend_to(tcx, x.def_id, |param, _| tcx.mk_param_from_def(param)),
);
let ty = if let Some(arg_idx) = arg_idx { fn_sig.input(arg_idx) } else { fn_sig.output() };
Some(tcx.erase_late_bound_regions(ty))
}
fn validate_late_bound_regions(
&self,
constrained_regions: FxHashSet<ty::BoundRegionKind>,

View file

@ -160,6 +160,33 @@ crate fn placeholder_type_error<'tcx>(
return;
}
placeholder_type_error_diag(
tcx,
span,
generics,
placeholder_types,
vec![],
suggest,
hir_ty,
kind,
)
.emit();
}
crate fn placeholder_type_error_diag<'tcx>(
tcx: TyCtxt<'tcx>,
span: Option<Span>,
generics: &[hir::GenericParam<'_>],
placeholder_types: Vec<Span>,
additional_spans: Vec<Span>,
suggest: bool,
hir_ty: Option<&hir::Ty<'_>>,
kind: &'static str,
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
if placeholder_types.is_empty() {
return bad_placeholder(tcx, additional_spans, kind);
}
let type_name = generics.next_type_param_name(None);
let mut sugg: Vec<_> =
placeholder_types.iter().map(|sp| (*sp, (*type_name).to_string())).collect();
@ -182,7 +209,8 @@ crate fn placeholder_type_error<'tcx>(
sugg.push((span, format!(", {}", type_name)));
}
let mut err = bad_placeholder(tcx, placeholder_types, kind);
let mut err =
bad_placeholder(tcx, placeholder_types.into_iter().chain(additional_spans).collect(), kind);
// Suggest, but only if it is not a function in const or static
if suggest {
@ -218,7 +246,8 @@ crate fn placeholder_type_error<'tcx>(
);
}
}
err.emit();
err
}
fn reject_placeholder_type_signatures_in_item<'tcx>(
@ -1868,50 +1897,17 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
generics,
..
})
| ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), ident, generics, .. })
| Item(hir::Item { kind: ItemKind::Fn(sig, generics, _), ident, .. }) => {
match get_infer_ret_ty(&sig.decl.output) {
Some(ty) => {
let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
// Typeck doesn't expect erased regions to be returned from `type_of`.
let fn_sig = tcx.fold_regions(fn_sig, &mut false, |r, _| match *r {
ty::ReErased => tcx.lifetimes.re_static,
_ => r,
});
let fn_sig = ty::Binder::dummy(fn_sig);
infer_return_ty_for_fn_sig(tcx, sig, *ident, generics, def_id, &icx)
}
let mut visitor = HirPlaceholderCollector::default();
visitor.visit_ty(ty);
let mut diag = bad_placeholder(tcx, visitor.0, "return type");
let ret_ty = fn_sig.skip_binder().output();
if !ret_ty.references_error() {
if !ret_ty.is_closure() {
let ret_ty_str = match ret_ty.kind() {
// Suggest a function pointer return type instead of a unique function definition
// (e.g. `fn() -> i32` instead of `fn() -> i32 { f }`, the latter of which is invalid
// syntax)
ty::FnDef(..) => ret_ty.fn_sig(tcx).to_string(),
_ => ret_ty.to_string(),
};
diag.span_suggestion(
ty.span,
"replace with the correct return type",
ret_ty_str,
Applicability::MaybeIncorrect,
);
} else {
// We're dealing with a closure, so we should suggest using `impl Fn` or trait bounds
// to prevent the user from getting a papercut while trying to use the unique closure
// syntax (e.g. `[closure@src/lib.rs:2:5: 2:9]`).
diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
diag.note("for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html");
}
}
diag.emit();
fn_sig
}
None => <dyn AstConv<'_>>::ty_of_fn(
ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), ident, generics, .. }) => {
// Do not try to inference the return type for a impl method coming from a trait
if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) =
tcx.hir().get(tcx.hir().get_parent_node(hir_id))
&& i.of_trait.is_some()
{
<dyn AstConv<'_>>::ty_of_fn(
&icx,
hir_id,
sig.header.unsafety,
@ -1920,7 +1916,9 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
generics,
Some(ident.span),
None,
),
)
} else {
infer_return_ty_for_fn_sig(tcx, sig, *ident, generics, def_id, &icx)
}
}
@ -1982,6 +1980,70 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
}
}
fn infer_return_ty_for_fn_sig<'tcx>(
tcx: TyCtxt<'tcx>,
sig: &hir::FnSig<'_>,
ident: Ident,
generics: &hir::Generics<'_>,
def_id: LocalDefId,
icx: &ItemCtxt<'tcx>,
) -> ty::PolyFnSig<'tcx> {
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
match get_infer_ret_ty(&sig.decl.output) {
Some(ty) => {
let fn_sig = tcx.typeck(def_id).liberated_fn_sigs()[hir_id];
// Typeck doesn't expect erased regions to be returned from `type_of`.
let fn_sig = tcx.fold_regions(fn_sig, &mut false, |r, _| match *r {
ty::ReErased => tcx.lifetimes.re_static,
_ => r,
});
let fn_sig = ty::Binder::dummy(fn_sig);
let mut visitor = HirPlaceholderCollector::default();
visitor.visit_ty(ty);
let mut diag = bad_placeholder(tcx, visitor.0, "return type");
let ret_ty = fn_sig.skip_binder().output();
if !ret_ty.references_error() {
if !ret_ty.is_closure() {
let ret_ty_str = match ret_ty.kind() {
// Suggest a function pointer return type instead of a unique function definition
// (e.g. `fn() -> i32` instead of `fn() -> i32 { f }`, the latter of which is invalid
// syntax)
ty::FnDef(..) => ret_ty.fn_sig(tcx).to_string(),
_ => ret_ty.to_string(),
};
diag.span_suggestion(
ty.span,
"replace with the correct return type",
ret_ty_str,
Applicability::MaybeIncorrect,
);
} else {
// We're dealing with a closure, so we should suggest using `impl Fn` or trait bounds
// to prevent the user from getting a papercut while trying to use the unique closure
// syntax (e.g. `[closure@src/lib.rs:2:5: 2:9]`).
diag.help("consider using an `Fn`, `FnMut`, or `FnOnce` trait bound");
diag.note("for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html");
}
}
diag.emit();
fn_sig
}
None => <dyn AstConv<'_>>::ty_of_fn(
icx,
hir_id,
sig.header.unsafety,
sig.header.abi,
sig.decl,
generics,
Some(ident.span),
None,
),
}
}
fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
let icx = ItemCtxt::new(tcx, def_id);
match tcx.hir().expect_item(def_id.expect_local()).kind {

View file

@ -162,6 +162,300 @@ fn test_insert() {
}
}
#[test]
fn test_get() {
let mut tester = VecDeque::new();
tester.push_back(1);
tester.push_back(2);
tester.push_back(3);
assert_eq!(tester.len(), 3);
assert_eq!(tester.get(1), Some(&2));
assert_eq!(tester.get(2), Some(&3));
assert_eq!(tester.get(0), Some(&1));
assert_eq!(tester.get(3), None);
tester.remove(0);
assert_eq!(tester.len(), 2);
assert_eq!(tester.get(0), Some(&2));
assert_eq!(tester.get(1), Some(&3));
assert_eq!(tester.get(2), None);
}
#[test]
fn test_get_mut() {
let mut tester = VecDeque::new();
tester.push_back(1);
tester.push_back(2);
tester.push_back(3);
assert_eq!(tester.len(), 3);
if let Some(elem) = tester.get_mut(0) {
assert_eq!(*elem, 1);
*elem = 10;
}
if let Some(elem) = tester.get_mut(2) {
assert_eq!(*elem, 3);
*elem = 30;
}
assert_eq!(tester.get(0), Some(&10));
assert_eq!(tester.get(2), Some(&30));
assert_eq!(tester.get_mut(3), None);
tester.remove(2);
assert_eq!(tester.len(), 2);
assert_eq!(tester.get(0), Some(&10));
assert_eq!(tester.get(1), Some(&2));
assert_eq!(tester.get(2), None);
}
#[test]
fn test_swap() {
let mut tester = VecDeque::new();
tester.push_back(1);
tester.push_back(2);
tester.push_back(3);
assert_eq!(tester, [1, 2, 3]);
tester.swap(0, 0);
assert_eq!(tester, [1, 2, 3]);
tester.swap(0, 1);
assert_eq!(tester, [2, 1, 3]);
tester.swap(2, 1);
assert_eq!(tester, [2, 3, 1]);
tester.swap(1, 2);
assert_eq!(tester, [2, 1, 3]);
tester.swap(0, 2);
assert_eq!(tester, [3, 1, 2]);
tester.swap(2, 2);
assert_eq!(tester, [3, 1, 2]);
}
#[test]
#[should_panic = "assertion failed: j < self.len()"]
fn test_swap_panic() {
let mut tester = VecDeque::new();
tester.push_back(1);
tester.push_back(2);
tester.push_back(3);
tester.swap(2, 3);
}
#[test]
fn test_reserve_exact() {
let mut tester: VecDeque<i32> = VecDeque::with_capacity(1);
assert!(tester.capacity() == 1);
tester.reserve_exact(50);
assert!(tester.capacity() >= 51);
tester.reserve_exact(40);
assert!(tester.capacity() >= 51);
tester.reserve_exact(200);
assert!(tester.capacity() >= 200);
}
#[test]
#[should_panic = "capacity overflow"]
fn test_reserve_exact_panic() {
let mut tester: VecDeque<i32> = VecDeque::new();
tester.reserve_exact(usize::MAX);
}
#[test]
fn test_try_reserve_exact() {
let mut tester: VecDeque<i32> = VecDeque::with_capacity(1);
assert!(tester.capacity() == 1);
assert_eq!(tester.try_reserve_exact(100), Ok(()));
assert!(tester.capacity() >= 100);
assert_eq!(tester.try_reserve_exact(50), Ok(()));
assert!(tester.capacity() >= 100);
assert_eq!(tester.try_reserve_exact(200), Ok(()));
assert!(tester.capacity() >= 200);
assert_eq!(tester.try_reserve_exact(0), Ok(()));
assert!(tester.capacity() >= 200);
assert!(tester.try_reserve_exact(usize::MAX).is_err());
}
#[test]
fn test_try_reserve() {
let mut tester: VecDeque<i32> = VecDeque::with_capacity(1);
assert!(tester.capacity() == 1);
assert_eq!(tester.try_reserve(100), Ok(()));
assert!(tester.capacity() >= 100);
assert_eq!(tester.try_reserve(50), Ok(()));
assert!(tester.capacity() >= 100);
assert_eq!(tester.try_reserve(200), Ok(()));
assert!(tester.capacity() >= 200);
assert_eq!(tester.try_reserve(0), Ok(()));
assert!(tester.capacity() >= 200);
assert!(tester.try_reserve(usize::MAX).is_err());
}
#[test]
fn test_contains() {
let mut tester = VecDeque::new();
tester.push_back(1);
tester.push_back(2);
tester.push_back(3);
assert!(tester.contains(&1));
assert!(tester.contains(&3));
assert!(!tester.contains(&0));
assert!(!tester.contains(&4));
tester.remove(0);
assert!(!tester.contains(&1));
assert!(tester.contains(&2));
assert!(tester.contains(&3));
}
#[test]
fn test_rotate_left_right() {
let mut tester: VecDeque<_> = (1..=10).collect();
assert_eq!(tester.len(), 10);
tester.rotate_left(0);
assert_eq!(tester, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
tester.rotate_right(0);
assert_eq!(tester, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
tester.rotate_left(3);
assert_eq!(tester, [4, 5, 6, 7, 8, 9, 10, 1, 2, 3]);
tester.rotate_right(5);
assert_eq!(tester, [9, 10, 1, 2, 3, 4, 5, 6, 7, 8]);
tester.rotate_left(tester.len());
assert_eq!(tester, [9, 10, 1, 2, 3, 4, 5, 6, 7, 8]);
tester.rotate_right(tester.len());
assert_eq!(tester, [9, 10, 1, 2, 3, 4, 5, 6, 7, 8]);
tester.rotate_left(1);
assert_eq!(tester, [10, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
}
#[test]
#[should_panic = "assertion failed: mid <= self.len()"]
fn test_rotate_left_panic() {
let mut tester: VecDeque<_> = (1..=10).collect();
tester.rotate_left(tester.len() + 1);
}
#[test]
#[should_panic = "assertion failed: k <= self.len()"]
fn test_rotate_right_panic() {
let mut tester: VecDeque<_> = (1..=10).collect();
tester.rotate_right(tester.len() + 1);
}
#[test]
fn test_binary_search() {
// If the givin VecDeque is not sorted, the returned result is unspecified and meaningless,
// as this method performs a binary search.
let tester: VecDeque<_> = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
assert_eq!(tester.binary_search(&0), Ok(0));
assert_eq!(tester.binary_search(&5), Ok(5));
assert_eq!(tester.binary_search(&55), Ok(10));
assert_eq!(tester.binary_search(&4), Err(5));
assert_eq!(tester.binary_search(&-1), Err(0));
assert!(matches!(tester.binary_search(&1), Ok(1..=2)));
let tester: VecDeque<_> = [1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3].into();
assert_eq!(tester.binary_search(&1), Ok(0));
assert!(matches!(tester.binary_search(&2), Ok(1..=4)));
assert!(matches!(tester.binary_search(&3), Ok(5..=13)));
assert_eq!(tester.binary_search(&-2), Err(0));
assert_eq!(tester.binary_search(&0), Err(0));
assert_eq!(tester.binary_search(&4), Err(14));
assert_eq!(tester.binary_search(&5), Err(14));
}
#[test]
fn test_binary_search_by() {
// If the givin VecDeque is not sorted, the returned result is unspecified and meaningless,
// as this method performs a binary search.
let tester: VecDeque<_> = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
assert_eq!(tester.binary_search_by(|x| x.cmp(&0)), Ok(0));
assert_eq!(tester.binary_search_by(|x| x.cmp(&5)), Ok(5));
assert_eq!(tester.binary_search_by(|x| x.cmp(&55)), Ok(10));
assert_eq!(tester.binary_search_by(|x| x.cmp(&4)), Err(5));
assert_eq!(tester.binary_search_by(|x| x.cmp(&-1)), Err(0));
assert!(matches!(tester.binary_search_by(|x| x.cmp(&1)), Ok(1..=2)));
}
#[test]
fn test_binary_search_key() {
// If the givin VecDeque is not sorted, the returned result is unspecified and meaningless,
// as this method performs a binary search.
let tester: VecDeque<_> = [
(-1, 0),
(2, 10),
(6, 5),
(7, 1),
(8, 10),
(10, 2),
(20, 3),
(24, 5),
(25, 18),
(28, 13),
(31, 21),
(32, 4),
(54, 25),
]
.into();
assert_eq!(tester.binary_search_by_key(&-1, |&(a, _b)| a), Ok(0));
assert_eq!(tester.binary_search_by_key(&8, |&(a, _b)| a), Ok(4));
assert_eq!(tester.binary_search_by_key(&25, |&(a, _b)| a), Ok(8));
assert_eq!(tester.binary_search_by_key(&54, |&(a, _b)| a), Ok(12));
assert_eq!(tester.binary_search_by_key(&-2, |&(a, _b)| a), Err(0));
assert_eq!(tester.binary_search_by_key(&1, |&(a, _b)| a), Err(1));
assert_eq!(tester.binary_search_by_key(&4, |&(a, _b)| a), Err(2));
assert_eq!(tester.binary_search_by_key(&13, |&(a, _b)| a), Err(6));
assert_eq!(tester.binary_search_by_key(&55, |&(a, _b)| a), Err(13));
assert_eq!(tester.binary_search_by_key(&100, |&(a, _b)| a), Err(13));
let tester: VecDeque<_> = [
(0, 0),
(2, 1),
(6, 1),
(5, 1),
(3, 1),
(1, 2),
(2, 3),
(4, 5),
(5, 8),
(8, 13),
(1, 21),
(2, 34),
(4, 55),
]
.into();
assert_eq!(tester.binary_search_by_key(&0, |&(_a, b)| b), Ok(0));
assert!(matches!(tester.binary_search_by_key(&1, |&(_a, b)| b), Ok(1..=4)));
assert_eq!(tester.binary_search_by_key(&8, |&(_a, b)| b), Ok(8));
assert_eq!(tester.binary_search_by_key(&13, |&(_a, b)| b), Ok(9));
assert_eq!(tester.binary_search_by_key(&55, |&(_a, b)| b), Ok(12));
assert_eq!(tester.binary_search_by_key(&-1, |&(_a, b)| b), Err(0));
assert_eq!(tester.binary_search_by_key(&4, |&(_a, b)| b), Err(7));
assert_eq!(tester.binary_search_by_key(&56, |&(_a, b)| b), Err(13));
assert_eq!(tester.binary_search_by_key(&100, |&(_a, b)| b), Err(13));
}
#[test]
fn make_contiguous_big_tail() {
let mut tester = VecDeque::with_capacity(15);

View file

@ -31,8 +31,8 @@ fn main() {
let mut cmd = Command::new(rustdoc);
// I am not actually sure why it's necessary to pass the sysroot for `--test`,
// but `test --doc --stage 0` is broken without it :(
// cfg(bootstrap)
// NOTE: the `--test` special-casing can be removed when https://github.com/rust-lang/cargo/pull/10594 lands on beta.
if target.is_some() || args.iter().any(|x| x == "--test") {
// The stage0 compiler has a special sysroot distinct from what we
// actually downloaded, so we just always pass the `--sysroot` option,
@ -65,13 +65,6 @@ fn main() {
}
}
// Needed to be able to run all rustdoc tests.
if let Some(ref x) = env::var_os("RUSTDOC_RESOURCE_SUFFIX") {
// This "unstable-options" can be removed when `--resource-suffix` is stabilized
cmd.arg("-Z").arg("unstable-options");
cmd.arg("--resource-suffix").arg(x);
}
if verbose > 1 {
eprintln!(
"rustdoc command: {:?}={:?} {:?}",

View file

@ -1,14 +1,12 @@
// compile-flags: -Z panic-in-drop=abort -O -Z new-llvm-pass-manager=no
// compile-flags: -Z panic-in-drop=abort -O
// ignore-msvc
// Ensure that unwinding code paths are eliminated from the output after
// optimization.
// This test uses -Z new-llvm-pass-manager=no, because the expected optimization does not happen
// on targets using SEH exceptions (i.e. MSVC) anymore. The core issue is that Rust promises that
// the drop_in_place() function can't unwind, but implements it in a way that *can*, because we
// currently go out of our way to allow longjmps, which also use the unwinding mechanism on MSVC
// targets. We should either forbid longjmps, or not assume nounwind, making this optimization
// incompatible with the current behavior of running cleanuppads on longjmp unwinding.
// This test uses ignore-msvc, because the expected optimization does not happen on targets using
// SEH exceptions with the new LLVM pass manager anymore, see
// https://github.com/llvm/llvm-project/issues/51311.
// CHECK-NOT: {{(call|invoke).*}}should_not_appear_in_output

View file

@ -1,4 +1,4 @@
// compile-flags: -C opt-level=0 -Z inline_mir=no
// unit-test: InstCombine
// ignore-wasm32 compiled with panic=abort by default
// EMIT_MIR combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff

View file

@ -23,9 +23,15 @@
}
bb0: {
StorageLive(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
_2 = &((*_1).0: T); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
StorageLive(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
_3 = &((*_1).1: u64); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
StorageLive(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
_4 = &((*_1).2: [f32; 3]); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
StorageLive(_5); // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
StorageLive(_6); // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
StorageLive(_7); // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
- _7 = &(*_2); // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
- _6 = &(*_7); // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
+ _7 = _2; // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9
@ -37,6 +43,10 @@
}
bb1: {
StorageDead(_6); // scope 1 at $DIR/combine_clone_of_primitives.rs:8:8: 8:9
StorageLive(_8); // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
StorageLive(_9); // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
StorageLive(_10); // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
- _10 = &(*_3); // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
- _9 = &(*_10); // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
- _8 = <u64 as Clone>::clone(move _9) -> [return: bb2, unwind: bb4]; // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11
@ -50,6 +60,10 @@
}
bb2: {
StorageDead(_9); // scope 1 at $DIR/combine_clone_of_primitives.rs:9:10: 9:11
StorageLive(_11); // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
StorageLive(_12); // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
StorageLive(_13); // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
- _13 = &(*_4); // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
- _12 = &(*_13); // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
- _11 = <[f32; 3] as Clone>::clone(move _12) -> [return: bb3, unwind: bb4]; // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16
@ -63,10 +77,20 @@
}
bb3: {
StorageDead(_12); // scope 1 at $DIR/combine_clone_of_primitives.rs:10:15: 10:16
Deinit(_0); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
(_0.0: T) = move _5; // scope 1 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
(_0.1: u64) = move _8; // scope 1 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
(_0.2: [f32; 3]) = move _11; // scope 1 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15
StorageDead(_13); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
StorageDead(_11); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
StorageDead(_10); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
StorageDead(_8); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
StorageDead(_7); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
StorageDead(_5); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
StorageDead(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
StorageDead(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
StorageDead(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15
return; // scope 0 at $DIR/combine_clone_of_primitives.rs:6:15: 6:15
}

View file

@ -68,8 +68,10 @@
+ bb3: {
StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch.rs:8:1: 8:2
return; // scope 0 at $DIR/early_otherwise_branch.rs:8:2: 8:2
+ }
+
}
- bb5 (cleanup): {
- resume; // scope 0 at $DIR/early_otherwise_branch.rs:3:1: 8:2
+ bb4: {
+ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:4:5: 4:17
+ switchInt(_7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:4:5: 4:17

View file

@ -32,7 +32,7 @@
StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch.rs:12:16: 12:17
StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch.rs:12:16: 12:17
_8 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:12:11: 12:17
- switchInt(move _8) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb7]; // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17
- switchInt(move _8) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17
+ StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17
+ _11 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17
+ StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17
@ -84,8 +84,8 @@
return; // scope 0 at $DIR/early_otherwise_branch.rs:17:2: 17:2
}
- bb7: {
- unreachable; // scope 0 at $DIR/early_otherwise_branch.rs:15:14: 15:15
- bb7 (cleanup): {
- resume; // scope 0 at $DIR/early_otherwise_branch.rs:11:1: 17:2
+ bb5: {
+ StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17
+ switchInt(_8) -> [0_isize: bb3, 1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17

View file

@ -68,8 +68,10 @@
+ bb3: {
StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch.rs:26:1: 26:2
return; // scope 0 at $DIR/early_otherwise_branch.rs:26:2: 26:2
+ }
+
}
- bb5 (cleanup): {
- resume; // scope 0 at $DIR/early_otherwise_branch.rs:21:1: 26:2
+ bb4: {
+ StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch.rs:22:5: 22:17
+ switchInt(_7) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:22:5: 22:17

View file

@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=4 -Z unsound-mir-opts
// unit-test: EarlyOtherwiseBranch
// EMIT_MIR early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff
fn opt1(x: Option<u32>, y: Option<u32>) -> u32 {
match (x, y) {

View file

@ -90,8 +90,10 @@
+ bb4: {
StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:9:1: 9:2
return; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:9:2: 9:2
+ }
+
}
- bb6 (cleanup): {
- resume; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:4:1: 9:2
+ bb5: {
+ StorageDead(_15); // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:5:5: 5:20
+ switchInt(_10) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_3_element_tuple.rs:5:5: 5:20

View file

@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=4 -Z unsound-mir-opts
// unit-test: EarlyOtherwiseBranch
// EMIT_MIR early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff
fn opt1(x: Option<u32>, y: Option<u32>, z: Option<u32>) -> u32 {

View file

@ -38,25 +38,29 @@
StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:16: 8:17
StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:16: 8:17
_8 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:11: 8:17
switchInt(move _8) -> [0_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:5: 8:17
switchInt(move _8) -> [0_isize: bb1, 1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:5: 8:17
}
bb1: {
_6 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:11: 8:17
switchInt(move _6) -> [0_isize: bb2, otherwise: bb6]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:5: 8:17
switchInt(move _6) -> [0_isize: bb2, 1_isize: bb7, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:5: 8:17
}
bb2: {
_0 = const 3_u32; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:12:25: 12:26
goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:12:25: 12:26
goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:12:25: 12:26
}
bb3: {
_7 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:11: 8:17
switchInt(move _7) -> [0_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:5: 8:17
unreachable; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:11: 8:17
}
bb4: {
_7 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:11: 8:17
switchInt(move _7) -> [0_isize: bb6, 1_isize: bb5, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:5: 8:17
}
bb5: {
StorageLive(_9); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:15: 9:16
_9 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:15: 9:16
StorageLive(_10); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:24: 9:25
@ -64,28 +68,32 @@
_0 = const 0_u32; // scope 1 at $DIR/early_otherwise_branch_noopt.rs:9:31: 9:32
StorageDead(_10); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:31: 9:32
StorageDead(_9); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:31: 9:32
goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:31: 9:32
goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:31: 9:32
}
bb5: {
bb6: {
StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:10:15: 10:16
_11 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:10:15: 10:16
_0 = const 1_u32; // scope 2 at $DIR/early_otherwise_branch_noopt.rs:10:28: 10:29
StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:10:28: 10:29
goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:10:28: 10:29
goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:10:28: 10:29
}
bb6: {
bb7: {
StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:11:21: 11:22
_12 = (((_3.1: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:11:21: 11:22
_0 = const 2_u32; // scope 3 at $DIR/early_otherwise_branch_noopt.rs:11:28: 11:29
StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:11:28: 11:29
goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:11:28: 11:29
goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:11:28: 11:29
}
bb7: {
bb8: {
StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:14:1: 14:2
return; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:14:2: 14:2
}
bb9 (cleanup): {
resume; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:7:1: 14:2
}
}

View file

@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts
// unit-test: EarlyOtherwiseBranch
// must not optimize as it does not follow the pattern of
// left and right hand side being the same variant

View file

@ -19,7 +19,7 @@
bb1: {
_0 = const 0_i32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:25:14: 25:15
return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:25:14: 25:15
goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:25:14: 25:15
}
bb2: {
@ -29,7 +29,7 @@
bb3: {
_0 = const 0_i32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:23:18: 23:19
return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:23:18: 23:19
goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:23:18: 23:19
}
bb4: {
@ -37,7 +37,15 @@
_5 = (((*_2) as Some).0: i32); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:18: 22:19
_0 = _5; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:22:24: 22:25
StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:24: 22:25
return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:24: 22:25
goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:24: 22:25
}
bb5: {
return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:27:2: 27:2
}
bb6 (cleanup): {
resume; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:18:1: 27:2
}
}

View file

@ -19,12 +19,20 @@
bb2: {
_0 = const 1_u32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:38: 13:39
return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:5: 13:52
goto -> bb4; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:5: 13:52
}
bb3: {
_0 = const 2_u32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:49: 13:50
return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:5: 13:52
goto -> bb4; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:5: 13:52
}
bb4: {
return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:14:2: 14:2
}
bb5 (cleanup): {
resume; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:12:1: 14:2
}
}

View file

@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts
// unit-test: EarlyOtherwiseBranch
// Tests various cases that the `early_otherwise_branch` opt should *not* optimize

View file

@ -1,4 +1,4 @@
// compile-flags: -O
// unit-test: SimplifyComparisonIntegral
// EMIT_MIR if_condition_int.opt_u32.SimplifyComparisonIntegral.diff
// EMIT_MIR if_condition_int.opt_negative.SimplifyComparisonIntegral.diff
// EMIT_MIR if_condition_int.opt_char.SimplifyComparisonIntegral.diff

View file

@ -26,5 +26,9 @@
StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:17:25: 17:26
return; // scope 0 at $DIR/if-condition-int.rs:18:2: 18:2
}
bb4 (cleanup): {
resume; // scope 0 at $DIR/if-condition-int.rs:16:1: 18:2
}
}

View file

@ -30,5 +30,9 @@
StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:53:34: 53:35
return; // scope 0 at $DIR/if-condition-int.rs:54:2: 54:2
}
bb4 (cleanup): {
resume; // scope 0 at $DIR/if-condition-int.rs:52:1: 54:2
}
}

View file

@ -54,5 +54,9 @@
StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:49:1: 49:2
return; // scope 0 at $DIR/if-condition-int.rs:49:2: 49:2
}
bb4 (cleanup): {
resume; // scope 0 at $DIR/if-condition-int.rs:43:1: 49:2
}
}

View file

@ -35,5 +35,9 @@
StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:21:32: 21:33
return; // scope 0 at $DIR/if-condition-int.rs:22:2: 22:2
}
bb4 (cleanup): {
resume; // scope 0 at $DIR/if-condition-int.rs:20:1: 22:2
}
}

View file

@ -35,5 +35,9 @@
StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:25:31: 25:32
return; // scope 0 at $DIR/if-condition-int.rs:26:2: 26:2
}
bb4 (cleanup): {
resume; // scope 0 at $DIR/if-condition-int.rs:24:1: 26:2
}
}

View file

@ -61,5 +61,9 @@
StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:39:5: 39:6
return; // scope 0 at $DIR/if-condition-int.rs:40:2: 40:2
}
bb7 (cleanup): {
resume; // scope 0 at $DIR/if-condition-int.rs:32:1: 40:2
}
}

View file

@ -35,5 +35,9 @@
StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:29:32: 29:33
return; // scope 0 at $DIR/if-condition-int.rs:30:2: 30:2
}
bb4 (cleanup): {
resume; // scope 0 at $DIR/if-condition-int.rs:28:1: 30:2
}
}

View file

@ -35,5 +35,9 @@
StorageDead(_2); // scope 0 at $DIR/if-condition-int.rs:12:31: 12:32
return; // scope 0 at $DIR/if-condition-int.rs:13:2: 13:2
}
bb4 (cleanup): {
resume; // scope 0 at $DIR/if-condition-int.rs:11:1: 13:2
}
}

View file

@ -1,4 +1,4 @@
// compile-flags: -Z mir-opt-level=3
// unit-test: LowerSliceLenCalls
// EMIT_MIR lower_slice_len.bound.LowerSliceLenCalls.diff
pub fn bound(index: usize, slice: &[u8]) -> u8 {

View file

@ -1,4 +1,4 @@
// compile-flags: -Zmir-opt-level=1
// unit-test: RenameReturnPlace
// EMIT_MIR nrvo_simple.nrvo.RenameReturnPlace.diff
fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] {

View file

@ -39,5 +39,9 @@
- StorageDead(_2); // scope 0 at $DIR/nrvo-simple.rs:8:1: 8:2
return; // scope 0 at $DIR/nrvo-simple.rs:8:2: 8:2
}
bb2 (cleanup): {
resume; // scope 0 at $DIR/nrvo-simple.rs:4:1: 8:2
}
}

View file

@ -0,0 +1,15 @@
// run-rustfix
#![allow(unused)]
trait Foo<T>: Sized {
fn bar(i: i32, t: T, s: &Self) -> (T, i32);
}
impl Foo<usize> for () {
fn bar(i: i32, t: usize, s: &()) -> (usize, i32) {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
(1, 2)
}
}
fn main() {}

View file

@ -0,0 +1,15 @@
// run-rustfix
#![allow(unused)]
trait Foo<T>: Sized {
fn bar(i: i32, t: T, s: &Self) -> (T, i32);
}
impl Foo<usize> for () {
fn bar(i: _, t: _, s: _) -> _ {
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions
(1, 2)
}
}
fn main() {}

View file

@ -0,0 +1,18 @@
error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
--> $DIR/replace-impl-infer-ty-from-trait.rs:9:15
|
LL | fn bar(i: _, t: _, s: _) -> _ {
| ^ ^ ^ ^ not allowed in type signatures
| | | |
| | | not allowed in type signatures
| | not allowed in type signatures
| not allowed in type signatures
|
help: try replacing `_` with the types in the corresponding trait method signature
|
LL | fn bar(i: i32, t: usize, s: &()) -> (usize, i32) {
| ~~~ ~~~~~ ~~~ ~~~~~~~~~~~~
error: aborting due to previous error
For more information about this error, try `rustc --explain E0121`.

View file

@ -1,16 +1,16 @@
error[E0478]: lifetime bound not satisfied
--> $DIR/issue-28848.rs:10:5
--> $DIR/issue-28848.rs:14:5
|
LL | Foo::<'a, 'b>::xmute(u)
| ^^^^^^^^^^^^^
|
note: lifetime parameter instantiated with the lifetime `'b` as defined here
--> $DIR/issue-28848.rs:9:16
--> $DIR/issue-28848.rs:13:16
|
LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () {
| ^^
note: but lifetime parameter must outlive the lifetime `'a` as defined here
--> $DIR/issue-28848.rs:9:12
--> $DIR/issue-28848.rs:13:12
|
LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () {
| ^^

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/issue-28848.rs:10:5
--> $DIR/issue-28848.rs:14:5
|
LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () {
| -- -- lifetime `'b` defined here

View file

@ -1,3 +1,7 @@
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
struct Foo<'a, 'b: 'a>(&'a &'b ());
impl<'a, 'b> Foo<'a, 'b> {
@ -7,7 +11,9 @@ impl<'a, 'b> Foo<'a, 'b> {
}
pub fn foo<'a, 'b>(u: &'b ()) -> &'a () {
Foo::<'a, 'b>::xmute(u) //~ ERROR lifetime bound not satisfied
Foo::<'a, 'b>::xmute(u)
//[base]~^ ERROR lifetime bound not satisfied
//[nll]~^^ ERROR lifetime may not live long enough
}
fn main() {}

View file

@ -1,5 +1,5 @@
error[E0308]: `if` and `else` have incompatible types
--> $DIR/region-invariant-static-error-reporting.rs:17:9
--> $DIR/region-invariant-static-error-reporting.rs:21:9
|
LL | let bad = if x.is_some() {
| _______________-
@ -14,7 +14,7 @@ LL | | };
= note: expected struct `Invariant<'a>`
found struct `Invariant<'static>`
note: the lifetime `'a` as defined here...
--> $DIR/region-invariant-static-error-reporting.rs:13:10
--> $DIR/region-invariant-static-error-reporting.rs:17:10
|
LL | fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) {
| ^^

View file

@ -1,5 +1,5 @@
error[E0521]: borrowed data escapes outside of function
--> $DIR/region-invariant-static-error-reporting.rs:15:9
--> $DIR/region-invariant-static-error-reporting.rs:19:9
|
LL | fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) {
| -- - `x` is a reference that is only valid in the function body

View file

@ -3,8 +3,12 @@
// over time, but this test used to exhibit some pretty bogus messages
// that were not remotely helpful.
// error-pattern:the lifetime `'a`
// error-pattern:the static lifetime
// revisions: base nll
// ignore-compare-mode-nll
//[base] error-pattern:the lifetime `'a`
//[base] error-pattern:the static lifetime
//[nll] compile-flags: -Z borrowck=mir
//[nll] error-pattern:argument requires that `'a` must outlive `'static`
struct Invariant<'a>(Option<&'a mut &'a mut ()>);
@ -12,9 +16,9 @@ fn mk_static() -> Invariant<'static> { Invariant(None) }
fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) {
let bad = if x.is_some() {
x.unwrap()
x.unwrap() //[nll]~ ERROR borrowed data escapes outside of function [E0521]
} else {
mk_static()
mk_static() //[base]~ ERROR `if` and `else` have incompatible types [E0308]
};
f(bad);
}

View file

@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:8:10
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:12:10
|
LL | fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) {
| --------- --------- these two types are declared with different lifetimes...
@ -8,7 +8,7 @@ LL | *x = *y;
| ^^ ...but data from `y` flows into `x` here
error[E0623]: lifetime mismatch
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:14:7
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:7
|
LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
| --------- --------- these two types are declared with different lifetimes...
@ -17,7 +17,7 @@ LL | a(x, y);
| ^ ...but data from `y` flows into `x` here
error[E0308]: mismatched types
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:43
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:28:43
|
LL | let _: fn(&mut &isize, &mut &isize) = a;
| ^ one type is more general than the other

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:8:5
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:12:5
|
LL | fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) {
| -- -- lifetime `'b` defined here
@ -12,7 +12,7 @@ LL | *x = *y;
= help: consider adding the following bound: `'b: 'a`
error: lifetime may not live long enough
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:14:5
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:5
|
LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
| -- -- lifetime `'b` defined here
@ -28,7 +28,7 @@ LL | a(x, y);
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error[E0308]: mismatched types
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:12
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:28:12
|
LL | let _: fn(&mut &isize, &mut &isize) = a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@ -37,7 +37,7 @@ LL | let _: fn(&mut &isize, &mut &isize) = a;
found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)`
error[E0308]: mismatched types
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:12
--> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:28:12
|
LL | let _: fn(&mut &isize, &mut &isize) = a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other

View file

@ -1,3 +1,7 @@
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
fn a<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) where 'b: 'a {
// Note: this is legal because of the `'b:'a` declaration.
*x = *y;
@ -5,19 +9,25 @@ fn a<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) where 'b: 'a {
fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) {
// Illegal now because there is no `'b:'a` declaration.
*x = *y; //~ ERROR E0623
*x = *y;
//[base]~^ ERROR E0623
//[nll]~^^ ERROR lifetime may not live long enough
}
fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
// Here we try to call `foo` but do not know that `'a` and `'b` are
// related as required.
a(x, y); //~ ERROR lifetime mismatch [E0623]
a(x, y);
//[base]~^ ERROR lifetime mismatch [E0623]
//[nll]~^^ ERROR lifetime may not live long enough
}
fn d() {
// 'a and 'b are early bound in the function `a` because they appear
// inconstraints:
let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR mismatched types
let _: fn(&mut &isize, &mut &isize) = a;
//~^ ERROR mismatched types [E0308]
//[nll]~^^ ERROR mismatched types [E0308]
}
fn e() {

View file

@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:9:10
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:13:10
|
LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
| --------- --------- these two types are declared with different lifetimes...
@ -8,7 +8,7 @@ LL | *x = *y;
| ^^ ...but data from `y` flows into `x` here
error[E0623]: lifetime mismatch
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:10:10
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:16:10
|
LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
| --------- ---------
@ -19,7 +19,7 @@ LL | *z = *y;
| ^^ ...but data from `y` flows into `z` here
error[E0623]: lifetime mismatch
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:16:7
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:7
|
LL | fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
| --------- --------- these two types are declared with different lifetimes...
@ -28,7 +28,7 @@ LL | a(x, y, z);
| ^ ...but data from `y` flows into `x` here
error[E0308]: mismatched types
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:56
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:30:56
|
LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
| ^ one type is more general than the other

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:9:5
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:13:5
|
LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
| -- -- lifetime `'b` defined here
@ -12,7 +12,7 @@ LL | *x = *y;
= help: consider adding the following bound: `'b: 'a`
error: lifetime may not live long enough
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:16:5
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:5
|
LL | fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
| -- -- lifetime `'b` defined here
@ -28,7 +28,7 @@ LL | a(x, y, z);
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error[E0308]: mismatched types
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:30:12
|
LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@ -37,7 +37,7 @@ LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
found fn pointer `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)`
error[E0308]: mismatched types
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:30:12
|
LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
@ -46,7 +46,7 @@ LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
found fn pointer `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)`
error[E0308]: mismatched types
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:30:12
|
LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other

View file

@ -1,82 +0,0 @@
error: lifetime may not live long enough
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:9:5
|
LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | // Illegal now because there is no `'b:'a` declaration.
LL | *x = *y;
| ^^^^^^^ assignment requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
error: lifetime may not live long enough
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:10:5
|
LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
| -- -- lifetime `'c` defined here
| |
| lifetime `'b` defined here
...
LL | *z = *y;
| ^^^^^^^ assignment requires that `'b` must outlive `'c`
|
= help: consider adding the following bound: `'b: 'c`
help: add bound `'b: 'a + 'c`
error: lifetime may not live long enough
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:16:5
|
LL | fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | a(x, y, z);
| ^^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
= note: requirement occurs because of a mutable reference to &isize
= note: mutable references are invariant over their type parameter
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error: lifetime may not live long enough
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:16:5
|
LL | fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
| -- -- lifetime `'c` defined here
| |
| lifetime `'b` defined here
...
LL | a(x, y, z);
| ^^^^^^^^^^ argument requires that `'b` must outlive `'c`
|
= help: consider adding the following bound: `'b: 'c`
= note: requirement occurs because of a mutable reference to &isize
= note: mutable references are invariant over their type parameter
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
help: add bound `'b: 'a + 'c`
error: higher-ranked subtype error
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12
|
LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: higher-ranked subtype error
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12
|
LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: higher-ranked subtype error
--> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12
|
LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 7 previous errors

View file

@ -1,3 +1,7 @@
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
fn a<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) where 'b: 'a + 'c {
// Note: this is legal because of the `'b:'a` declaration.
*x = *y;
@ -6,20 +10,27 @@ fn a<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) where
fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
// Illegal now because there is no `'b:'a` declaration.
*x = *y; //~ ERROR E0623
*z = *y; //~ ERROR E0623
*x = *y;
//[base]~^ ERROR E0623
//[nll]~^^ ERROR lifetime may not live long enough
*z = *y; //[base]~ ERROR E0623
}
fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
// Here we try to call `foo` but do not know that `'a` and `'b` are
// related as required.
a(x, y, z); //~ ERROR lifetime mismatch [E0623]
a(x, y, z);
//[base]~^ ERROR lifetime mismatch [E0623]
//[nll]~^^ ERROR lifetime may not live long enough
}
fn d() {
// 'a and 'b are early bound in the function `a` because they appear
// inconstraints:
let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; //~ ERROR E0308
let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
//~^ ERROR E0308
//[nll]~^^ ERROR mismatched types [E0308]
//[nll]~| ERROR mismatched types [E0308]
}
fn e() {

View file

@ -1,26 +1,26 @@
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> $DIR/region-object-lifetime-2.rs:10:7
--> $DIR/region-object-lifetime-2.rs:14:7
|
LL | x.borrowed()
| ^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
--> $DIR/region-object-lifetime-2.rs:9:42
--> $DIR/region-object-lifetime-2.rs:13:42
|
LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () {
| ^^
note: ...so that reference does not outlive borrowed content
--> $DIR/region-object-lifetime-2.rs:10:5
--> $DIR/region-object-lifetime-2.rs:14:5
|
LL | x.borrowed()
| ^
note: but, the lifetime must be valid for the lifetime `'b` as defined here...
--> $DIR/region-object-lifetime-2.rs:9:45
--> $DIR/region-object-lifetime-2.rs:13:45
|
LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () {
| ^^
note: ...so that reference does not outlive borrowed content
--> $DIR/region-object-lifetime-2.rs:10:5
--> $DIR/region-object-lifetime-2.rs:14:5
|
LL | x.borrowed()
| ^^^^^^^^^^^^

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/region-object-lifetime-2.rs:10:5
--> $DIR/region-object-lifetime-2.rs:14:5
|
LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () {
| -- -- lifetime `'b` defined here

View file

@ -1,13 +1,19 @@
// Various tests related to testing how region inference works
// with respect to the object receivers.
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
trait Foo {
fn borrowed<'a>(&'a self) -> &'a ();
}
// Borrowed receiver but two distinct lifetimes, we get an error.
fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () {
x.borrowed() //~ ERROR cannot infer
x.borrowed()
//[base]~^ ERROR cannot infer
//[nll]~^^ ERROR lifetime may not live long enough
}
fn main() {}

View file

@ -1,26 +1,26 @@
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> $DIR/region-object-lifetime-4.rs:12:7
--> $DIR/region-object-lifetime-4.rs:16:7
|
LL | x.borrowed()
| ^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
--> $DIR/region-object-lifetime-4.rs:11:41
--> $DIR/region-object-lifetime-4.rs:15:41
|
LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () {
| ^^
note: ...so that reference does not outlive borrowed content
--> $DIR/region-object-lifetime-4.rs:12:5
--> $DIR/region-object-lifetime-4.rs:16:5
|
LL | x.borrowed()
| ^
note: but, the lifetime must be valid for the lifetime `'b` as defined here...
--> $DIR/region-object-lifetime-4.rs:11:44
--> $DIR/region-object-lifetime-4.rs:15:44
|
LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () {
| ^^
note: ...so that reference does not outlive borrowed content
--> $DIR/region-object-lifetime-4.rs:12:5
--> $DIR/region-object-lifetime-4.rs:16:5
|
LL | x.borrowed()
| ^^^^^^^^^^^^

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/region-object-lifetime-4.rs:12:5
--> $DIR/region-object-lifetime-4.rs:16:5
|
LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () {
| -- -- lifetime `'b` defined here

View file

@ -1,6 +1,10 @@
// Various tests related to testing how region inference works
// with respect to the object receivers.
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
trait Foo {
fn borrowed<'a>(&'a self) -> &'a ();
}
@ -9,7 +13,9 @@ trait Foo {
// with the longer lifetime when (from the signature) we only know
// that it lives as long as the shorter lifetime. Therefore, error.
fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () {
x.borrowed() //~ ERROR cannot infer
x.borrowed()
//[base]~^ ERROR cannot infer
//[nll]~^^ ERROR lifetime may not live long enough
}
fn main() {}

View file

@ -1,5 +1,5 @@
error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/region-object-lifetime-in-coercion.rs:8:46
--> $DIR/region-object-lifetime-in-coercion.rs:12:46
|
LL | fn a(v: &[u8]) -> Box<dyn Foo + 'static> {
| ----- this data with an anonymous lifetime `'_`...
@ -16,7 +16,7 @@ LL | fn a(v: &'static [u8]) -> Box<dyn Foo + 'static> {
| ~~~~~~~~~~~~~
error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/region-object-lifetime-in-coercion.rs:13:14
--> $DIR/region-object-lifetime-in-coercion.rs:19:14
|
LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
| ----- this data with an anonymous lifetime `'_`...
@ -24,7 +24,7 @@ LL | Box::new(v)
| ^ ...is used and required to live as long as `'static` here
|
note: `'static` lifetime requirement introduced by the return type
--> $DIR/region-object-lifetime-in-coercion.rs:12:33
--> $DIR/region-object-lifetime-in-coercion.rs:18:33
|
LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
| ^^^^^^^ `'static` requirement introduced here
@ -40,7 +40,7 @@ LL | fn b(v: &'static [u8]) -> Box<dyn Foo + 'static> {
| ~~~~~~~~~~~~~
error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/region-object-lifetime-in-coercion.rs:19:14
--> $DIR/region-object-lifetime-in-coercion.rs:27:14
|
LL | fn c(v: &[u8]) -> Box<dyn Foo> {
| ----- this data with an anonymous lifetime `'_`...
@ -49,7 +49,7 @@ LL | Box::new(v)
| ^ ...is used and required to live as long as `'static` here
|
note: `'static` lifetime requirement introduced by the return type
--> $DIR/region-object-lifetime-in-coercion.rs:16:23
--> $DIR/region-object-lifetime-in-coercion.rs:24:23
|
LL | fn c(v: &[u8]) -> Box<dyn Foo> {
| ^^^^^^^ `'static` requirement introduced here
@ -62,30 +62,30 @@ LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> {
| ++++
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> $DIR/region-object-lifetime-in-coercion.rs:23:14
--> $DIR/region-object-lifetime-in-coercion.rs:33:14
|
LL | Box::new(v)
| ^
|
note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
--> $DIR/region-object-lifetime-in-coercion.rs:22:6
--> $DIR/region-object-lifetime-in-coercion.rs:32:6
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
| ^^
note: ...so that the expression is assignable
--> $DIR/region-object-lifetime-in-coercion.rs:23:14
--> $DIR/region-object-lifetime-in-coercion.rs:33:14
|
LL | Box::new(v)
| ^
= note: expected `&[u8]`
found `&'a [u8]`
note: but, the lifetime must be valid for the lifetime `'b` as defined here...
--> $DIR/region-object-lifetime-in-coercion.rs:22:9
--> $DIR/region-object-lifetime-in-coercion.rs:32:9
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
| ^^
note: ...so that the types are compatible
--> $DIR/region-object-lifetime-in-coercion.rs:23:5
--> $DIR/region-object-lifetime-in-coercion.rs:33:5
|
LL | Box::new(v)
| ^^^^^^^^^^^

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/region-object-lifetime-in-coercion.rs:8:12
--> $DIR/region-object-lifetime-in-coercion.rs:12:12
|
LL | fn a(v: &[u8]) -> Box<dyn Foo + 'static> {
| - let's call the lifetime of this reference `'1`
@ -7,7 +7,7 @@ LL | let x: Box<dyn Foo + 'static> = Box::new(v);
| ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/region-object-lifetime-in-coercion.rs:13:5
--> $DIR/region-object-lifetime-in-coercion.rs:19:5
|
LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
| - let's call the lifetime of this reference `'1`
@ -15,7 +15,7 @@ LL | Box::new(v)
| ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/region-object-lifetime-in-coercion.rs:19:5
--> $DIR/region-object-lifetime-in-coercion.rs:27:5
|
LL | fn c(v: &[u8]) -> Box<dyn Foo> {
| - let's call the lifetime of this reference `'1`
@ -24,7 +24,7 @@ LL | Box::new(v)
| ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/region-object-lifetime-in-coercion.rs:23:5
--> $DIR/region-object-lifetime-in-coercion.rs:33:5
|
LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
| -- -- lifetime `'b` defined here

View file

@ -1,26 +1,38 @@
// Test that attempts to implicitly coerce a value into an
// object respect the lifetime bound on the object type.
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
trait Foo {}
impl<'a> Foo for &'a [u8] {}
fn a(v: &[u8]) -> Box<dyn Foo + 'static> {
let x: Box<dyn Foo + 'static> = Box::new(v); //~ ERROR E0759
let x: Box<dyn Foo + 'static> = Box::new(v);
//[base]~^ ERROR E0759
//[nll]~^^ ERROR lifetime may not live long enough
x
}
fn b(v: &[u8]) -> Box<dyn Foo + 'static> {
Box::new(v) //~ ERROR E0759
Box::new(v)
//[base]~^ ERROR E0759
//[nll]~^^ ERROR lifetime may not live long enough
}
fn c(v: &[u8]) -> Box<dyn Foo> {
// same as previous case due to RFC 599
Box::new(v) //~ ERROR E0759
Box::new(v)
//[base]~^ ERROR E0759
//[nll]~^^ ERROR lifetime may not live long enough
}
fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {
Box::new(v) //~ ERROR cannot infer an appropriate lifetime due to conflicting
Box::new(v)
//[base]~^ ERROR cannot infer an appropriate lifetime due to conflicting
//[nll]~^^ ERROR lifetime may not live long enough
}
fn e<'a:'b,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> {

View file

@ -1,5 +1,5 @@
error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/regions-addr-of-self.rs:7:37
--> $DIR/regions-addr-of-self.rs:11:37
|
LL | pub fn chase_cat(&mut self) {
| --------- this data with an anonymous lifetime `'_`...

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/regions-addr-of-self.rs:7:16
--> $DIR/regions-addr-of-self.rs:11:16
|
LL | pub fn chase_cat(&mut self) {
| - let's call the lifetime of this reference `'1`

View file

@ -1,10 +1,16 @@
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
struct Dog {
cats_chased: usize,
}
impl Dog {
pub fn chase_cat(&mut self) {
let p: &'static mut usize = &mut self.cats_chased; //~ ERROR E0759
let p: &'static mut usize = &mut self.cats_chased;
//[base]~^ ERROR E0759
//[nll]~^^ ERROR lifetime may not live long enough
*p += 1;
}

View file

@ -1,22 +1,22 @@
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> $DIR/regions-addr-of-upvar-self.rs:8:41
--> $DIR/regions-addr-of-upvar-self.rs:12:41
|
LL | let p: &'static mut usize = &mut self.food;
| ^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'_` as defined here...
--> $DIR/regions-addr-of-upvar-self.rs:7:18
--> $DIR/regions-addr-of-upvar-self.rs:11:18
|
LL | let _f = || {
| ^^
note: ...so that closure can access `self`
--> $DIR/regions-addr-of-upvar-self.rs:8:41
--> $DIR/regions-addr-of-upvar-self.rs:12:41
|
LL | let p: &'static mut usize = &mut self.food;
| ^^^^^^^^^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that reference does not outlive borrowed content
--> $DIR/regions-addr-of-upvar-self.rs:8:41
--> $DIR/regions-addr-of-upvar-self.rs:12:41
|
LL | let p: &'static mut usize = &mut self.food;
| ^^^^^^^^^^^^^^

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/regions-addr-of-upvar-self.rs:8:20
--> $DIR/regions-addr-of-upvar-self.rs:12:20
|
LL | let _f = || {
| -- lifetime `'1` represents this closure's body
@ -9,7 +9,7 @@ LL | let p: &'static mut usize = &mut self.food;
= note: closure implements `FnMut`, so references to captured variables can't escape the closure
error: lifetime may not live long enough
--> $DIR/regions-addr-of-upvar-self.rs:8:20
--> $DIR/regions-addr-of-upvar-self.rs:12:20
|
LL | pub fn chase_cat(&mut self) {
| - let's call the lifetime of this reference `'1`
@ -18,7 +18,7 @@ LL | let p: &'static mut usize = &mut self.food;
| ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static`
error[E0597]: `self` does not live long enough
--> $DIR/regions-addr-of-upvar-self.rs:8:46
--> $DIR/regions-addr-of-upvar-self.rs:12:46
|
LL | let _f = || {
| -- value captured here

View file

@ -1,3 +1,7 @@
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
struct Dog {
food: usize,
}
@ -5,7 +9,11 @@ struct Dog {
impl Dog {
pub fn chase_cat(&mut self) {
let _f = || {
let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer
let p: &'static mut usize = &mut self.food;
//[base]~^ ERROR cannot infer
//[nll]~^^ ERROR lifetime may not live long enough
//[nll]~^^^ ERROR lifetime may not live long enough
//[nll]~^^^^ ERROR E0597
*p = 3;
};
}

View file

@ -1,71 +1,71 @@
error[E0477]: the type `&'a isize` does not fulfill the required lifetime
--> $DIR/regions-bounded-by-trait-requiring-static.rs:22:5
--> $DIR/regions-bounded-by-trait-requiring-static.rs:26:5
|
LL | assert_send::<&'a isize>();
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
note: type must satisfy the static lifetime as required by this binding
--> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18
--> $DIR/regions-bounded-by-trait-requiring-static.rs:10:18
|
LL | fn assert_send<T:'static>() { }
| ^^^^^^^
error[E0477]: the type `&'a str` does not fulfill the required lifetime
--> $DIR/regions-bounded-by-trait-requiring-static.rs:26:5
--> $DIR/regions-bounded-by-trait-requiring-static.rs:32:5
|
LL | assert_send::<&'a str>();
| ^^^^^^^^^^^^^^^^^^^^^^
|
note: type must satisfy the static lifetime as required by this binding
--> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18
--> $DIR/regions-bounded-by-trait-requiring-static.rs:10:18
|
LL | fn assert_send<T:'static>() { }
| ^^^^^^^
error[E0477]: the type `&'a [isize]` does not fulfill the required lifetime
--> $DIR/regions-bounded-by-trait-requiring-static.rs:30:5
--> $DIR/regions-bounded-by-trait-requiring-static.rs:38:5
|
LL | assert_send::<&'a [isize]>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: type must satisfy the static lifetime as required by this binding
--> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18
--> $DIR/regions-bounded-by-trait-requiring-static.rs:10:18
|
LL | fn assert_send<T:'static>() { }
| ^^^^^^^
error[E0477]: the type `Box<&'a isize>` does not fulfill the required lifetime
--> $DIR/regions-bounded-by-trait-requiring-static.rs:44:5
--> $DIR/regions-bounded-by-trait-requiring-static.rs:54:5
|
LL | assert_send::<Box<&'a isize>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: type must satisfy the static lifetime as required by this binding
--> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18
--> $DIR/regions-bounded-by-trait-requiring-static.rs:10:18
|
LL | fn assert_send<T:'static>() { }
| ^^^^^^^
error[E0477]: the type `*const &'a isize` does not fulfill the required lifetime
--> $DIR/regions-bounded-by-trait-requiring-static.rs:55:5
--> $DIR/regions-bounded-by-trait-requiring-static.rs:67:5
|
LL | assert_send::<*const &'a isize>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: type must satisfy the static lifetime as required by this binding
--> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18
--> $DIR/regions-bounded-by-trait-requiring-static.rs:10:18
|
LL | fn assert_send<T:'static>() { }
| ^^^^^^^
error[E0477]: the type `*mut &'a isize` does not fulfill the required lifetime
--> $DIR/regions-bounded-by-trait-requiring-static.rs:59:5
--> $DIR/regions-bounded-by-trait-requiring-static.rs:73:5
|
LL | assert_send::<*mut &'a isize>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: type must satisfy the static lifetime as required by this binding
--> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18
--> $DIR/regions-bounded-by-trait-requiring-static.rs:10:18
|
LL | fn assert_send<T:'static>() { }
| ^^^^^^^

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/regions-bounded-by-trait-requiring-static.rs:22:5
--> $DIR/regions-bounded-by-trait-requiring-static.rs:26:5
|
LL | fn param_not_ok<'a>(x: &'a isize) {
| -- lifetime `'a` defined here
@ -7,7 +7,7 @@ LL | assert_send::<&'a isize>();
| ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/regions-bounded-by-trait-requiring-static.rs:26:5
--> $DIR/regions-bounded-by-trait-requiring-static.rs:32:5
|
LL | fn param_not_ok1<'a>(_: &'a isize) {
| -- lifetime `'a` defined here
@ -15,7 +15,7 @@ LL | assert_send::<&'a str>();
| ^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/regions-bounded-by-trait-requiring-static.rs:30:5
--> $DIR/regions-bounded-by-trait-requiring-static.rs:38:5
|
LL | fn param_not_ok2<'a>(_: &'a isize) {
| -- lifetime `'a` defined here
@ -23,7 +23,7 @@ LL | assert_send::<&'a [isize]>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/regions-bounded-by-trait-requiring-static.rs:44:5
--> $DIR/regions-bounded-by-trait-requiring-static.rs:54:5
|
LL | fn box_with_region_not_ok<'a>() {
| -- lifetime `'a` defined here
@ -31,7 +31,7 @@ LL | assert_send::<Box<&'a isize>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/regions-bounded-by-trait-requiring-static.rs:55:5
--> $DIR/regions-bounded-by-trait-requiring-static.rs:67:5
|
LL | fn unsafe_ok2<'a>(_: &'a isize) {
| -- lifetime `'a` defined here
@ -39,7 +39,7 @@ LL | assert_send::<*const &'a isize>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/regions-bounded-by-trait-requiring-static.rs:59:5
--> $DIR/regions-bounded-by-trait-requiring-static.rs:73:5
|
LL | fn unsafe_ok3<'a>(_: &'a isize) {
| -- lifetime `'a` defined here

View file

@ -2,6 +2,10 @@
// in this file all test region bound and lifetime violations that are
// detected during type check.
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
trait Dummy : 'static { }
fn assert_send<T:'static>() { }
@ -19,15 +23,21 @@ fn static_lifime_ok<'a,T,U:Send>(_: &'a isize) {
// otherwise lifetime pointers are not ok
fn param_not_ok<'a>(x: &'a isize) {
assert_send::<&'a isize>(); //~ ERROR does not fulfill the required lifetime
assert_send::<&'a isize>();
//[base]~^ ERROR does not fulfill the required lifetime
//[nll]~^^ ERROR lifetime may not live long enough
}
fn param_not_ok1<'a>(_: &'a isize) {
assert_send::<&'a str>(); //~ ERROR does not fulfill the required lifetime
assert_send::<&'a str>();
//[base]~^ ERROR does not fulfill the required lifetime
//[nll]~^^ ERROR lifetime may not live long enough
}
fn param_not_ok2<'a>(_: &'a isize) {
assert_send::<&'a [isize]>(); //~ ERROR does not fulfill the required lifetime
assert_send::<&'a [isize]>();
//[base]~^ ERROR does not fulfill the required lifetime
//[nll]~^^ ERROR lifetime may not live long enough
}
// boxes are ok
@ -41,7 +51,9 @@ fn box_ok() {
// but not if they own a bad thing
fn box_with_region_not_ok<'a>() {
assert_send::<Box<&'a isize>>(); //~ ERROR does not fulfill the required lifetime
assert_send::<Box<&'a isize>>();
//[base]~^ ERROR does not fulfill the required lifetime
//[nll]~^^ ERROR lifetime may not live long enough
}
// raw pointers are ok unless they point at unsendable things
@ -52,11 +64,15 @@ fn unsafe_ok1<'a>(_: &'a isize) {
}
fn unsafe_ok2<'a>(_: &'a isize) {
assert_send::<*const &'a isize>(); //~ ERROR does not fulfill the required lifetime
assert_send::<*const &'a isize>();
//[base]~^ ERROR does not fulfill the required lifetime
//[nll]~^^ ERROR lifetime may not live long enough
}
fn unsafe_ok3<'a>(_: &'a isize) {
assert_send::<*mut &'a isize>(); //~ ERROR does not fulfill the required lifetime
assert_send::<*mut &'a isize>();
//[base]~^ ERROR does not fulfill the required lifetime
//[nll]~^^ ERROR lifetime may not live long enough
}
fn main() {

View file

@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
--> $DIR/regions-bounded-method-type-parameters-cross-crate.rs:20:7
--> $DIR/regions-bounded-method-type-parameters-cross-crate.rs:23:7
|
LL | fn call_bigger_region<'x, 'y>(a: Inv<'x>, b: Inv<'y>) {
| ------- ------- these two types are declared with different lifetimes...

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/regions-bounded-method-type-parameters-cross-crate.rs:20:5
--> $DIR/regions-bounded-method-type-parameters-cross-crate.rs:23:5
|
LL | fn call_bigger_region<'x, 'y>(a: Inv<'x>, b: Inv<'y>) {
| -- -- lifetime `'y` defined here

View file

@ -1,4 +1,7 @@
// aux-build:rbmtp_cross_crate_lib.rs
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
// Check explicit region bounds on methods in the cross crate case.
@ -17,7 +20,9 @@ fn call_into_maybe_owned<'x,F:IntoMaybeOwned<'x>>(f: F) {
fn call_bigger_region<'x, 'y>(a: Inv<'x>, b: Inv<'y>) {
// Here the value provided for 'y is 'y, and hence 'y:'x does not hold.
a.bigger_region(b) //~ ERROR lifetime mismatch [E0623]
a.bigger_region(b)
//[base]~^ ERROR lifetime mismatch [E0623]
//[nll]~^^ ERROR lifetime may not live long enough
}
fn main() { }

View file

@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
--> $DIR/regions-bounded-method-type-parameters-trait-bound.rs:20:7
--> $DIR/regions-bounded-method-type-parameters-trait-bound.rs:24:7
|
LL | fn caller2<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) {
| ------- ------- these two types are declared with different lifetimes...

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/regions-bounded-method-type-parameters-trait-bound.rs:20:5
--> $DIR/regions-bounded-method-type-parameters-trait-bound.rs:24:5
|
LL | fn caller2<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) {
| -- -- lifetime `'b` defined here

View file

@ -2,6 +2,10 @@
// nominal types (but not on other types) and that they are type
// checked.
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
struct Inv<'a> { // invariant w/r/t 'a
x: &'a mut &'a isize
}
@ -17,7 +21,9 @@ fn caller1<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) {
fn caller2<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) {
// Here the value provided for 'y is 'b, and hence 'b:'a does not hold.
f.method(b); //~ ERROR lifetime mismatch [E0623]
f.method(b);
//[base]~^ ERROR lifetime mismatch [E0623]
//[nll]~^^ ERROR lifetime may not live long enough
}
fn caller3<'a,'b:'a,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) {

View file

@ -1,11 +1,11 @@
error[E0477]: the type `&'a isize` does not fulfill the required lifetime
--> $DIR/regions-bounded-method-type-parameters.rs:12:9
--> $DIR/regions-bounded-method-type-parameters.rs:16:9
|
LL | Foo.some_method::<&'a isize>();
| ^^^^^^^^^^^
|
note: type must satisfy the static lifetime as required by this binding
--> $DIR/regions-bounded-method-type-parameters.rs:8:22
--> $DIR/regions-bounded-method-type-parameters.rs:12:22
|
LL | fn some_method<A:'static>(self) { }
| ^^^^^^^

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/regions-bounded-method-type-parameters.rs:12:9
--> $DIR/regions-bounded-method-type-parameters.rs:16:9
|
LL | fn caller<'a>(x: &isize) {
| -- lifetime `'a` defined here

View file

@ -2,6 +2,10 @@
// nominal types (but not on other types) and that they are type
// checked.
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
struct Foo;
impl Foo {
@ -10,7 +14,8 @@ impl Foo {
fn caller<'a>(x: &isize) {
Foo.some_method::<&'a isize>();
//~^ ERROR does not fulfill the required lifetime
//[base]~^ ERROR does not fulfill the required lifetime
//[nll]~^^ ERROR lifetime may not live long enough
}
fn main() { }

View file

@ -1,5 +1,5 @@
error[E0308]: mismatched types
--> $DIR/regions-bounds.rs:9:12
--> $DIR/regions-bounds.rs:13:12
|
LL | return e;
| ^ lifetime mismatch
@ -7,18 +7,18 @@ LL | return e;
= note: expected struct `TupleStruct<'b>`
found struct `TupleStruct<'a>`
note: the lifetime `'a` as defined here...
--> $DIR/regions-bounds.rs:8:10
--> $DIR/regions-bounds.rs:12:10
|
LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> {
| ^^
note: ...does not necessarily outlive the lifetime `'b` as defined here
--> $DIR/regions-bounds.rs:8:13
--> $DIR/regions-bounds.rs:12:13
|
LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> {
| ^^
error[E0308]: mismatched types
--> $DIR/regions-bounds.rs:13:12
--> $DIR/regions-bounds.rs:19:12
|
LL | return e;
| ^ lifetime mismatch
@ -26,12 +26,12 @@ LL | return e;
= note: expected struct `Struct<'b>`
found struct `Struct<'a>`
note: the lifetime `'a` as defined here...
--> $DIR/regions-bounds.rs:12:10
--> $DIR/regions-bounds.rs:18:10
|
LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> {
| ^^
note: ...does not necessarily outlive the lifetime `'b` as defined here
--> $DIR/regions-bounds.rs:12:13
--> $DIR/regions-bounds.rs:18:13
|
LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> {
| ^^

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/regions-bounds.rs:9:12
--> $DIR/regions-bounds.rs:13:12
|
LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> {
| -- -- lifetime `'b` defined here
@ -11,7 +11,7 @@ LL | return e;
= help: consider adding the following bound: `'a: 'b`
error: lifetime may not live long enough
--> $DIR/regions-bounds.rs:13:12
--> $DIR/regions-bounds.rs:19:12
|
LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> {
| -- -- lifetime `'b` defined here

View file

@ -2,15 +2,23 @@
// nominal types (but not on other types) and that they are type
// checked.
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
struct TupleStruct<'a>(&'a isize);
struct Struct<'a> { x:&'a isize }
fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> {
return e; //~ ERROR mismatched types
return e;
//[base]~^ ERROR mismatched types
//[nll]~^^ ERROR lifetime may not live long enough
}
fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> {
return e; //~ ERROR mismatched types
return e;
//[base]~^ ERROR mismatched types
//[nll]~^^ ERROR lifetime may not live long enough
}
fn main() { }

View file

@ -1,5 +1,5 @@
error[E0310]: the associated type `<T as Iter>::Item` may not live long enough
--> $DIR/regions-close-associated-type-into-object.rs:15:5
--> $DIR/regions-close-associated-type-into-object.rs:19:5
|
LL | Box::new(item)
| ^^^^^^^^^^^^^^
@ -8,7 +8,7 @@ LL | Box::new(item)
= note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds
error[E0310]: the associated type `<T as Iter>::Item` may not live long enough
--> $DIR/regions-close-associated-type-into-object.rs:22:5
--> $DIR/regions-close-associated-type-into-object.rs:26:5
|
LL | Box::new(item)
| ^^^^^^^^^^^^^^
@ -17,7 +17,7 @@ LL | Box::new(item)
= note: ...so that the type `Box<<T as Iter>::Item>` will meet its required lifetime bounds
error[E0309]: the associated type `<T as Iter>::Item` may not live long enough
--> $DIR/regions-close-associated-type-into-object.rs:28:5
--> $DIR/regions-close-associated-type-into-object.rs:32:5
|
LL | Box::new(item)
| ^^^^^^^^^^^^^^
@ -26,7 +26,7 @@ LL | Box::new(item)
= note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds
error[E0309]: the associated type `<T as Iter>::Item` may not live long enough
--> $DIR/regions-close-associated-type-into-object.rs:35:5
--> $DIR/regions-close-associated-type-into-object.rs:39:5
|
LL | Box::new(item)
| ^^^^^^^^^^^^^^

View file

@ -1,5 +1,5 @@
error[E0310]: the associated type `<T as Iter>::Item` may not live long enough
--> $DIR/regions-close-associated-type-into-object.rs:15:5
--> $DIR/regions-close-associated-type-into-object.rs:19:5
|
LL | Box::new(item)
| ^^^^^^^^^^^^^^
@ -8,7 +8,7 @@ LL | Box::new(item)
= note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds
error[E0310]: the associated type `<T as Iter>::Item` may not live long enough
--> $DIR/regions-close-associated-type-into-object.rs:22:5
--> $DIR/regions-close-associated-type-into-object.rs:26:5
|
LL | Box::new(item)
| ^^^^^^^^^^^^^^
@ -17,7 +17,7 @@ LL | Box::new(item)
= note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds
error[E0309]: the associated type `<T as Iter>::Item` may not live long enough
--> $DIR/regions-close-associated-type-into-object.rs:28:5
--> $DIR/regions-close-associated-type-into-object.rs:32:5
|
LL | Box::new(item)
| ^^^^^^^^^^^^^^
@ -26,7 +26,7 @@ LL | Box::new(item)
= note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds
error[E0309]: the associated type `<T as Iter>::Item` may not live long enough
--> $DIR/regions-close-associated-type-into-object.rs:35:5
--> $DIR/regions-close-associated-type-into-object.rs:39:5
|
LL | Box::new(item)
| ^^^^^^^^^^^^^^

View file

@ -1,3 +1,7 @@
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
trait X {}

View file

@ -1,5 +1,5 @@
error[E0759]: `v` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/regions-close-object-into-object-2.rs:9:16
--> $DIR/regions-close-object-into-object-2.rs:13:16
|
LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
| ------------------ this data with lifetime `'a`...
@ -7,7 +7,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^ ...is used and required to live as long as `'static` here
|
note: `'static` lifetime requirement introduced by the return type
--> $DIR/regions-close-object-into-object-2.rs:8:60
--> $DIR/regions-close-object-into-object-2.rs:12:60
|
LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
| ^^^^^^^ `'static` requirement introduced here

View file

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/regions-close-object-into-object-2.rs:9:5
--> $DIR/regions-close-object-into-object-2.rs:13:5
|
LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
| -- lifetime `'a` defined here
@ -7,7 +7,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error[E0515]: cannot return value referencing local data `*v`
--> $DIR/regions-close-object-into-object-2.rs:9:5
--> $DIR/regions-close-object-into-object-2.rs:13:5
|
LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^^^^---^^^^^^^^^^^^^^^^

View file

@ -1,3 +1,7 @@
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
trait A<T> { }
struct B<'a, T:'a>(&'a (dyn A<T> + 'a));
@ -6,7 +10,10 @@ trait X { }
impl<'a, T> X for B<'a, T> {}
fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> {
Box::new(B(&*v)) as Box<dyn X> //~ ERROR E0759
Box::new(B(&*v)) as Box<dyn X>
//[base]~^ ERROR E0759
//[nll]~^^ ERROR lifetime may not live long enough
//[nll]~| ERROR cannot return value referencing local data `*v` [E0515]
}
fn main() { }

View file

@ -1,5 +1,5 @@
error[E0759]: `v` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/regions-close-object-into-object-4.rs:9:16
--> $DIR/regions-close-object-into-object-4.rs:13:16
|
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
| ---------------- this data with lifetime `'a`...
@ -7,7 +7,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^ ...is used and required to live as long as `'static` here
|
note: `'static` lifetime requirement introduced by the return type
--> $DIR/regions-close-object-into-object-4.rs:8:52
--> $DIR/regions-close-object-into-object-4.rs:12:52
|
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
| ^^^^^^^ `'static` requirement introduced here

View file

@ -1,5 +1,5 @@
error[E0310]: the parameter type `U` may not live long enough
--> $DIR/regions-close-object-into-object-4.rs:9:5
--> $DIR/regions-close-object-into-object-4.rs:13:5
|
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
| - help: consider adding an explicit lifetime bound...: `U: 'static`
@ -7,7 +7,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds
error[E0310]: the parameter type `U` may not live long enough
--> $DIR/regions-close-object-into-object-4.rs:9:5
--> $DIR/regions-close-object-into-object-4.rs:13:5
|
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
| - help: consider adding an explicit lifetime bound...: `U: 'static`
@ -15,7 +15,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds
error[E0310]: the parameter type `U` may not live long enough
--> $DIR/regions-close-object-into-object-4.rs:9:5
--> $DIR/regions-close-object-into-object-4.rs:13:5
|
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
| - help: consider adding an explicit lifetime bound...: `U: 'static`
@ -23,7 +23,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds
error: lifetime may not live long enough
--> $DIR/regions-close-object-into-object-4.rs:9:5
--> $DIR/regions-close-object-into-object-4.rs:13:5
|
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
| -- lifetime `'a` defined here
@ -31,7 +31,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error[E0515]: cannot return value referencing local data `*v`
--> $DIR/regions-close-object-into-object-4.rs:9:5
--> $DIR/regions-close-object-into-object-4.rs:13:5
|
LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^^^^---^^^^^^^^^^^^^^^^
@ -40,7 +40,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| returns a value referencing data owned by the current function
error[E0310]: the parameter type `U` may not live long enough
--> $DIR/regions-close-object-into-object-4.rs:9:14
--> $DIR/regions-close-object-into-object-4.rs:13:14
|
LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
| - help: consider adding an explicit lifetime bound...: `U: 'static`

View file

@ -1,3 +1,7 @@
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
trait A<T> { }
struct B<'a, T:'a>(&'a (dyn A<T> + 'a));
@ -6,7 +10,15 @@ trait X { }
impl<'a, T> X for B<'a, T> {}
fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> {
Box::new(B(&*v)) as Box<dyn X> //~ ERROR E0759
Box::new(B(&*v)) as Box<dyn X>
//[base]~^ ERROR E0759
//[nll]~^^ ERROR the parameter type `U` may not live long enough [E0310]
//[nll]~| ERROR the parameter type `U` may not live long enough [E0310]
//[nll]~| ERROR the parameter type `U` may not live long enough [E0310]
//[nll]~| ERROR lifetime may not live long enough
//[nll]~| ERROR cannot return value referencing local data `*v` [E0515]
//[nll]~| ERROR the parameter type `U` may not live long enough [E0310]
}
fn main() {}

View file

@ -1,5 +1,5 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:5
--> $DIR/regions-close-object-into-object-5.rs:21:5
|
LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
@ -8,13 +8,13 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> $DIR/regions-close-object-into-object-5.rs:9:17
--> $DIR/regions-close-object-into-object-5.rs:13:17
|
LL | struct B<'a, T: 'a>(&'a (A<T> + 'a));
| ^^
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:5
--> $DIR/regions-close-object-into-object-5.rs:21:5
|
LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
@ -23,7 +23,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^^^^^^^^^ ...so that the type `B<'_, T>` will meet its required lifetime bounds
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:14
--> $DIR/regions-close-object-into-object-5.rs:21:14
|
LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
@ -32,13 +32,13 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^ ...so that the type `T` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> $DIR/regions-close-object-into-object-5.rs:9:17
--> $DIR/regions-close-object-into-object-5.rs:13:17
|
LL | struct B<'a, T: 'a>(&'a (A<T> + 'a));
| ^^
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:14
--> $DIR/regions-close-object-into-object-5.rs:21:14
|
LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
@ -47,13 +47,13 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
|
note: ...that is required by this bound
--> $DIR/regions-close-object-into-object-5.rs:9:17
--> $DIR/regions-close-object-into-object-5.rs:13:17
|
LL | struct B<'a, T: 'a>(&'a (A<T> + 'a));
| ^^
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:16
--> $DIR/regions-close-object-into-object-5.rs:21:16
|
LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
@ -62,7 +62,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^ ...so that the reference type `&dyn A<T>` does not outlive the data it points at
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:16
--> $DIR/regions-close-object-into-object-5.rs:21:16
|
LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
@ -71,7 +71,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^ ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:16
--> $DIR/regions-close-object-into-object-5.rs:21:16
|
LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`

View file

@ -1,5 +1,5 @@
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:5
--> $DIR/regions-close-object-into-object-5.rs:21:5
|
LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
@ -8,7 +8,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:5
--> $DIR/regions-close-object-into-object-5.rs:21:5
|
LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
@ -17,7 +17,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:5
--> $DIR/regions-close-object-into-object-5.rs:21:5
|
LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`
@ -26,7 +26,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
error[E0515]: cannot return value referencing local data `*v`
--> $DIR/regions-close-object-into-object-5.rs:17:5
--> $DIR/regions-close-object-into-object-5.rs:21:5
|
LL | Box::new(B(&*v)) as Box<dyn X>
| ^^^^^^^^^^^---^^^^^^^^^^^^^^^^
@ -35,7 +35,7 @@ LL | Box::new(B(&*v)) as Box<dyn X>
| returns a value referencing data owned by the current function
error[E0310]: the parameter type `T` may not live long enough
--> $DIR/regions-close-object-into-object-5.rs:17:14
--> $DIR/regions-close-object-into-object-5.rs:21:14
|
LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
| - help: consider adding an explicit lifetime bound...: `T: 'static`

View file

@ -1,3 +1,7 @@
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
#![allow(warnings)]
@ -19,9 +23,10 @@ fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> {
//~| ERROR the parameter type `T` may not live long enough
//~| ERROR the parameter type `T` may not live long enough
//~| ERROR the parameter type `T` may not live long enough
//~| ERROR the parameter type `T` may not live long enough
//~| ERROR the parameter type `T` may not live long enough
//~| ERROR the parameter type `T` may not live long enough
//[base]~| ERROR the parameter type `T` may not live long enough
//[base]~| ERROR the parameter type `T` may not live long enough
//[base]~| ERROR the parameter type `T` may not live long enough
//[nll]~| ERROR cannot return value referencing local data `*v` [E0515]
}
fn main() {}

View file

@ -1,5 +1,5 @@
error[E0310]: the parameter type `A` may not live long enough
--> $DIR/regions-close-over-type-parameter-1.rs:12:5
--> $DIR/regions-close-over-type-parameter-1.rs:15:5
|
LL | fn make_object1<A: SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
| -- help: consider adding an explicit lifetime bound...: `A: 'static +`
@ -7,7 +7,7 @@ LL | Box::new(v) as Box<dyn SomeTrait + 'static>
| ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
error[E0309]: the parameter type `A` may not live long enough
--> $DIR/regions-close-over-type-parameter-1.rs:21:5
--> $DIR/regions-close-over-type-parameter-1.rs:24:5
|
LL | fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box<dyn SomeTrait + 'b> {
| -- help: consider adding an explicit lifetime bound...: `A: 'b +`

View file

@ -1,5 +1,5 @@
error[E0310]: the parameter type `A` may not live long enough
--> $DIR/regions-close-over-type-parameter-1.rs:12:5
--> $DIR/regions-close-over-type-parameter-1.rs:15:5
|
LL | fn make_object1<A: SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> {
| -- help: consider adding an explicit lifetime bound...: `A: 'static +`
@ -7,7 +7,7 @@ LL | Box::new(v) as Box<dyn SomeTrait + 'static>
| ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds
error[E0309]: the parameter type `A` may not live long enough
--> $DIR/regions-close-over-type-parameter-1.rs:21:5
--> $DIR/regions-close-over-type-parameter-1.rs:24:5
|
LL | fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box<dyn SomeTrait + 'b> {
| -- help: consider adding an explicit lifetime bound...: `A: 'b +`

View file

@ -2,6 +2,9 @@
// an object. This should yield errors unless `A` (and the object)
// both have suitable bounds.
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
trait SomeTrait {
fn get(&self) -> isize;

Some files were not shown because too many files have changed in this diff Show more