diff options
Diffstat (limited to 'tests/ui/lifetimes')
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`. |