in which inferable outlives-requirements are linted
RFC 2093 (tracking issue #44493) lets us leave off commonsensically inferable `T: 'a` outlives requirements. (A separate feature-gate was split off for the case of 'static lifetimes, for which questions still remain.) Detecting these was requested as an idioms-2018 lint. It turns out that issuing a correct, autofixable suggestion here is somewhat subtle in the presence of other bounds and generic parameters. Basically, we want to handle these three cases: • One outlives-bound. We want to drop the bound altogether, including the colon— MyStruct<'a, T: 'a> ^^^^ help: remove this bound • An outlives bound first, followed by a trait bound. We want to delete the outlives bound and the following plus sign (and hopefully get the whitespace right, too)— MyStruct<'a, T: 'a + MyTrait> ^^^^^ help: remove this bound • An outlives bound after a trait bound. We want to delete the outlives lifetime and the preceding plus sign— MyStruct<'a, T: MyTrait + 'a> ^^^^^ help: remove this bound This gets (slightly) even more complicated in the case of where clauses, where we want to drop the where clause altogether if there's just the one bound. Hopefully the comments are enough to explain what's going on! A script (in Python, sorry) was used to generate the hopefully-sufficiently-exhaustive UI test input. Some of these are split off into a different file because rust-lang-nursery/rustfix#141 (and, causally upstream of that, #53934) prevents them from being `run-rustfix`-tested. We also make sure to include a UI test of a case (copied from RFC 2093) where the outlives-bound can't be inferred. Special thanks to Niko Matsakis for pointing out the `inferred_outlives_of` query, rather than blindly stripping outlives requirements as if we weren't a production compiler and didn't care. This concerns #52042.
This commit is contained in:
parent
7d52cbce6d
commit
032d97fa01
9 changed files with 1095 additions and 1 deletions
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(unused)]
|
||||
#![deny(explicit_outlives_requirements)]
|
||||
|
||||
use std::fmt::{Debug, Display};
|
||||
|
||||
// These examples should live in edition-lint-infer-outlives.rs, but are split
|
||||
// into this separate file because they can't be `rustfix`'d (and thus, can't
|
||||
// be part of a `run-rustfix` test file) until rust-lang-nursery/rustfix#141
|
||||
// is solved
|
||||
|
||||
struct TeeOutlivesAyIsDebugBee<'a, 'b, T: 'a + Debug + 'b> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyIsDebugBee<'a, 'b, T> where T: 'a + Debug + 'b {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeYooOutlivesAyIsDebugBee<'a, 'b, T, U: 'a + Debug + 'b> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T: 'a, U: 'b + Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: &'b U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyYooIsDebugBee<'a, 'b, T: 'a, U: Debug + 'b> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: &'b U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyYooWhereBee<'a, 'b, T: 'a, U> where U: 'b {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: &'b U
|
||||
}
|
||||
|
||||
struct TeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U> where U: 'a + Debug + 'b {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyYooWhereBeeIsDebug<'a, 'b, T: 'a, U> where U: 'b + Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: &'b U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyYooWhereIsDebugBee<'a, 'b, T: 'a, U> where U: Debug + 'b {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: &'b U
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyYooWhereBeeIsDebug<'a, 'b, T, U> where T: 'a, U: 'b + Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: &'b U
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyYooWhereIsDebugBee<'a, 'b, T, U> where T: 'a, U: Debug + 'b {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: &'b U
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-multispan.rs:21:43
|
||||
|
|
||||
LL | struct TeeOutlivesAyIsDebugBee<'a, 'b, T: 'a + Debug + 'b> {
|
||||
| ^^^^^ ^^^^^
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/edition-lint-infer-outlives-multispan.rs:12:9
|
||||
|
|
||||
LL | #![deny(explicit_outlives_requirements)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: remove these bounds
|
||||
|
|
||||
LL | struct TeeOutlivesAyIsDebugBee<'a, 'b, T: Debug> {
|
||||
| -- --
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-multispan.rs:26:57
|
||||
|
|
||||
LL | struct TeeWhereOutlivesAyIsDebugBee<'a, 'b, T> where T: 'a + Debug + 'b {
|
||||
| ^^^^^ ^^^^^
|
||||
help: remove these bounds
|
||||
|
|
||||
LL | struct TeeWhereOutlivesAyIsDebugBee<'a, 'b, T> where T: Debug {
|
||||
| -- --
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-multispan.rs:31:49
|
||||
|
|
||||
LL | struct TeeYooOutlivesAyIsDebugBee<'a, 'b, T, U: 'a + Debug + 'b> {
|
||||
| ^^^^^ ^^^^^
|
||||
help: remove these bounds
|
||||
|
|
||||
LL | struct TeeYooOutlivesAyIsDebugBee<'a, 'b, T, U: Debug> {
|
||||
| -- --
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-multispan.rs:37:44
|
||||
|
|
||||
LL | struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T: 'a, U: 'b + Debug> {
|
||||
| ^^^^ ^^^^^
|
||||
help: remove these bounds
|
||||
|
|
||||
LL | struct TeeOutlivesAyYooBeeIsDebug<'a, 'b, T, U: Debug> {
|
||||
| -- --
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-multispan.rs:43:44
|
||||
|
|
||||
LL | struct TeeOutlivesAyYooIsDebugBee<'a, 'b, T: 'a, U: Debug + 'b> {
|
||||
| ^^^^ ^^^^^
|
||||
help: remove these bounds
|
||||
|
|
||||
LL | struct TeeOutlivesAyYooIsDebugBee<'a, 'b, T, U: Debug> {
|
||||
| -- --
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-multispan.rs:49:42
|
||||
|
|
||||
LL | struct TeeOutlivesAyYooWhereBee<'a, 'b, T: 'a, U> where U: 'b {
|
||||
| ^^^^ ^^^^^^^^^^^^
|
||||
help: remove these bounds
|
||||
|
|
||||
LL | struct TeeOutlivesAyYooWhereBee<'a, 'b, T, U> {
|
||||
| -- --
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-multispan.rs:55:63
|
||||
|
|
||||
LL | struct TeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U> where U: 'a + Debug + 'b {
|
||||
| ^^^^^ ^^^^^
|
||||
help: remove these bounds
|
||||
|
|
||||
LL | struct TeeYooWhereOutlivesAyIsDebugBee<'a, 'b, T, U> where U: Debug {
|
||||
| -- --
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-multispan.rs:61:49
|
||||
|
|
||||
LL | struct TeeOutlivesAyYooWhereBeeIsDebug<'a, 'b, T: 'a, U> where U: 'b + Debug {
|
||||
| ^^^^ ^^^^^
|
||||
help: remove these bounds
|
||||
|
|
||||
LL | struct TeeOutlivesAyYooWhereBeeIsDebug<'a, 'b, T, U> where U: Debug {
|
||||
| -- --
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-multispan.rs:67:49
|
||||
|
|
||||
LL | struct TeeOutlivesAyYooWhereIsDebugBee<'a, 'b, T: 'a, U> where U: Debug + 'b {
|
||||
| ^^^^ ^^^^^
|
||||
help: remove these bounds
|
||||
|
|
||||
LL | struct TeeOutlivesAyYooWhereIsDebugBee<'a, 'b, T, U> where U: Debug {
|
||||
| -- --
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-multispan.rs:73:65
|
||||
|
|
||||
LL | struct TeeWhereOutlivesAyYooWhereBeeIsDebug<'a, 'b, T, U> where T: 'a, U: 'b + Debug {
|
||||
| ^^^^^^^ ^^^^^
|
||||
help: remove these bounds
|
||||
|
|
||||
LL | struct TeeWhereOutlivesAyYooWhereBeeIsDebug<'a, 'b, T, U> where U: Debug {
|
||||
| -- --
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives-multispan.rs:79:65
|
||||
|
|
||||
LL | struct TeeWhereOutlivesAyYooWhereIsDebugBee<'a, 'b, T, U> where T: 'a, U: Debug + 'b {
|
||||
| ^^^^^^^ ^^^^^
|
||||
help: remove these bounds
|
||||
|
|
||||
LL | struct TeeWhereOutlivesAyYooWhereIsDebugBee<'a, 'b, T, U> where U: Debug {
|
||||
| -- --
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
212
src/test/ui/rust-2018/edition-lint-infer-outlives.fixed
Normal file
212
src/test/ui/rust-2018/edition-lint-infer-outlives.fixed
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// run-rustfix
|
||||
|
||||
#![allow(unused)]
|
||||
#![deny(explicit_outlives_requirements)]
|
||||
|
||||
use std::fmt::{Debug, Display};
|
||||
|
||||
|
||||
// Programmatically generated examples!
|
||||
//
|
||||
// Exercise outlives bounds for each of the following parameter/position
|
||||
// combinations—
|
||||
//
|
||||
// • one generic parameter (T) bound inline
|
||||
// • one parameter (T) with a where clause
|
||||
// • two parameters (T and U), both bound inline
|
||||
// • two paramters (T and U), one bound inline, one with a where clause
|
||||
// • two parameters (T and U), both with where clauses
|
||||
//
|
||||
// —and for every permutation of 0, 1, or 2 lifetimes to outlive and 0 or 1
|
||||
// trait bounds distributed among said parameters (subject to no where clause
|
||||
// being empty and the struct having at least one lifetime).
|
||||
|
||||
|
||||
struct TeeOutlivesAy<'a, T> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyIsDebug<'a, T: Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T
|
||||
}
|
||||
|
||||
struct TeeIsDebugOutlivesAy<'a, T: Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyBee<'a, 'b, T> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyBeeIsDebug<'a, 'b, T: Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeIsDebugOutlivesAyBee<'a, 'b, T: Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAy<'a, T> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyIsDebug<'a, T> where T: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T
|
||||
}
|
||||
|
||||
struct TeeWhereIsDebugOutlivesAy<'a, T> where T: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyBee<'a, 'b, T> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyBeeIsDebug<'a, 'b, T> where T: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeWhereIsDebugOutlivesAyBee<'a, 'b, T> where T: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeYooOutlivesAy<'a, T, U> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a U
|
||||
}
|
||||
|
||||
struct TeeYooOutlivesAyIsDebug<'a, T, U: Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a U
|
||||
}
|
||||
|
||||
struct TeeYooIsDebugOutlivesAy<'a, T, U: Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyYooIsDebug<'a, T, U: Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: U
|
||||
}
|
||||
|
||||
struct TeeYooOutlivesAyBee<'a, 'b, T, U> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeYooOutlivesAyBeeIsDebug<'a, 'b, T, U: Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeYooIsDebugOutlivesAyBee<'a, 'b, T, U: Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyBeeYooIsDebug<'a, 'b, T, U: Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T,
|
||||
yoo: U
|
||||
}
|
||||
|
||||
struct TeeYooWhereOutlivesAy<'a, T, U> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a U
|
||||
}
|
||||
|
||||
struct TeeYooWhereOutlivesAyIsDebug<'a, T, U> where U: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a U
|
||||
}
|
||||
|
||||
struct TeeYooWhereIsDebugOutlivesAy<'a, T, U> where U: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyYooWhereIsDebug<'a, T, U> where U: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: U
|
||||
}
|
||||
|
||||
struct TeeYooWhereOutlivesAyBee<'a, 'b, T, U> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeYooWhereOutlivesAyBeeIsDebug<'a, 'b, T, U> where U: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeYooWhereIsDebugOutlivesAyBee<'a, 'b, T, U> where U: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyBeeYooWhereIsDebug<'a, 'b, T, U> where U: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T,
|
||||
yoo: U
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyYooWhereIsDebug<'a, T, U> where U: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: U
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyBeeYooWhereIsDebug<'a, 'b, T, U> where U: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T,
|
||||
yoo: U
|
||||
}
|
||||
|
||||
|
||||
// But outlives inference for 'static lifetimes is under a separate
|
||||
// feature-gate for now
|
||||
// (https://github.com/rust-lang/rust/issues/44493#issuecomment-407846046).
|
||||
struct StaticRef<T: 'static> {
|
||||
field: &'static T
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
212
src/test/ui/rust-2018/edition-lint-infer-outlives.rs
Normal file
212
src/test/ui/rust-2018/edition-lint-infer-outlives.rs
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// run-rustfix
|
||||
|
||||
#![allow(unused)]
|
||||
#![deny(explicit_outlives_requirements)]
|
||||
|
||||
use std::fmt::{Debug, Display};
|
||||
|
||||
|
||||
// Programmatically generated examples!
|
||||
//
|
||||
// Exercise outlives bounds for each of the following parameter/position
|
||||
// combinations—
|
||||
//
|
||||
// • one generic parameter (T) bound inline
|
||||
// • one parameter (T) with a where clause
|
||||
// • two parameters (T and U), both bound inline
|
||||
// • two paramters (T and U), one bound inline, one with a where clause
|
||||
// • two parameters (T and U), both with where clauses
|
||||
//
|
||||
// —and for every permutation of 0, 1, or 2 lifetimes to outlive and 0 or 1
|
||||
// trait bounds distributed among said parameters (subject to no where clause
|
||||
// being empty and the struct having at least one lifetime).
|
||||
|
||||
|
||||
struct TeeOutlivesAy<'a, T: 'a> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyIsDebug<'a, T: 'a + Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T
|
||||
}
|
||||
|
||||
struct TeeIsDebugOutlivesAy<'a, T: Debug + 'a> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyBee<'a, 'b, T: 'a + 'b> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyBeeIsDebug<'a, 'b, T: 'a + 'b + Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeIsDebugOutlivesAyBee<'a, 'b, T: Debug + 'a + 'b> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAy<'a, T> where T: 'a {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyIsDebug<'a, T> where T: 'a + Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T
|
||||
}
|
||||
|
||||
struct TeeWhereIsDebugOutlivesAy<'a, T> where T: Debug + 'a {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyBee<'a, 'b, T> where T: 'a + 'b {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyBeeIsDebug<'a, 'b, T> where T: 'a + 'b + Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeWhereIsDebugOutlivesAyBee<'a, 'b, T> where T: Debug + 'a + 'b {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T
|
||||
}
|
||||
|
||||
struct TeeYooOutlivesAy<'a, T, U: 'a> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a U
|
||||
}
|
||||
|
||||
struct TeeYooOutlivesAyIsDebug<'a, T, U: 'a + Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a U
|
||||
}
|
||||
|
||||
struct TeeYooIsDebugOutlivesAy<'a, T, U: Debug + 'a> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyYooIsDebug<'a, T: 'a, U: Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: U
|
||||
}
|
||||
|
||||
struct TeeYooOutlivesAyBee<'a, 'b, T, U: 'a + 'b> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeYooOutlivesAyBeeIsDebug<'a, 'b, T, U: 'a + 'b + Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeYooIsDebugOutlivesAyBee<'a, 'b, T, U: Debug + 'a + 'b> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyBeeYooIsDebug<'a, 'b, T: 'a + 'b, U: Debug> {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T,
|
||||
yoo: U
|
||||
}
|
||||
|
||||
struct TeeYooWhereOutlivesAy<'a, T, U> where U: 'a {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a U
|
||||
}
|
||||
|
||||
struct TeeYooWhereOutlivesAyIsDebug<'a, T, U> where U: 'a + Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a U
|
||||
}
|
||||
|
||||
struct TeeYooWhereIsDebugOutlivesAy<'a, T, U> where U: Debug + 'a {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyYooWhereIsDebug<'a, T: 'a, U> where U: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: U
|
||||
}
|
||||
|
||||
struct TeeYooWhereOutlivesAyBee<'a, 'b, T, U> where U: 'a + 'b {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeYooWhereOutlivesAyBeeIsDebug<'a, 'b, T, U> where U: 'a + 'b + Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeYooWhereIsDebugOutlivesAyBee<'a, 'b, T, U> where U: Debug + 'a + 'b {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: T,
|
||||
yoo: &'a &'b U
|
||||
}
|
||||
|
||||
struct TeeOutlivesAyBeeYooWhereIsDebug<'a, 'b, T: 'a + 'b, U> where U: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T,
|
||||
yoo: U
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyYooWhereIsDebug<'a, T, U> where T: 'a, U: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a T,
|
||||
yoo: U
|
||||
}
|
||||
|
||||
struct TeeWhereOutlivesAyBeeYooWhereIsDebug<'a, 'b, T, U> where T: 'a + 'b, U: Debug {
|
||||
//~^ ERROR outlives requirements can be inferred
|
||||
tee: &'a &'b T,
|
||||
yoo: U
|
||||
}
|
||||
|
||||
|
||||
// But outlives inference for 'static lifetimes is under a separate
|
||||
// feature-gate for now
|
||||
// (https://github.com/rust-lang/rust/issues/44493#issuecomment-407846046).
|
||||
struct StaticRef<T: 'static> {
|
||||
field: &'static T
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
188
src/test/ui/rust-2018/edition-lint-infer-outlives.stderr
Normal file
188
src/test/ui/rust-2018/edition-lint-infer-outlives.stderr
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:35:27
|
||||
|
|
||||
LL | struct TeeOutlivesAy<'a, T: 'a> {
|
||||
| ^^^^ help: remove this bound
|
||||
|
|
||||
note: lint level defined here
|
||||
--> $DIR/edition-lint-infer-outlives.rs:14:9
|
||||
|
|
||||
LL | #![deny(explicit_outlives_requirements)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:40:36
|
||||
|
|
||||
LL | struct TeeOutlivesAyIsDebug<'a, T: 'a + Debug> {
|
||||
| ^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:45:41
|
||||
|
|
||||
LL | struct TeeIsDebugOutlivesAy<'a, T: Debug + 'a> {
|
||||
| ^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:50:34
|
||||
|
|
||||
LL | struct TeeOutlivesAyBee<'a, 'b, T: 'a + 'b> {
|
||||
| ^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:55:43
|
||||
|
|
||||
LL | struct TeeOutlivesAyBeeIsDebug<'a, 'b, T: 'a + 'b + Debug> {
|
||||
| ^^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:60:48
|
||||
|
|
||||
LL | struct TeeIsDebugOutlivesAyBee<'a, 'b, T: Debug + 'a + 'b> {
|
||||
| ^^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:65:33
|
||||
|
|
||||
LL | struct TeeWhereOutlivesAy<'a, T> where T: 'a {
|
||||
| ^^^^^^^^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:70:50
|
||||
|
|
||||
LL | struct TeeWhereOutlivesAyIsDebug<'a, T> where T: 'a + Debug {
|
||||
| ^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:75:55
|
||||
|
|
||||
LL | struct TeeWhereIsDebugOutlivesAy<'a, T> where T: Debug + 'a {
|
||||
| ^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:80:40
|
||||
|
|
||||
LL | struct TeeWhereOutlivesAyBee<'a, 'b, T> where T: 'a + 'b {
|
||||
| ^^^^^^^^^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:85:57
|
||||
|
|
||||
LL | struct TeeWhereOutlivesAyBeeIsDebug<'a, 'b, T> where T: 'a + 'b + Debug {
|
||||
| ^^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:90:62
|
||||
|
|
||||
LL | struct TeeWhereIsDebugOutlivesAyBee<'a, 'b, T> where T: Debug + 'a + 'b {
|
||||
| ^^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:95:33
|
||||
|
|
||||
LL | struct TeeYooOutlivesAy<'a, T, U: 'a> {
|
||||
| ^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:101:42
|
||||
|
|
||||
LL | struct TeeYooOutlivesAyIsDebug<'a, T, U: 'a + Debug> {
|
||||
| ^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:107:47
|
||||
|
|
||||
LL | struct TeeYooIsDebugOutlivesAy<'a, T, U: Debug + 'a> {
|
||||
| ^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:113:37
|
||||
|
|
||||
LL | struct TeeOutlivesAyYooIsDebug<'a, T: 'a, U: Debug> {
|
||||
| ^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:119:40
|
||||
|
|
||||
LL | struct TeeYooOutlivesAyBee<'a, 'b, T, U: 'a + 'b> {
|
||||
| ^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:125:49
|
||||
|
|
||||
LL | struct TeeYooOutlivesAyBeeIsDebug<'a, 'b, T, U: 'a + 'b + Debug> {
|
||||
| ^^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:131:54
|
||||
|
|
||||
LL | struct TeeYooIsDebugOutlivesAyBee<'a, 'b, T, U: Debug + 'a + 'b> {
|
||||
| ^^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:137:44
|
||||
|
|
||||
LL | struct TeeOutlivesAyBeeYooIsDebug<'a, 'b, T: 'a + 'b, U: Debug> {
|
||||
| ^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:143:39
|
||||
|
|
||||
LL | struct TeeYooWhereOutlivesAy<'a, T, U> where U: 'a {
|
||||
| ^^^^^^^^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:149:56
|
||||
|
|
||||
LL | struct TeeYooWhereOutlivesAyIsDebug<'a, T, U> where U: 'a + Debug {
|
||||
| ^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:155:61
|
||||
|
|
||||
LL | struct TeeYooWhereIsDebugOutlivesAy<'a, T, U> where U: Debug + 'a {
|
||||
| ^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:161:42
|
||||
|
|
||||
LL | struct TeeOutlivesAyYooWhereIsDebug<'a, T: 'a, U> where U: Debug {
|
||||
| ^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:167:46
|
||||
|
|
||||
LL | struct TeeYooWhereOutlivesAyBee<'a, 'b, T, U> where U: 'a + 'b {
|
||||
| ^^^^^^^^^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:173:63
|
||||
|
|
||||
LL | struct TeeYooWhereOutlivesAyBeeIsDebug<'a, 'b, T, U> where U: 'a + 'b + Debug {
|
||||
| ^^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:179:68
|
||||
|
|
||||
LL | struct TeeYooWhereIsDebugOutlivesAyBee<'a, 'b, T, U> where U: Debug + 'a + 'b {
|
||||
| ^^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:185:49
|
||||
|
|
||||
LL | struct TeeOutlivesAyBeeYooWhereIsDebug<'a, 'b, T: 'a + 'b, U> where U: Debug {
|
||||
| ^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:191:58
|
||||
|
|
||||
LL | struct TeeWhereOutlivesAyYooWhereIsDebug<'a, T, U> where T: 'a, U: Debug {
|
||||
| ^^^^^^^ help: remove this bound
|
||||
|
||||
error: outlives requirements can be inferred
|
||||
--> $DIR/edition-lint-infer-outlives.rs:197:65
|
||||
|
|
||||
LL | struct TeeWhereOutlivesAyBeeYooWhereIsDebug<'a, 'b, T, U> where T: 'a + 'b, U: Debug {
|
||||
| ^^^^^^^^^^^^ help: remove these bounds
|
||||
|
||||
error: aborting due to 30 previous errors
|
||||
|
||||
40
src/test/ui/rust-2018/edition-lint-uninferable-outlives.rs
Normal file
40
src/test/ui/rust-2018/edition-lint-uninferable-outlives.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-pass
|
||||
|
||||
#![allow(unused)]
|
||||
#![deny(explicit_outlives_requirements)]
|
||||
|
||||
// A case where we can't infer the outlives requirement. Example copied from
|
||||
// RFC 2093.
|
||||
// (https://rust-lang.github.io/rfcs/2093-infer-outlives.html
|
||||
// #where-explicit-annotations-would-still-be-required)
|
||||
|
||||
|
||||
trait MakeRef<'a> {
|
||||
type Type;
|
||||
}
|
||||
|
||||
impl<'a, T> MakeRef<'a> for Vec<T>
|
||||
where T: 'a // still required
|
||||
{
|
||||
type Type = &'a T;
|
||||
}
|
||||
|
||||
|
||||
struct Foo<'a, T>
|
||||
where T: 'a // still required, not inferred from `field`
|
||||
{
|
||||
field: <Vec<T> as MakeRef<'a>>::Type
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue