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:
commit
1f631e8e93
206 changed files with 1602 additions and 621 deletions
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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: {:?}={:?} {:?}",
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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] {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {}
|
15
src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.rs
Normal file
15
src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.rs
Normal 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() {}
|
|
@ -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`.
|
|
@ -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 () {
|
||||
| ^^
|
|
@ -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
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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>)) {
|
||||
| ^^
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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() {
|
||||
|
|
|
@ -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()
|
||||
| ^^^^^^^^^^^^
|
|
@ -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
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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()
|
||||
| ^^^^^^^^^^^^
|
|
@ -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
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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)
|
||||
| ^^^^^^^^^^^
|
|
@ -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
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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 `'_`...
|
|
@ -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`
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
| ^^^^^^^^^^^^^^
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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>() { }
|
||||
| ^^^^^^^
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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...
|
|
@ -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
|
||||
|
|
|
@ -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() { }
|
||||
|
|
|
@ -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...
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) { }
|
||||
| ^^^^^^^
|
|
@ -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
|
||||
|
|
|
@ -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() { }
|
||||
|
|
|
@ -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> {
|
||||
| ^^
|
|
@ -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
|
||||
|
|
|
@ -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() { }
|
||||
|
|
|
@ -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)
|
||||
| ^^^^^^^^^^^^^^
|
|
@ -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)
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
// revisions: base nll
|
||||
// ignore-compare-mode-nll
|
||||
//[nll] compile-flags: -Z borrowck=mir
|
||||
|
||||
trait X {}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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>
|
||||
| ^^^^^^^^^^^---^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -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() { }
|
||||
|
|
|
@ -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
|
|
@ -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`
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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`
|
|
@ -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`
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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 +`
|
|
@ -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 +`
|
||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue