142 lines
4.1 KiB
Rust
142 lines
4.1 KiB
Rust
//@ edition:2018
|
|
//@ aux-build:edition-lint-infer-outlives-macro.rs
|
|
//@ run-rustfix
|
|
|
|
#![deny(explicit_outlives_requirements)]
|
|
#![allow(dead_code)]
|
|
|
|
#[macro_use]
|
|
extern crate edition_lint_infer_outlives_macro;
|
|
|
|
// Test that the lint does not fire if the predicate is from the local crate,
|
|
// but all the bounds are from an external macro.
|
|
macro_rules! make_foo {
|
|
($a:tt) => {
|
|
struct Foo<$a, 'b: $a> {
|
|
foo: &$a &'b (),
|
|
}
|
|
|
|
struct FooWhere<$a, 'b> where 'b: $a {
|
|
foo: &$a &'b (),
|
|
}
|
|
}
|
|
}
|
|
|
|
gimme_a! {make_foo!}
|
|
|
|
struct Bar<'a, 'b> {
|
|
//~^ ERROR: outlives requirements can be inferred
|
|
bar: &'a &'b (),
|
|
}
|
|
|
|
struct BarWhere<'a, 'b> {
|
|
//~^ ERROR: outlives requirements can be inferred
|
|
bar: &'a &'b (),
|
|
}
|
|
|
|
// Test that the lint *does* fire if the predicate is contained in a local macro.
|
|
mod everything_inside {
|
|
macro_rules! m {
|
|
('b: 'a) => {
|
|
struct Foo<'a, 'b>(&'a &'b ());
|
|
//~^ ERROR: outlives requirements can be inferred
|
|
struct Bar<'a, 'b>(&'a &'b ()) ;
|
|
//~^ ERROR: outlives requirements can be inferred
|
|
struct Baz<'a, 'b>(&'a &'b ()) where (): Sized, ;
|
|
//~^ ERROR: outlives requirements can be inferred
|
|
};
|
|
}
|
|
m!('b: 'a);
|
|
}
|
|
|
|
mod inner_lifetime_outside_colon_inside {
|
|
macro_rules! m {
|
|
($b:lifetime: 'a) => {
|
|
struct Foo<'a, $b>(&'a &$b ());
|
|
//~^ ERROR: outlives requirements can be inferred
|
|
struct Bar<'a, $b>(&'a &$b ()) ;
|
|
//~^ ERROR: outlives requirements can be inferred
|
|
struct Baz<'a, $b>(&'a &$b ()) where (): Sized, ;
|
|
//~^ ERROR: outlives requirements can be inferred
|
|
}
|
|
}
|
|
m!('b: 'a);
|
|
}
|
|
|
|
mod outer_lifetime_outside_colon_inside {
|
|
macro_rules! m {
|
|
('b: $a:lifetime) => {
|
|
struct Foo<$a, 'b: $a>(&$a &'b ());
|
|
struct Bar<$a, 'b>(&$a &'b ()) where 'b: $a;
|
|
struct Baz<$a, 'b>(&$a &'b ()) where (): Sized, 'b: $a;
|
|
}
|
|
}
|
|
m!('b: 'a);
|
|
}
|
|
|
|
mod both_lifetimes_outside_colon_inside {
|
|
macro_rules! m {
|
|
($b:lifetime: $a:lifetime) => {
|
|
struct Foo<$a, $b: $a>(&$a &$b ());
|
|
struct Bar<$a, $b>(&$a &$b ()) where $b: $a;
|
|
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b: $a;
|
|
}
|
|
}
|
|
m!('b: 'a);
|
|
}
|
|
|
|
mod everything_outside {
|
|
macro_rules! m {
|
|
($b:lifetime $colon:tt $a:lifetime) => {
|
|
struct Foo<$a, $b $colon $a>(&$a &$b ());
|
|
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
|
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
|
}
|
|
}
|
|
m!('b: 'a);
|
|
}
|
|
|
|
mod everything_outside_with_tt_inner {
|
|
macro_rules! m {
|
|
($b:tt $colon:tt $a:lifetime) => {
|
|
struct Foo<$a, $b $colon $a>(&$a &$b ());
|
|
struct Bar<$a, $b>(&$a &$b ()) where $b $colon $a;
|
|
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, $b $colon $a;
|
|
}
|
|
}
|
|
m!('b: 'a);
|
|
}
|
|
|
|
// FIXME: These should be consistent.
|
|
mod everything_outside_with_tt_outer {
|
|
macro_rules! m {
|
|
($b:lifetime $colon:tt $a:tt) => {
|
|
// FIXME: replacement span is corrupted due to a collision in metavar span table.
|
|
// struct Foo<$a, $b $colon $a>(&$a &$b ());
|
|
// ^ ERROR: outlives requirements can be inferred
|
|
struct Bar<$a, $b>(&$a &$b ()) ;
|
|
//~^ ERROR: outlives requirements can be inferred
|
|
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, ;
|
|
//~^ ERROR: outlives requirements can be inferred
|
|
}
|
|
}
|
|
m!('b: 'a);
|
|
}
|
|
|
|
mod everything_outside_with_tt_both {
|
|
macro_rules! m {
|
|
($b:tt $colon:tt $a:tt) => {
|
|
// FIXME: replacement span is corrupted due to a collision in metavar span table.
|
|
// struct Foo<$a, $b $colon $a>(&$a &$b ());
|
|
// ^ ERROR: outlives requirements can be inferred
|
|
struct Bar<$a, $b>(&$a &$b ()) ;
|
|
//~^ ERROR: outlives requirements can be inferred
|
|
struct Baz<$a, $b>(&$a &$b ()) where (): Sized, ;
|
|
//~^ ERROR: outlives requirements can be inferred
|
|
}
|
|
}
|
|
m!('b: 'a);
|
|
}
|
|
|
|
fn main() {}
|