summaryrefslogtreecommitdiffstats
path: root/tests/ui/lifetimes
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/lifetimes')
-rw-r--r--tests/ui/lifetimes/auxiliary/issue-91763-aux.rs47
-rw-r--r--tests/ui/lifetimes/auxiliary/lifetime_bound_will_change_warning_lib.rs11
-rw-r--r--tests/ui/lifetimes/bare-trait-object-borrowck.rs24
-rw-r--r--tests/ui/lifetimes/bare-trait-object.rs25
-rw-r--r--tests/ui/lifetimes/borrowck-let-suggestion.rs12
-rw-r--r--tests/ui/lifetimes/borrowck-let-suggestion.stderr17
-rw-r--r--tests/ui/lifetimes/conflicting-bounds.rs11
-rw-r--r--tests/ui/lifetimes/conflicting-bounds.stderr14
-rw-r--r--tests/ui/lifetimes/copy_modulo_regions.rs17
-rw-r--r--tests/ui/lifetimes/copy_modulo_regions.stderr14
-rw-r--r--tests/ui/lifetimes/elided-lifetime-in-param-pat.rs11
-rw-r--r--tests/ui/lifetimes/elided-lifetime-in-path-in-impl-Fn.rs19
-rw-r--r--tests/ui/lifetimes/elided-lifetime-in-path-in-pat.rs13
-rw-r--r--tests/ui/lifetimes/elided-lifetime-in-path-in-type-relative-expression.rs17
-rw-r--r--tests/ui/lifetimes/fullwidth-ampersand.rs7
-rw-r--r--tests/ui/lifetimes/fullwidth-ampersand.stderr26
-rw-r--r--tests/ui/lifetimes/issue-105227.fixed26
-rw-r--r--tests/ui/lifetimes/issue-105227.rs26
-rw-r--r--tests/ui/lifetimes/issue-105227.stderr47
-rw-r--r--tests/ui/lifetimes/issue-105507.fixed43
-rw-r--r--tests/ui/lifetimes/issue-105507.rs43
-rw-r--r--tests/ui/lifetimes/issue-105507.stderr34
-rw-r--r--tests/ui/lifetimes/issue-17728.rs122
-rw-r--r--tests/ui/lifetimes/issue-17728.stderr21
-rw-r--r--tests/ui/lifetimes/issue-26638.rs13
-rw-r--r--tests/ui/lifetimes/issue-26638.stderr73
-rw-r--r--tests/ui/lifetimes/issue-34979.rs9
-rw-r--r--tests/ui/lifetimes/issue-34979.stderr20
-rw-r--r--tests/ui/lifetimes/issue-54378.rs26
-rw-r--r--tests/ui/lifetimes/issue-55796.rs26
-rw-r--r--tests/ui/lifetimes/issue-55796.stderr20
-rw-r--r--tests/ui/lifetimes/issue-64173-unused-lifetimes.rs19
-rw-r--r--tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr35
-rw-r--r--tests/ui/lifetimes/issue-67498.rs21
-rw-r--r--tests/ui/lifetimes/issue-70917-lifetimes-in-fn-def.rs13
-rw-r--r--tests/ui/lifetimes/issue-76168-hr-outlives-2.rs22
-rw-r--r--tests/ui/lifetimes/issue-76168-hr-outlives.rs19
-rw-r--r--tests/ui/lifetimes/issue-77175.rs19
-rw-r--r--tests/ui/lifetimes/issue-79187-2.rs29
-rw-r--r--tests/ui/lifetimes/issue-79187-2.stderr77
-rw-r--r--tests/ui/lifetimes/issue-79187.rs8
-rw-r--r--tests/ui/lifetimes/issue-79187.stderr31
-rw-r--r--tests/ui/lifetimes/issue-83737-binders-across-types.rs14
-rw-r--r--tests/ui/lifetimes/issue-83737-erasing-bound-vars.rs14
-rw-r--r--tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs8
-rw-r--r--tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr9
-rw-r--r--tests/ui/lifetimes/issue-83907-invalid-fn-like-path.rs7
-rw-r--r--tests/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr17
-rw-r--r--tests/ui/lifetimes/issue-84398.rs20
-rw-r--r--tests/ui/lifetimes/issue-84604.rs9
-rw-r--r--tests/ui/lifetimes/issue-90170-elision-mismatch.fixed9
-rw-r--r--tests/ui/lifetimes/issue-90170-elision-mismatch.rs9
-rw-r--r--tests/ui/lifetimes/issue-90170-elision-mismatch.stderr44
-rw-r--r--tests/ui/lifetimes/issue-90600-expected-return-static-indirect.rs15
-rw-r--r--tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr24
-rw-r--r--tests/ui/lifetimes/issue-91763.rs11
-rw-r--r--tests/ui/lifetimes/issue-91763.stderr18
-rw-r--r--tests/ui/lifetimes/issue-95023.rs11
-rw-r--r--tests/ui/lifetimes/issue-95023.stderr38
-rw-r--r--tests/ui/lifetimes/issue-97193.rs9
-rw-r--r--tests/ui/lifetimes/issue-97193.stderr28
-rw-r--r--tests/ui/lifetimes/issue-97194.rs10
-rw-r--r--tests/ui/lifetimes/issue-97194.stderr36
-rw-r--r--tests/ui/lifetimes/lifetime-bound-will-change-warning.rs56
-rw-r--r--tests/ui/lifetimes/lifetime-bound-will-change-warning.stderr31
-rw-r--r--tests/ui/lifetimes/lifetime-doesnt-live-long-enough.rs49
-rw-r--r--tests/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr68
-rw-r--r--tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs51
-rw-r--r--tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr87
-rw-r--r--tests/ui/lifetimes/lifetime-elision-return-type-trait.rs13
-rw-r--r--tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr9
-rw-r--r--tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs14
-rw-r--r--tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs20
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs5
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs5
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs8
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs14
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs18
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr13
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs5
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.stderr11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs15
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr13
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs14
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr13
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs5
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr15
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs9
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.stderr11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs9
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.stderr11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs10
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.stderr15
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.stderr15
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.stderr15
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs6
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr17
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs7
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr32
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr13
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs13
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr15
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs10
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr14
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs10
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs6
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr14
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs9
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr21
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs8
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs8
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs11
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr17
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs12
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr17
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs7
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr29
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs10
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr17
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs7
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr29
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs6
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr17
-rw-r--r--tests/ui/lifetimes/lifetime-errors/issue_74400.rs16
-rw-r--r--tests/ui/lifetimes/lifetime-errors/issue_74400.stderr38
-rw-r--r--tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs37
-rw-r--r--tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr46
-rw-r--r--tests/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs12
-rw-r--r--tests/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr16
-rw-r--r--tests/ui/lifetimes/lifetime-no-keyword.rs7
-rw-r--r--tests/ui/lifetimes/lifetime-no-keyword.stderr26
-rw-r--r--tests/ui/lifetimes/missing-lifetime-in-alias.rs31
-rw-r--r--tests/ui/lifetimes/missing-lifetime-in-alias.stderr47
-rw-r--r--tests/ui/lifetimes/nested-binder-print.rs10
-rw-r--r--tests/ui/lifetimes/nested-binder-print.stderr14
-rw-r--r--tests/ui/lifetimes/nested.rs7
-rw-r--r--tests/ui/lifetimes/re-empty-in-error.rs10
-rw-r--r--tests/ui/lifetimes/re-empty-in-error.stderr10
-rw-r--r--tests/ui/lifetimes/shadow.rs8
-rw-r--r--tests/ui/lifetimes/shadow.stderr20
-rw-r--r--tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed13
-rw-r--r--tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs13
-rw-r--r--tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr24
-rw-r--r--tests/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.rs16
-rw-r--r--tests/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.stderr36
-rw-r--r--tests/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs3
-rw-r--r--tests/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr21
-rw-r--r--tests/ui/lifetimes/unusual-rib-combinations.rs28
-rw-r--r--tests/ui/lifetimes/unusual-rib-combinations.stderr61
169 files changed, 3319 insertions, 0 deletions
diff --git a/tests/ui/lifetimes/auxiliary/issue-91763-aux.rs b/tests/ui/lifetimes/auxiliary/issue-91763-aux.rs
new file mode 100644
index 000000000..0335f72b7
--- /dev/null
+++ b/tests/ui/lifetimes/auxiliary/issue-91763-aux.rs
@@ -0,0 +1,47 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+//#![feature(proc_macro_diagnostic, proc_macro_span, proc_macro_def_site)]
+
+extern crate proc_macro;
+
+use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
+use std::iter::FromIterator;
+
+#[proc_macro_attribute]
+pub fn repro(_args: TokenStream, input: TokenStream) -> TokenStream {
+ let call_site = Span::call_site();
+ let span = input.into_iter().nth(8).unwrap().span();
+
+ //fn f(_: &::std::fmt::Formatter) {}
+ TokenStream::from_iter([
+ TokenTree::Ident(Ident::new("fn", call_site)),
+ TokenTree::Ident(Ident::new("f", call_site)),
+ TokenTree::Group(Group::new(
+ Delimiter::Parenthesis,
+ TokenStream::from_iter([
+ TokenTree::Ident(Ident::new("_", call_site)),
+ TokenTree::Punct(punct(':', Spacing::Alone, call_site)),
+ TokenTree::Punct(punct('&', Spacing::Alone, call_site)),
+ TokenTree::Punct(punct(':', Spacing::Joint, span)),
+ TokenTree::Punct(punct(':', Spacing::Alone, span)),
+ TokenTree::Ident(Ident::new("std", span)),
+ TokenTree::Punct(punct(':', Spacing::Joint, span)),
+ TokenTree::Punct(punct(':', Spacing::Alone, span)),
+ TokenTree::Ident(Ident::new("fmt", span)),
+ TokenTree::Punct(punct(':', Spacing::Joint, span)),
+ TokenTree::Punct(punct(':', Spacing::Alone, span)),
+ TokenTree::Ident(Ident::new("Formatter", span)),
+ ]),
+ )),
+ TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::new())),
+ ])
+}
+
+fn punct(ch: char, spacing: Spacing, span: Span) -> Punct {
+ let mut punct = Punct::new(ch, spacing);
+ punct.set_span(span);
+ punct
+}
diff --git a/tests/ui/lifetimes/auxiliary/lifetime_bound_will_change_warning_lib.rs b/tests/ui/lifetimes/auxiliary/lifetime_bound_will_change_warning_lib.rs
new file mode 100644
index 000000000..58f1b81cf
--- /dev/null
+++ b/tests/ui/lifetimes/auxiliary/lifetime_bound_will_change_warning_lib.rs
@@ -0,0 +1,11 @@
+#![crate_type = "rlib"]
+
+// Helper for testing that we get suitable warnings when lifetime
+// bound change will cause breakage.
+
+pub fn just_ref(x: &Fn()) {
+}
+
+pub fn ref_obj(x: &Box<Fn()>) {
+ // this will change to &Box<Fn()+'static>...
+}
diff --git a/tests/ui/lifetimes/bare-trait-object-borrowck.rs b/tests/ui/lifetimes/bare-trait-object-borrowck.rs
new file mode 100644
index 000000000..45f5e4ae1
--- /dev/null
+++ b/tests/ui/lifetimes/bare-trait-object-borrowck.rs
@@ -0,0 +1,24 @@
+#![allow(bare_trait_objects)]
+// check-pass
+pub struct FormatWith<'a, I, F> {
+ sep: &'a str,
+ /// FormatWith uses interior mutability because Display::fmt takes &self.
+ inner: RefCell<Option<(I, F)>>,
+}
+
+use std::cell::RefCell;
+use std::fmt;
+
+struct Layout;
+
+pub fn new_format<'a, I, F>(iter: I, separator: &'a str, f: F) -> FormatWith<'a, I, F>
+where
+ I: Iterator,
+ F: FnMut(I::Item, &mut FnMut(&fmt::Display) -> fmt::Result) -> fmt::Result,
+{
+ FormatWith { sep: separator, inner: RefCell::new(Some((iter, f))) }
+}
+
+fn main() {
+ let _ = new_format(0..32, " | ", |i, f| f(&format_args!("0x{:x}", i)));
+}
diff --git a/tests/ui/lifetimes/bare-trait-object.rs b/tests/ui/lifetimes/bare-trait-object.rs
new file mode 100644
index 000000000..9eff618c7
--- /dev/null
+++ b/tests/ui/lifetimes/bare-trait-object.rs
@@ -0,0 +1,25 @@
+// Verify that lifetime resolution correctly accounts for `Fn` bare trait objects.
+// check-pass
+#![allow(bare_trait_objects)]
+
+// This should work as: fn next_u32(fill_buf: &mut dyn FnMut(&mut [u8]))
+fn next_u32(fill_buf: &mut FnMut(&mut [u8])) {
+ let mut buf: [u8; 4] = [0; 4];
+ fill_buf(&mut buf);
+}
+
+fn explicit(fill_buf: &mut dyn FnMut(&mut [u8])) {
+ let mut buf: [u8; 4] = [0; 4];
+ fill_buf(&mut buf);
+}
+
+fn main() {
+ let _: fn(&mut FnMut(&mut [u8])) = next_u32;
+ let _: &dyn Fn(&mut FnMut(&mut [u8])) = &next_u32;
+ let _: fn(&mut FnMut(&mut [u8])) = explicit;
+ let _: &dyn Fn(&mut FnMut(&mut [u8])) = &explicit;
+ let _: fn(&mut dyn FnMut(&mut [u8])) = next_u32;
+ let _: &dyn Fn(&mut dyn FnMut(&mut [u8])) = &next_u32;
+ let _: fn(&mut dyn FnMut(&mut [u8])) = explicit;
+ let _: &dyn Fn(&mut dyn FnMut(&mut [u8])) = &explicit;
+}
diff --git a/tests/ui/lifetimes/borrowck-let-suggestion.rs b/tests/ui/lifetimes/borrowck-let-suggestion.rs
new file mode 100644
index 000000000..3d591a506
--- /dev/null
+++ b/tests/ui/lifetimes/borrowck-let-suggestion.rs
@@ -0,0 +1,12 @@
+fn f() {
+ let mut x = vec![1].iter();
+ //~^ ERROR temporary value dropped while borrowed
+ x.use_mut();
+}
+
+fn main() {
+ f();
+}
+
+trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } }
+impl<T> Fake for T { }
diff --git a/tests/ui/lifetimes/borrowck-let-suggestion.stderr b/tests/ui/lifetimes/borrowck-let-suggestion.stderr
new file mode 100644
index 000000000..987b051b1
--- /dev/null
+++ b/tests/ui/lifetimes/borrowck-let-suggestion.stderr
@@ -0,0 +1,17 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/borrowck-let-suggestion.rs:2:17
+ |
+LL | let mut x = vec![1].iter();
+ | ^^^^^^^ - temporary value is freed at the end of this statement
+ | |
+ | creates a temporary value which is freed while still in use
+LL |
+LL | x.use_mut();
+ | ----------- borrow later used here
+ |
+ = note: consider using a `let` binding to create a longer lived value
+ = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/lifetimes/conflicting-bounds.rs b/tests/ui/lifetimes/conflicting-bounds.rs
new file mode 100644
index 000000000..f37f163db
--- /dev/null
+++ b/tests/ui/lifetimes/conflicting-bounds.rs
@@ -0,0 +1,11 @@
+//~ type annotations needed: cannot satisfy `Self: Gen<'source>`
+
+pub trait Gen<'source> {
+ type Output;
+
+ fn gen<T>(&self) -> T
+ where
+ Self: for<'s> Gen<'s, Output = T>;
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/conflicting-bounds.stderr b/tests/ui/lifetimes/conflicting-bounds.stderr
new file mode 100644
index 000000000..42aa39366
--- /dev/null
+++ b/tests/ui/lifetimes/conflicting-bounds.stderr
@@ -0,0 +1,14 @@
+error[E0283]: type annotations needed: cannot satisfy `Self: Gen<'source>`
+ |
+note: multiple `impl`s or `where` clauses satisfying `Self: Gen<'source>` found
+ --> $DIR/conflicting-bounds.rs:3:1
+ |
+LL | pub trait Gen<'source> {
+ | ^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | Self: for<'s> Gen<'s, Output = T>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/lifetimes/copy_modulo_regions.rs b/tests/ui/lifetimes/copy_modulo_regions.rs
new file mode 100644
index 000000000..040fc4a00
--- /dev/null
+++ b/tests/ui/lifetimes/copy_modulo_regions.rs
@@ -0,0 +1,17 @@
+#[derive(Clone)]
+struct Foo<'a>(fn(&'a ()) -> &'a ());
+
+impl Copy for Foo<'static> {}
+
+fn mk_foo<'a>() -> Foo<'a> {
+ println!("mk_foo");
+ Foo(|x| x)
+}
+
+fn foo<'a>() -> [Foo<'a>; 100] {
+ [mk_foo::<'a>(); 100] //~ ERROR lifetime may not live long enough
+}
+
+fn main() {
+ foo();
+}
diff --git a/tests/ui/lifetimes/copy_modulo_regions.stderr b/tests/ui/lifetimes/copy_modulo_regions.stderr
new file mode 100644
index 000000000..87dbb64ab
--- /dev/null
+++ b/tests/ui/lifetimes/copy_modulo_regions.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+ --> $DIR/copy_modulo_regions.rs:12:5
+ |
+LL | fn foo<'a>() -> [Foo<'a>; 100] {
+ | -- lifetime `'a` defined here
+LL | [mk_foo::<'a>(); 100]
+ | ^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+ |
+ = note: requirement occurs because of the type `Foo<'_>`, which makes the generic argument `'_` invariant
+ = note: the struct `Foo<'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
+
diff --git a/tests/ui/lifetimes/elided-lifetime-in-param-pat.rs b/tests/ui/lifetimes/elided-lifetime-in-param-pat.rs
new file mode 100644
index 000000000..c1425fa42
--- /dev/null
+++ b/tests/ui/lifetimes/elided-lifetime-in-param-pat.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+struct S<T> {
+ _t: T,
+}
+
+fn f(S::<&i8> { .. }: S<&i8>) {}
+
+fn main() {
+ f(S { _t: &42_i8 });
+}
diff --git a/tests/ui/lifetimes/elided-lifetime-in-path-in-impl-Fn.rs b/tests/ui/lifetimes/elided-lifetime-in-path-in-impl-Fn.rs
new file mode 100644
index 000000000..9c9965d8f
--- /dev/null
+++ b/tests/ui/lifetimes/elided-lifetime-in-path-in-impl-Fn.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+struct Foo<'a>(&'a ());
+
+fn with_fn() -> fn(Foo) {
+ |_| ()
+}
+
+fn with_impl_fn() -> impl Fn(Foo) {
+ |_| ()
+}
+
+fn with_where_fn<T>()
+where
+ T: Fn(Foo),
+{
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/elided-lifetime-in-path-in-pat.rs b/tests/ui/lifetimes/elided-lifetime-in-path-in-pat.rs
new file mode 100644
index 000000000..ff84d2511
--- /dev/null
+++ b/tests/ui/lifetimes/elided-lifetime-in-path-in-pat.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+struct Foo<'a> {
+ x: &'a (),
+}
+
+// The lifetime in pattern-position `Foo` is elided.
+// Verify that lowering does not create an independent lifetime parameter for it.
+fn foo<'a>(Foo { x }: Foo<'a>) {
+ *x
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/elided-lifetime-in-path-in-type-relative-expression.rs b/tests/ui/lifetimes/elided-lifetime-in-path-in-type-relative-expression.rs
new file mode 100644
index 000000000..b9d2711fd
--- /dev/null
+++ b/tests/ui/lifetimes/elided-lifetime-in-path-in-type-relative-expression.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+struct Sqlite {}
+
+trait HasArguments<'q> {
+ type Arguments;
+}
+
+impl<'q> HasArguments<'q> for Sqlite {
+ type Arguments = std::marker::PhantomData<&'q ()>;
+}
+
+fn foo() {
+ let _ = <Sqlite as HasArguments>::Arguments::default();
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/fullwidth-ampersand.rs b/tests/ui/lifetimes/fullwidth-ampersand.rs
new file mode 100644
index 000000000..7d8948bd8
--- /dev/null
+++ b/tests/ui/lifetimes/fullwidth-ampersand.rs
@@ -0,0 +1,7 @@
+// Verify that we do not ICE when the user uses a multubyte ampersand.
+
+fn f(_: &&()) -> &() { todo!() }
+//~^ ERROR unknown start of token: \u{ff06}
+//~| ERROR missing lifetime specifier [E0106]
+
+fn main() {}
diff --git a/tests/ui/lifetimes/fullwidth-ampersand.stderr b/tests/ui/lifetimes/fullwidth-ampersand.stderr
new file mode 100644
index 000000000..4645254f4
--- /dev/null
+++ b/tests/ui/lifetimes/fullwidth-ampersand.stderr
@@ -0,0 +1,26 @@
+error: unknown start of token: \u{ff06}
+ --> $DIR/fullwidth-ampersand.rs:3:10
+ |
+LL | fn f(_: &&()) -> &() { todo!() }
+ | ^^
+ |
+help: Unicode character '&' (Fullwidth Ampersand) looks like '&' (Ampersand), but it is not
+ |
+LL | fn f(_: &&()) -> &() { todo!() }
+ | ~
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/fullwidth-ampersand.rs:3:18
+ |
+LL | fn f(_: &&()) -> &() { todo!() }
+ | ----- ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but the signature does not say which one of argument 1's 2 lifetimes it is borrowed from
+help: consider introducing a named lifetime parameter
+ |
+LL | fn f<'a>(_: &'a &'a ()) -> &'a () { todo!() }
+ | ++++ ++ ++ ++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/lifetimes/issue-105227.fixed b/tests/ui/lifetimes/issue-105227.fixed
new file mode 100644
index 000000000..f6ed9c82e
--- /dev/null
+++ b/tests/ui/lifetimes/issue-105227.fixed
@@ -0,0 +1,26 @@
+// Regression test for issue #105227.
+
+// run-rustfix
+#![allow(warnings)]
+fn chars0<'a>(v :(&'a str, &'a str)) -> impl Iterator<Item = char> + 'a {
+//~^ HELP to declare that `impl Iterator<Item = char>` captures `'_`, you can introduce a named lifetime parameter `'a`
+ v.0.chars().chain(v.1.chars())
+ //~^ ERROR hidden type for `impl Iterator<Item = char>` captures lifetime that does not appear in bounds
+}
+
+fn chars1<'a>(v0 : &'a str, v1 : &'a str) -> impl Iterator<Item = char> + 'a {
+//~^ HELP to declare that `impl Iterator<Item = char>` captures `'_`, you can introduce a named lifetime parameter `'a`
+ v0.chars().chain(v1.chars())
+ //~^ ERROR hidden type for `impl Iterator<Item = char>` captures lifetime that does not appear in bound
+}
+
+fn chars2<'b>(v0 : &'b str, v1 : &'b str, v2 : &'b str) ->
+//~^ HELP to declare that `impl Iterator<Item = char>` captures `'_`, you can use the named lifetime parameter `'b`
+ (impl Iterator<Item = char> + 'b , &'b str)
+{
+ (v0.chars().chain(v1.chars()), v2)
+ //~^ ERROR hidden type for `impl Iterator<Item = char>` captures lifetime that does not appear in bound
+}
+
+fn main() {
+}
diff --git a/tests/ui/lifetimes/issue-105227.rs b/tests/ui/lifetimes/issue-105227.rs
new file mode 100644
index 000000000..6427a50bb
--- /dev/null
+++ b/tests/ui/lifetimes/issue-105227.rs
@@ -0,0 +1,26 @@
+// Regression test for issue #105227.
+
+// run-rustfix
+#![allow(warnings)]
+fn chars0(v :(& str, &str)) -> impl Iterator<Item = char> {
+//~^ HELP to declare that `impl Iterator<Item = char>` captures `'_`, you can introduce a named lifetime parameter `'a`
+ v.0.chars().chain(v.1.chars())
+ //~^ ERROR hidden type for `impl Iterator<Item = char>` captures lifetime that does not appear in bounds
+}
+
+fn chars1(v0 : & str, v1 : &str) -> impl Iterator<Item = char> {
+//~^ HELP to declare that `impl Iterator<Item = char>` captures `'_`, you can introduce a named lifetime parameter `'a`
+ v0.chars().chain(v1.chars())
+ //~^ ERROR hidden type for `impl Iterator<Item = char>` captures lifetime that does not appear in bound
+}
+
+fn chars2<'b>(v0 : &str, v1 : &'_ str, v2 : &'b str) ->
+//~^ HELP to declare that `impl Iterator<Item = char>` captures `'_`, you can use the named lifetime parameter `'b`
+ (impl Iterator<Item = char>, &'b str)
+{
+ (v0.chars().chain(v1.chars()), v2)
+ //~^ ERROR hidden type for `impl Iterator<Item = char>` captures lifetime that does not appear in bound
+}
+
+fn main() {
+}
diff --git a/tests/ui/lifetimes/issue-105227.stderr b/tests/ui/lifetimes/issue-105227.stderr
new file mode 100644
index 000000000..d21145937
--- /dev/null
+++ b/tests/ui/lifetimes/issue-105227.stderr
@@ -0,0 +1,47 @@
+error[E0700]: hidden type for `impl Iterator<Item = char>` captures lifetime that does not appear in bounds
+ --> $DIR/issue-105227.rs:7:5
+ |
+LL | fn chars0(v :(& str, &str)) -> impl Iterator<Item = char> {
+ | ----- hidden type `std::iter::Chain<Chars<'_>, Chars<'_>>` captures the anonymous lifetime defined here
+LL |
+LL | v.0.chars().chain(v.1.chars())
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: to declare that `impl Iterator<Item = char>` captures `'_`, you can introduce a named lifetime parameter `'a`
+ |
+LL | fn chars0<'a>(v :(&'a str, &'a str)) -> impl Iterator<Item = char> + 'a {
+ | ++++ ++ ++ ++++
+
+error[E0700]: hidden type for `impl Iterator<Item = char>` captures lifetime that does not appear in bounds
+ --> $DIR/issue-105227.rs:13:5
+ |
+LL | fn chars1(v0 : & str, v1 : &str) -> impl Iterator<Item = char> {
+ | ----- hidden type `std::iter::Chain<Chars<'_>, Chars<'_>>` captures the anonymous lifetime defined here
+LL |
+LL | v0.chars().chain(v1.chars())
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: to declare that `impl Iterator<Item = char>` captures `'_`, you can introduce a named lifetime parameter `'a`
+ |
+LL | fn chars1<'a>(v0 : &'a str, v1 : &'a str) -> impl Iterator<Item = char> + 'a {
+ | ++++ ++ ++ ++++
+
+error[E0700]: hidden type for `impl Iterator<Item = char>` captures lifetime that does not appear in bounds
+ --> $DIR/issue-105227.rs:21:5
+ |
+LL | fn chars2<'b>(v0 : &str, v1 : &'_ str, v2 : &'b str) ->
+ | ---- hidden type `std::iter::Chain<Chars<'_>, Chars<'_>>` captures the anonymous lifetime defined here
+...
+LL | (v0.chars().chain(v1.chars()), v2)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+help: to declare that `impl Iterator<Item = char>` captures `'_`, you can use the named lifetime parameter `'b`
+ |
+LL ~ fn chars2<'b>(v0 : &'b str, v1 : &'b str, v2 : &'b str) ->
+LL |
+LL ~ (impl Iterator<Item = char> + 'b , &'b str)
+ |
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0700`.
diff --git a/tests/ui/lifetimes/issue-105507.fixed b/tests/ui/lifetimes/issue-105507.fixed
new file mode 100644
index 000000000..277ce8a77
--- /dev/null
+++ b/tests/ui/lifetimes/issue-105507.fixed
@@ -0,0 +1,43 @@
+// run-rustfix
+//
+#![allow(warnings)]
+struct Wrapper<'a, T: ?Sized>(&'a T);
+
+trait Project {
+ type Projected<'a> where Self: 'a;
+ fn project(this: Wrapper<'_, Self>) -> Self::Projected<'_>;
+}
+trait MyTrait {}
+trait ProjectedMyTrait {}
+
+impl<T> Project for Option<T> {
+ type Projected<'a> = Option<Wrapper<'a, T>> where T: 'a;
+ fn project(this: Wrapper<'_, Self>) -> Self::Projected<'_> {
+ this.0.as_ref().map(Wrapper)
+ }
+}
+
+impl<T: MyTrait> MyTrait for Option<Wrapper<'_, T>> {}
+
+impl<T: ProjectedMyTrait> MyTrait for Wrapper<'_, T> {}
+
+impl<T> ProjectedMyTrait for T
+ where
+ T: Project,
+ for<'a> T::Projected<'a>: MyTrait,
+ //~^ NOTE due to current limitations in the borrow checker, this implies a `'static` lifetime
+ //~| NOTE due to current limitations in the borrow checker, this implies a `'static` lifetime
+{}
+
+fn require_trait<T: MyTrait>(_: T) {}
+
+fn foo<T : MyTrait + 'static + 'static, U : MyTrait + 'static + 'static>(wrap: Wrapper<'_, Option<T>>, wrap1: Wrapper<'_, Option<U>>) {
+ //~^ HELP consider restricting the type parameter to the `'static` lifetime
+ //~| HELP consider restricting the type parameter to the `'static` lifetime
+ require_trait(wrap);
+ //~^ ERROR `T` does not live long enough
+ require_trait(wrap1);
+ //~^ ERROR `U` does not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-105507.rs b/tests/ui/lifetimes/issue-105507.rs
new file mode 100644
index 000000000..f46c6b6f2
--- /dev/null
+++ b/tests/ui/lifetimes/issue-105507.rs
@@ -0,0 +1,43 @@
+// run-rustfix
+//
+#![allow(warnings)]
+struct Wrapper<'a, T: ?Sized>(&'a T);
+
+trait Project {
+ type Projected<'a> where Self: 'a;
+ fn project(this: Wrapper<'_, Self>) -> Self::Projected<'_>;
+}
+trait MyTrait {}
+trait ProjectedMyTrait {}
+
+impl<T> Project for Option<T> {
+ type Projected<'a> = Option<Wrapper<'a, T>> where T: 'a;
+ fn project(this: Wrapper<'_, Self>) -> Self::Projected<'_> {
+ this.0.as_ref().map(Wrapper)
+ }
+}
+
+impl<T: MyTrait> MyTrait for Option<Wrapper<'_, T>> {}
+
+impl<T: ProjectedMyTrait> MyTrait for Wrapper<'_, T> {}
+
+impl<T> ProjectedMyTrait for T
+ where
+ T: Project,
+ for<'a> T::Projected<'a>: MyTrait,
+ //~^ NOTE due to current limitations in the borrow checker, this implies a `'static` lifetime
+ //~| NOTE due to current limitations in the borrow checker, this implies a `'static` lifetime
+{}
+
+fn require_trait<T: MyTrait>(_: T) {}
+
+fn foo<T : MyTrait, U : MyTrait>(wrap: Wrapper<'_, Option<T>>, wrap1: Wrapper<'_, Option<U>>) {
+ //~^ HELP consider restricting the type parameter to the `'static` lifetime
+ //~| HELP consider restricting the type parameter to the `'static` lifetime
+ require_trait(wrap);
+ //~^ ERROR `T` does not live long enough
+ require_trait(wrap1);
+ //~^ ERROR `U` does not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-105507.stderr b/tests/ui/lifetimes/issue-105507.stderr
new file mode 100644
index 000000000..44d3a7eb9
--- /dev/null
+++ b/tests/ui/lifetimes/issue-105507.stderr
@@ -0,0 +1,34 @@
+error: `T` does not live long enough
+ --> $DIR/issue-105507.rs:37:5
+ |
+LL | require_trait(wrap);
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/issue-105507.rs:27:35
+ |
+LL | for<'a> T::Projected<'a>: MyTrait,
+ | ^^^^^^^
+help: consider restricting the type parameter to the `'static` lifetime
+ |
+LL | fn foo<T : MyTrait + 'static, U : MyTrait + 'static>(wrap: Wrapper<'_, Option<T>>, wrap1: Wrapper<'_, Option<U>>) {
+ | +++++++++ +++++++++
+
+error: `U` does not live long enough
+ --> $DIR/issue-105507.rs:39:5
+ |
+LL | require_trait(wrap1);
+ | ^^^^^^^^^^^^^^^^^^^^
+ |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+ --> $DIR/issue-105507.rs:27:35
+ |
+LL | for<'a> T::Projected<'a>: MyTrait,
+ | ^^^^^^^
+help: consider restricting the type parameter to the `'static` lifetime
+ |
+LL | fn foo<T : MyTrait + 'static, U : MyTrait + 'static>(wrap: Wrapper<'_, Option<T>>, wrap1: Wrapper<'_, Option<U>>) {
+ | +++++++++ +++++++++
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lifetimes/issue-17728.rs b/tests/ui/lifetimes/issue-17728.rs
new file mode 100644
index 000000000..6aca159c4
--- /dev/null
+++ b/tests/ui/lifetimes/issue-17728.rs
@@ -0,0 +1,122 @@
+use std::fmt::{Debug, Formatter, Error};
+use std::collections::HashMap;
+
+trait HasInventory {
+ fn getInventory<'s>(&'s self) -> &'s mut Inventory;
+ fn addToInventory(&self, item: &Item);
+ fn removeFromInventory(&self, itemName: &str) -> bool;
+}
+
+trait TraversesWorld {
+ fn attemptTraverse(&self, room: &Room, directionStr: &str) -> Result<&Room, &str> {
+ let direction = str_to_direction(directionStr);
+ let maybe_room = room.direction_to_room.get(&direction);
+ match maybe_room {
+ Some(entry) => Ok(entry),
+ _ => Err("Direction does not exist in room.")
+ }
+ }
+}
+
+
+#[derive(Debug, Eq, PartialEq, Hash)]
+enum RoomDirection {
+ West,
+ East,
+ North,
+ South,
+ Up,
+ Down,
+ In,
+ Out,
+
+ None
+}
+
+struct Room {
+ description: String,
+ items: Vec<Item>,
+ direction_to_room: HashMap<RoomDirection, Room>,
+}
+
+impl Room {
+ fn new(description: &'static str) -> Room {
+ Room {
+ description: description.to_string(),
+ items: Vec::new(),
+ direction_to_room: HashMap::new()
+ }
+ }
+
+ fn add_direction(&mut self, direction: RoomDirection, room: Room) {
+ self.direction_to_room.insert(direction, room);
+ }
+}
+
+struct Item {
+ name: String,
+}
+
+struct Inventory {
+ items: Vec<Item>,
+}
+
+impl Inventory {
+ fn new() -> Inventory {
+ Inventory {
+ items: Vec::new()
+ }
+ }
+}
+
+struct Player {
+ name: String,
+ inventory: Inventory,
+}
+
+impl Player {
+ fn new(name: &'static str) -> Player {
+ Player {
+ name: name.to_string(),
+ inventory: Inventory::new()
+ }
+ }
+}
+
+impl TraversesWorld for Player {
+}
+
+impl Debug for Player {
+ fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
+ formatter.write_str("Player{ name:");
+ formatter.write_str(&self.name);
+ formatter.write_str(" }");
+ Ok(())
+ }
+}
+
+fn str_to_direction(to_parse: &str) -> RoomDirection {
+ match to_parse {
+ "w" | "west" => RoomDirection::West,
+ "e" | "east" => RoomDirection::East,
+ "n" | "north" => RoomDirection::North,
+ "s" | "south" => RoomDirection::South,
+ "in" => RoomDirection::In,
+ "out" => RoomDirection::Out,
+ "up" => RoomDirection::Up,
+ "down" => RoomDirection::Down,
+ _ => None
+ }
+ //~^^ ERROR `match` arms have incompatible types
+}
+
+fn main() {
+ let mut player = Player::new("Test player");
+ let mut room = Room::new("A test room");
+ println!("Made a player: {:?}", player);
+ println!("Direction parse: {:?}", str_to_direction("east"));
+ match player.attemptTraverse(&room, "west") {
+ Ok(_) => println!("Was able to move west"),
+ Err(msg) => println!("Not able to move west: {}", msg)
+ };
+}
diff --git a/tests/ui/lifetimes/issue-17728.stderr b/tests/ui/lifetimes/issue-17728.stderr
new file mode 100644
index 000000000..3b25902d7
--- /dev/null
+++ b/tests/ui/lifetimes/issue-17728.stderr
@@ -0,0 +1,21 @@
+error[E0308]: `match` arms have incompatible types
+ --> $DIR/issue-17728.rs:108:14
+ |
+LL | / match to_parse {
+LL | | "w" | "west" => RoomDirection::West,
+LL | | "e" | "east" => RoomDirection::East,
+LL | | "n" | "north" => RoomDirection::North,
+... |
+LL | | "down" => RoomDirection::Down,
+ | | ------------------- this and all prior arms are found to be of type `RoomDirection`
+LL | | _ => None
+ | | ^^^^ expected enum `RoomDirection`, found enum `Option`
+LL | | }
+ | |_____- `match` arms have incompatible types
+ |
+ = note: expected enum `RoomDirection`
+ found enum `Option<_>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/lifetimes/issue-26638.rs b/tests/ui/lifetimes/issue-26638.rs
new file mode 100644
index 000000000..4bec3b341
--- /dev/null
+++ b/tests/ui/lifetimes/issue-26638.rs
@@ -0,0 +1,13 @@
+fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
+//~^ ERROR missing lifetime specifier [E0106]
+//~| ERROR mismatched types
+
+fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
+//~^ ERROR missing lifetime specifier [E0106]
+//~| ERROR mismatched types
+//~| ERROR function takes 1 argument but 0 arguments were supplied
+
+fn parse_type_3() -> &str { unimplemented!() }
+//~^ ERROR missing lifetime specifier [E0106]
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-26638.stderr b/tests/ui/lifetimes/issue-26638.stderr
new file mode 100644
index 000000000..98d39d614
--- /dev/null
+++ b/tests/ui/lifetimes/issue-26638.stderr
@@ -0,0 +1,73 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/issue-26638.rs:1:62
+ |
+LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
+ | ------------------------------------ ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from
+help: consider introducing a named lifetime parameter
+ |
+LL | fn parse_type<'a>(iter: Box<dyn Iterator<Item=&'a str>+'static>) -> &'a str { iter.next() }
+ | ++++ ++ ++
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/issue-26638.rs:5:40
+ |
+LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
+ | ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &'static str { iter() }
+ | +++++++
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/issue-26638.rs:10:22
+ |
+LL | fn parse_type_3() -> &str { unimplemented!() }
+ | ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn parse_type_3() -> &'static str { unimplemented!() }
+ | +++++++
+
+error[E0308]: mismatched types
+ --> $DIR/issue-26638.rs:1:69
+ |
+LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() }
+ | ---- ^^^^^^^^^^^ expected `&str`, found enum `Option`
+ | |
+ | expected `&'static str` because of return type
+ |
+ = note: expected reference `&'static str`
+ found enum `Option<&str>`
+
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
+ --> $DIR/issue-26638.rs:5:47
+ |
+LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
+ | ^^^^-- an argument of type `&u8` is missing
+ |
+help: provide the argument
+ |
+LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter(/* &u8 */) }
+ | ~~~~~~~~~~~
+
+error[E0308]: mismatched types
+ --> $DIR/issue-26638.rs:5:47
+ |
+LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
+ | ---- ^^^^^^ expected `str`, found `u8`
+ | |
+ | expected `&'static str` because of return type
+ |
+ = note: expected reference `&'static str`
+ found reference `&u8`
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0061, E0106, E0308.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/tests/ui/lifetimes/issue-34979.rs b/tests/ui/lifetimes/issue-34979.rs
new file mode 100644
index 000000000..252486dd9
--- /dev/null
+++ b/tests/ui/lifetimes/issue-34979.rs
@@ -0,0 +1,9 @@
+trait Foo {}
+impl<'a, T> Foo for &'a T {}
+
+struct Ctx<'a>(&'a ())
+where
+ &'a (): Foo, //~ ERROR: type annotations needed
+ &'static (): Foo;
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-34979.stderr b/tests/ui/lifetimes/issue-34979.stderr
new file mode 100644
index 000000000..3d4208031
--- /dev/null
+++ b/tests/ui/lifetimes/issue-34979.stderr
@@ -0,0 +1,20 @@
+error[E0283]: type annotations needed: cannot satisfy `&'a (): Foo`
+ --> $DIR/issue-34979.rs:6:13
+ |
+LL | &'a (): Foo,
+ | ^^^
+ |
+note: multiple `impl`s or `where` clauses satisfying `&'a (): Foo` found
+ --> $DIR/issue-34979.rs:2:1
+ |
+LL | impl<'a, T> Foo for &'a T {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | &'a (): Foo,
+ | ^^^
+LL | &'static (): Foo;
+ | ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/lifetimes/issue-54378.rs b/tests/ui/lifetimes/issue-54378.rs
new file mode 100644
index 000000000..aa42d4a7c
--- /dev/null
+++ b/tests/ui/lifetimes/issue-54378.rs
@@ -0,0 +1,26 @@
+// check-pass
+
+// Regression test for #54378.
+
+#![feature(never_type)]
+
+use std::marker::PhantomData;
+
+pub trait Machine<'a, 'mir, 'tcx>: Sized {
+ type MemoryKinds: ::std::fmt::Debug + Copy + Eq;
+ const MUT_STATIC_KIND: Option<Self::MemoryKinds>;
+}
+
+pub struct CompileTimeEvaluator<'a, 'mir, 'tcx: 'a+'mir> {
+ pub _data: PhantomData<(&'a (), &'mir (), &'tcx ())>,
+}
+
+impl<'a, 'mir, 'tcx: 'a + 'mir> Machine<'a, 'mir, 'tcx>
+ for CompileTimeEvaluator<'a, 'mir, 'tcx>
+{
+ type MemoryKinds = !;
+
+ const MUT_STATIC_KIND: Option<!> = None;
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-55796.rs b/tests/ui/lifetimes/issue-55796.rs
new file mode 100644
index 000000000..a7b27a999
--- /dev/null
+++ b/tests/ui/lifetimes/issue-55796.rs
@@ -0,0 +1,26 @@
+pub trait EdgeTrait<N> {
+ fn target(&self) -> N;
+}
+
+pub trait Graph<'a> {
+ type Node;
+ type Edge: EdgeTrait<Self::Node>;
+ type NodesIter: Iterator<Item = Self::Node> + 'a;
+ type EdgesIter: Iterator<Item = Self::Edge> + 'a;
+
+ fn nodes(&'a self) -> Self::NodesIter;
+ fn out_edges(&'a self, u: &Self::Node) -> Self::EdgesIter;
+ fn in_edges(&'a self, u: &Self::Node) -> Self::EdgesIter;
+
+ fn out_neighbors(&'a self, u: &Self::Node) -> Box<dyn Iterator<Item = Self::Node>> {
+ Box::new(self.out_edges(u).map(|e| e.target()))
+ //~^ ERROR lifetime may not live long enough
+ }
+
+ fn in_neighbors(&'a self, u: &Self::Node) -> Box<dyn Iterator<Item = Self::Node>> {
+ Box::new(self.in_edges(u).map(|e| e.target()))
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-55796.stderr b/tests/ui/lifetimes/issue-55796.stderr
new file mode 100644
index 000000000..5809a56cd
--- /dev/null
+++ b/tests/ui/lifetimes/issue-55796.stderr
@@ -0,0 +1,20 @@
+error: lifetime may not live long enough
+ --> $DIR/issue-55796.rs:16:9
+ |
+LL | pub trait Graph<'a> {
+ | -- lifetime `'a` defined here
+...
+LL | Box::new(self.out_edges(u).map(|e| e.target()))
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: lifetime may not live long enough
+ --> $DIR/issue-55796.rs:21:9
+ |
+LL | pub trait Graph<'a> {
+ | -- lifetime `'a` defined here
+...
+LL | Box::new(self.in_edges(u).map(|e| e.target()))
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lifetimes/issue-64173-unused-lifetimes.rs b/tests/ui/lifetimes/issue-64173-unused-lifetimes.rs
new file mode 100644
index 000000000..8080dd7dc
--- /dev/null
+++ b/tests/ui/lifetimes/issue-64173-unused-lifetimes.rs
@@ -0,0 +1,19 @@
+use std::mem::size_of;
+
+struct Foo<'s> { //~ ERROR: parameter `'s` is never used
+ array: [(); size_of::<&Self>()],
+ //~^ ERROR: generic `Self` types are currently not permitted in anonymous constants
+}
+
+// The below is taken from https://github.com/rust-lang/rust/issues/66152#issuecomment-550275017
+// as the root cause seems the same.
+
+const fn foo<T>() -> usize {
+ 0
+}
+
+struct Bar<'a> { //~ ERROR: parameter `'a` is never used
+ beta: [(); foo::<&'a ()>()], //~ ERROR: a non-static lifetime is not allowed in a `const`
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr
new file mode 100644
index 000000000..a487cbea5
--- /dev/null
+++ b/tests/ui/lifetimes/issue-64173-unused-lifetimes.stderr
@@ -0,0 +1,35 @@
+error[E0658]: a non-static lifetime is not allowed in a `const`
+ --> $DIR/issue-64173-unused-lifetimes.rs:16:23
+ |
+LL | beta: [(); foo::<&'a ()>()],
+ | ^^
+ |
+ = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
+ = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable
+
+error: generic `Self` types are currently not permitted in anonymous constants
+ --> $DIR/issue-64173-unused-lifetimes.rs:4:28
+ |
+LL | array: [(); size_of::<&Self>()],
+ | ^^^^
+
+error[E0392]: parameter `'s` is never used
+ --> $DIR/issue-64173-unused-lifetimes.rs:3:12
+ |
+LL | struct Foo<'s> {
+ | ^^ unused parameter
+ |
+ = help: consider removing `'s`, referring to it in a field, or using a marker such as `PhantomData`
+
+error[E0392]: parameter `'a` is never used
+ --> $DIR/issue-64173-unused-lifetimes.rs:15:12
+ |
+LL | struct Bar<'a> {
+ | ^^ unused parameter
+ |
+ = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0392, E0658.
+For more information about an error, try `rustc --explain E0392`.
diff --git a/tests/ui/lifetimes/issue-67498.rs b/tests/ui/lifetimes/issue-67498.rs
new file mode 100644
index 000000000..8d8826435
--- /dev/null
+++ b/tests/ui/lifetimes/issue-67498.rs
@@ -0,0 +1,21 @@
+// check-pass
+
+// Regression test for #67498.
+
+pub fn f<'a, 'b, 'd, 'e> (
+ x: for<'c> fn(
+ fn(&'c fn(&'c ())),
+ fn(&'c fn(&'c ())),
+ fn(&'c fn(&'c ())),
+ fn(&'c fn(&'c ())),
+ )
+) -> fn(
+ fn(&'a fn(&'d ())),
+ fn(&'b fn(&'d ())),
+ fn(&'a fn(&'e ())),
+ fn(&'b fn(&'e ())),
+) {
+ x
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-70917-lifetimes-in-fn-def.rs b/tests/ui/lifetimes/issue-70917-lifetimes-in-fn-def.rs
new file mode 100644
index 000000000..b9aab2714
--- /dev/null
+++ b/tests/ui/lifetimes/issue-70917-lifetimes-in-fn-def.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+fn assert_static<T: 'static>(_: T) {}
+
+// NOTE(eddyb) the `'a: 'a` may look a bit strange, but we *really* want
+// `'a` to be an *early-bound* parameter, otherwise it doesn't matter anyway.
+fn capture_lifetime<'a: 'a>() {}
+
+fn test_lifetime<'a>() {
+ assert_static(capture_lifetime::<'a>);
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-2.rs b/tests/ui/lifetimes/issue-76168-hr-outlives-2.rs
new file mode 100644
index 000000000..348586fa2
--- /dev/null
+++ b/tests/ui/lifetimes/issue-76168-hr-outlives-2.rs
@@ -0,0 +1,22 @@
+// edition:2018
+// check-pass
+
+trait Trait<Input> {
+ type Output;
+}
+
+async fn walk<F>(filter: F)
+where
+ for<'a> F: Trait<&'a u32> + 'a,
+ for<'a> <F as Trait<&'a u32>>::Output: 'a,
+{
+}
+
+async fn walk2<F: 'static>(filter: F)
+where
+ for<'a> F: Trait<&'a u32> + 'a,
+ for<'a> <F as Trait<&'a u32>>::Output: 'a,
+{
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives.rs b/tests/ui/lifetimes/issue-76168-hr-outlives.rs
new file mode 100644
index 000000000..9366e94c9
--- /dev/null
+++ b/tests/ui/lifetimes/issue-76168-hr-outlives.rs
@@ -0,0 +1,19 @@
+// edition:2018
+// check-pass
+
+#![feature(unboxed_closures)]
+use std::future::Future;
+
+async fn wrapper<F>(f: F)
+where for<'a> F: FnOnce<(&'a mut i32,)>,
+ for<'a> <F as FnOnce<(&'a mut i32,)>>::Output: Future<Output=()> + 'a
+{
+ let mut i = 41;
+ f(&mut i).await;
+}
+
+async fn add_one(i: &mut i32) {
+ *i = *i + 1;
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-77175.rs b/tests/ui/lifetimes/issue-77175.rs
new file mode 100644
index 000000000..2282752b6
--- /dev/null
+++ b/tests/ui/lifetimes/issue-77175.rs
@@ -0,0 +1,19 @@
+#[deny(single_use_lifetimes)]
+// edition:2018
+// check-pass
+
+// Prior to the fix, the compiler complained that the 'a lifetime was only used
+// once. This was obviously wrong since the lifetime is used twice: For the s3
+// parameter and the return type. The issue was caused by the compiler
+// desugaring the async function into a generator that uses only a single
+// lifetime, which then the validator complained about becauase of the
+// single_use_lifetimes constraints.
+async fn bar<'a>(s1: String, s2: &'_ str, s3: &'a str) -> &'a str {
+ s3
+}
+
+fn foo<'a>(s1: String, s2: &'_ str, s3: &'a str) -> &'a str {
+ s3
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-79187-2.rs b/tests/ui/lifetimes/issue-79187-2.rs
new file mode 100644
index 000000000..fff92c30b
--- /dev/null
+++ b/tests/ui/lifetimes/issue-79187-2.rs
@@ -0,0 +1,29 @@
+trait Foo {}
+
+impl<F> Foo for F where F: Fn(&i32) -> &i32 {}
+
+fn take_foo(_: impl Foo) {}
+
+fn main() {
+ take_foo(|a| a);
+ //~^ ERROR implementation of `FnOnce` is not general enough
+ //~| ERROR mismatched types
+ take_foo(|a: &i32| a);
+ //~^ ERROR lifetime may not live long enough
+ //~| ERROR mismatched types
+ take_foo(|a: &i32| -> &i32 { a });
+ //~^ ERROR lifetime may not live long enough
+ //~| ERROR mismatched types
+
+ // OK
+ take_foo(identity(|a| a));
+ take_foo(identity(|a: &i32| a));
+ take_foo(identity(|a: &i32| -> &i32 { a }));
+
+ fn identity<F>(t: F) -> F
+ where
+ F: Fn(&i32) -> &i32,
+ {
+ t
+ }
+}
diff --git a/tests/ui/lifetimes/issue-79187-2.stderr b/tests/ui/lifetimes/issue-79187-2.stderr
new file mode 100644
index 000000000..c5f654b37
--- /dev/null
+++ b/tests/ui/lifetimes/issue-79187-2.stderr
@@ -0,0 +1,77 @@
+error: lifetime may not live long enough
+ --> $DIR/issue-79187-2.rs:11:24
+ |
+LL | take_foo(|a: &i32| a);
+ | - - ^ returning this value requires that `'1` must outlive `'2`
+ | | |
+ | | return type of closure is &'2 i32
+ | let's call the lifetime of this reference `'1`
+
+error: lifetime may not live long enough
+ --> $DIR/issue-79187-2.rs:14:34
+ |
+LL | take_foo(|a: &i32| -> &i32 { a });
+ | - - ^ returning this value requires that `'1` must outlive `'2`
+ | | |
+ | | let's call the lifetime of this reference `'2`
+ | let's call the lifetime of this reference `'1`
+
+error: implementation of `FnOnce` is not general enough
+ --> $DIR/issue-79187-2.rs:8:5
+ |
+LL | take_foo(|a| a);
+ | ^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
+ |
+ = note: closure with signature `fn(&'2 i32) -> &i32` must implement `FnOnce<(&'1 i32,)>`, for any lifetime `'1`...
+ = note: ...but it actually implements `FnOnce<(&'2 i32,)>`, for some specific lifetime `'2`
+
+error[E0308]: mismatched types
+ --> $DIR/issue-79187-2.rs:8:5
+ |
+LL | take_foo(|a| a);
+ | ^^^^^^^^^^^^^^^ one type is more general than the other
+ |
+ = note: expected trait `for<'a> Fn<(&'a i32,)>`
+ found trait `Fn<(&i32,)>`
+note: this closure does not fulfill the lifetime requirements
+ --> $DIR/issue-79187-2.rs:8:14
+ |
+LL | take_foo(|a| a);
+ | ^^^
+note: the lifetime requirement is introduced here
+ --> $DIR/issue-79187-2.rs:5:21
+ |
+LL | fn take_foo(_: impl Foo) {}
+ | ^^^
+
+error[E0308]: mismatched types
+ --> $DIR/issue-79187-2.rs:11:5
+ |
+LL | take_foo(|a: &i32| a);
+ | ^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+ |
+ = note: expected reference `&i32`
+ found reference `&i32`
+note: the lifetime requirement is introduced here
+ --> $DIR/issue-79187-2.rs:5:21
+ |
+LL | fn take_foo(_: impl Foo) {}
+ | ^^^
+
+error[E0308]: mismatched types
+ --> $DIR/issue-79187-2.rs:14:5
+ |
+LL | take_foo(|a: &i32| -> &i32 { a });
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+ |
+ = note: expected reference `&i32`
+ found reference `&i32`
+note: the lifetime requirement is introduced here
+ --> $DIR/issue-79187-2.rs:5:21
+ |
+LL | fn take_foo(_: impl Foo) {}
+ | ^^^
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/lifetimes/issue-79187.rs b/tests/ui/lifetimes/issue-79187.rs
new file mode 100644
index 000000000..8e1304562
--- /dev/null
+++ b/tests/ui/lifetimes/issue-79187.rs
@@ -0,0 +1,8 @@
+fn thing(x: impl FnOnce(&u32)) {}
+
+fn main() {
+ let f = |_| ();
+ thing(f);
+ //~^ ERROR mismatched types
+ //~^^ ERROR implementation of `FnOnce` is not general enough
+}
diff --git a/tests/ui/lifetimes/issue-79187.stderr b/tests/ui/lifetimes/issue-79187.stderr
new file mode 100644
index 000000000..ee6e7b89d
--- /dev/null
+++ b/tests/ui/lifetimes/issue-79187.stderr
@@ -0,0 +1,31 @@
+error[E0308]: mismatched types
+ --> $DIR/issue-79187.rs:5:5
+ |
+LL | thing(f);
+ | ^^^^^^^^ one type is more general than the other
+ |
+ = note: expected trait `for<'a> FnOnce<(&'a u32,)>`
+ found trait `FnOnce<(&u32,)>`
+note: this closure does not fulfill the lifetime requirements
+ --> $DIR/issue-79187.rs:4:13
+ |
+LL | let f = |_| ();
+ | ^^^
+note: the lifetime requirement is introduced here
+ --> $DIR/issue-79187.rs:1:18
+ |
+LL | fn thing(x: impl FnOnce(&u32)) {}
+ | ^^^^^^^^^^^^
+
+error: implementation of `FnOnce` is not general enough
+ --> $DIR/issue-79187.rs:5:5
+ |
+LL | thing(f);
+ | ^^^^^^^^ implementation of `FnOnce` is not general enough
+ |
+ = note: closure with signature `fn(&'2 u32)` must implement `FnOnce<(&'1 u32,)>`, for any lifetime `'1`...
+ = note: ...but it actually implements `FnOnce<(&'2 u32,)>`, for some specific lifetime `'2`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/lifetimes/issue-83737-binders-across-types.rs b/tests/ui/lifetimes/issue-83737-binders-across-types.rs
new file mode 100644
index 000000000..e130561e4
--- /dev/null
+++ b/tests/ui/lifetimes/issue-83737-binders-across-types.rs
@@ -0,0 +1,14 @@
+// build-pass
+// compile-flags: --edition 2018
+// compile-flags: --crate-type rlib
+
+use std::future::Future;
+
+async fn handle<F>(slf: &F)
+where
+ F: Fn(&()) -> Box<dyn Future<Output = ()> + Unpin>,
+{
+ (slf)(&()).await;
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-83737-erasing-bound-vars.rs b/tests/ui/lifetimes/issue-83737-erasing-bound-vars.rs
new file mode 100644
index 000000000..c496a3556
--- /dev/null
+++ b/tests/ui/lifetimes/issue-83737-erasing-bound-vars.rs
@@ -0,0 +1,14 @@
+// build-pass
+// compile-flags: --edition 2018
+// compile-flags: --crate-type rlib
+
+use std::future::Future;
+
+async fn handle<F>(slf: &F)
+where
+ F: Fn(&()) -> Box<dyn for<'a> Future<Output = ()> + Unpin>,
+{
+ (slf)(&()).await;
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs
new file mode 100644
index 000000000..7f0ea730d
--- /dev/null
+++ b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.rs
@@ -0,0 +1,8 @@
+// check-fail
+
+struct Foo {}
+impl Foo {
+ fn bar(foo: Foo<Target = usize>) {}
+ //~^ associated type bindings are not allowed here
+}
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr
new file mode 100644
index 000000000..f7bdee633
--- /dev/null
+++ b/tests/ui/lifetimes/issue-83753-invalid-associated-type-supertrait-hrtb.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+ --> $DIR/issue-83753-invalid-associated-type-supertrait-hrtb.rs:5:21
+ |
+LL | fn bar(foo: Foo<Target = usize>) {}
+ | ^^^^^^^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.rs b/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.rs
new file mode 100644
index 000000000..604687ce7
--- /dev/null
+++ b/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.rs
@@ -0,0 +1,7 @@
+// check-fail
+
+static STATIC_VAR_FIVE: &One();
+//~^ cannot find type
+//~| free static item without body
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr b/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr
new file mode 100644
index 000000000..e57933da5
--- /dev/null
+++ b/tests/ui/lifetimes/issue-83907-invalid-fn-like-path.stderr
@@ -0,0 +1,17 @@
+error: free static item without body
+ --> $DIR/issue-83907-invalid-fn-like-path.rs:3:1
+ |
+LL | static STATIC_VAR_FIVE: &One();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the static: `= <expr>;`
+
+error[E0412]: cannot find type `One` in this scope
+ --> $DIR/issue-83907-invalid-fn-like-path.rs:3:26
+ |
+LL | static STATIC_VAR_FIVE: &One();
+ | ^^^ not found in this scope
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/lifetimes/issue-84398.rs b/tests/ui/lifetimes/issue-84398.rs
new file mode 100644
index 000000000..1912fa59b
--- /dev/null
+++ b/tests/ui/lifetimes/issue-84398.rs
@@ -0,0 +1,20 @@
+// check-pass
+
+pub trait Deserialize<'de>: Sized {}
+pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
+
+pub trait Extensible {
+ type Config;
+}
+
+// The `C` here generates a `C: Sized` candidate
+pub trait Installer<C> {
+ fn init<B: Extensible<Config = C>>(&mut self) -> ()
+ where
+ // This clause generates a `for<'de> C: Sized` candidate
+ B::Config: DeserializeOwned,
+ {
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-84604.rs b/tests/ui/lifetimes/issue-84604.rs
new file mode 100644
index 000000000..b315ef051
--- /dev/null
+++ b/tests/ui/lifetimes/issue-84604.rs
@@ -0,0 +1,9 @@
+// run-pass
+// compile-flags: -Csymbol-mangling-version=v0
+
+pub fn f<T: ?Sized>() {}
+pub trait Frob<T: ?Sized> {}
+fn main() {
+ f::<dyn Frob<str>>();
+ f::<dyn for<'a> Frob<str>>();
+}
diff --git a/tests/ui/lifetimes/issue-90170-elision-mismatch.fixed b/tests/ui/lifetimes/issue-90170-elision-mismatch.fixed
new file mode 100644
index 000000000..bd85da1a7
--- /dev/null
+++ b/tests/ui/lifetimes/issue-90170-elision-mismatch.fixed
@@ -0,0 +1,9 @@
+// run-rustfix
+
+pub fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } //~ ERROR lifetime may not live long enough
+
+pub fn foo2<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } //~ ERROR lifetime may not live long enough
+
+pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } //~ ERROR lifetime may not live long enough
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-90170-elision-mismatch.rs b/tests/ui/lifetimes/issue-90170-elision-mismatch.rs
new file mode 100644
index 000000000..3c495368b
--- /dev/null
+++ b/tests/ui/lifetimes/issue-90170-elision-mismatch.rs
@@ -0,0 +1,9 @@
+// run-rustfix
+
+pub fn foo(x: &mut Vec<&u8>, y: &u8) { x.push(y); } //~ ERROR lifetime may not live long enough
+
+pub fn foo2(x: &mut Vec<&'_ u8>, y: &u8) { x.push(y); } //~ ERROR lifetime may not live long enough
+
+pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&u8>, y: &u8) { x.push(y); } //~ ERROR lifetime may not live long enough
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-90170-elision-mismatch.stderr b/tests/ui/lifetimes/issue-90170-elision-mismatch.stderr
new file mode 100644
index 000000000..48fb3fb4a
--- /dev/null
+++ b/tests/ui/lifetimes/issue-90170-elision-mismatch.stderr
@@ -0,0 +1,44 @@
+error: lifetime may not live long enough
+ --> $DIR/issue-90170-elision-mismatch.rs:3:40
+ |
+LL | pub fn foo(x: &mut Vec<&u8>, y: &u8) { x.push(y); }
+ | - - ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+ | | |
+ | | let's call the lifetime of this reference `'1`
+ | let's call the lifetime of this reference `'2`
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | pub fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/issue-90170-elision-mismatch.rs:5:44
+ |
+LL | pub fn foo2(x: &mut Vec<&'_ u8>, y: &u8) { x.push(y); }
+ | - - ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+ | | |
+ | | let's call the lifetime of this reference `'1`
+ | let's call the lifetime of this reference `'2`
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | pub fn foo2<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
+ | ++++ ~~ ++
+
+error: lifetime may not live long enough
+ --> $DIR/issue-90170-elision-mismatch.rs:7:63
+ |
+LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&u8>, y: &u8) { x.push(y); }
+ | - - ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+ | | |
+ | | let's call the lifetime of this reference `'1`
+ | let's call the lifetime of this reference `'2`
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); }
+ | ++ ++
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.rs b/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.rs
new file mode 100644
index 000000000..ce4cddc9b
--- /dev/null
+++ b/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.rs
@@ -0,0 +1,15 @@
+use std::cell::RefCell;
+use std::io::Read;
+
+fn main() {}
+
+fn inner(mut foo: &[u8]) {
+ let refcell = RefCell::new(&mut foo);
+ //~^ ERROR `foo` does not live long enough
+ let read = &refcell as &RefCell<dyn Read>;
+ //~^ ERROR lifetime may not live long enough
+
+ read_thing(read);
+}
+
+fn read_thing(refcell: &RefCell<dyn Read>) {}
diff --git a/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr b/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr
new file mode 100644
index 000000000..99e1e7217
--- /dev/null
+++ b/tests/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr
@@ -0,0 +1,24 @@
+error[E0597]: `foo` does not live long enough
+ --> $DIR/issue-90600-expected-return-static-indirect.rs:7:32
+ |
+LL | let refcell = RefCell::new(&mut foo);
+ | ^^^^^^^^ borrowed value does not live long enough
+LL |
+LL | let read = &refcell as &RefCell<dyn Read>;
+ | -------- cast requires that `foo` is borrowed for `'static`
+...
+LL | }
+ | - `foo` dropped here while still borrowed
+
+error: lifetime may not live long enough
+ --> $DIR/issue-90600-expected-return-static-indirect.rs:9:16
+ |
+LL | fn inner(mut foo: &[u8]) {
+ | - let's call the lifetime of this reference `'1`
+...
+LL | let read = &refcell as &RefCell<dyn Read>;
+ | ^^^^^^^^ cast requires that `'1` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/lifetimes/issue-91763.rs b/tests/ui/lifetimes/issue-91763.rs
new file mode 100644
index 000000000..2e8807fe6
--- /dev/null
+++ b/tests/ui/lifetimes/issue-91763.rs
@@ -0,0 +1,11 @@
+// aux-build:issue-91763-aux.rs
+
+#![deny(elided_lifetimes_in_paths)]
+
+extern crate issue_91763_aux;
+
+#[issue_91763_aux::repro]
+fn f() -> Ptr<Thing>;
+//~^ ERROR hidden lifetime parameters in types are deprecated
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-91763.stderr b/tests/ui/lifetimes/issue-91763.stderr
new file mode 100644
index 000000000..6ccf008c0
--- /dev/null
+++ b/tests/ui/lifetimes/issue-91763.stderr
@@ -0,0 +1,18 @@
+error: hidden lifetime parameters in types are deprecated
+ --> $DIR/issue-91763.rs:8:20
+ |
+LL | fn f() -> Ptr<Thing>;
+ | ^ expected lifetime parameter
+ |
+note: the lint level is defined here
+ --> $DIR/issue-91763.rs:3:9
+ |
+LL | #![deny(elided_lifetimes_in_paths)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+help: indicate the anonymous lifetime
+ |
+LL | fn f() -> Ptr<Thing><'_>;
+ | ++++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/issue-95023.rs b/tests/ui/lifetimes/issue-95023.rs
new file mode 100644
index 000000000..3fba8c00c
--- /dev/null
+++ b/tests/ui/lifetimes/issue-95023.rs
@@ -0,0 +1,11 @@
+struct ErrorKind;
+struct Error(ErrorKind);
+impl Fn(&isize) for Error {
+ //~^ ERROR manual implementations of `Fn` are experimental [E0183]
+ //~^^ ERROR associated type bindings are not allowed here [E0229]
+ fn foo<const N: usize>(&self) -> Self::B<{N}>;
+ //~^ ERROR associated function in `impl` without body
+ //~^^ ERROR method `foo` is not a member of trait `Fn` [E0407]
+ //~^^^ ERROR associated type `B` not found for `Self` [E0220]
+}
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-95023.stderr b/tests/ui/lifetimes/issue-95023.stderr
new file mode 100644
index 000000000..35c3797c7
--- /dev/null
+++ b/tests/ui/lifetimes/issue-95023.stderr
@@ -0,0 +1,38 @@
+error: associated function in `impl` without body
+ --> $DIR/issue-95023.rs:6:5
+ |
+LL | fn foo<const N: usize>(&self) -> Self::B<{N}>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+ | |
+ | help: provide a definition for the function: `{ <body> }`
+
+error[E0407]: method `foo` is not a member of trait `Fn`
+ --> $DIR/issue-95023.rs:6:5
+ |
+LL | fn foo<const N: usize>(&self) -> Self::B<{N}>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a member of trait `Fn`
+
+error[E0183]: manual implementations of `Fn` are experimental
+ --> $DIR/issue-95023.rs:3:6
+ |
+LL | impl Fn(&isize) for Error {
+ | ^^^^^^^^^^ manual implementations of `Fn` are experimental
+ |
+ = help: add `#![feature(unboxed_closures)]` to the crate attributes to enable
+
+error[E0229]: associated type bindings are not allowed here
+ --> $DIR/issue-95023.rs:3:6
+ |
+LL | impl Fn(&isize) for Error {
+ | ^^^^^^^^^^ associated type not allowed here
+
+error[E0220]: associated type `B` not found for `Self`
+ --> $DIR/issue-95023.rs:6:44
+ |
+LL | fn foo<const N: usize>(&self) -> Self::B<{N}>;
+ | ^ associated type `B` not found
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0183, E0220, E0229, E0407.
+For more information about an error, try `rustc --explain E0183`.
diff --git a/tests/ui/lifetimes/issue-97193.rs b/tests/ui/lifetimes/issue-97193.rs
new file mode 100644
index 000000000..6c82c29dd
--- /dev/null
+++ b/tests/ui/lifetimes/issue-97193.rs
@@ -0,0 +1,9 @@
+extern "C" {
+ fn a(&mut self) {
+ //~^ ERROR incorrect function inside `extern` block
+ //~| ERROR `self` parameter is only allowed in associated functions
+ fn b(buf: &Self) {}
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-97193.stderr b/tests/ui/lifetimes/issue-97193.stderr
new file mode 100644
index 000000000..21be543cc
--- /dev/null
+++ b/tests/ui/lifetimes/issue-97193.stderr
@@ -0,0 +1,28 @@
+error: incorrect function inside `extern` block
+ --> $DIR/issue-97193.rs:2:8
+ |
+LL | extern "C" {
+ | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body
+LL | fn a(&mut self) {
+ | ________^____________-
+ | | |
+ | | cannot have a body
+LL | |
+LL | |
+LL | | fn b(buf: &Self) {}
+LL | | }
+ | |_____- help: remove the invalid body: `;`
+ |
+ = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/issue-97193.rs:2:10
+ |
+LL | fn a(&mut self) {
+ | ^^^^^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lifetimes/issue-97194.rs b/tests/ui/lifetimes/issue-97194.rs
new file mode 100644
index 000000000..5f3560dbe
--- /dev/null
+++ b/tests/ui/lifetimes/issue-97194.rs
@@ -0,0 +1,10 @@
+extern "C" {
+ fn bget(&self, index: [usize; Self::DIM]) -> bool {
+ //~^ ERROR incorrect function inside `extern` block
+ //~| ERROR `self` parameter is only allowed in associated functions
+ //~| ERROR failed to resolve: `Self`
+ type T<'a> = &'a str;
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/issue-97194.stderr b/tests/ui/lifetimes/issue-97194.stderr
new file mode 100644
index 000000000..93bde285a
--- /dev/null
+++ b/tests/ui/lifetimes/issue-97194.stderr
@@ -0,0 +1,36 @@
+error: incorrect function inside `extern` block
+ --> $DIR/issue-97194.rs:2:8
+ |
+LL | extern "C" {
+ | ---------- `extern` blocks define existing foreign functions and functions inside of them cannot have a body
+LL | fn bget(&self, index: [usize; Self::DIM]) -> bool {
+ | ________^^^^___________________________________________-
+ | | |
+ | | cannot have a body
+LL | |
+LL | |
+LL | |
+LL | | type T<'a> = &'a str;
+LL | | }
+ | |_____- help: remove the invalid body: `;`
+ |
+ = help: you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
+ = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
+
+error: `self` parameter is only allowed in associated functions
+ --> $DIR/issue-97194.rs:2:13
+ |
+LL | fn bget(&self, index: [usize; Self::DIM]) -> bool {
+ | ^^^^^ not semantically valid as function parameter
+ |
+ = note: associated functions are those in `impl` or `trait` definitions
+
+error[E0433]: failed to resolve: `Self` is only available in impls, traits, and type definitions
+ --> $DIR/issue-97194.rs:2:35
+ |
+LL | fn bget(&self, index: [usize; Self::DIM]) -> bool {
+ | ^^^^ `Self` is only available in impls, traits, and type definitions
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0433`.
diff --git a/tests/ui/lifetimes/lifetime-bound-will-change-warning.rs b/tests/ui/lifetimes/lifetime-bound-will-change-warning.rs
new file mode 100644
index 000000000..0d0303705
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-bound-will-change-warning.rs
@@ -0,0 +1,56 @@
+// aux-build:lifetime_bound_will_change_warning_lib.rs
+
+// Test that various corner cases cause an error. These are tests
+// that used to pass before we tweaked object defaults.
+
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+
+extern crate lifetime_bound_will_change_warning_lib as lib;
+
+fn just_ref(x: &dyn Fn()) {
+}
+
+fn ref_obj(x: &Box<dyn Fn()>) {
+ // this will change to &Box<Fn()+'static>...
+
+ // Note: no warning is issued here, because the type of `x` will change to 'static
+ if false { ref_obj(x); }
+}
+
+fn test1<'a>(x: &'a Box<dyn Fn() + 'a>) {
+ // just_ref will stay the same.
+ just_ref(&**x)
+}
+
+fn test1cc<'a>(x: &'a Box<dyn Fn() + 'a>) {
+ // same as test1, but cross-crate
+ lib::just_ref(&**x)
+}
+
+fn test2<'a>(x: &'a Box<dyn Fn() + 'a>) {
+ // but ref_obj will not, so warn.
+ ref_obj(x)
+ //~^ ERROR borrowed data escapes
+}
+
+fn test2cc<'a>(x: &'a Box<dyn Fn() + 'a>) {
+ // same as test2, but cross crate
+ lib::ref_obj(x)
+ //~^ ERROR borrowed data escapes
+}
+
+fn test3<'a>(x: &'a Box<dyn Fn() + 'static>) {
+ // here, we have a 'static bound, so even when ref_obj changes, no error results
+ ref_obj(x)
+}
+
+fn test3cc<'a>(x: &'a Box<dyn Fn() + 'static>) {
+ // same as test3, but cross crate
+ lib::ref_obj(x)
+}
+
+
+fn main() {
+}
diff --git a/tests/ui/lifetimes/lifetime-bound-will-change-warning.stderr b/tests/ui/lifetimes/lifetime-bound-will-change-warning.stderr
new file mode 100644
index 000000000..c51580f28
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-bound-will-change-warning.stderr
@@ -0,0 +1,31 @@
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/lifetime-bound-will-change-warning.rs:34:5
+ |
+LL | fn test2<'a>(x: &'a Box<dyn Fn() + 'a>) {
+ | -- - `x` is a reference that is only valid in the function body
+ | |
+ | lifetime `'a` defined here
+LL | // but ref_obj will not, so warn.
+LL | ref_obj(x)
+ | ^^^^^^^^^^
+ | |
+ | `x` escapes the function body here
+ | argument requires that `'a` must outlive `'static`
+
+error[E0521]: borrowed data escapes outside of function
+ --> $DIR/lifetime-bound-will-change-warning.rs:40:5
+ |
+LL | fn test2cc<'a>(x: &'a Box<dyn Fn() + 'a>) {
+ | -- - `x` is a reference that is only valid in the function body
+ | |
+ | lifetime `'a` defined here
+LL | // same as test2, but cross crate
+LL | lib::ref_obj(x)
+ | ^^^^^^^^^^^^^^^
+ | |
+ | `x` escapes the function body here
+ | argument requires that `'a` must outlive `'static`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0521`.
diff --git a/tests/ui/lifetimes/lifetime-doesnt-live-long-enough.rs b/tests/ui/lifetimes/lifetime-doesnt-live-long-enough.rs
new file mode 100644
index 000000000..d2b782c92
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-doesnt-live-long-enough.rs
@@ -0,0 +1,49 @@
+trait ListItem<'a> {
+ fn list_name() -> &'a str;
+}
+
+trait Collection { fn len(&self) -> usize; }
+
+// is now well formed. RFC 2093
+struct List<'a, T: ListItem<'a>> {
+ slice: &'a [T]
+}
+
+impl<'a, T: ListItem<'a>> Collection for List<'a, T> {
+ fn len(&self) -> usize {
+ 0
+ }
+}
+
+struct Foo<T> {
+ foo: &'static T
+ //~^ ERROR may not live long enough
+}
+
+trait X<K>: Sized {
+ fn foo<'a, L: X<&'a Nested<K>>>();
+ //~^ ERROR may not live long enough
+
+ // check that we give a sane error for `Self`
+ fn bar<'a, L: X<&'a Nested<Self>>>();
+ //~^ ERROR may not live long enough
+
+ // check that we give a sane error for nested generics
+ fn baz<'a, L, M: X<&'a Nested<L>>>() {
+ //~^ ERROR may not live long enough
+ }
+}
+
+trait TraitB {}
+
+struct Nested<K>(K);
+impl<K> Nested<K> {
+ fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
+ //~^ ERROR may not live long enough
+ }
+ fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
+ //~^ ERROR may not live long enough
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr b/tests/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
new file mode 100644
index 000000000..affb4e8d0
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr
@@ -0,0 +1,68 @@
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/lifetime-doesnt-live-long-enough.rs:19:10
+ |
+LL | foo: &'static T
+ | ^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | struct Foo<T: 'static> {
+ | +++++++++
+
+error[E0309]: the parameter type `K` may not live long enough
+ --> $DIR/lifetime-doesnt-live-long-enough.rs:41:33
+ |
+LL | fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
+ | ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | impl<K: 'a> Nested<K> {
+ | ++++
+
+error[E0309]: the parameter type `M` may not live long enough
+ --> $DIR/lifetime-doesnt-live-long-enough.rs:44:36
+ |
+LL | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
+ | ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<M>` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b + 'a>() {
+ | ++++
+
+error[E0309]: the parameter type `K` may not live long enough
+ --> $DIR/lifetime-doesnt-live-long-enough.rs:24:19
+ |
+LL | fn foo<'a, L: X<&'a Nested<K>>>();
+ | ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | trait X<K: 'a>: Sized {
+ | ++++
+
+error[E0309]: the parameter type `Self` may not live long enough
+ --> $DIR/lifetime-doesnt-live-long-enough.rs:28:19
+ |
+LL | fn bar<'a, L: X<&'a Nested<Self>>>();
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: consider adding an explicit lifetime bound `Self: 'a`...
+ = note: ...so that the reference type `&'a Nested<Self>` does not outlive the data it points at
+
+error[E0309]: the parameter type `L` may not live long enough
+ --> $DIR/lifetime-doesnt-live-long-enough.rs:32:22
+ |
+LL | fn baz<'a, L, M: X<&'a Nested<L>>>() {
+ | ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<L>` does not outlive the data it points at
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn baz<'a, L: 'a, M: X<&'a Nested<L>>>() {
+ | ++++
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0309, E0310.
+For more information about an error, try `rustc --explain E0309`.
diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
new file mode 100644
index 000000000..d0a8fe795
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.rs
@@ -0,0 +1,51 @@
+// Lifetime annotation needed because we have no arguments.
+fn f() -> &isize { //~ ERROR missing lifetime specifier
+ panic!()
+}
+
+// Lifetime annotation needed because we have two by-reference parameters.
+fn g(_x: &isize, _y: &isize) -> &isize { //~ ERROR missing lifetime specifier
+ panic!()
+}
+
+struct Foo<'a> {
+ x: &'a isize,
+}
+
+// Lifetime annotation needed because we have two lifetimes: one as a parameter
+// and one on the reference.
+fn h(_x: &Foo) -> &isize { //~ ERROR missing lifetime specifier
+ panic!()
+}
+
+fn i(_x: isize) -> &isize { //~ ERROR missing lifetime specifier
+ panic!()
+}
+
+// Cases which used to work but now don't.
+
+type StaticStr = &'static str; // hides 'static
+trait WithLifetime<'a> {
+ type Output; // can hide 'a
+}
+
+// This worked because the type of the first argument contains
+// 'static, although StaticStr doesn't even have parameters.
+fn j(_x: StaticStr) -> &isize { //~ ERROR missing lifetime specifier
+ panic!()
+}
+
+// This worked because the compiler resolved the argument type
+// to <T as WithLifetime<'a>>::Output which has the hidden 'a.
+fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize {
+//~^ ERROR missing lifetime specifier
+ panic!()
+}
+
+fn l<'a>(_: &'a str, _: &'a str) -> &str { "" }
+//~^ ERROR missing lifetime specifier
+
+// This is ok because both `'a` are for the same parameter.
+fn m<'a>(_: &'a Foo<'a>) -> &str { "" }
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
new file mode 100644
index 000000000..5eee953ef
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr
@@ -0,0 +1,87 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:2:11
+ |
+LL | fn f() -> &isize {
+ | ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn f() -> &'static isize {
+ | +++++++
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:33
+ |
+LL | fn g(_x: &isize, _y: &isize) -> &isize {
+ | ------ ------ ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y`
+help: consider introducing a named lifetime parameter
+ |
+LL | fn g<'a>(_x: &'a isize, _y: &'a isize) -> &'a isize {
+ | ++++ ++ ++ ++
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:19
+ |
+LL | fn h(_x: &Foo) -> &isize {
+ | ---- ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from
+help: consider introducing a named lifetime parameter
+ |
+LL | fn h<'a>(_x: &'a Foo<'a>) -> &'a isize {
+ | ++++ ++ ++++ ++
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:21:20
+ |
+LL | fn i(_x: isize) -> &isize {
+ | ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn i(_x: isize) -> &'static isize {
+ | +++++++
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:34:24
+ |
+LL | fn j(_x: StaticStr) -> &isize {
+ | ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'static` lifetime
+ |
+LL | fn j(_x: StaticStr) -> &'static isize {
+ | +++++++
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:40:49
+ |
+LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &isize {
+ | ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
+help: consider using the `'a` lifetime
+ |
+LL | fn k<'a, T: WithLifetime<'a>>(_x: T::Output) -> &'a isize {
+ | ++
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:45:37
+ |
+LL | fn l<'a>(_: &'a str, _: &'a str) -> &str { "" }
+ | ------- ------- ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments
+help: consider using the `'a` lifetime
+ |
+LL | fn l<'a>(_: &'a str, _: &'a str) -> &'a str { "" }
+ | ++
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-trait.rs b/tests/ui/lifetimes/lifetime-elision-return-type-trait.rs
new file mode 100644
index 000000000..5168cb20d
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-elision-return-type-trait.rs
@@ -0,0 +1,13 @@
+trait Future {
+ type Item;
+ type Error;
+}
+
+use std::error::Error;
+
+fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> {
+ //~^ ERROR not satisfied
+ Ok(())
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr
new file mode 100644
index 000000000..ef1127c59
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-elision-return-type-trait.stderr
@@ -0,0 +1,9 @@
+error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied
+ --> $DIR/lifetime-elision-return-type-trait.rs:8:13
+ |
+LL | fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `Result<(), _>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs b/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs
new file mode 100644
index 000000000..b0c09c751
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.rs
@@ -0,0 +1,14 @@
+struct Foo {
+ field: i32,
+}
+
+fn foo2<'a>(a: &'a Foo, x: &i32) -> &'a i32 {
+ if true {
+ let p: &i32 = &a.field;
+ &*p
+ } else {
+ &*x //~ ERROR explicit lifetime
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.stderr b/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.stderr
new file mode 100644
index 000000000..63d00875d
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/42701_one_named_and_one_anonymous.stderr
@@ -0,0 +1,12 @@
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/42701_one_named_and_one_anonymous.rs:10:9
+ |
+LL | fn foo2<'a>(a: &'a Foo, x: &i32) -> &'a i32 {
+ | ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
+...
+LL | &*x
+ | ^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs
new file mode 100644
index 000000000..35f70dd19
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.rs
@@ -0,0 +1,20 @@
+#[derive(Clone)]
+enum Foo<'a> {
+ Bar(&'a str),
+}
+
+impl<'a> Foo<'a> {
+ fn bar(&self, other: Foo) -> Foo<'a> {
+ match *self {
+ Foo::Bar(s) => {
+ if s == "test" {
+ other //~ ERROR explicit lifetime
+ } else {
+ self.clone()
+ }
+ }
+ }
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr
new file mode 100644
index 000000000..64aa8361c
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.stderr
@@ -0,0 +1,12 @@
+error[E0621]: explicit lifetime required in the type of `other`
+ --> $DIR/ex1-return-one-existing-name-early-bound-in-struct.rs:11:21
+ |
+LL | fn bar(&self, other: Foo) -> Foo<'a> {
+ | --- help: add explicit lifetime `'a` to the type of `other`: `Foo<'a>`
+...
+LL | other
+ | ^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs
new file mode 100644
index 000000000..9b15b378d
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.rs
@@ -0,0 +1,5 @@
+fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+ if x > y { x } else { y } //~ ERROR explicit lifetime
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr
new file mode 100644
index 000000000..b40481ecd
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-2.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/ex1-return-one-existing-name-if-else-2.rs:2:16
+ |
+LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+ | ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
+LL | if x > y { x } else { y }
+ | ^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs
new file mode 100644
index 000000000..6b062125c
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.rs
@@ -0,0 +1,5 @@
+fn foo<'a>((x, y): (&'a i32, &i32)) -> &'a i32 {
+ if x > y { x } else { y } //~ ERROR explicit lifetime
+}
+
+fn main () { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr
new file mode 100644
index 000000000..194fd9589
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-3.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in parameter type
+ --> $DIR/ex1-return-one-existing-name-if-else-3.rs:2:27
+ |
+LL | fn foo<'a>((x, y): (&'a i32, &i32)) -> &'a i32 {
+ | --------------- help: add explicit lifetime `'a` to type: `(&'a i32, &'a i32)`
+LL | if x > y { x } else { y }
+ | ^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs
new file mode 100644
index 000000000..7bc3fa623
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.rs
@@ -0,0 +1,8 @@
+trait Foo {
+
+fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+ if x > y { x } else { y } //~ ERROR explicit lifetime
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr
new file mode 100644
index 000000000..64f4bd0fc
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-2.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/ex1-return-one-existing-name-if-else-using-impl-2.rs:4:15
+ |
+LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+ | ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
+LL | if x > y { x } else { y }
+ | ^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs
new file mode 100644
index 000000000..a1126d6bb
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.rs
@@ -0,0 +1,14 @@
+struct Foo {
+ field: i32
+}
+
+impl Foo {
+ fn foo<'a>(&'a self, x: &i32) -> &i32 {
+
+ if true { &self.field } else { x } //~ ERROR explicit lifetime
+
+ }
+
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
new file mode 100644
index 000000000..961f9de66
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl-3.stderr
@@ -0,0 +1,12 @@
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/ex1-return-one-existing-name-if-else-using-impl-3.rs:8:36
+ |
+LL | fn foo<'a>(&'a self, x: &i32) -> &i32 {
+ | ---- help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
+LL |
+LL | if true { &self.field } else { x }
+ | ^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs
new file mode 100644
index 000000000..f0d73deb3
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.rs
@@ -0,0 +1,18 @@
+trait Foo {
+
+ fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32;
+
+}
+
+impl Foo for () {
+
+ fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+
+ if x > y { x } else { y }
+ //~^ ERROR lifetime may not live long enough
+
+ }
+
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr
new file mode 100644
index 000000000..5bb763813
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else-using-impl.stderr
@@ -0,0 +1,13 @@
+error: lifetime may not live long enough
+ --> $DIR/ex1-return-one-existing-name-if-else-using-impl.rs:11:20
+ |
+LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32 {
+ | -- - let's call the lifetime of this reference `'1`
+ | |
+ | lifetime `'a` defined here
+LL |
+LL | if x > y { x } else { y }
+ | ^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs
new file mode 100644
index 000000000..f72d567bb
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.rs
@@ -0,0 +1,5 @@
+fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {
+ if x > y { x } else { y } //~ ERROR explicit lifetime
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.stderr
new file mode 100644
index 000000000..29a706957
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-if-else.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in the type of `y`
+ --> $DIR/ex1-return-one-existing-name-if-else.rs:2:27
+ |
+LL | fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {
+ | ---- help: add explicit lifetime `'a` to the type of `y`: `&'a i32`
+LL | if x > y { x } else { y }
+ | ^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs
new file mode 100644
index 000000000..49993aca3
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.rs
@@ -0,0 +1,15 @@
+struct Foo {
+ field: i32
+}
+
+impl Foo {
+ fn foo<'a>(&self, x: &'a i32) -> &i32 {
+
+ x
+ //~^ ERROR lifetime may not live long enough
+
+ }
+
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr
new file mode 100644
index 000000000..4bcd7cf95
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr
@@ -0,0 +1,13 @@
+error: lifetime may not live long enough
+ --> $DIR/ex1-return-one-existing-name-return-type-is-anon.rs:8:5
+ |
+LL | fn foo<'a>(&self, x: &'a i32) -> &i32 {
+ | -- - let's call the lifetime of this reference `'1`
+ | |
+ | lifetime `'a` defined here
+LL |
+LL | x
+ | ^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs
new file mode 100644
index 000000000..63d81a57d
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.rs
@@ -0,0 +1,14 @@
+struct Foo {
+ field: i32,
+}
+
+impl Foo {
+ fn foo<'a>(&self, x: &'a Foo) -> &'a Foo {
+
+ if true { x } else { self }
+ //~^ ERROR lifetime may not live long enough
+
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr
new file mode 100644
index 000000000..34a64f8a6
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr
@@ -0,0 +1,13 @@
+error: lifetime may not live long enough
+ --> $DIR/ex1-return-one-existing-name-self-is-anon.rs:8:30
+ |
+LL | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo {
+ | -- - let's call the lifetime of this reference `'1`
+ | |
+ | lifetime `'a` defined here
+LL |
+LL | if true { x } else { self }
+ | ^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs
new file mode 100644
index 000000000..d6c918843
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs
@@ -0,0 +1,5 @@
+fn foo(x: &i32, y: &i32) -> &i32 { //~ ERROR missing lifetime
+ if x > y { x } else { y }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
new file mode 100644
index 000000000..bcc3e9510
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
@@ -0,0 +1,15 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/ex1b-return-no-names-if-else.rs:1:29
+ |
+LL | fn foo(x: &i32, y: &i32) -> &i32 {
+ | ---- ---- ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y`
+help: consider introducing a named lifetime parameter
+ |
+LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
+ | ++++ ++ ++ ++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs
new file mode 100644
index 000000000..998a48ce2
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.rs
@@ -0,0 +1,9 @@
+struct Ref<'a, T: 'a> {
+ data: &'a T
+}
+
+fn foo<'a>(x: Ref<i32>, y: &mut Vec<Ref<'a, i32>>) {
+ y.push(x); //~ ERROR explicit lifetime
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.stderr
new file mode 100644
index 000000000..90d4754eb
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-2.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in the type of `x`
+ --> $DIR/ex2a-push-one-existing-name-2.rs:6:5
+ |
+LL | fn foo<'a>(x: Ref<i32>, y: &mut Vec<Ref<'a, i32>>) {
+ | -------- help: add explicit lifetime `'a` to the type of `x`: `Ref<'a, i32>`
+LL | y.push(x);
+ | ^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs
new file mode 100644
index 000000000..d18b50d0d
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.rs
@@ -0,0 +1,11 @@
+trait Foo<'a> {}
+impl<'a, T> Foo<'a> for T {}
+
+fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &T)
+ where i32: Foo<'a>,
+ u32: Foo<'b>
+{
+ x.push(y); //~ ERROR explicit lifetime required
+}
+fn main() {
+}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr
new file mode 100644
index 000000000..a03e16b3b
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name-early-bound.stderr
@@ -0,0 +1,12 @@
+error[E0621]: explicit lifetime required in the type of `y`
+ --> $DIR/ex2a-push-one-existing-name-early-bound.rs:8:5
+ |
+LL | fn baz<'a, 'b, T>(x: &mut Vec<&'a T>, y: &T)
+ | -- help: add explicit lifetime `'a` to the type of `y`: `&'a T`
+...
+LL | x.push(y);
+ | ^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs
new file mode 100644
index 000000000..5188ea1cc
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.rs
@@ -0,0 +1,9 @@
+struct Ref<'a, T: 'a> {
+ data: &'a T
+}
+
+fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) {
+ x.push(y); //~ ERROR explicit lifetime
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.stderr b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.stderr
new file mode 100644
index 000000000..487b34e3d
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2a-push-one-existing-name.stderr
@@ -0,0 +1,11 @@
+error[E0621]: explicit lifetime required in the type of `y`
+ --> $DIR/ex2a-push-one-existing-name.rs:6:5
+ |
+LL | fn foo<'a>(x: &mut Vec<Ref<'a, i32>>, y: Ref<i32>) {
+ | -------- help: add explicit lifetime `'a` to the type of `y`: `Ref<'a, i32>`
+LL | x.push(y);
+ | ^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0621`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs b/tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs
new file mode 100644
index 000000000..27424d79b
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.rs
@@ -0,0 +1,10 @@
+struct Ref<'a, T: 'a> {
+ data: &'a T
+}
+
+fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
+ x.push(y);
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.stderr b/tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.stderr
new file mode 100644
index 000000000..1622ce422
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2b-push-no-existing-names.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+ --> $DIR/ex2b-push-no-existing-names.rs:6:5
+ |
+LL | fn foo(x: &mut Vec<Ref<i32>>, y: Ref<i32>) {
+ | - - has type `Ref<'1, i32>`
+ | |
+ | has type `&mut Vec<Ref<'2, i32>>`
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs b/tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs
new file mode 100644
index 000000000..2236d78ef
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.rs
@@ -0,0 +1,11 @@
+struct Ref<'a, T: 'a> {
+ data: &'a T
+}
+
+fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+ let z = Ref { data: y.data };
+ x.push(z);
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.stderr b/tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.stderr
new file mode 100644
index 000000000..99fab4631
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2c-push-inference-variable.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+ --> $DIR/ex2c-push-inference-variable.rs:7:5
+ |
+LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+ | -- -- lifetime `'c` defined here
+ | |
+ | lifetime `'b` defined here
+LL | let z = Ref { data: y.data };
+LL | x.push(z);
+ | ^^^^^^^^^ argument requires that `'c` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'c: 'b`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs b/tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs
new file mode 100644
index 000000000..f57323029
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.rs
@@ -0,0 +1,12 @@
+struct Ref<'a, T: 'a> {
+ data: &'a T
+}
+
+fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+ let a: &mut Vec<Ref<i32>> = x;
+ let b = Ref { data: y.data };
+ a.push(b);
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.stderr
new file mode 100644
index 000000000..52c5752f6
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2d-push-inference-variable-2.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+ --> $DIR/ex2d-push-inference-variable-2.rs:8:5
+ |
+LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+ | -- -- lifetime `'c` defined here
+ | |
+ | lifetime `'b` defined here
+...
+LL | a.push(b);
+ | ^^^^^^^^^ argument requires that `'c` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'c: 'b`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs b/tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs
new file mode 100644
index 000000000..4a934bbf0
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.rs
@@ -0,0 +1,12 @@
+struct Ref<'a, T: 'a> {
+ data: &'a T
+}
+
+fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+ let a: &mut Vec<Ref<i32>> = x;
+ let b = Ref { data: y.data };
+ Vec::push(a, b);
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.stderr
new file mode 100644
index 000000000..e90c81ee3
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex2e-push-inference-variable-3.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+ --> $DIR/ex2e-push-inference-variable-3.rs:8:5
+ |
+LL | fn foo<'a, 'b, 'c>(x: &'a mut Vec<Ref<'b, i32>>, y: Ref<'c, i32>) {
+ | -- -- lifetime `'c` defined here
+ | |
+ | lifetime `'b` defined here
+...
+LL | Vec::push(a, b);
+ | ^^^^^^^^^^^^^^^ argument requires that `'c` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'c: 'b`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs
new file mode 100644
index 000000000..09ee9accc
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.rs
@@ -0,0 +1,6 @@
+fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) {
+ *v = x;
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr
new file mode 100644
index 000000000..5a23f1e0e
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-2.rs:2:5
+ |
+LL | fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | *v = x;
+ | ^^^^^^ assignment requires that `'1` must outlive `'2`
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | fn foo<'a>(&mut (ref mut v, w): &mut (&'a u8, &u8), x: &'a u8) {
+ | ++++ ++ ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs
new file mode 100644
index 000000000..b3106db77
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.rs
@@ -0,0 +1,7 @@
+fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
+ z.push((x,y));
+ //~^ ERROR lifetime may not live long enough
+ //~| ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr
new file mode 100644
index 000000000..6ba130308
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.stderr
@@ -0,0 +1,32 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-3.rs:2:5
+ |
+LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | z.push((x,y));
+ | ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | fn foo<'a>(z: &mut Vec<(&'a u8,&u8)>, (x, y): (&'a u8, &u8)) {
+ | ++++ ++ ++
+
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-3.rs:2:5
+ |
+LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) {
+ | - - let's call the lifetime of this reference `'3`
+ | |
+ | let's call the lifetime of this reference `'4`
+LL | z.push((x,y));
+ | ^^^^^^^^^^^^^ argument requires that `'3` must outlive `'4`
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | fn foo<'a>(z: &mut Vec<(&u8,&'a u8)>, (x, y): (&u8, &'a u8)) {
+ | ++++ ++ ++
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs
new file mode 100644
index 000000000..5d0367783
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.rs
@@ -0,0 +1,11 @@
+struct Ref<'a, 'b> {
+ a: &'a u32,
+ b: &'b u32,
+}
+
+fn foo(mut x: Ref, y: Ref) {
+ x.b = y.b;
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr
new file mode 100644
index 000000000..4c0ffe5c0
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-2.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-both-are-structs-2.rs:7:5
+ |
+LL | fn foo(mut x: Ref, y: Ref) {
+ | ----- - has type `Ref<'_, '1>`
+ | |
+ | has type `Ref<'_, '2>`
+LL | x.b = y.b;
+ | ^^^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs
new file mode 100644
index 000000000..4a479f19c
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.rs
@@ -0,0 +1,11 @@
+struct Ref<'a, 'b> {
+ a: &'a u32,
+ b: &'b u32,
+}
+
+fn foo(mut x: Ref) {
+ x.a = x.b;
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr
new file mode 100644
index 000000000..97c665347
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-3.stderr
@@ -0,0 +1,13 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-both-are-structs-3.rs:7:5
+ |
+LL | fn foo(mut x: Ref) {
+ | -----
+ | |
+ | has type `Ref<'_, '1>`
+ | has type `Ref<'2, '_>`
+LL | x.a = x.b;
+ | ^^^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs
new file mode 100644
index 000000000..9b8cfe670
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs
@@ -0,0 +1,13 @@
+struct Ref<'a> {
+ x: &'a u32,
+}
+
+fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>)
+ where &'a (): Sized,
+ &'b u32: Sized
+{
+ x.push(y);
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr
new file mode 100644
index 000000000..b3d0bc2b8
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-earlybound-regions.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-both-are-structs-earlybound-regions.rs:9:5
+ |
+LL | fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>)
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+...
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs
new file mode 100644
index 000000000..db934a0be
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.rs
@@ -0,0 +1,10 @@
+struct Ref<'a> {
+ x: &'a u32,
+}
+
+fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>) {
+ x.push(y);
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr
new file mode 100644
index 000000000..fbe98a426
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs-latebound-regions.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-both-are-structs-latebound-regions.rs:6:5
+ |
+LL | fn foo<'a, 'b>(mut x: Vec<Ref<'a>>, y: Ref<'b>) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs
new file mode 100644
index 000000000..4bf5db41f
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.rs
@@ -0,0 +1,10 @@
+struct Ref<'a> {
+ x: &'a u32,
+}
+
+fn foo(mut x: Vec<Ref>, y: Ref) {
+ x.push(y);
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr
new file mode 100644
index 000000000..9630729d0
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-both-are-structs.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-both-are-structs.rs:6:5
+ |
+LL | fn foo(mut x: Vec<Ref>, y: Ref) {
+ | ----- - has type `Ref<'1>`
+ | |
+ | has type `Vec<Ref<'2>>`
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs
new file mode 100644
index 000000000..8dcb814b2
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.rs
@@ -0,0 +1,6 @@
+fn foo<'a,'b>(x: &mut Vec<&'a u8>, y: &'b u8) {
+ x.push(y);
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr
new file mode 100644
index 000000000..1e24032fc
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-latebound-regions.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-latebound-regions.rs:2:5
+ |
+LL | fn foo<'a,'b>(x: &mut Vec<&'a u8>, y: &'b u8) {
+ | -- -- lifetime `'b` defined here
+ | |
+ | lifetime `'a` defined here
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs
new file mode 100644
index 000000000..e4df870bc
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.rs
@@ -0,0 +1,9 @@
+struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 }
+
+fn foo(mut x: Ref, y: &u32) {
+ y = x.b;
+ //~^ ERROR lifetime may not live long enough
+ //~| ERROR cannot assign to immutable argument
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr
new file mode 100644
index 000000000..bbd62902d
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-2.stderr
@@ -0,0 +1,21 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:4:5
+ |
+LL | fn foo(mut x: Ref, y: &u32) {
+ | ----- - let's call the lifetime of this reference `'2`
+ | |
+ | has type `Ref<'_, '1>`
+LL | y = x.b;
+ | ^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error[E0384]: cannot assign to immutable argument `y`
+ --> $DIR/ex3-both-anon-regions-one-is-struct-2.rs:4:5
+ |
+LL | fn foo(mut x: Ref, y: &u32) {
+ | - help: consider making this binding mutable: `mut y`
+LL | y = x.b;
+ | ^^^^^^^ cannot assign to immutable argument
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0384`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs
new file mode 100644
index 000000000..00de48278
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.rs
@@ -0,0 +1,8 @@
+struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 }
+
+fn foo(mut y: Ref, x: &u32) {
+ y.b = x;
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr
new file mode 100644
index 000000000..79e7e8e15
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-3.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-one-is-struct-3.rs:4:5
+ |
+LL | fn foo(mut y: Ref, x: &u32) {
+ | ----- - let's call the lifetime of this reference `'1`
+ | |
+ | has type `Ref<'_, '2>`
+LL | y.b = x;
+ | ^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs
new file mode 100644
index 000000000..00de48278
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.rs
@@ -0,0 +1,8 @@
+struct Ref<'a, 'b> { a: &'a u32, b: &'b u32 }
+
+fn foo(mut y: Ref, x: &u32) {
+ y.b = x;
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr
new file mode 100644
index 000000000..53615fd1a
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct-4.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-one-is-struct-4.rs:4:5
+ |
+LL | fn foo(mut y: Ref, x: &u32) {
+ | ----- - let's call the lifetime of this reference `'1`
+ | |
+ | has type `Ref<'_, '2>`
+LL | y.b = x;
+ | ^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs
new file mode 100644
index 000000000..5bb0e28d4
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.rs
@@ -0,0 +1,11 @@
+struct Ref<'a, 'b> {
+ a: &'a u32,
+ b: &'b u32,
+}
+
+fn foo(mut x: Ref, y: &u32) {
+ x.b = y;
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr
new file mode 100644
index 000000000..6ff441167
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-one-is-struct.stderr
@@ -0,0 +1,12 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-one-is-struct.rs:7:5
+ |
+LL | fn foo(mut x: Ref, y: &u32) {
+ | ----- - let's call the lifetime of this reference `'1`
+ | |
+ | has type `Ref<'_, '2>`
+LL | x.b = y;
+ | ^^^^^^^ assignment requires that `'1` must outlive `'2`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs
new file mode 100644
index 000000000..3ffd7be4e
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.rs
@@ -0,0 +1,12 @@
+struct Foo {
+ field: i32
+}
+
+impl Foo {
+ fn foo<'a>(&self, x: &i32) -> &i32 {
+ x
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr
new file mode 100644
index 000000000..5601335d2
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-return-type-is-anon.rs:7:5
+ |
+LL | fn foo<'a>(&self, x: &i32) -> &i32 {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | x
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn foo<'a>(&'a self, x: &'a i32) -> &i32 {
+ | ++ ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs
new file mode 100644
index 000000000..9b67a7742
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.rs
@@ -0,0 +1,12 @@
+struct Foo {
+ field: i32,
+}
+
+impl Foo {
+ fn foo<'a>(&self, x: &Foo) -> &Foo {
+ if true { x } else { self }
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr
new file mode 100644
index 000000000..e221902c4
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-self-is-anon.rs:7:19
+ |
+LL | fn foo<'a>(&self, x: &Foo) -> &Foo {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | if true { x } else { self }
+ | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn foo<'a>(&'a self, x: &'a Foo) -> &Foo {
+ | ++ ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs
new file mode 100644
index 000000000..2f67750d8
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.rs
@@ -0,0 +1,7 @@
+fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
+ y.push(z);
+ //~^ ERROR lifetime may not live long enough
+ //~| ERROR cannot borrow
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr
new file mode 100644
index 000000000..cc2447b18
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.stderr
@@ -0,0 +1,29 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-using-fn-items.rs:2:3
+ |
+LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | y.push(z);
+ | ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | fn foo<'a>(x:fn(&u8, &u8), y: Vec<&'a u8>, z: &'a u8) {
+ | ++++ ++ ++
+
+error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
+ --> $DIR/ex3-both-anon-regions-using-fn-items.rs:2:3
+ |
+LL | y.push(z);
+ | ^^^^^^^^^ cannot borrow as mutable
+ |
+help: consider changing this to be mutable
+ |
+LL | fn foo(x:fn(&u8, &u8), mut y: Vec<&u8>, z: &u8) {
+ | +++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs
new file mode 100644
index 000000000..73e1789f2
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.rs
@@ -0,0 +1,10 @@
+trait Foo {
+ fn foo<'a>(x: &mut Vec<&u8>, y: &u8);
+}
+impl Foo for () {
+ fn foo(x: &mut Vec<&u8>, y: &u8) {
+ x.push(y);
+ //~^ ERROR lifetime may not live long enough
+ }
+}
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr
new file mode 100644
index 000000000..9661f1e51
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-using-impl-items.rs:6:9
+ |
+LL | fn foo(x: &mut Vec<&u8>, y: &u8) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+ |
+help: consider introducing a named lifetime parameter and update trait if needed
+ |
+LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
+ | ++++ ++ ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs
new file mode 100644
index 000000000..97fa9ef91
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.rs
@@ -0,0 +1,7 @@
+fn foo(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
+ y.push(z);
+ //~^ ERROR lifetime may not live long enough
+ //~| ERROR cannot borrow
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr
new file mode 100644
index 000000000..2ba5afa80
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.stderr
@@ -0,0 +1,29 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:2:3
+ |
+LL | fn foo(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | y.push(z);
+ | ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | fn foo<'a>(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&'a u8>, z: &'a u8) {
+ | ++++ ++ ++
+
+error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
+ --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:2:3
+ |
+LL | y.push(z);
+ | ^^^^^^^^^ cannot borrow as mutable
+ |
+help: consider changing this to be mutable
+ |
+LL | fn foo(x:Box<dyn Fn(&u8, &u8)> , mut y: Vec<&u8>, z: &u8) {
+ | +++
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs
new file mode 100644
index 000000000..ca0feaba8
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.rs
@@ -0,0 +1,6 @@
+fn foo(x: &mut Vec<&u8>, y: &u8) {
+ x.push(y);
+ //~^ ERROR lifetime may not live long enough
+}
+
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr
new file mode 100644
index 000000000..ec9fac0c2
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.stderr
@@ -0,0 +1,17 @@
+error: lifetime may not live long enough
+ --> $DIR/ex3-both-anon-regions.rs:2:5
+ |
+LL | fn foo(x: &mut Vec<&u8>, y: &u8) {
+ | - - let's call the lifetime of this reference `'1`
+ | |
+ | let's call the lifetime of this reference `'2`
+LL | x.push(y);
+ | ^^^^^^^^^ argument requires that `'1` must outlive `'2`
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
+ | ++++ ++ ++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-errors/issue_74400.rs b/tests/ui/lifetimes/lifetime-errors/issue_74400.rs
new file mode 100644
index 000000000..ddb8bacce
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/issue_74400.rs
@@ -0,0 +1,16 @@
+//! Regression test for #74400: Type mismatch in function arguments E0631, E0271 are falsely
+//! recognized as E0308 mismatched types.
+
+use std::convert::identity;
+
+fn main() {}
+
+fn f<T, S>(data: &[T], key: impl Fn(&T) -> S) {
+}
+
+fn g<T>(data: &[T]) {
+ f(data, identity)
+ //~^ ERROR the parameter type
+ //~| ERROR mismatched types
+ //~| ERROR implementation of `FnOnce` is not general
+}
diff --git a/tests/ui/lifetimes/lifetime-errors/issue_74400.stderr b/tests/ui/lifetimes/lifetime-errors/issue_74400.stderr
new file mode 100644
index 000000000..7049f28e2
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/issue_74400.stderr
@@ -0,0 +1,38 @@
+error[E0310]: the parameter type `T` may not live long enough
+ --> $DIR/issue_74400.rs:12:5
+ |
+LL | f(data, identity)
+ | ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn g<T: 'static>(data: &[T]) {
+ | +++++++++
+
+error[E0308]: mismatched types
+ --> $DIR/issue_74400.rs:12:5
+ |
+LL | f(data, identity)
+ | ^^^^^^^^^^^^^^^^^ one type is more general than the other
+ |
+ = note: expected trait `for<'a> Fn<(&'a T,)>`
+ found trait `Fn<(&T,)>`
+note: the lifetime requirement is introduced here
+ --> $DIR/issue_74400.rs:8:34
+ |
+LL | fn f<T, S>(data: &[T], key: impl Fn(&T) -> S) {
+ | ^^^^^^^^^^^
+
+error: implementation of `FnOnce` is not general enough
+ --> $DIR/issue_74400.rs:12:5
+ |
+LL | f(data, identity)
+ | ^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
+ |
+ = note: `fn(&'2 T) -> &'2 T {identity::<&'2 T>}` must implement `FnOnce<(&'1 T,)>`, for any lifetime `'1`...
+ = note: ...but it actually implements `FnOnce<(&'2 T,)>`, for some specific lifetime `'2`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0308, E0310.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs b/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs
new file mode 100644
index 000000000..81a20c587
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.rs
@@ -0,0 +1,37 @@
+// Check notes are placed on an assignment that can actually precede the current assignment
+// Don't emit a first assignment for assignment in a loop.
+
+fn test() {
+ let x;
+ if true {
+ x = 1;
+ } else {
+ x = 2;
+ x = 3; //~ ERROR [E0384]
+ }
+}
+
+fn test_in_loop() {
+ loop {
+ let x;
+ if true {
+ x = 1;
+ } else {
+ x = 2;
+ x = 3; //~ ERROR [E0384]
+ }
+ }
+}
+
+fn test_using_loop() {
+ let x;
+ loop {
+ if true {
+ x = 1; //~ ERROR [E0384]
+ } else {
+ x = 2; //~ ERROR [E0384]
+ }
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr b/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr
new file mode 100644
index 000000000..b47a47d63
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr
@@ -0,0 +1,46 @@
+error[E0384]: cannot assign twice to immutable variable `x`
+ --> $DIR/liveness-assign-imm-local-notes.rs:10:9
+ |
+LL | let x;
+ | - help: consider making this binding mutable: `mut x`
+...
+LL | x = 2;
+ | ----- first assignment to `x`
+LL | x = 3;
+ | ^^^^^ cannot assign twice to immutable variable
+
+error[E0384]: cannot assign twice to immutable variable `x`
+ --> $DIR/liveness-assign-imm-local-notes.rs:21:13
+ |
+LL | let x;
+ | - help: consider making this binding mutable: `mut x`
+...
+LL | x = 2;
+ | ----- first assignment to `x`
+LL | x = 3;
+ | ^^^^^ cannot assign twice to immutable variable
+
+error[E0384]: cannot assign twice to immutable variable `x`
+ --> $DIR/liveness-assign-imm-local-notes.rs:30:13
+ |
+LL | let x;
+ | - help: consider making this binding mutable: `mut x`
+...
+LL | x = 1;
+ | ^^^^^ cannot assign twice to immutable variable
+
+error[E0384]: cannot assign twice to immutable variable `x`
+ --> $DIR/liveness-assign-imm-local-notes.rs:32:13
+ |
+LL | let x;
+ | - help: consider making this binding mutable: `mut x`
+...
+LL | x = 1;
+ | ----- first assignment to `x`
+LL | } else {
+LL | x = 2;
+ | ^^^^^ cannot assign twice to immutable variable
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0384`.
diff --git a/tests/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs b/tests/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs
new file mode 100644
index 000000000..2ce1a0f45
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.rs
@@ -0,0 +1,12 @@
+trait Foo {
+ fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32;
+}
+
+impl Foo for () {
+ fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
+ //~^ ERROR `impl` item signature doesn't match `trait` item signature
+ if x > y { x } else { y }
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr b/tests/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr
new file mode 100644
index 000000000..9c61d5a0c
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-mismatch-between-trait-and-impl.stderr
@@ -0,0 +1,16 @@
+error: `impl` item signature doesn't match `trait` item signature
+ --> $DIR/lifetime-mismatch-between-trait-and-impl.rs:6:5
+ |
+LL | fn foo<'a>(x: &i32, y: &'a i32) -> &'a i32;
+ | ------------------------------------------- expected `fn(&'1 i32, &'a i32) -> &'a i32`
+...
+LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ found `fn(&'1 i32, &'1 i32) -> &'1 i32`
+ |
+ = note: expected signature `fn(&'1 i32, &'a i32) -> &'a i32`
+ found signature `fn(&'1 i32, &'1 i32) -> &'1 i32`
+ = help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
+ = help: verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/lifetime-no-keyword.rs b/tests/ui/lifetimes/lifetime-no-keyword.rs
new file mode 100644
index 000000000..f466f44f5
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-no-keyword.rs
@@ -0,0 +1,7 @@
+fn foo<'a>(a: &'a isize) { }
+fn bar(a: &'static isize) { }
+fn baz<'let>(a: &'let isize) { } //~ ERROR lifetimes cannot use keyword names
+//~^ ERROR lifetimes cannot use keyword names
+fn zab<'self>(a: &'self isize) { } //~ ERROR lifetimes cannot use keyword names
+//~^ ERROR lifetimes cannot use keyword names
+fn main() { }
diff --git a/tests/ui/lifetimes/lifetime-no-keyword.stderr b/tests/ui/lifetimes/lifetime-no-keyword.stderr
new file mode 100644
index 000000000..ba8ceb80f
--- /dev/null
+++ b/tests/ui/lifetimes/lifetime-no-keyword.stderr
@@ -0,0 +1,26 @@
+error: lifetimes cannot use keyword names
+ --> $DIR/lifetime-no-keyword.rs:3:8
+ |
+LL | fn baz<'let>(a: &'let isize) { }
+ | ^^^^
+
+error: lifetimes cannot use keyword names
+ --> $DIR/lifetime-no-keyword.rs:3:18
+ |
+LL | fn baz<'let>(a: &'let isize) { }
+ | ^^^^
+
+error: lifetimes cannot use keyword names
+ --> $DIR/lifetime-no-keyword.rs:5:8
+ |
+LL | fn zab<'self>(a: &'self isize) { }
+ | ^^^^^
+
+error: lifetimes cannot use keyword names
+ --> $DIR/lifetime-no-keyword.rs:5:19
+ |
+LL | fn zab<'self>(a: &'self isize) { }
+ | ^^^^^
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lifetimes/missing-lifetime-in-alias.rs b/tests/ui/lifetimes/missing-lifetime-in-alias.rs
new file mode 100644
index 000000000..51c564c01
--- /dev/null
+++ b/tests/ui/lifetimes/missing-lifetime-in-alias.rs
@@ -0,0 +1,31 @@
+trait Trait<'a> {
+ type Foo;
+
+ type Bar<'b>
+ //~^ NOTE associated type defined here, with 1 lifetime parameter
+ //~| NOTE
+ where
+ Self: 'b;
+}
+
+struct Impl<'a>(&'a ());
+
+impl<'a> Trait<'a> for Impl<'a> {
+ type Foo = &'a ();
+ type Bar<'b> = &'b ();
+}
+
+type A<'a> = Impl<'a>;
+
+type B<'a> = <A<'a> as Trait>::Foo;
+//~^ ERROR missing lifetime specifier
+//~| NOTE expected named lifetime parameter
+
+type C<'a, 'b> = <A<'a> as Trait>::Bar;
+//~^ ERROR missing lifetime specifier
+//~| ERROR missing generics for associated type
+//~| NOTE expected named lifetime parameter
+//~| NOTE these named lifetimes are available to use
+//~| NOTE expected 1 lifetime argument
+
+fn main() {}
diff --git a/tests/ui/lifetimes/missing-lifetime-in-alias.stderr b/tests/ui/lifetimes/missing-lifetime-in-alias.stderr
new file mode 100644
index 000000000..20159e144
--- /dev/null
+++ b/tests/ui/lifetimes/missing-lifetime-in-alias.stderr
@@ -0,0 +1,47 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/missing-lifetime-in-alias.rs:20:24
+ |
+LL | type B<'a> = <A<'a> as Trait>::Foo;
+ | ^^^^^ expected named lifetime parameter
+ |
+help: consider using the `'a` lifetime
+ |
+LL | type B<'a> = <A<'a> as Trait<'a>>::Foo;
+ | ++++
+
+error[E0106]: missing lifetime specifier
+ --> $DIR/missing-lifetime-in-alias.rs:24:28
+ |
+LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
+ | ^^^^^ expected named lifetime parameter
+ |
+note: these named lifetimes are available to use
+ --> $DIR/missing-lifetime-in-alias.rs:24:8
+ |
+LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
+ | ^^ ^^
+help: consider using one of the available lifetimes here
+ |
+LL | type C<'a, 'b> = <A<'a> as Trait<'lifetime>>::Bar;
+ | +++++++++++
+
+error[E0107]: missing generics for associated type `Trait::Bar`
+ --> $DIR/missing-lifetime-in-alias.rs:24:36
+ |
+LL | type C<'a, 'b> = <A<'a> as Trait>::Bar;
+ | ^^^ expected 1 lifetime argument
+ |
+note: associated type defined here, with 1 lifetime parameter: `'b`
+ --> $DIR/missing-lifetime-in-alias.rs:4:10
+ |
+LL | type Bar<'b>
+ | ^^^ --
+help: add missing lifetime argument
+ |
+LL | type C<'a, 'b> = <A<'a> as Trait>::Bar<'a>;
+ | ++++
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0106, E0107.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/lifetimes/nested-binder-print.rs b/tests/ui/lifetimes/nested-binder-print.rs
new file mode 100644
index 000000000..f97f349fd
--- /dev/null
+++ b/tests/ui/lifetimes/nested-binder-print.rs
@@ -0,0 +1,10 @@
+struct TwoLt<'a, 'b>(&'a (), &'b ());
+type Foo<'a> = fn(TwoLt<'_, 'a>);
+
+fn foo() {
+ let y: for<'a> fn(Foo<'a>);
+ let x: u32 = y;
+ //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/nested-binder-print.stderr b/tests/ui/lifetimes/nested-binder-print.stderr
new file mode 100644
index 000000000..32dd89693
--- /dev/null
+++ b/tests/ui/lifetimes/nested-binder-print.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+ --> $DIR/nested-binder-print.rs:6:18
+ |
+LL | let x: u32 = y;
+ | --- ^ expected `u32`, found fn pointer
+ | |
+ | expected due to this
+ |
+ = note: expected type `u32`
+ found fn pointer `for<'a> fn(for<'b> fn(TwoLt<'b, 'a>))`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/lifetimes/nested.rs b/tests/ui/lifetimes/nested.rs
new file mode 100644
index 000000000..f3f1f2016
--- /dev/null
+++ b/tests/ui/lifetimes/nested.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+fn method<'a>(_i: &'a i32) {
+ fn inner<'a>(_j: &'a f32) {}
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/re-empty-in-error.rs b/tests/ui/lifetimes/re-empty-in-error.rs
new file mode 100644
index 000000000..554028a96
--- /dev/null
+++ b/tests/ui/lifetimes/re-empty-in-error.rs
@@ -0,0 +1,10 @@
+// We didn't have a single test mentioning
+// `ReEmpty` and this test changes that.
+fn foo<'a>(_a: &'a u32) where for<'b> &'b (): 'a {
+}
+
+fn main() {
+ foo(&10);
+ //~^ ERROR higher-ranked lifetime error
+ //~| NOTE could not prove
+}
diff --git a/tests/ui/lifetimes/re-empty-in-error.stderr b/tests/ui/lifetimes/re-empty-in-error.stderr
new file mode 100644
index 000000000..c35d8ecec
--- /dev/null
+++ b/tests/ui/lifetimes/re-empty-in-error.stderr
@@ -0,0 +1,10 @@
+error: higher-ranked lifetime error
+ --> $DIR/re-empty-in-error.rs:7:5
+ |
+LL | foo(&10);
+ | ^^^^^^^^
+ |
+ = note: could not prove `for<'b> &'b (): 'a`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/lifetimes/shadow.rs b/tests/ui/lifetimes/shadow.rs
new file mode 100644
index 000000000..e2124887e
--- /dev/null
+++ b/tests/ui/lifetimes/shadow.rs
@@ -0,0 +1,8 @@
+struct Foo<T>(T);
+
+impl<'s> Foo<&'s u8> {
+ fn bar<'s>(&self, x: &'s u8) {} //~ ERROR shadows a lifetime name
+ fn baz(x: for<'s> fn(&'s u32)) {} //~ ERROR shadows a lifetime name
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/shadow.stderr b/tests/ui/lifetimes/shadow.stderr
new file mode 100644
index 000000000..b834e90d8
--- /dev/null
+++ b/tests/ui/lifetimes/shadow.stderr
@@ -0,0 +1,20 @@
+error[E0496]: lifetime name `'s` shadows a lifetime name that is already in scope
+ --> $DIR/shadow.rs:4:12
+ |
+LL | impl<'s> Foo<&'s u8> {
+ | -- first declared here
+LL | fn bar<'s>(&self, x: &'s u8) {}
+ | ^^ lifetime `'s` already in scope
+
+error[E0496]: lifetime name `'s` shadows a lifetime name that is already in scope
+ --> $DIR/shadow.rs:5:19
+ |
+LL | impl<'s> Foo<&'s u8> {
+ | -- first declared here
+LL | fn bar<'s>(&self, x: &'s u8) {}
+LL | fn baz(x: for<'s> fn(&'s u32)) {}
+ | ^^ lifetime `'s` already in scope
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0496`.
diff --git a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed
new file mode 100644
index 000000000..f977f0bd3
--- /dev/null
+++ b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed
@@ -0,0 +1,13 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
+ with_restriction::<T>(x) //~ ERROR the parameter type `T` may not live long enough
+}
+
+fn with_restriction<'b, T: 'b>(x: &'b ()) -> &'b () {
+ x
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs
new file mode 100644
index 000000000..d6ce112ec
--- /dev/null
+++ b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.rs
@@ -0,0 +1,13 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+fn no_restriction<T>(x: &()) -> &() {
+ with_restriction::<T>(x) //~ ERROR the parameter type `T` may not live long enough
+}
+
+fn with_restriction<'b, T: 'b>(x: &'b ()) -> &'b () {
+ x
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
new file mode 100644
index 000000000..2d58d3a02
--- /dev/null
+++ b/tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.stderr
@@ -0,0 +1,24 @@
+error[E0311]: the parameter type `T` may not live long enough
+ --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:6:5
+ |
+LL | with_restriction::<T>(x)
+ | ^^^^^^^^^^^^^^^^^^^^^
+ |
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
+ --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:5:25
+ |
+LL | fn no_restriction<T>(x: &()) -> &() {
+ | ^^^
+note: ...so that the type `T` will meet its required lifetime bounds
+ --> $DIR/suggest-introducing-and-adding-missing-lifetime.rs:6:5
+ |
+LL | with_restriction::<T>(x)
+ | ^^^^^^^^^^^^^^^^^^^^^
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
+ | +++ ++++ ++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0311`.
diff --git a/tests/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.rs b/tests/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.rs
new file mode 100644
index 000000000..cc29f9de7
--- /dev/null
+++ b/tests/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.rs
@@ -0,0 +1,16 @@
+#[derive(Eq, PartialEq)]
+struct Test {
+ a: &'b str,
+ //~^ ERROR use of undeclared lifetime name `'b`
+ //~| ERROR use of undeclared lifetime name `'b`
+}
+
+trait T {
+ fn foo(&'static self) {}
+}
+
+impl T for Test {
+ fn foo(&'b self) {} //~ ERROR use of undeclared lifetime name `'b`
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.stderr b/tests/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.stderr
new file mode 100644
index 000000000..0d6ade415
--- /dev/null
+++ b/tests/ui/lifetimes/undeclared-lifetime-used-in-debug-macro-issue-70152.stderr
@@ -0,0 +1,36 @@
+error[E0261]: use of undeclared lifetime name `'b`
+ --> $DIR/undeclared-lifetime-used-in-debug-macro-issue-70152.rs:3:9
+ |
+LL | struct Test {
+ | - help: consider introducing lifetime `'b` here: `<'b>`
+LL | a: &'b str,
+ | ^^ undeclared lifetime
+
+error[E0261]: use of undeclared lifetime name `'b`
+ --> $DIR/undeclared-lifetime-used-in-debug-macro-issue-70152.rs:3:9
+ |
+LL | #[derive(Eq, PartialEq)]
+ | -- lifetime `'b` is missing in item created through this procedural macro
+LL | struct Test {
+ | - help: consider introducing lifetime `'b` here: `<'b>`
+LL | a: &'b str,
+ | ^^ undeclared lifetime
+
+error[E0261]: use of undeclared lifetime name `'b`
+ --> $DIR/undeclared-lifetime-used-in-debug-macro-issue-70152.rs:13:13
+ |
+LL | fn foo(&'b self) {}
+ | ^^ undeclared lifetime
+ |
+help: consider introducing lifetime `'b` here
+ |
+LL | fn foo<'b>(&'b self) {}
+ | ++++
+help: consider introducing lifetime `'b` here
+ |
+LL | impl<'b> T for Test {
+ | ++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs b/tests/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs
new file mode 100644
index 000000000..8deb36551
--- /dev/null
+++ b/tests/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs
@@ -0,0 +1,3 @@
+fn main() {
+ [0].iter().flat_map(|a| [0].iter().map(|_| &a)); //~ ERROR closure may outlive
+}
diff --git a/tests/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr b/tests/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr
new file mode 100644
index 000000000..439904509
--- /dev/null
+++ b/tests/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr
@@ -0,0 +1,21 @@
+error[E0373]: closure may outlive the current function, but it borrows `a`, which is owned by the current function
+ --> $DIR/unnamed-closure-doesnt-life-long-enough-issue-67634.rs:2:44
+ |
+LL | [0].iter().flat_map(|a| [0].iter().map(|_| &a));
+ | ^^^ - `a` is borrowed here
+ | |
+ | may outlive borrowed value `a`
+ |
+note: closure is returned here
+ --> $DIR/unnamed-closure-doesnt-life-long-enough-issue-67634.rs:2:29
+ |
+LL | [0].iter().flat_map(|a| [0].iter().map(|_| &a));
+ | ^^^^^^^^^^^^^^^^^^^^^^
+help: to force the closure to take ownership of `a` (and any other referenced variables), use the `move` keyword
+ |
+LL | [0].iter().flat_map(|a| [0].iter().map(move |_| &a));
+ | ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0373`.
diff --git a/tests/ui/lifetimes/unusual-rib-combinations.rs b/tests/ui/lifetimes/unusual-rib-combinations.rs
new file mode 100644
index 000000000..b4c86aab8
--- /dev/null
+++ b/tests/ui/lifetimes/unusual-rib-combinations.rs
@@ -0,0 +1,28 @@
+#![feature(inline_const)]
+
+struct S<'a>(&'a u8);
+fn foo() {}
+
+// Paren generic args in AnonConst
+fn a() -> [u8; foo::()] {
+//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
+//~| ERROR mismatched types
+ panic!()
+}
+
+// Paren generic args in ConstGeneric
+fn b<const C: u8()>() {}
+//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
+
+// Paren generic args in AnonymousReportError
+fn c<T = u8()>() {}
+//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
+//~| ERROR defaults for type parameters are only allowed in
+//~| WARN this was previously accepted
+
+// Elided lifetime in path in ConstGeneric
+fn d<const C: S>() {}
+//~^ ERROR missing lifetime specifier
+//~| ERROR `S<'static>` is forbidden as the type of a const generic parameter
+
+fn main() {}
diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr
new file mode 100644
index 000000000..6d7b42506
--- /dev/null
+++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr
@@ -0,0 +1,61 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/unusual-rib-combinations.rs:24:15
+ |
+LL | fn d<const C: S>() {}
+ | ^ expected named lifetime parameter
+ |
+help: consider introducing a named lifetime parameter
+ |
+LL | fn d<'a, const C: S<'a>>() {}
+ | +++ ++++
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+ --> $DIR/unusual-rib-combinations.rs:7:16
+ |
+LL | fn a() -> [u8; foo::()] {
+ | ^^^^^^^ only `Fn` traits may use parentheses
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+ --> $DIR/unusual-rib-combinations.rs:14:15
+ |
+LL | fn b<const C: u8()>() {}
+ | ^^^^ only `Fn` traits may use parentheses
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+ --> $DIR/unusual-rib-combinations.rs:18:10
+ |
+LL | fn c<T = u8()>() {}
+ | ^^^^ only `Fn` traits may use parentheses
+
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+ --> $DIR/unusual-rib-combinations.rs:18:6
+ |
+LL | fn c<T = u8()>() {}
+ | ^^^^^^^^
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
+ = note: `#[deny(invalid_type_param_default)]` on by default
+
+error[E0308]: mismatched types
+ --> $DIR/unusual-rib-combinations.rs:7:16
+ |
+LL | fn a() -> [u8; foo::()] {
+ | ^^^^^^^ expected `usize`, found fn item
+ |
+ = note: expected type `usize`
+ found fn item `fn() {foo}`
+
+error: `S<'static>` is forbidden as the type of a const generic parameter
+ --> $DIR/unusual-rib-combinations.rs:24:15
+ |
+LL | fn d<const C: S>() {}
+ | ^
+ |
+ = note: the only supported types are integers, `bool` and `char`
+ = help: more complex types are supported with `#![feature(adt_const_params)]`
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0106, E0214, E0308.
+For more information about an error, try `rustc --explain E0106`.