Auto merge of #95565 - jackh726:remove-borrowck-mode, r=nikomatsakis

Remove migrate borrowck mode

Closes #58781
Closes #43234

# Stabilization proposal

This PR proposes the stabilization of `#![feature(nll)]` and the removal of `-Z borrowck`. Current borrow checking behavior of item bodies is currently done by first infering regions *lexically* and reporting any errors during HIR type checking. If there *are* any errors, then MIR borrowck (NLL) never occurs. If there *aren't* any errors, then MIR borrowck happens and any errors there would be reported. This PR removes the lexical region check of item bodies entirely and only uses MIR borrowck. Because MIR borrowck could never *not* be run for a compiled program, this should not break any programs. It does, however, change diagnostics significantly and allows a slightly larger set of programs to compile.

Tracking issue: #43234
RFC: https://github.com/rust-lang/rfcs/blob/master/text/2094-nll.md
Version: 1.63 (2022-06-30 => beta, 2022-08-11 => stable).

## Motivation

Over time, the Rust borrow checker has become "smarter" and thus allowed more programs to compile. There have been three different implementations: AST borrowck, MIR borrowck, and polonius (well, in progress). Additionally, there is the "lexical region resolver", which (roughly) solves the constraints generated through HIR typeck. It is not a full borrow checker, but does emit some errors.

The AST borrowck was the original implementation of the borrow checker and was part of the initially stabilized Rust 1.0. In mid 2017, work began to implement the current MIR borrow checker and that effort ompleted by the end of 2017, for the most part. During 2018, efforts were made to migrate away from the AST borrow checker to the MIR borrow checker - eventually culminating into "migrate" mode - where HIR typeck with lexical region resolving following by MIR borrow checking - being active by default in the 2018 edition.

In early 2019, migrate mode was turned on by default in the 2015 edition as well, but with MIR borrowck errors emitted as warnings. By late 2019, these warnings were upgraded to full errors. This was followed by the complete removal of the AST borrow checker.

In the period since, various errors emitted by the MIR borrow checker have been improved to the point that they are mostly the same or better than those emitted by the lexical region resolver.

While there do remain some degradations in errors (tracked under the [NLL-diagnostics tag](https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3ANLL-diagnostics), those are sufficiently small and rare enough that increased flexibility of MIR borrow check-only is now a worthwhile tradeoff.

## What is stabilized

As said previously, this does not fundamentally change the landscape of accepted programs. However, there are a [few](https://github.com/rust-lang/rust/issues?q=is%3Aopen+is%3Aissue+label%3ANLL-fixed-by-NLL) cases where programs can compile under `feature(nll)`, but not otherwise.

There are two notable patterns that are "fixed" by this stabilization. First, the `scoped_threads` feature, which is a continutation of a pre-1.0 API, can sometimes emit a [weird lifetime error](https://github.com/rust-lang/rust/issues/95527) without NLL. Second, actually seen in the standard library. In the `Extend` impl for `HashMap`, there is an implied bound of `K: 'a` that is available with NLL on but not without - this is utilized in the impl.

As mentioned before, there are a large number of diagnostic differences. Most of them are better, but some are worse. None are serious or happen often enough to need to block this PR. The biggest change is the loss of error code for a number of lifetime errors in favor of more general "lifetime may not live long enough" error. While this may *seem* bad, the former error codes were just attempts to somewhat-arbitrarily bin together lifetime errors of the same type; however, on paper, they end up being roughly the same with roughly the same kinds of solutions.

## What isn't stabilized

This PR does not completely remove the lexical region resolver. In the future, it may be possible to remove that (while still keeping HIR typeck) or to remove it together with HIR typeck.

## Tests

Many test outputs get updated by this PR. However, there are number of tests specifically geared towards NLL under `src/test/ui/nll`

## History

* On 2017-07-14, [tracking issue opened](https://github.com/rust-lang/rust/issues/43234)
* On 2017-07-20, [initial empty MIR pass added](https://github.com/rust-lang/rust/pull/43271)
* On 2017-08-29, [RFC opened](https://github.com/rust-lang/rfcs/pull/2094)
* On 2017-11-16, [Integrate MIR type-checker with NLL](https://github.com/rust-lang/rust/pull/45825)
* On 2017-12-20, [NLL feature complete](https://github.com/rust-lang/rust/pull/46862)
* On 2018-07-07, [Don't run AST borrowck on mir mode](https://github.com/rust-lang/rust/pull/52083)
* On 2018-07-27, [Add migrate mode](https://github.com/rust-lang/rust/pull/52681)
* On 2019-04-22, [Enable migrate mode on 2015 edition](https://github.com/rust-lang/rust/pull/59114)
* On 2019-08-26, [Don't downgrade errors on 2015 edition](https://github.com/rust-lang/rust/pull/64221)
* On 2019-08-27, [Remove AST borrowck](https://github.com/rust-lang/rust/pull/64790)
This commit is contained in:
bors 2022-06-07 05:04:14 +00:00
commit bb55bd449e
985 changed files with 1824 additions and 12137 deletions

View File

@ -33,7 +33,6 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![no_std]
#![forbid(unsafe_code)]
#![feature(nll)]
#[macro_use]
extern crate alloc;

View File

@ -17,7 +17,6 @@
#![feature(let_chains)]
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(nll)]
#![feature(slice_internals)]
#![feature(stmt_expr_attributes)]
#![recursion_limit = "256"]

View File

@ -9,7 +9,6 @@
#![feature(is_sorted)]
#![feature(let_chains)]
#![feature(let_else)]
#![feature(nll)]
#![feature(proc_macro_internals)]
#![feature(proc_macro_quote)]
#![recursion_limit = "256"]

View File

@ -9,7 +9,6 @@
#![feature(let_else)]
#![feature(extern_types)]
#![feature(once_cell)]
#![feature(nll)]
#![feature(iter_intersperse)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]

View File

@ -3,7 +3,6 @@
#![feature(try_blocks)]
#![feature(let_else)]
#![feature(once_cell)]
#![feature(nll)]
#![feature(associated_type_bounds)]
#![feature(strict_provenance)]
#![feature(int_roundings)]

View File

@ -5,7 +5,6 @@
//! This API is completely unstable and subject to change.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(nll)]
#![feature(let_else)]
#![feature(once_cell)]
#![recursion_limit = "256"]

View File

@ -1,8 +1,10 @@
#### Note: this error code is no longer emitted by the compiler.
Reference's lifetime of borrowed content doesn't match the expected lifetime.
Erroneous code example:
```compile_fail,E0312
```compile_fail
pub fn opt_str<'a>(maybestr: &'a Option<String>) -> &'static str {
if maybestr.is_none() {
"(none)"

View File

@ -1,8 +1,10 @@
#### Note: this error code is no longer emitted by the compiler.
The type does not fulfill the required lifetime.
Erroneous code example:
```compile_fail,E0477
```compile_fail
use std::sync::Mutex;
struct MyString<'a> {

View File

@ -1,8 +1,10 @@
#### Note: this error code is no longer emitted by the compiler.
A lifetime cannot be determined in the given situation.
Erroneous code example:
```compile_fail,E0495
```compile_fail
fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T {
match (&t,) { // error!
((u,),) => u,

View File

@ -3,39 +3,70 @@ A lifetime didn't match what was expected.
Erroneous code example:
```compile_fail,E0623
struct Foo<'a> {
x: &'a isize,
}
struct Foo<'a, 'b, T>(std::marker::PhantomData<(&'a (), &'b (), T)>)
where
T: Convert<'a, 'b>;
fn bar<'short, 'long>(c: Foo<'short>, l: &'long isize) {
let _: Foo<'long> = c; // error!
trait Convert<'a, 'b>: Sized {
fn cast(&'a self) -> &'b Self;
}
impl<'long: 'short, 'short, T> Convert<'long, 'short> for T {
fn cast(&'long self) -> &'short T {
self
}
}
// error
fn badboi<'in_, 'out, T>(
x: Foo<'in_, 'out, T>,
sadness: &'in_ T
) -> &'out T {
sadness.cast()
}
```
In this example, we tried to set a value with an incompatible lifetime to
another one (`'long` is unrelated to `'short`). We can solve this issue in
another one (`'in_` is unrelated to `'out`). We can solve this issue in
two different ways:
Either we make `'short` live at least as long as `'long`:
Either we make `'in_` live at least as long as `'out`:
```
struct Foo<'a> {
x: &'a isize,
}
struct Foo<'a, 'b, T>(std::marker::PhantomData<(&'a (), &'b (), T)>)
where
T: Convert<'a, 'b>;
// we set 'short to live at least as long as 'long
fn bar<'short: 'long, 'long>(c: Foo<'short>, l: &'long isize) {
let _: Foo<'long> = c; // ok!
trait Convert<'a, 'b>: Sized {
fn cast(&'a self) -> &'b Self;
}
impl<'long: 'short, 'short, T> Convert<'long, 'short> for T {
fn cast(&'long self) -> &'short T {
self
}
}
fn badboi<'in_: 'out, 'out, T>(
x: Foo<'in_, 'out, T>,
sadness: &'in_ T
) -> &'out T {
sadness.cast()
}
```
Or we use only one lifetime:
```
struct Foo<'a> {
x: &'a isize,
struct Foo<'a, 'b, T>(std::marker::PhantomData<(&'a (), &'b (), T)>)
where
T: Convert<'a, 'b>;
trait Convert<'a, 'b>: Sized {
fn cast(&'a self) -> &'b Self;
}
fn bar<'short>(c: Foo<'short>, l: &'short isize) {
let _: Foo<'short> = c; // ok!
impl<'long: 'short, 'short, T> Convert<'long, 'short> for T {
fn cast(&'long self) -> &'short T {
self
}
}
fn badboi<'out, T>(x: Foo<'out, 'out, T>, sadness: &'out T) -> &'out T {
sadness.cast()
}
```

View File

@ -4,8 +4,6 @@ lifetime of a type that implements the `Drop` trait.
Erroneous code example:
```compile_fail,E0713
#![feature(nll)]
pub struct S<'a> { data: &'a mut String }
impl<'a> Drop for S<'a> {

View File

@ -1,8 +1,10 @@
#### Note: this error code is no longer emitted by the compiler.
Return type involving a trait did not require `'static` lifetime.
Erroneous code examples:
```compile_fail,E0759
```compile_fail
use std::fmt::Debug;
fn foo(x: &i32) -> impl Debug { // error!

View File

@ -1,9 +1,11 @@
#### Note: this error code is no longer emitted by the compiler.
A trait object has some specific lifetime `'1`, but it was used in a way that
requires it to have a `'static` lifetime.
Example of erroneous code:
```compile_fail,E0772
```compile_fail
trait BooleanLike {}
trait Person {}

View File

@ -8,7 +8,6 @@
#![feature(if_let_guard)]
#![feature(let_else)]
#![feature(never_type)]
#![feature(nll)]
#![feature(adt_const_params)]
#![allow(incomplete_features)]
#![allow(rustc::potential_query_instability)]

View File

@ -221,6 +221,8 @@ declare_features! (
(accepted, native_link_modifiers, "1.61.0", Some(81490), None),
/// Allows specifying the whole-archive link modifier
(accepted, native_link_modifiers_whole_archive, "1.61.0", Some(81490), None),
/// Allows using non lexical lifetimes (RFC 2094).
(accepted, nll, "1.63.0", Some(43234), None),
/// Allows using `#![no_std]`.
(accepted, no_std, "1.6.0", None, None),
/// Allows defining identifiers beyond ASCII.

View File

@ -461,8 +461,6 @@ declare_features! (
(active, never_type, "1.13.0", Some(35121), None),
/// Allows diverging expressions to fall back to `!` rather than `()`.
(active, never_type_fallback, "1.41.0", Some(65992), None),
/// Allows using non lexical lifetimes (RFC 2094).
(active, nll, "1.0.0", Some(43234), None),
/// Allows `#![no_core]`.
(active, no_core, "1.3.0", Some(29639), None),
/// Allows function attribute `#[no_coverage]`, to bypass coverage

View File

@ -273,7 +273,6 @@
html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
test(attr(allow(unused_variables), deny(warnings)))
)]
#![feature(nll)]
use LabelText::*;

View File

@ -3,7 +3,6 @@
#![deny(missing_docs)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(let_else)]
#![feature(nll)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]

View File

@ -42,18 +42,7 @@ pub(crate) fn resolve<'tcx>(
let values = resolver.infer_variable_values(&mut errors);
(values, errors)
}
RegionckMode::Erase { suppress_errors: false } => {
// Do real inference to get errors, then erase the results.
let mut values = resolver.infer_variable_values(&mut errors);
let re_erased = region_rels.tcx.lifetimes.re_erased;
values.values.iter_mut().for_each(|v| match *v {
VarValue::Value(ref mut r) => *r = re_erased,
VarValue::ErrorValue => {}
});
(values, errors)
}
RegionckMode::Erase { suppress_errors: true } => {
RegionckMode::Erase => {
// Skip region inference entirely.
(resolver.erased_data(region_rels.tcx), Vec::new())
}

View File

@ -29,7 +29,6 @@ use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Substs
pub use rustc_middle::ty::IntVarValue;
use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt};
use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
use rustc_session::config::BorrowckMode;
use rustc_span::symbol::Symbol;
use rustc_span::Span;
@ -97,29 +96,7 @@ pub enum RegionckMode {
#[default]
Solve,
/// Erase the results of region after solving.
Erase {
/// A flag that is used to suppress region errors, when we are doing
/// region checks that the NLL borrow checker will also do -- it might
/// be set to true.
suppress_errors: bool,
},
}
impl RegionckMode {
/// Indicates that the MIR borrowck will repeat these region
/// checks, so we should ignore errors if NLL is (unconditionally)
/// enabled.
pub fn for_item_body(tcx: TyCtxt<'_>) -> Self {
// FIXME(Centril): Once we actually remove `::Migrate` also make
// this always `true` and then proceed to eliminate the dead code.
match tcx.borrowck_mode() {
// If we're on Migrate mode, report AST region errors
BorrowckMode::Migrate => RegionckMode::Erase { suppress_errors: false },
// If we're on MIR, don't report AST region errors as they should be reported by NLL
BorrowckMode::Mir => RegionckMode::Erase { suppress_errors: true },
}
}
Erase,
}
/// This type contains all the things within `InferCtxt` that sit within a

View File

@ -2,7 +2,6 @@
#![feature(let_else)]
#![feature(internal_output_capture)]
#![feature(thread_spawn_unchecked)]
#![feature(nll)]
#![feature(once_cell)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]

View File

@ -644,7 +644,6 @@ fn test_debugging_options_tracking_hash() {
// Make sure that changing an [UNTRACKED] option leaves the hash unchanged.
// This list is in alphabetical order.
untracked!(assert_incr_state, Some(String::from("loaded")));
untracked!(borrowck, String::from("other"));
untracked!(deduplicate_diagnostics, false);
untracked!(dep_tasks, true);
untracked!(dlltool, Some(PathBuf::from("custom_dlltool.exe")));

View File

@ -36,7 +36,6 @@
#![feature(let_chains)]
#![feature(let_else)]
#![feature(never_type)]
#![feature(nll)]
#![recursion_limit = "256"]
#[macro_use]

View File

@ -1,4 +1,3 @@
#![feature(nll)]
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
// NOTE: This crate only exists to allow linking on mingw targets.

View File

@ -6,7 +6,6 @@
#![feature(iter_from_generator)]
#![feature(let_chains)]
#![feature(let_else)]
#![feature(nll)]
#![feature(once_cell)]
#![feature(proc_macro_internals)]
#![feature(macro_metavar_expr)]

View File

@ -39,7 +39,6 @@
#![feature(never_type)]
#![feature(extern_types)]
#![feature(new_uninit)]
#![feature(nll)]
#![feature(once_cell)]
#![feature(let_chains)]
#![feature(let_else)]

View File

@ -49,7 +49,7 @@ use rustc_macros::HashStable;
use rustc_middle::mir::FakeReadCause;
use rustc_query_system::ich::StableHashingContext;
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
use rustc_session::config::{CrateType, OutputFilenames};
use rustc_session::lint::{Level, Lint};
use rustc_session::Limit;
use rustc_session::Session;
@ -1470,44 +1470,6 @@ impl<'tcx> TyCtxt<'tcx> {
self.on_disk_cache.as_ref().map_or(Ok(()), |c| c.serialize(self, encoder))
}
/// If `true`, we should use the MIR-based borrowck, but also
/// fall back on the AST borrowck if the MIR-based one errors.
pub fn migrate_borrowck(self) -> bool {
self.borrowck_mode().migrate()
}
/// What mode(s) of borrowck should we run? AST? MIR? both?
/// (Also considers the `#![feature(nll)]` setting.)
pub fn borrowck_mode(self) -> BorrowckMode {
// Here are the main constraints we need to deal with:
//
// 1. An opts.borrowck_mode of `BorrowckMode::Migrate` is
// synonymous with no `-Z borrowck=...` flag at all.
//
// 2. We want to allow developers on the Nightly channel
// to opt back into the "hard error" mode for NLL,
// (which they can do via specifying `#![feature(nll)]`
// explicitly in their crate).
//
// So, this precedence list is how pnkfelix chose to work with
// the above constraints:
//
// * `#![feature(nll)]` *always* means use NLL with hard
// errors. (To simplify the code here, it now even overrides
// a user's attempt to specify `-Z borrowck=compare`, which
// we arguably do not need anymore and should remove.)
//
// * Otherwise, if no `-Z borrowck=...` then use migrate mode
//
// * Otherwise, use the behavior requested via `-Z borrowck=...`
if self.features().nll {
return BorrowckMode::Mir;
}
self.sess.opts.borrowck_mode
}
/// If `true`, we should use lazy normalization for constants, otherwise
/// we still evaluate them eagerly.
#[inline]

View File

@ -11,7 +11,6 @@
#![feature(let_chains)]
#![feature(map_try_insert)]
#![feature(min_specialization)]
#![feature(nll)]
#![feature(try_blocks)]
#![recursion_limit = "256"]

View File

@ -7,7 +7,6 @@
//! of the Unstable Book for some examples.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(nll)]
#![recursion_limit = "256"]
use rustc_lint::LintStore;

View File

@ -1,5 +1,4 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(nll)]
#![feature(control_flow_enum)]
#![feature(try_blocks)]
#![feature(associated_type_defaults)]

View File

@ -1,7 +1,6 @@
//! Support for serializing the dep-graph and reloading it.
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(nll)]
#![feature(min_specialization)]
#![feature(once_cell)]
#![feature(rustc_attrs)]

View File

@ -13,7 +13,7 @@
#![feature(let_chains)]
#![feature(let_else)]
#![feature(never_type)]
#![feature(nll)]
#![cfg_attr(bootstrap, feature(nll))]
#![recursion_limit = "256"]
#![allow(rustdoc::private_intra_doc_links)]
#![allow(rustc::potential_query_instability)]

View File

@ -1,6 +1,5 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(if_let_guard)]
#![feature(nll)]
#![feature(let_else)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]

View File

@ -10,7 +10,6 @@ Core encoding and decoding interfaces.
test(attr(allow(unused_variables), deny(warnings)))
)]
#![feature(never_type)]
#![feature(nll)]
#![feature(associated_type_bounds)]
#![feature(min_specialization)]
#![feature(core_intrinsics)]

View File

@ -741,7 +741,6 @@ impl Default for Options {
incremental: None,
debugging_opts: Default::default(),
prints: Vec::new(),
borrowck_mode: BorrowckMode::Migrate,
cg: Default::default(),
error_format: ErrorOutputType::default(),
externs: Externs(BTreeMap::new()),
@ -2084,14 +2083,6 @@ fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec<
.collect()
}
fn parse_borrowck_mode(dopts: &DebuggingOptions, error_format: ErrorOutputType) -> BorrowckMode {
match dopts.borrowck.as_ref() {
"migrate" => BorrowckMode::Migrate,
"mir" => BorrowckMode::Mir,
m => early_error(error_format, &format!("unknown borrowck mode `{m}`")),
}
}
pub fn parse_externs(
matches: &getopts::Matches,
debugging_opts: &DebuggingOptions,
@ -2429,8 +2420,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
let test = matches.opt_present("test");
let borrowck_mode = parse_borrowck_mode(&debugging_opts, error_format);
if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
early_warn(error_format, "-C remark requires \"-C debuginfo=n\" to show source locations");
}
@ -2506,7 +2495,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
incremental,
debugging_opts,
prints,
borrowck_mode,
cg,
error_format,
externs,

View File

@ -178,9 +178,6 @@ top_level_options!(
debugging_opts: DebuggingOptions [SUBSTRUCT],
prints: Vec<PrintRequest> [UNTRACKED],
/// Determines which borrow checker(s) to run. This is the parsed, sanitized
/// version of `debugging_opts.borrowck`, which is just a plain string.
borrowck_mode: BorrowckMode [UNTRACKED],
cg: CodegenOptions [SUBSTRUCT],
externs: Externs [UNTRACKED],
crate_name: Option<String> [TRACKED],
@ -1210,8 +1207,6 @@ options! {
binary_dep_depinfo: bool = (false, parse_bool, [TRACKED],
"include artifacts (sysroot, crate dependencies) used during compilation in dep-info \
(default: no)"),
borrowck: String = ("migrate".to_string(), parse_string, [UNTRACKED],
"select which borrowck is used (`mir` or `migrate`) (default: `migrate`)"),
branch_protection: Option<BranchProtection> = (None, parse_branch_protection, [TRACKED],
"set options for branch target identification and pointer authentication on AArch64"),
cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED],

View File

@ -18,7 +18,6 @@
#![feature(let_else)]
#![feature(if_let_guard)]
#![feature(negative_impls)]
#![feature(nll)]
#![feature(min_specialization)]
#![feature(rustc_attrs)]
#![allow(rustc::potential_query_instability)]

View File

@ -89,7 +89,6 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(never_type)]
#![feature(nll)]
#![recursion_limit = "256"]
#![allow(rustc::potential_query_instability)]

View File

@ -13,7 +13,6 @@
#![feature(let_else)]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(nll)]
#![feature(rustc_attrs)]
#![feature(step_trait)]

View File

@ -2,7 +2,6 @@
//! the guts are broken up into modules; see the comments in those modules.
#![feature(let_else)]
#![feature(nll)]
#![recursion_limit = "256"]
#[macro_use]

View File

@ -7,7 +7,6 @@
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
#![feature(control_flow_enum)]
#![feature(let_else)]
#![feature(nll)]
#![recursion_limit = "256"]
#[macro_use]

View File

@ -165,7 +165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rcx.visit_body(body);
rcx.visit_region_obligations(id);
}
rcx.resolve_regions_and_report_errors(RegionckMode::for_item_body(self.tcx));
rcx.resolve_regions_and_report_errors(RegionckMode::Erase);
}
/// Region checking during the WF phase for items. `wf_tys` are the
@ -208,7 +208,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rcx.visit_fn_body(fn_id, body, self.tcx.hir().span(fn_id));
}
rcx.resolve_regions_and_report_errors(RegionckMode::for_item_body(self.tcx));
rcx.resolve_regions_and_report_errors(RegionckMode::Erase);
}
}

View File

@ -69,7 +69,6 @@ This API is completely unstable and subject to change.
#![feature(let_else)]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(nll)]
#![feature(once_cell)]
#![feature(slice_partition_dedup)]
#![feature(try_blocks)]

View File

@ -166,7 +166,6 @@
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(nll)] // Not necessary, but here to test the `nll` feature.
#![feature(rustc_allow_const_fn_unstable)]
#![feature(rustc_attrs)]
#![feature(pointer_is_aligned)]

View File

@ -9,7 +9,6 @@
#![panic_runtime]
#![allow(unused_features)]
#![feature(core_intrinsics)]
#![feature(nll)]
#![feature(panic_runtime)]
#![feature(std_internals)]
#![feature(staged_api)]

View File

@ -16,7 +16,6 @@
#![doc(issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
#![feature(core_intrinsics)]
#![feature(lang_items)]
#![feature(nll)]
#![feature(panic_unwind)]
#![feature(staged_api)]
#![feature(std_internals)]

View File

@ -21,7 +21,6 @@
// Please avoid unstable features where possible to minimize the amount of changes necessary
// to make it compile with rust-analyzer on stable.
#![feature(rustc_allow_const_fn_unstable)]
#![feature(nll)]
#![feature(staged_api)]
#![feature(allow_internal_unstable)]
#![feature(decl_macro)]

View File

@ -7,5 +7,4 @@
issue = "none"
)]
#![allow(unused_features)]
#![feature(nll)]
#![feature(staged_api)]

View File

@ -2167,7 +2167,7 @@ mod use_keyword {}
/// is missing: the `'b` lifetime is not known to live at least as long as `'a`
/// which means this function cannot ensure it always returns a valid reference:
///
/// ```rust,compile_fail,E0623
/// ```rust,compile_fail
/// fn select<'a, 'b>(s1: &'a str, s2: &'b str, second: bool) -> &'a str
/// {
/// if second { s2 } else { s1 }

View File

@ -248,7 +248,7 @@
#![feature(needs_panic_runtime)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(nll)]
#![cfg_attr(bootstrap, feature(nll))]
#![feature(platform_intrinsics)]
#![feature(prelude_import)]
#![feature(rustc_attrs)]

View File

@ -15,7 +15,6 @@
#![unstable(feature = "test", issue = "50297")]
#![doc(test(attr(deny(warnings))))]
#![feature(nll)]
#![feature(bench_black_box)]
#![feature(internal_output_capture)]
#![feature(staged_api)]

View File

@ -2,7 +2,6 @@
#![unstable(feature = "panic_unwind", issue = "32837")]
#![feature(link_cfg)]
#![feature(native_link_modifiers_bundle)]
#![feature(nll)]
#![feature(staged_api)]
#![feature(c_unwind)]
#![feature(cfg_target_abi)]

View File

@ -452,7 +452,7 @@ Arguments:
./x.py test library/std --test-args hash_map
./x.py test library/std --stage 0 --no-doc
./x.py test src/test/ui --bless
./x.py test src/test/ui --compare-mode nll
./x.py test src/test/ui --compare-mode chalk
Note that `test src/test/* --stage N` does NOT depend on `build compiler/rustc --stage N`;
just like `build library/std --stage N` it tests the compiler produced by the previous

View File

@ -1167,12 +1167,7 @@ macro_rules! test_definitions {
};
}
default_test_with_compare_mode!(Ui {
path: "src/test/ui",
mode: "ui",
suite: "ui",
compare_mode: "nll"
});
default_test!(Ui { path: "src/test/ui", mode: "ui", suite: "ui" });
default_test!(RunPassValgrind {
path: "src/test/run-pass-valgrind",

View File

@ -11,7 +11,7 @@
#![feature(drain_filter)]
#![feature(let_chains)]
#![feature(let_else)]
#![feature(nll)]
#![cfg_attr(bootstrap, feature(nll))]
#![feature(test)]
#![feature(never_type)]
#![feature(once_cell)]

View File

@ -1,113 +1,113 @@
// MIR for `full_tested_match` after PromoteTemps
fn full_tested_match() -> () {
let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:14:28: 14:28
let mut _1: (i32, i32); // in scope 0 at $DIR/match_false_edges.rs:15:13: 19:6
let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
let mut _3: isize; // in scope 0 at $DIR/match_false_edges.rs:16:9: 16:16
let mut _4: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
let _5: i32; // in scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
let _6: &i32; // in scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
let mut _7: bool; // in scope 0 at $DIR/match_false_edges.rs:16:20: 16:27
let mut _8: i32; // in scope 0 at $DIR/match_false_edges.rs:16:35: 16:36
let _9: i32; // in scope 0 at $DIR/match_false_edges.rs:17:14: 17:15
let mut _10: i32; // in scope 0 at $DIR/match_false_edges.rs:17:24: 17:25
let mut _11: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:12:28: 12:28
let mut _1: (i32, i32); // in scope 0 at $DIR/match_false_edges.rs:13:13: 17:6
let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:13:19: 13:27
let mut _3: isize; // in scope 0 at $DIR/match_false_edges.rs:14:9: 14:16
let mut _4: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:13:19: 13:27
let _5: i32; // in scope 0 at $DIR/match_false_edges.rs:14:14: 14:15
let _6: &i32; // in scope 0 at $DIR/match_false_edges.rs:14:14: 14:15
let mut _7: bool; // in scope 0 at $DIR/match_false_edges.rs:14:20: 14:27
let mut _8: i32; // in scope 0 at $DIR/match_false_edges.rs:14:35: 14:36
let _9: i32; // in scope 0 at $DIR/match_false_edges.rs:15:14: 15:15
let mut _10: i32; // in scope 0 at $DIR/match_false_edges.rs:15:24: 15:25
let mut _11: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:14:14: 14:15
scope 1 {
}
scope 2 {
debug x => _5; // in scope 2 at $DIR/match_false_edges.rs:16:14: 16:15
debug x => _6; // in scope 2 at $DIR/match_false_edges.rs:16:14: 16:15
debug x => _5; // in scope 2 at $DIR/match_false_edges.rs:14:14: 14:15
debug x => _6; // in scope 2 at $DIR/match_false_edges.rs:14:14: 14:15
}
scope 3 {
debug y => _9; // in scope 3 at $DIR/match_false_edges.rs:17:14: 17:15
debug y => _9; // in scope 3 at $DIR/match_false_edges.rs:15:14: 15:15
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:15:13: 19:6
StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
_2 = Option::<i32>::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
_3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
switchInt(move _3) -> [0_isize: bb1, 1_isize: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:15:13: 15:27
StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:13:13: 17:6
StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:13:19: 13:27
_2 = Option::<i32>::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:13:19: 13:27
FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:13:19: 13:27
_3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:13:19: 13:27
switchInt(move _3) -> [0_isize: bb1, 1_isize: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:13:13: 13:27
}
bb1: {
_1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:18:17: 18:23
goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:18:17: 18:23
_1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:16:17: 16:23
goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:16:17: 16:23
}
bb2: {
falseEdge -> [real: bb5, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:16:9: 16:16
falseEdge -> [real: bb5, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:14:9: 14:16
}
bb3: {
falseEdge -> [real: bb9, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:17:9: 17:16
falseEdge -> [real: bb9, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:15:9: 15:16
}
bb4: {
unreachable; // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
unreachable; // scope 0 at $DIR/match_false_edges.rs:13:19: 13:27
}
bb5: {
StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
_11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:14:14: 14:15
_11 = const full_tested_match::promoted[0]; // scope 0 at $DIR/match_false_edges.rs:14:14: 14:15
// mir::Constant
// + span: $DIR/match_false_edges.rs:16:14: 16:15
// + span: $DIR/match_false_edges.rs:14:14: 14:15
// + literal: Const { ty: &Option<i32>, val: Unevaluated(full_tested_match, [], Some(promoted[0])) }
_6 = &(((*_11) as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
_4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:15:19: 15:27
StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:16:20: 16:27
_7 = guard() -> [return: bb6, unwind: bb11]; // scope 0 at $DIR/match_false_edges.rs:16:20: 16:27
_6 = &(((*_11) as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:14:14: 14:15
_4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:13:19: 13:27
StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:14:20: 14:27
_7 = guard() -> [return: bb6, unwind: bb11]; // scope 0 at $DIR/match_false_edges.rs:14:20: 14:27
// mir::Constant
// + span: $DIR/match_false_edges.rs:16:20: 16:25
// + span: $DIR/match_false_edges.rs:14:20: 14:25
// + literal: Const { ty: fn() -> bool {guard}, val: Value(Scalar(<ZST>)) }
}
bb6: {
switchInt(move _7) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:16:20: 16:27
switchInt(move _7) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:14:20: 14:27
}
bb7: {
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:16:26: 16:27
FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_false_edges.rs:16:26: 16:27
FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_false_edges.rs:16:26: 16:27
StorageLive(_5); // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
_5 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:16:14: 16:15
StorageLive(_8); // scope 2 at $DIR/match_false_edges.rs:16:35: 16:36
_8 = _5; // scope 2 at $DIR/match_false_edges.rs:16:35: 16:36
_1 = (const 1_i32, move _8); // scope 2 at $DIR/match_false_edges.rs:16:31: 16:37
StorageDead(_8); // scope 2 at $DIR/match_false_edges.rs:16:36: 16:37
StorageDead(_5); // scope 0 at $DIR/match_false_edges.rs:16:36: 16:37
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:16:36: 16:37
goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:16:36: 16:37
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:14:26: 14:27
FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_false_edges.rs:14:26: 14:27
FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_false_edges.rs:14:26: 14:27
StorageLive(_5); // scope 0 at $DIR/match_false_edges.rs:14:14: 14:15
_5 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:14:14: 14:15
StorageLive(_8); // scope 2 at $DIR/match_false_edges.rs:14:35: 14:36
_8 = _5; // scope 2 at $DIR/match_false_edges.rs:14:35: 14:36
_1 = (const 1_i32, move _8); // scope 2 at $DIR/match_false_edges.rs:14:31: 14:37
StorageDead(_8); // scope 2 at $DIR/match_false_edges.rs:14:36: 14:37
StorageDead(_5); // scope 0 at $DIR/match_false_edges.rs:14:36: 14:37
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:14:36: 14:37
goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:14:36: 14:37
}
bb8: {
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:16:26: 16:27
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:16:36: 16:37
goto -> bb3; // scope 0 at $DIR/match_false_edges.rs:16:20: 16:27
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:14:26: 14:27
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:14:36: 14:37
goto -> bb3; // scope 0 at $DIR/match_false_edges.rs:14:20: 14:27
}
bb9: {
StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:17:14: 17:15
_9 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:17:14: 17:15
StorageLive(_10); // scope 3 at $DIR/match_false_edges.rs:17:24: 17:25
_10 = _9; // scope 3 at $DIR/match_false_edges.rs:17:24: 17:25
_1 = (const 2_i32, move _10); // scope 3 at $DIR/match_false_edges.rs:17:20: 17:26
StorageDead(_10); // scope 3 at $DIR/match_false_edges.rs:17:25: 17:26
StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:17:25: 17:26
goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:17:25: 17:26
StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:15:14: 15:15
_9 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:15:14: 15:15
StorageLive(_10); // scope 3 at $DIR/match_false_edges.rs:15:24: 15:25
_10 = _9; // scope 3 at $DIR/match_false_edges.rs:15:24: 15:25
_1 = (const 2_i32, move _10); // scope 3 at $DIR/match_false_edges.rs:15:20: 15:26
StorageDead(_10); // scope 3 at $DIR/match_false_edges.rs:15:25: 15:26
StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:15:25: 15:26
goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:15:25: 15:26
}
bb10: {
StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:19:6: 19:7
StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:19:6: 19:7
_0 = const (); // scope 0 at $DIR/match_false_edges.rs:14:28: 20:2
return; // scope 0 at $DIR/match_false_edges.rs:20:2: 20:2
StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:17:6: 17:7
StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:17:6: 17:7
_0 = const (); // scope 0 at $DIR/match_false_edges.rs:12:28: 18:2
return; // scope 0 at $DIR/match_false_edges.rs:18:2: 18:2
}
bb11 (cleanup): {
resume; // scope 0 at $DIR/match_false_edges.rs:14:1: 20:2
resume; // scope 0 at $DIR/match_false_edges.rs:12:1: 18:2
}
}

View File

@ -1,108 +1,108 @@
// MIR for `full_tested_match2` before PromoteTemps
fn full_tested_match2() -> () {
let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:25:29: 25:29
let mut _1: (i32, i32); // in scope 0 at $DIR/match_false_edges.rs:26:13: 30:6
let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:26:19: 26:27
let mut _3: isize; // in scope 0 at $DIR/match_false_edges.rs:27:9: 27:16
let mut _4: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:26:19: 26:27
let _5: i32; // in scope 0 at $DIR/match_false_edges.rs:27:14: 27:15
let _6: &i32; // in scope 0 at $DIR/match_false_edges.rs:27:14: 27:15
let mut _7: bool; // in scope 0 at $DIR/match_false_edges.rs:27:20: 27:27
let mut _8: i32; // in scope 0 at $DIR/match_false_edges.rs:27:35: 27:36
let _9: i32; // in scope 0 at $DIR/match_false_edges.rs:29:14: 29:15
let mut _10: i32; // in scope 0 at $DIR/match_false_edges.rs:29:24: 29:25
let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:23:29: 23:29
let mut _1: (i32, i32); // in scope 0 at $DIR/match_false_edges.rs:24:13: 28:6
let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:24:19: 24:27
let mut _3: isize; // in scope 0 at $DIR/match_false_edges.rs:25:9: 25:16
let mut _4: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:24:19: 24:27
let _5: i32; // in scope 0 at $DIR/match_false_edges.rs:25:14: 25:15
let _6: &i32; // in scope 0 at $DIR/match_false_edges.rs:25:14: 25:15
let mut _7: bool; // in scope 0 at $DIR/match_false_edges.rs:25:20: 25:27
let mut _8: i32; // in scope 0 at $DIR/match_false_edges.rs:25:35: 25:36
let _9: i32; // in scope 0 at $DIR/match_false_edges.rs:27:14: 27:15
let mut _10: i32; // in scope 0 at $DIR/match_false_edges.rs:27:24: 27:25
scope 1 {
}
scope 2 {
debug x => _5; // in scope 2 at $DIR/match_false_edges.rs:27:14: 27:15
debug x => _6; // in scope 2 at $DIR/match_false_edges.rs:27:14: 27:15
debug x => _5; // in scope 2 at $DIR/match_false_edges.rs:25:14: 25:15
debug x => _6; // in scope 2 at $DIR/match_false_edges.rs:25:14: 25:15
}
scope 3 {
debug y => _9; // in scope 3 at $DIR/match_false_edges.rs:29:14: 29:15
debug y => _9; // in scope 3 at $DIR/match_false_edges.rs:27:14: 27:15
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:26:13: 30:6
StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27
_2 = Option::<i32>::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27
FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27
_3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27
switchInt(move _3) -> [0_isize: bb1, 1_isize: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:26:13: 26:27
StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:24:13: 28:6
StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:24:19: 24:27
_2 = Option::<i32>::Some(const 42_i32); // scope 0 at $DIR/match_false_edges.rs:24:19: 24:27
FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:24:19: 24:27
_3 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:24:19: 24:27
switchInt(move _3) -> [0_isize: bb1, 1_isize: bb2, otherwise: bb4]; // scope 0 at $DIR/match_false_edges.rs:24:13: 24:27
}
bb1: {
falseEdge -> [real: bb9, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:28:9: 28:13
falseEdge -> [real: bb9, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:26:9: 26:13
}
bb2: {
falseEdge -> [real: bb5, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:27:9: 27:16
falseEdge -> [real: bb5, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:25:9: 25:16
}
bb3: {
StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:29:14: 29:15
_9 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:29:14: 29:15
StorageLive(_10); // scope 3 at $DIR/match_false_edges.rs:29:24: 29:25
_10 = _9; // scope 3 at $DIR/match_false_edges.rs:29:24: 29:25
_1 = (const 2_i32, move _10); // scope 3 at $DIR/match_false_edges.rs:29:20: 29:26
StorageDead(_10); // scope 3 at $DIR/match_false_edges.rs:29:25: 29:26
StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:29:25: 29:26
goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:29:25: 29:26
StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:27:14: 27:15
_9 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:27:14: 27:15
StorageLive(_10); // scope 3 at $DIR/match_false_edges.rs:27:24: 27:25
_10 = _9; // scope 3 at $DIR/match_false_edges.rs:27:24: 27:25
_1 = (const 2_i32, move _10); // scope 3 at $DIR/match_false_edges.rs:27:20: 27:26
StorageDead(_10); // scope 3 at $DIR/match_false_edges.rs:27:25: 27:26
StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:27:25: 27:26
goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:27:25: 27:26
}
bb4: {
unreachable; // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27
unreachable; // scope 0 at $DIR/match_false_edges.rs:24:19: 24:27
}
bb5: {
StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:27:14: 27:15
_6 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:27:14: 27:15
_4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:26:19: 26:27
StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:27:20: 27:27
_7 = guard() -> [return: bb6, unwind: bb11]; // scope 0 at $DIR/match_false_edges.rs:27:20: 27:27
StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:25:14: 25:15
_6 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:25:14: 25:15
_4 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:24:19: 24:27
StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:25:20: 25:27
_7 = guard() -> [return: bb6, unwind: bb11]; // scope 0 at $DIR/match_false_edges.rs:25:20: 25:27
// mir::Constant
// + span: $DIR/match_false_edges.rs:27:20: 27:25
// + span: $DIR/match_false_edges.rs:25:20: 25:25
// + literal: Const { ty: fn() -> bool {guard}, val: Value(Scalar(<ZST>)) }
}
bb6: {
switchInt(move _7) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:27:20: 27:27
switchInt(move _7) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:25:20: 25:27
}
bb7: {
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:27:26: 27:27
FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_false_edges.rs:27:26: 27:27
FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_false_edges.rs:27:26: 27:27
StorageLive(_5); // scope 0 at $DIR/match_false_edges.rs:27:14: 27:15
_5 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:27:14: 27:15
StorageLive(_8); // scope 2 at $DIR/match_false_edges.rs:27:35: 27:36
_8 = _5; // scope 2 at $DIR/match_false_edges.rs:27:35: 27:36
_1 = (const 1_i32, move _8); // scope 2 at $DIR/match_false_edges.rs:27:31: 27:37
StorageDead(_8); // scope 2 at $DIR/match_false_edges.rs:27:36: 27:37
StorageDead(_5); // scope 0 at $DIR/match_false_edges.rs:27:36: 27:37
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:27:36: 27:37
goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:27:36: 27:37
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:25:26: 25:27
FakeRead(ForMatchGuard, _4); // scope 0 at $DIR/match_false_edges.rs:25:26: 25:27
FakeRead(ForGuardBinding, _6); // scope 0 at $DIR/match_false_edges.rs:25:26: 25:27
StorageLive(_5); // scope 0 at $DIR/match_false_edges.rs:25:14: 25:15
_5 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:25:14: 25:15
StorageLive(_8); // scope 2 at $DIR/match_false_edges.rs:25:35: 25:36
_8 = _5; // scope 2 at $DIR/match_false_edges.rs:25:35: 25:36
_1 = (const 1_i32, move _8); // scope 2 at $DIR/match_false_edges.rs:25:31: 25:37
StorageDead(_8); // scope 2 at $DIR/match_false_edges.rs:25:36: 25:37
StorageDead(_5); // scope 0 at $DIR/match_false_edges.rs:25:36: 25:37
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:25:36: 25:37
goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:25:36: 25:37
}
bb8: {
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:27:26: 27:27
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:27:36: 27:37
falseEdge -> [real: bb3, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:27:20: 27:27
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:25:26: 25:27
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:25:36: 25:37
falseEdge -> [real: bb3, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:25:20: 25:27
}
bb9: {
_1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:28:17: 28:23
goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:28:17: 28:23
_1 = (const 3_i32, const 3_i32); // scope 0 at $DIR/match_false_edges.rs:26:17: 26:23
goto -> bb10; // scope 0 at $DIR/match_false_edges.rs:26:17: 26:23
}
bb10: {
StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:30:6: 30:7
StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:30:6: 30:7
_0 = const (); // scope 0 at $DIR/match_false_edges.rs:25:29: 31:2
return; // scope 0 at $DIR/match_false_edges.rs:31:2: 31:2
StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:28:6: 28:7
StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:28:6: 28:7
_0 = const (); // scope 0 at $DIR/match_false_edges.rs:23:29: 29:2
return; // scope 0 at $DIR/match_false_edges.rs:29:2: 29:2
}
bb11 (cleanup): {
resume; // scope 0 at $DIR/match_false_edges.rs:25:1: 31:2
resume; // scope 0 at $DIR/match_false_edges.rs:23:1: 29:2
}
}

View File

@ -1,153 +1,153 @@
// MIR for `main` before PromoteTemps
fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:34:11: 34:11
let mut _1: i32; // in scope 0 at $DIR/match_false_edges.rs:35:13: 40:6
let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:35:19: 35:26
let mut _3: isize; // in scope 0 at $DIR/match_false_edges.rs:38:9: 38:16
let mut _4: isize; // in scope 0 at $DIR/match_false_edges.rs:36:9: 36:17
let mut _5: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:35:19: 35:26
let _6: i32; // in scope 0 at $DIR/match_false_edges.rs:36:14: 36:16
let _7: &i32; // in scope 0 at $DIR/match_false_edges.rs:36:14: 36:16
let mut _8: bool; // in scope 0 at $DIR/match_false_edges.rs:36:21: 36:28
let _9: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:37:9: 37:11
let _10: i32; // in scope 0 at $DIR/match_false_edges.rs:38:14: 38:15
let _11: &i32; // in scope 0 at $DIR/match_false_edges.rs:38:14: 38:15
let mut _12: bool; // in scope 0 at $DIR/match_false_edges.rs:38:20: 38:29
let mut _13: i32; // in scope 0 at $DIR/match_false_edges.rs:38:27: 38:28
let _14: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:39:9: 39:11
let mut _0: (); // return place in scope 0 at $DIR/match_false_edges.rs:32:11: 32:11
let mut _1: i32; // in scope 0 at $DIR/match_false_edges.rs:33:13: 38:6
let mut _2: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:33:19: 33:26
let mut _3: isize; // in scope 0 at $DIR/match_false_edges.rs:36:9: 36:16
let mut _4: isize; // in scope 0 at $DIR/match_false_edges.rs:34:9: 34:17
let mut _5: &std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:33:19: 33:26
let _6: i32; // in scope 0 at $DIR/match_false_edges.rs:34:14: 34:16
let _7: &i32; // in scope 0 at $DIR/match_false_edges.rs:34:14: 34:16
let mut _8: bool; // in scope 0 at $DIR/match_false_edges.rs:34:21: 34:28
let _9: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:35:9: 35:11
let _10: i32; // in scope 0 at $DIR/match_false_edges.rs:36:14: 36:15
let _11: &i32; // in scope 0 at $DIR/match_false_edges.rs:36:14: 36:15
let mut _12: bool; // in scope 0 at $DIR/match_false_edges.rs:36:20: 36:29
let mut _13: i32; // in scope 0 at $DIR/match_false_edges.rs:36:27: 36:28
let _14: std::option::Option<i32>; // in scope 0 at $DIR/match_false_edges.rs:37:9: 37:11
scope 1 {
}
scope 2 {
debug _w => _6; // in scope 2 at $DIR/match_false_edges.rs:36:14: 36:16
debug _w => _7; // in scope 2 at $DIR/match_false_edges.rs:36:14: 36:16
debug _w => _6; // in scope 2 at $DIR/match_false_edges.rs:34:14: 34:16
debug _w => _7; // in scope 2 at $DIR/match_false_edges.rs:34:14: 34:16
}
scope 3 {
debug _x => _9; // in scope 3 at $DIR/match_false_edges.rs:37:9: 37:11
debug _x => _9; // in scope 3 at $DIR/match_false_edges.rs:35:9: 35:11
}
scope 4 {
debug y => _10; // in scope 4 at $DIR/match_false_edges.rs:38:14: 38:15
debug y => _11; // in scope 4 at $DIR/match_false_edges.rs:38:14: 38:15
debug y => _10; // in scope 4 at $DIR/match_false_edges.rs:36:14: 36:15
debug y => _11; // in scope 4 at $DIR/match_false_edges.rs:36:14: 36:15
}
scope 5 {
debug _z => _14; // in scope 5 at $DIR/match_false_edges.rs:39:9: 39:11
debug _z => _14; // in scope 5 at $DIR/match_false_edges.rs:37:9: 37:11
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:35:13: 40:6
StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26
_2 = Option::<i32>::Some(const 1_i32); // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26
FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26
_4 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26
switchInt(move _4) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/match_false_edges.rs:35:13: 35:26
StorageLive(_1); // scope 0 at $DIR/match_false_edges.rs:33:13: 38:6
StorageLive(_2); // scope 0 at $DIR/match_false_edges.rs:33:19: 33:26
_2 = Option::<i32>::Some(const 1_i32); // scope 0 at $DIR/match_false_edges.rs:33:19: 33:26
FakeRead(ForMatchedPlace(None), _2); // scope 0 at $DIR/match_false_edges.rs:33:19: 33:26
_4 = discriminant(_2); // scope 0 at $DIR/match_false_edges.rs:33:19: 33:26
switchInt(move _4) -> [1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/match_false_edges.rs:33:13: 33:26
}
bb1: {
falseEdge -> [real: bb9, imaginary: bb4]; // scope 0 at $DIR/match_false_edges.rs:37:9: 37:11
falseEdge -> [real: bb9, imaginary: bb4]; // scope 0 at $DIR/match_false_edges.rs:35:9: 35:11
}
bb2: {
falseEdge -> [real: bb5, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:36:9: 36:17
falseEdge -> [real: bb5, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:34:9: 34:17
}
bb3: {
StorageLive(_14); // scope 0 at $DIR/match_false_edges.rs:39:9: 39:11
_14 = _2; // scope 0 at $DIR/match_false_edges.rs:39:9: 39:11
_1 = const 4_i32; // scope 5 at $DIR/match_false_edges.rs:39:15: 39:16
StorageDead(_14); // scope 0 at $DIR/match_false_edges.rs:39:15: 39:16
goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:39:15: 39:16
StorageLive(_14); // scope 0 at $DIR/match_false_edges.rs:37:9: 37:11
_14 = _2; // scope 0 at $DIR/match_false_edges.rs:37:9: 37:11
_1 = const 4_i32; // scope 5 at $DIR/match_false_edges.rs:37:15: 37:16
StorageDead(_14); // scope 0 at $DIR/match_false_edges.rs:37:15: 37:16
goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:37:15: 37:16
}
bb4: {
falseEdge -> [real: bb10, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:38:9: 38:16
falseEdge -> [real: bb10, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:36:9: 36:16
}
bb5: {
StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:36:14: 36:16
_7 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:36:14: 36:16
_5 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26
StorageLive(_8); // scope 0 at $DIR/match_false_edges.rs:36:21: 36:28
_8 = guard() -> [return: bb6, unwind: bb15]; // scope 0 at $DIR/match_false_edges.rs:36:21: 36:28
StorageLive(_7); // scope 0 at $DIR/match_false_edges.rs:34:14: 34:16
_7 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:34:14: 34:16
_5 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:33:19: 33:26
StorageLive(_8); // scope 0 at $DIR/match_false_edges.rs:34:21: 34:28
_8 = guard() -> [return: bb6, unwind: bb15]; // scope 0 at $DIR/match_false_edges.rs:34:21: 34:28
// mir::Constant
// + span: $DIR/match_false_edges.rs:36:21: 36:26
// + span: $DIR/match_false_edges.rs:34:21: 34:26
// + literal: Const { ty: fn() -> bool {guard}, val: Value(Scalar(<ZST>)) }
}
bb6: {
switchInt(move _8) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:36:21: 36:28
switchInt(move _8) -> [false: bb8, otherwise: bb7]; // scope 0 at $DIR/match_false_edges.rs:34:21: 34:28
}
bb7: {
StorageDead(_8); // scope 0 at $DIR/match_false_edges.rs:36:27: 36:28
FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/match_false_edges.rs:36:27: 36:28
FakeRead(ForGuardBinding, _7); // scope 0 at $DIR/match_false_edges.rs:36:27: 36:28
StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:36:14: 36:16
_6 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:36:14: 36:16
_1 = const 1_i32; // scope 2 at $DIR/match_false_edges.rs:36:32: 36:33
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:36:32: 36:33
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:36:32: 36:33
goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:36:32: 36:33
StorageDead(_8); // scope 0 at $DIR/match_false_edges.rs:34:27: 34:28
FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/match_false_edges.rs:34:27: 34:28
FakeRead(ForGuardBinding, _7); // scope 0 at $DIR/match_false_edges.rs:34:27: 34:28
StorageLive(_6); // scope 0 at $DIR/match_false_edges.rs:34:14: 34:16
_6 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:34:14: 34:16
_1 = const 1_i32; // scope 2 at $DIR/match_false_edges.rs:34:32: 34:33
StorageDead(_6); // scope 0 at $DIR/match_false_edges.rs:34:32: 34:33
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:34:32: 34:33
goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:34:32: 34:33
}
bb8: {
StorageDead(_8); // scope 0 at $DIR/match_false_edges.rs:36:27: 36:28
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:36:32: 36:33
falseEdge -> [real: bb1, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:36:21: 36:28
StorageDead(_8); // scope 0 at $DIR/match_false_edges.rs:34:27: 34:28
StorageDead(_7); // scope 0 at $DIR/match_false_edges.rs:34:32: 34:33
falseEdge -> [real: bb1, imaginary: bb1]; // scope 0 at $DIR/match_false_edges.rs:34:21: 34:28
}
bb9: {
StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:37:9: 37:11
_9 = _2; // scope 0 at $DIR/match_false_edges.rs:37:9: 37:11
_1 = const 2_i32; // scope 3 at $DIR/match_false_edges.rs:37:15: 37:16
StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:37:15: 37:16
goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:37:15: 37:16
StorageLive(_9); // scope 0 at $DIR/match_false_edges.rs:35:9: 35:11
_9 = _2; // scope 0 at $DIR/match_false_edges.rs:35:9: 35:11
_1 = const 2_i32; // scope 3 at $DIR/match_false_edges.rs:35:15: 35:16
StorageDead(_9); // scope 0 at $DIR/match_false_edges.rs:35:15: 35:16
goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:35:15: 35:16
}
bb10: {
StorageLive(_11); // scope 0 at $DIR/match_false_edges.rs:38:14: 38:15
_11 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:38:14: 38:15
_5 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:35:19: 35:26
StorageLive(_12); // scope 0 at $DIR/match_false_edges.rs:38:20: 38:29
StorageLive(_13); // scope 0 at $DIR/match_false_edges.rs:38:27: 38:28
_13 = (*_11); // scope 0 at $DIR/match_false_edges.rs:38:27: 38:28
_12 = guard2(move _13) -> [return: bb11, unwind: bb15]; // scope 0 at $DIR/match_false_edges.rs:38:20: 38:29
StorageLive(_11); // scope 0 at $DIR/match_false_edges.rs:36:14: 36:15
_11 = &((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:36:14: 36:15
_5 = &shallow _2; // scope 0 at $DIR/match_false_edges.rs:33:19: 33:26
StorageLive(_12); // scope 0 at $DIR/match_false_edges.rs:36:20: 36:29
StorageLive(_13); // scope 0 at $DIR/match_false_edges.rs:36:27: 36:28
_13 = (*_11); // scope 0 at $DIR/match_false_edges.rs:36:27: 36:28
_12 = guard2(move _13) -> [return: bb11, unwind: bb15]; // scope 0 at $DIR/match_false_edges.rs:36:20: 36:29
// mir::Constant
// + span: $DIR/match_false_edges.rs:38:20: 38:26
// + span: $DIR/match_false_edges.rs:36:20: 36:26
// + literal: Const { ty: fn(i32) -> bool {guard2}, val: Value(Scalar(<ZST>)) }
}
bb11: {
switchInt(move _12) -> [false: bb13, otherwise: bb12]; // scope 0 at $DIR/match_false_edges.rs:38:20: 38:29
switchInt(move _12) -> [false: bb13, otherwise: bb12]; // scope 0 at $DIR/match_false_edges.rs:36:20: 36:29
}
bb12: {
StorageDead(_13); // scope 0 at $DIR/match_false_edges.rs:38:28: 38:29
StorageDead(_12); // scope 0 at $DIR/match_false_edges.rs:38:28: 38:29
FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/match_false_edges.rs:38:28: 38:29
FakeRead(ForGuardBinding, _11); // scope 0 at $DIR/match_false_edges.rs:38:28: 38:29
StorageLive(_10); // scope 0 at $DIR/match_false_edges.rs:38:14: 38:15
_10 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:38:14: 38:15
_1 = const 3_i32; // scope 4 at $DIR/match_false_edges.rs:38:33: 38:34
StorageDead(_10); // scope 0 at $DIR/match_false_edges.rs:38:33: 38:34
StorageDead(_11); // scope 0 at $DIR/match_false_edges.rs:38:33: 38:34
goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:38:33: 38:34
StorageDead(_13); // scope 0 at $DIR/match_false_edges.rs:36:28: 36:29
StorageDead(_12); // scope 0 at $DIR/match_false_edges.rs:36:28: 36:29
FakeRead(ForMatchGuard, _5); // scope 0 at $DIR/match_false_edges.rs:36:28: 36:29
FakeRead(ForGuardBinding, _11); // scope 0 at $DIR/match_false_edges.rs:36:28: 36:29
StorageLive(_10); // scope 0 at $DIR/match_false_edges.rs:36:14: 36:15
_10 = ((_2 as Some).0: i32); // scope 0 at $DIR/match_false_edges.rs:36:14: 36:15
_1 = const 3_i32; // scope 4 at $DIR/match_false_edges.rs:36:33: 36:34
StorageDead(_10); // scope 0 at $DIR/match_false_edges.rs:36:33: 36:34
StorageDead(_11); // scope 0 at $DIR/match_false_edges.rs:36:33: 36:34
goto -> bb14; // scope 0 at $DIR/match_false_edges.rs:36:33: 36:34
}
bb13: {
StorageDead(_13); // scope 0 at $DIR/match_false_edges.rs:38:28: 38:29
StorageDead(_12); // scope 0 at $DIR/match_false_edges.rs:38:28: 38:29
StorageDead(_11); // scope 0 at $DIR/match_false_edges.rs:38:33: 38:34
falseEdge -> [real: bb3, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:38:20: 38:29
StorageDead(_13); // scope 0 at $DIR/match_false_edges.rs:36:28: 36:29
StorageDead(_12); // scope 0 at $DIR/match_false_edges.rs:36:28: 36:29
StorageDead(_11); // scope 0 at $DIR/match_false_edges.rs:36:33: 36:34
falseEdge -> [real: bb3, imaginary: bb3]; // scope 0 at $DIR/match_false_edges.rs:36:20: 36:29
}
bb14: {
StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:40:6: 40:7
StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:40:6: 40:7
_0 = const (); // scope 0 at $DIR/match_false_edges.rs:34:11: 41:2
return; // scope 0 at $DIR/match_false_edges.rs:41:2: 41:2
StorageDead(_2); // scope 0 at $DIR/match_false_edges.rs:38:6: 38:7
StorageDead(_1); // scope 0 at $DIR/match_false_edges.rs:38:6: 38:7
_0 = const (); // scope 0 at $DIR/match_false_edges.rs:32:11: 39:2
return; // scope 0 at $DIR/match_false_edges.rs:39:2: 39:2
}
bb15 (cleanup): {
resume; // scope 0 at $DIR/match_false_edges.rs:34:1: 41:2
resume; // scope 0 at $DIR/match_false_edges.rs:32:1: 39:2
}
}

View File

@ -1,5 +1,3 @@
// compile-flags: -Z borrowck=mir
fn guard() -> bool {
false
}

View File

@ -3,7 +3,7 @@
// suitable variables and that we setup the outlives relationship
// between R0 and R1 properly.
// compile-flags:-Zborrowck=mir -Zverbose
// compile-flags: -Zverbose
// ^^^^^^^^^ force compiler to dump more region information
#![allow(warnings)]

View File

@ -2,7 +2,7 @@
// in the type of `p` includes the points after `&v[0]` up to (but not
// including) the call to `use_x`. The `else` branch is not included.
// compile-flags:-Zborrowck=mir -Zverbose
// compile-flags:-Zverbose
// ^^^^^^^^^ force compiler to dump more region information
#![allow(warnings)]

View File

@ -3,7 +3,7 @@
// random #![feature] to ensure that crate attrs
// do not offset things
/// ```rust
/// #![feature(nll)]
/// #![feature(bool_to_option)]
/// let x: char = 1;
/// ```
pub fn foo() {
@ -13,7 +13,7 @@ pub fn foo() {
/// Add some text around the test...
///
/// ```rust
/// #![feature(nll)]
/// #![feature(bool_to_option)]
/// let x: char = 1;
/// ```
///
@ -22,7 +22,7 @@ pub fn foo() {
/// Let's also add a second test in the same doc comment.
///
/// ```rust
/// #![feature(nll)]
/// #![feature(bool_to_option)]
/// let x: char = 1;
/// ```
pub fn bar() {}

View File

@ -1,21 +0,0 @@
error[E0623]: lifetime mismatch
--> $DIR/implied-region-constraints.rs:21:64
|
LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>)
| ------------- this type is declared with multiple lifetimes...
...
LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0;
| ^^^^^ ...but data with one lifetime flows into the other here
error[E0623]: lifetime mismatch
--> $DIR/implied-region-constraints.rs:43:72
|
LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>)
| -------------- this type is declared with multiple lifetimes...
...
LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x;
| ^^ ...but data with one lifetime flows into the other here
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0623`.

View File

@ -1,7 +1,3 @@
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
#![feature(associated_type_bounds)]
trait Tr1 { type As1; }
@ -19,8 +15,7 @@ where
{
// This should fail because `T: 'b` is not implied from `WF(St<'a, 'b, T>)`.
let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0;
//[base]~^ ERROR lifetime mismatch [E0623]
//[nll]~^^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
}
enum En7<'a, 'b, T> // `<T::As1 as Tr2>::As2: 'a` is implied.
@ -41,8 +36,7 @@ where
En7::V0(x) => {
// Also fails for the same reason as above:
let _failure_proves_not_implied_outlives_region_b: &'b T = &x;
//[base]~^ ERROR lifetime mismatch [E0623]
//[nll]~^^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
},
En7::V1(_) => {},
}

View File

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/implied-region-constraints.rs:21:56
--> $DIR/implied-region-constraints.rs:17:56
|
LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>)
| -- -- lifetime `'b` defined here
@ -12,7 +12,7 @@ LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0;
= help: consider adding the following bound: `'a: 'b`
error: lifetime may not live long enough
--> $DIR/implied-region-constraints.rs:43:64
--> $DIR/implied-region-constraints.rs:38:64
|
LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>)
| -- -- lifetime `'b` defined here

View File

@ -1,92 +0,0 @@
error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
--> $DIR/associated-types-eq-hr.rs:91:5
|
LL | foo::<UintStruct>();
| ^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
|
note: expected this to be `&isize`
--> $DIR/associated-types-eq-hr.rs:30:14
|
LL | type A = &'a usize;
| ^^^^^^^^^
= note: expected reference `&isize`
found reference `&usize`
note: required by a bound in `foo`
--> $DIR/associated-types-eq-hr.rs:49:36
|
LL | fn foo<T>()
| --- required by a bound in this
LL | where
LL | T: for<'x> TheTrait<&'x isize, A = &'x isize>,
| ^^^^^^^^^^^^^ required by this bound in `foo`
error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
--> $DIR/associated-types-eq-hr.rs:95:5
|
LL | bar::<IntStruct>();
| ^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
|
note: expected this to be `&usize`
--> $DIR/associated-types-eq-hr.rs:18:14
|
LL | type A = &'a isize;
| ^^^^^^^^^
= note: expected reference `&usize`
found reference `&isize`
note: required by a bound in `bar`
--> $DIR/associated-types-eq-hr.rs:56:36
|
LL | fn bar<T>()
| --- required by a bound in this
LL | where
LL | T: for<'x> TheTrait<&'x isize, A = &'x usize>,
| ^^^^^^^^^^^^^ required by this bound in `bar`
error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:100:5
|
LL | tuple_one::<Tuple>();
| ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
|
= note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
= note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:100:5
|
LL | tuple_one::<Tuple>();
| ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
|
= note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
= note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:106:5
|
LL | tuple_two::<Tuple>();
| ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
|
= note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
= note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:106:5
|
LL | tuple_two::<Tuple>();
| ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
|
= note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
= note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:116:5
|
LL | tuple_four::<Tuple>();
| ^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
|
= note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
= note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0271`.

View File

@ -1,7 +1,3 @@
// revisions: base nll
// ignore-compare-mode-nll
//[nll] compile-flags: -Z borrowck=mir
// Check testing of equality constraints in a higher-ranked context.
pub trait TheTrait<T> {
@ -98,14 +94,10 @@ pub fn call_bar() {
pub fn call_tuple_one() {
tuple_one::<Tuple>();
//[base]~^ ERROR implementation of `TheTrait` is not general enough
//[base]~| ERROR implementation of `TheTrait` is not general enough
}
pub fn call_tuple_two() {
tuple_two::<Tuple>();
//[base]~^ ERROR implementation of `TheTrait` is not general enough
//[base]~| ERROR implementation of `TheTrait` is not general enough
}
pub fn call_tuple_three() {
@ -114,7 +106,6 @@ pub fn call_tuple_three() {
pub fn call_tuple_four() {
tuple_four::<Tuple>();
//[base]~^ ERROR implementation of `TheTrait` is not general enough
}
fn main() {}

View File

@ -1,18 +1,18 @@
error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
--> $DIR/associated-types-eq-hr.rs:91:5
--> $DIR/associated-types-eq-hr.rs:87:5
|
LL | foo::<UintStruct>();
| ^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
|
note: expected this to be `&isize`
--> $DIR/associated-types-eq-hr.rs:30:14
--> $DIR/associated-types-eq-hr.rs:26:14
|
LL | type A = &'a usize;
| ^^^^^^^^^
= note: expected reference `&isize`
found reference `&usize`
note: required by a bound in `foo`
--> $DIR/associated-types-eq-hr.rs:49:36
--> $DIR/associated-types-eq-hr.rs:45:36
|
LL | fn foo<T>()
| --- required by a bound in this
@ -21,20 +21,20 @@ LL | T: for<'x> TheTrait<&'x isize, A = &'x isize>,
| ^^^^^^^^^^^^^ required by this bound in `foo`
error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
--> $DIR/associated-types-eq-hr.rs:95:5
--> $DIR/associated-types-eq-hr.rs:91:5
|
LL | bar::<IntStruct>();
| ^^^^^^^^^^^^^^^^ type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
|
note: expected this to be `&usize`
--> $DIR/associated-types-eq-hr.rs:18:14
--> $DIR/associated-types-eq-hr.rs:14:14
|
LL | type A = &'a isize;
| ^^^^^^^^^
= note: expected reference `&usize`
found reference `&isize`
note: required by a bound in `bar`
--> $DIR/associated-types-eq-hr.rs:56:36
--> $DIR/associated-types-eq-hr.rs:52:36
|
LL | fn bar<T>()
| --- required by a bound in this

View File

@ -1,14 +0,0 @@
error[E0623]: lifetime mismatch
--> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:26:40
|
LL | x: <I as Foo<&'a isize>>::A,
| --------- these two types are declared with different lifetimes...
LL | y: <I as Foo<&'b isize>>::A,
| ---------
...
LL | let z: I::A = if cond { x } else { y };
| ^ ...but data from `x` flows into `y` here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0623`.

View File

@ -1,7 +1,3 @@
// ignore-compare-mode-nll
// revisions: base nll
// [nll]compile-flags: -Zborrowck=mir
// Check projection of an associated type out of a higher-ranked
// trait-bound in the context of a function body.
@ -24,9 +20,8 @@ fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>(
{
// x and y here have two distinct lifetimes:
let z: I::A = if cond { x } else { y };
//[base]~^ ERROR lifetime mismatch
//[nll]~^^ ERROR lifetime may not live long enough
//[nll]~| ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
//~| ERROR lifetime may not live long enough
}
pub fn main() {}

View File

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:26:29
--> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:22:29
|
LL | fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>(
| -- -- lifetime `'b` defined here
@ -12,7 +12,7 @@ LL | let z: I::A = if cond { x } else { y };
= help: consider adding the following bound: `'a: 'b`
error: lifetime may not live long enough
--> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:26:40
--> $DIR/associated-types-project-from-hrtb-in-fn-body.rs:22:40
|
LL | fn bar<'a, 'b, I : for<'x> Foo<&'x isize>>(
| -- -- lifetime `'b` defined here

View File

@ -1,21 +0,0 @@
error[E0623]: lifetime mismatch
--> $DIR/associated-types-subtyping-1.rs:31:38
|
LL | fn method2<'a,'b,T>(x: &'a T, y: &'b T)
| ----- ----- these two types are declared with different lifetimes...
...
LL | let _c: <T as Trait<'b>>::Type = a;
| ^ ...but data from `y` flows into `x` here
error[E0623]: lifetime mismatch
--> $DIR/associated-types-subtyping-1.rs:41:38
|
LL | fn method3<'a,'b,T>(x: &'a T, y: &'b T)
| ----- ----- these two types are declared with different lifetimes...
...
LL | let _c: <T as Trait<'a>>::Type = b;
| ^ ...but data from `y` flows into `x` here
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0623`.

View File

@ -1,7 +1,3 @@
// ignore-compare-mode-nll
// revisions: base nll
// [nll]compile-flags: -Zborrowck=mir
#![allow(unused_variables)]
fn make_any<T>() -> T { loop {} }
@ -26,10 +22,9 @@ fn method2<'a,'b,T>(x: &'a T, y: &'b T)
{
// Note that &'static T <: &'a T.
let a: <T as Trait<'a>>::Type = make_any();
//[nll]~^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
let b: <T as Trait<'b>>::Type = make_any();
let _c: <T as Trait<'b>>::Type = a;
//[base]~^ ERROR E0623
}
fn method3<'a,'b,T>(x: &'a T, y: &'b T)
@ -39,8 +34,7 @@ fn method3<'a,'b,T>(x: &'a T, y: &'b T)
let a: <T as Trait<'a>>::Type = make_any();
let b: <T as Trait<'b>>::Type = make_any();
let _c: <T as Trait<'a>>::Type = b;
//[base]~^ ERROR E0623
//[nll]~^^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
}
fn method4<'a,'b,T>(x: &'a T, y: &'b T)

View File

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/associated-types-subtyping-1.rs:28:12
--> $DIR/associated-types-subtyping-1.rs:24:12
|
LL | fn method2<'a,'b,T>(x: &'a T, y: &'b T)
| -- -- lifetime `'b` defined here
@ -12,7 +12,7 @@ LL | let a: <T as Trait<'a>>::Type = make_any();
= help: consider adding the following bound: `'b: 'a`
error: lifetime may not live long enough
--> $DIR/associated-types-subtyping-1.rs:41:13
--> $DIR/associated-types-subtyping-1.rs:36:13
|
LL | fn method3<'a,'b,T>(x: &'a T, y: &'b T)
| -- -- lifetime `'b` defined here

View File

@ -1,25 +0,0 @@
error[E0623]: lifetime mismatch
--> $DIR/project-fn-ret-contravariant-nll.rs:51:5
|
LL | fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
| ------- ------------------
| |
| this parameter and the return type are declared with different lifetimes...
...
LL | (a, b)
| ^ ...but data from `y` is returned here
error[E0623]: lifetime mismatch
--> $DIR/project-fn-ret-contravariant-nll.rs:51:8
|
LL | fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
| ------- ------------------
| |
| this parameter and the return type are declared with different lifetimes...
...
LL | (a, b)
| ^ ...but data from `x` is returned here
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0623`.

View File

@ -1,55 +0,0 @@
#![feature(unboxed_closures)]
// Test for projection cache. We should be able to project distinct
// lifetimes from `foo` as we reinstantiate it multiple times, but not
// if we do it just once. In this variant, the region `'a` is used in
// an contravariant position, which affects the results.
// revisions: ok oneuse transmute krisskross
//[ok] check-pass
//[oneuse] check-pass
// ignore-compare-mode-nll
// FIXME(nll): When stabilizing, this test should replace `project-fn-ret-contravariant.rs`
// The two would normally be just revisions, but this test uses revisions heavily, so splitting into
// a separate test is just easier.
#![allow(dead_code, unused_variables)]
fn foo<'a>() -> &'a u32 { loop { } }
fn bar<T>(t: T, x: T::Output) -> T::Output
where T: FnOnce<()>
{
t()
}
#[cfg(ok)] // two instantiations: OK
fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
let a = bar(foo, x);
let b = bar(foo, y);
(a, b)
}
#[cfg(oneuse)] // one instantiation: OK (surprisingly)
fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
let f /* : fn() -> &'static u32 */ = foo; // <-- inferred type annotated
let a = bar(f, x); // this is considered ok because fn args are contravariant...
let b = bar(f, y); // ...and hence we infer T to distinct values in each call.
(a, b)
}
#[cfg(transmute)] // one instantiations: BAD
fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
bar(foo, x) //[transmute]~ ERROR E0759
}
#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
let a = bar(foo, y);
let b = bar(foo, x);
(a, b) //[krisskross]~ ERROR lifetime mismatch [E0623]
//[krisskross]~^ ERROR lifetime mismatch [E0623]
}
fn main() { }

View File

@ -1,11 +0,0 @@
error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/project-fn-ret-contravariant-nll.rs:44:8
|
LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
| ------- this data with lifetime `'a`...
LL | bar(foo, x)
| ^^^ - ...is used and required to live as long as `'static` here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0759`.

View File

@ -1,25 +1,30 @@
error[E0623]: lifetime mismatch
--> $DIR/project-fn-ret-contravariant.rs:52:5
error: lifetime may not live long enough
--> $DIR/project-fn-ret-contravariant.rs:46:4
|
LL | fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
| ------- ------------------
| -- -- lifetime `'b` defined here
| |
| this parameter and the return type are declared with different lifetimes...
| lifetime `'a` defined here
...
LL | (a, b)
| ^ ...but data from `y` is returned here
| ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
= help: consider adding the following bound: `'a: 'b`
error[E0623]: lifetime mismatch
--> $DIR/project-fn-ret-contravariant.rs:52:8
error: lifetime may not live long enough
--> $DIR/project-fn-ret-contravariant.rs:46:4
|
LL | fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
| ------- ------------------
| -- -- lifetime `'b` defined here
| |
| this parameter and the return type are declared with different lifetimes...
| lifetime `'a` defined here
...
LL | (a, b)
| ^ ...but data from `x` is returned here
| ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
= help: consider adding the following bound: `'b: 'a`
help: `'a` and `'b` must be the same: replace one with the other
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0623`.

View File

@ -9,12 +9,6 @@
//[ok] check-pass
//[oneuse] check-pass
// ignore-compare-mode-nll
// FIXME(nll): When stabilizing, this test should be replaced with
// `project-fn-ret-contravariant-nll.rs` The two would normally be just
// revisions, but this test uses revisions heavily, so splitting into
// a separate test is just easier.
#![allow(dead_code, unused_variables)]
fn foo<'a>() -> &'a u32 { loop { } }
@ -42,15 +36,15 @@ fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
#[cfg(transmute)] // one instantiations: BAD
fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
bar(foo, x) //[transmute]~ ERROR E0759
bar(foo, x) //[transmute]~ ERROR lifetime may not live long enough
}
#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
let a = bar(foo, y);
let b = bar(foo, x);
(a, b) //[krisskross]~ ERROR lifetime mismatch [E0623]
//[krisskross]~^ ERROR lifetime mismatch [E0623]
(a, b) //[krisskross]~ ERROR lifetime may not live long enough
//[krisskross]~^ ERROR lifetime may not live long enough
}
fn main() { }

View File

@ -1,11 +1,10 @@
error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/project-fn-ret-contravariant.rs:45:8
error: lifetime may not live long enough
--> $DIR/project-fn-ret-contravariant.rs:39:4
|
LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
| ------- this data with lifetime `'a`...
| -- lifetime `'a` defined here
LL | bar(foo, x)
| ^^^ - ...is used and required to live as long as `'static` here
| ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0759`.

View File

@ -1,36 +0,0 @@
error: lifetime may not live long enough
--> $DIR/project-fn-ret-invariant-nll.rs:64:5
|
LL | fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | (a, b)
| ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
= help: consider adding the following bound: `'a: 'b`
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error: lifetime may not live long enough
--> $DIR/project-fn-ret-invariant-nll.rs:64:5
|
LL | fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | (a, b)
| ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
= help: consider adding the following bound: `'b: 'a`
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
help: `'a` and `'b` must be the same: replace one with the other
error: aborting due to 2 previous errors

View File

@ -1,36 +0,0 @@
error: lifetime may not live long enough
--> $DIR/project-fn-ret-invariant-nll.rs:46:13
|
LL | fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | let f = foo; // <-- No consistent type can be inferred for `f` here.
LL | let a = bar(f, x);
| ^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
= help: consider adding the following bound: `'a: 'b`
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error: lifetime may not live long enough
--> $DIR/project-fn-ret-invariant-nll.rs:46:13
|
LL | fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | let f = foo; // <-- No consistent type can be inferred for `f` here.
LL | let a = bar(f, x);
| ^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
= note: requirement occurs because of a function pointer to `foo`
= note: the function `foo` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
help: `'a` and `'b` must be the same: replace one with the other
error: aborting due to 2 previous errors

View File

@ -1,69 +0,0 @@
#![feature(unboxed_closures)]
// Test for projection cache. We should be able to project distinct
// lifetimes from `foo` as we reinstantiate it multiple times, but not
// if we do it just once. In this variant, the region `'a` is used in
// an invariant position, which affects the results.
// revisions: ok oneuse transmute krisskross
//[ok] check-pass
// compile-flags: -Z borrowck=mir
// ignore-compare-mode-nll
// FIXME(nll): When stabilizing, this test should replace with `project-fn-ret-invariant.rs`
// The two would normally be just revisions, but this test uses revisions heavily, so splitting into
// a separate test is just easier.
#![allow(dead_code, unused_variables)]
use std::marker::PhantomData;
struct Type<'a> {
// Invariant
data: PhantomData<fn(&'a u32) -> &'a u32>,
}
fn foo<'a>() -> Type<'a> {
loop {}
}
fn bar<T>(t: T, x: T::Output) -> T::Output
where
T: FnOnce<()>,
{
t()
}
#[cfg(ok)] // two instantiations: OK
fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
let a = bar(foo, x);
let b = bar(foo, y);
(a, b)
}
#[cfg(oneuse)] // one instantiation: BAD
fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
let f = foo; // <-- No consistent type can be inferred for `f` here.
let a = bar(f, x); //[oneuse]~ ERROR lifetime may not live long enough
//[oneuse]~^ ERROR lifetime may not live long enough
let b = bar(f, y);
(a, b)
}
#[cfg(transmute)] // one instantiations: BAD
fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
// Cannot instantiate `foo` with any lifetime other than `'a`,
// since it is provided as input.
bar(foo, x) //[transmute]~ ERROR lifetime may not live long enough
}
#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
let a = bar(foo, y);
let b = bar(foo, x);
(a, b)
//[krisskross]~^ ERROR lifetime may not live long enough
//[krisskross]~| ERROR lifetime may not live long enough
}
fn main() {}

View File

@ -1,15 +0,0 @@
error: lifetime may not live long enough
--> $DIR/project-fn-ret-invariant-nll.rs:57:5
|
LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
| -- lifetime `'a` defined here
...
LL | bar(foo, x)
| ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error: aborting due to previous error

View File

@ -1,24 +1,36 @@
error[E0623]: lifetime mismatch
--> $DIR/project-fn-ret-invariant.rs:60:22
error: lifetime may not live long enough
--> $DIR/project-fn-ret-invariant.rs:59:5
|
LL | fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
| -------- --------------------
| -- -- lifetime `'b` defined here
| |
| this parameter and the return type are declared with different lifetimes...
LL | let a = bar(foo, y);
| ^ ...but data from `x` is returned here
error[E0623]: lifetime mismatch
--> $DIR/project-fn-ret-invariant.rs:62:9
|
LL | fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
| -------- --------------------
| |
| this parameter and the return type are declared with different lifetimes...
| lifetime `'a` defined here
...
LL | (a, b)
| ^ ...but data from `x` is returned here
| ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
= help: consider adding the following bound: `'a: 'b`
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error: lifetime may not live long enough
--> $DIR/project-fn-ret-invariant.rs:59:5
|
LL | fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
...
LL | (a, b)
| ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
= help: consider adding the following bound: `'b: 'a`
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
help: `'a` and `'b` must be the same: replace one with the other
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0623`.

View File

@ -1,14 +1,36 @@
error[E0623]: lifetime mismatch
--> $DIR/project-fn-ret-invariant.rs:46:20
error: lifetime may not live long enough
--> $DIR/project-fn-ret-invariant.rs:40:13
|
LL | fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
| -------- --------------------
| -- -- lifetime `'b` defined here
| |
| this parameter and the return type are declared with different lifetimes...
...
LL | let b = bar(f, y);
| ^ ...but data from `x` is returned here
| lifetime `'a` defined here
LL | let f = foo; // <-- No consistent type can be inferred for `f` here.
LL | let a = bar(f, x);
| ^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
= help: consider adding the following bound: `'a: 'b`
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error: aborting due to previous error
error: lifetime may not live long enough
--> $DIR/project-fn-ret-invariant.rs:40:13
|
LL | fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | let f = foo; // <-- No consistent type can be inferred for `f` here.
LL | let a = bar(f, x);
| ^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
= note: requirement occurs because of a function pointer to `foo`
= note: the function `foo` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
help: `'a` and `'b` must be the same: replace one with the other
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0623`.

View File

@ -7,11 +7,6 @@
// revisions: ok oneuse transmute krisskross
//[ok] check-pass
// ignore-compare-mode-nll
// FIXME(nll): When stabilizing, this test should be replaced with `project-fn-ret-invariant-nll.rs`
// The two would normally be just revisions, but this test uses revisions heavily, so splitting into
// a separate test is just easier.
#![allow(dead_code, unused_variables)]
use std::marker::PhantomData;
@ -43,7 +38,9 @@ fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
let f = foo; // <-- No consistent type can be inferred for `f` here.
let a = bar(f, x);
let b = bar(f, y); //[oneuse]~ ERROR lifetime mismatch [E0623]
//[oneuse]~^ ERROR lifetime may not live long enough
//[oneuse]~| ERROR lifetime may not live long enough
let b = bar(f, y);
(a, b)
}
@ -52,14 +49,16 @@ fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
// Cannot instantiate `foo` with any lifetime other than `'a`,
// since it is provided as input.
bar(foo, x) //[transmute]~ ERROR E0759
bar(foo, x) //[transmute]~ ERROR lifetime may not live long enough
}
#[cfg(krisskross)] // two instantiations, mixing and matching: BAD
fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
let a = bar(foo, y); //[krisskross]~ ERROR E0623
let a = bar(foo, y);
let b = bar(foo, x);
(a, b) //[krisskross]~ ERROR E0623
(a, b)
//[krisskross]~^ ERROR lifetime may not live long enough
//[krisskross]~| ERROR lifetime may not live long enough
}
fn main() {}

View File

@ -1,21 +1,15 @@
error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/project-fn-ret-invariant.rs:55:9
error: lifetime may not live long enough
--> $DIR/project-fn-ret-invariant.rs:52:5
|
LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
| -------- this data with lifetime `'a`...
| -- lifetime `'a` defined here
...
LL | bar(foo, x)
| ^^^ - ...is used and required to live as long as `'static` here
| ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
note: `'static` lifetime requirement introduced by the return type
--> $DIR/project-fn-ret-invariant.rs:51:37
|
LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
| ^^^^^^^ `'static` requirement introduced here
...
LL | bar(foo, x)
| ----------- because of this returned expression
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
error: aborting due to previous error
For more information about this error, try `rustc --explain E0759`.

View File

@ -1,17 +0,0 @@
error[E0308]: mismatched types
--> $DIR/higher-ranked-projection.rs:25:5
|
LL | foo(());
| ^^^^^^^ one type is more general than the other
|
= note: expected reference `&'a ()`
found reference `&()`
note: the lifetime requirement is introduced here
--> $DIR/higher-ranked-projection.rs:15:33
|
LL | where for<'a> &'a T: Mirror<Image=U>
| ^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,13 +1,13 @@
error[E0308]: mismatched types
--> $DIR/higher-ranked-projection.rs:25:5
--> $DIR/higher-ranked-projection.rs:23:5
|
LL | foo(());
| ^^^ lifetime mismatch
| ^^^^^^^ one type is more general than the other
|
= note: expected reference `&'a ()`
found reference `&()`
note: the lifetime requirement is introduced here
--> $DIR/higher-ranked-projection.rs:15:33
--> $DIR/higher-ranked-projection.rs:14:33
|
LL | where for<'a> &'a T: Mirror<Image=U>
| ^^^^^^^

View File

@ -2,7 +2,7 @@ error[E0308]: mismatched types
--> $DIR/higher-ranked-projection.rs:25:5
|
LL | foo(());
| ^^^ lifetime mismatch
| ^^^^^^^ one type is more general than the other
|
= note: expected reference `&'a ()`
found reference `&()`

View File

@ -1,17 +1,2 @@
error[E0308]: mismatched types
--> $DIR/higher-ranked-projection.rs:25:5
|
LL | foo(());
| ^^^^^^^ one type is more general than the other
|
= note: expected reference `&'a ()`
found reference `&()`
note: the lifetime requirement is introduced here
--> $DIR/higher-ranked-projection.rs:16:33
|
LL | where for<'a> &'a T: Mirror<Image=U>
| ^^^^^^^
error: unknown debugging option: `borrowck`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,7 +1,5 @@
// ignore-compare-mode-nll
// revisions: good badbase badnll
// revisions: good bad
//[good] check-pass
// [badnll]compile-flags: -Zborrowck=mir
trait Mirror {
type Image;
@ -11,7 +9,7 @@ impl<T> Mirror for T {
type Image = T;
}
#[cfg(any(badbase, badnll))]
#[cfg(bad)]
fn foo<U, T>(_t: T)
where for<'a> &'a T: Mirror<Image=U>
{}
@ -23,6 +21,5 @@ fn foo<U, T>(_t: T)
fn main() {
foo(());
//[badbase]~^ ERROR mismatched types
//[badnll]~^^ ERROR mismatched types
//[bad]~^ ERROR mismatched types
}

View File

@ -1,31 +0,0 @@
error[E0623]: lifetime mismatch
--> $DIR/issue-76547.rs:24:13
|
LL | async fn fut(bufs: &mut [&mut [u8]]) {
| ---------------- these two types are declared with different lifetimes...
LL | ListFut(bufs).await
| ^^^^ ...but data from `bufs` flows into `bufs` here
|
= note: each elided lifetime in input position becomes a distinct lifetime
help: consider introducing a named lifetime parameter
|
LL | async fn fut<'a>(bufs: &'a mut [&'a mut [u8]]) {
| ++++ ++ ++
error[E0623]: lifetime mismatch
--> $DIR/issue-76547.rs:39:14
|
LL | async fn fut2(bufs: &mut [&mut [u8]]) -> i32 {
| ---------------- these two types are declared with different lifetimes...
LL | ListFut2(bufs).await
| ^^^^ ...but data from `bufs` flows into `bufs` here
|
= note: each elided lifetime in input position becomes a distinct lifetime
help: consider introducing a named lifetime parameter
|
LL | async fn fut2<'a>(bufs: &'a mut [&'a mut [u8]]) -> i32 {
| ++++ ++ ++
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0623`.

View File

@ -1,7 +1,3 @@
// ignore-compare-mode-nll
// revisions: base nll
// [nll]compile-flags: -Zborrowck=mir
// Test for diagnostic improvement issue #76547
// edition:2018
@ -22,8 +18,7 @@ impl<'a> Future for ListFut<'a> {
async fn fut(bufs: &mut [&mut [u8]]) {
ListFut(bufs).await
//[base]~^ ERROR lifetime mismatch
//[nll]~^^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
}
pub struct ListFut2<'a>(&'a mut [&'a mut [u8]]);
@ -37,8 +32,7 @@ impl<'a> Future for ListFut2<'a> {
async fn fut2(bufs: &mut [&mut [u8]]) -> i32 {
ListFut2(bufs).await
//[base]~^ ERROR lifetime mismatch
//[nll]~^^ ERROR lifetime may not live long enough
//~^ ERROR lifetime may not live long enough
}
fn main() {}

View File

@ -1,5 +1,5 @@
error: lifetime may not live long enough
--> $DIR/issue-76547.rs:24:13
--> $DIR/issue-76547.rs:20:13
|
LL | async fn fut(bufs: &mut [&mut [u8]]) {
| - - let's call the lifetime of this reference `'2`
@ -14,7 +14,7 @@ LL | async fn fut<'a>(bufs: &'a mut [&'a mut [u8]]) {
| ++++ ++ ++
error: lifetime may not live long enough
--> $DIR/issue-76547.rs:39:14
--> $DIR/issue-76547.rs:34:14
|
LL | async fn fut2(bufs: &mut [&mut [u8]]) -> i32 {
| - - let's call the lifetime of this reference `'2`

View File

@ -1,18 +0,0 @@
error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/issue-62097.rs:16:31
|
LL | pub async fn run_dummy_fn(&self) {
| ^^^^^ this data with an anonymous lifetime `'_`...
LL |
LL | foo(|| self.bar()).await;
| --- ...is used and required to live as long as `'static` here
|
note: `'static` lifetime requirement introduced by this bound
--> $DIR/issue-62097.rs:8:19
|
LL | F: FnOnce() + 'static
| ^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0759`.

View File

@ -1,7 +1,3 @@
// ignore-compare-mode-nll
// revisions: base nll
// [nll]compile-flags: -Zborrowck=mir
// edition:2018
async fn foo<F>(fun: F)
where
@ -14,10 +10,9 @@ struct Struct;
impl Struct {
pub async fn run_dummy_fn(&self) {
//[base]~^ ERROR E0759
foo(|| self.bar()).await;
//[nll]~^ ERROR closure may outlive the current function
//[nll]~| ERROR borrowed data escapes outside of associated function
//~^ ERROR closure may outlive the current function
//~| ERROR borrowed data escapes outside of associated function
}
pub fn bar(&self) {}

View File

@ -1,5 +1,5 @@
error[E0373]: closure may outlive the current function, but it borrows `self`, which is owned by the current function
--> $DIR/issue-62097.rs:18:13
--> $DIR/issue-62097.rs:13:13
|
LL | foo(|| self.bar()).await;
| ^^ ---- `self` is borrowed here
@ -7,7 +7,7 @@ LL | foo(|| self.bar()).await;
| may outlive borrowed value `self`
|
note: function requires argument type to outlive `'static`
--> $DIR/issue-62097.rs:18:9
--> $DIR/issue-62097.rs:13:9
|
LL | foo(|| self.bar()).await;
| ^^^^^^^^^^^^^^^^^^
@ -17,14 +17,13 @@ LL | foo(move || self.bar()).await;
| ++++
error[E0521]: borrowed data escapes outside of associated function
--> $DIR/issue-62097.rs:18:9
--> $DIR/issue-62097.rs:13:9
|
LL | pub async fn run_dummy_fn(&self) {
| -----
| |
| `self` is a reference that is only valid in the associated function body
| let's call the lifetime of this reference `'1`
LL |
LL | foo(|| self.bar()).await;
| ^^^^^^^^^^^^^^^^^^
| |

View File

@ -1,12 +0,0 @@
error[E0621]: explicit lifetime required in the type of `foo`
--> $DIR/issue-63388-1.rs:19:9
|
LL | &'a self, foo: &dyn Foo
| -------- help: add explicit lifetime `'a` to the type of `foo`: `&'a (dyn Foo + 'a)`
...
LL | foo
| ^^^ lifetime `'a` required
error: aborting due to previous error
For more information about this error, try `rustc --explain E0621`.

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