summaryrefslogtreecommitdiffstats
path: root/tests/ui/impl-trait/in-trait
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/impl-trait/in-trait')
-rw-r--r--tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs13
-rw-r--r--tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs3
-rw-r--r--tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs3
-rw-r--r--tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr18
-rw-r--r--tests/ui/impl-trait/in-trait/deep-match-works.rs7
-rw-r--r--tests/ui/impl-trait/in-trait/foreign.rs14
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102140.stderr6
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102571.rs8
-rw-r--r--tests/ui/impl-trait/in-trait/issue-102571.stderr2
-rw-r--r--tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs19
-rw-r--r--tests/ui/impl-trait/in-trait/nested-rpitit.rs10
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety-sized.rs23
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.rs3
-rw-r--r--tests/ui/impl-trait/in-trait/object-safety.stderr17
-rw-r--r--tests/ui/impl-trait/in-trait/refine.rs48
-rw-r--r--tests/ui/impl-trait/in-trait/refine.stderr67
-rw-r--r--tests/ui/impl-trait/in-trait/reveal.rs5
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs26
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr16
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs23
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr16
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs3
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr14
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.rs46
-rw-r--r--tests/ui/impl-trait/in-trait/signature-mismatch.stderr61
-rw-r--r--tests/ui/impl-trait/in-trait/specialization-substs-remap.rs5
-rw-r--r--tests/ui/impl-trait/in-trait/success.rs9
-rw-r--r--tests/ui/impl-trait/in-trait/variance.rs20
-rw-r--r--tests/ui/impl-trait/in-trait/variance.stderr26
29 files changed, 428 insertions, 103 deletions
diff --git a/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs b/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs
new file mode 100644
index 000000000..e62662f2f
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs
@@ -0,0 +1,13 @@
+// compile-flags: --crate-type=lib
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![deny(refining_impl_trait)]
+
+pub trait Tr<T> {
+ fn foo() -> impl for<'a> Tr<&'a Self>;
+}
+
+impl<T> Tr<T> for () {
+ fn foo() -> impl for<'a> Tr<&'a Self> {}
+}
diff --git a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
index cfc2193f6..6e9940211 100644
--- a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
+++ b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs
@@ -1,4 +1,4 @@
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
use std::ops::Deref;
@@ -8,6 +8,7 @@ pub trait Foo {
pub struct Foreign;
impl Foo for Foreign {
+ #[expect(refining_impl_trait)]
fn bar(self) -> &'static () {
&()
}
diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs
index ff7ad4bf3..fbbbb8585 100644
--- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs
+++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.rs
@@ -2,7 +2,7 @@
#![feature(return_position_impl_trait_in_trait)]
-trait Iterable {
+pub trait Iterable {
type Item<'a>
where
Self: 'a;
@@ -17,6 +17,7 @@ impl<'a, I: 'a + Iterable> Iterable for &'a I {
//~^ ERROR impl has stricter requirements than trait
fn iter(&self) -> impl 'a + Iterator<Item = I::Item<'a>> {
+ //~^ WARN impl trait in impl method signature does not match trait method signature
(*self).iter()
}
}
diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr
index 106b8a7c8..a5fb338ea 100644
--- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr
+++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit.stderr
@@ -12,6 +12,22 @@ help: copy the `where` clause predicates from the trait
LL | where Self: 'b;
| ~~~~~~~~~~~~~~
-error: aborting due to previous error
+warning: impl trait in impl method signature does not match trait method signature
+ --> $DIR/bad-item-bound-within-rpitit.rs:19:28
+ |
+LL | fn iter(&self) -> impl '_ + Iterator<Item = Self::Item<'_>>;
+ | ----------------------------------------- return type from trait method defined here
+...
+LL | fn iter(&self) -> impl 'a + Iterator<Item = I::Item<'a>> {
+ | ^^ this bound is stronger than that defined on the trait
+ |
+ = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
+ = note: `#[warn(refining_impl_trait)]` on by default
+help: replace the return type so that it matches the trait
+ |
+LL | fn iter(&self) -> impl Iterator<Item = <Self as Iterable>::Item<'_>> + '_ {
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0276`.
diff --git a/tests/ui/impl-trait/in-trait/deep-match-works.rs b/tests/ui/impl-trait/in-trait/deep-match-works.rs
index 78cff97c6..fc290f11f 100644
--- a/tests/ui/impl-trait/in-trait/deep-match-works.rs
+++ b/tests/ui/impl-trait/in-trait/deep-match-works.rs
@@ -1,15 +1,16 @@
// check-pass
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
#![allow(incomplete_features)]
-struct Wrapper<T>(T);
+pub struct Wrapper<T>(T);
-trait Foo {
+pub trait Foo {
fn bar() -> Wrapper<impl Sized>;
}
impl Foo for () {
+ #[expect(refining_impl_trait)]
fn bar() -> Wrapper<i32> {
Wrapper(0)
}
diff --git a/tests/ui/impl-trait/in-trait/foreign.rs b/tests/ui/impl-trait/in-trait/foreign.rs
index b0c93a029..6285d7786 100644
--- a/tests/ui/impl-trait/in-trait/foreign.rs
+++ b/tests/ui/impl-trait/in-trait/foreign.rs
@@ -1,14 +1,25 @@
// check-pass
// aux-build: rpitit.rs
+#![feature(lint_reasons)]
+
extern crate rpitit;
use rpitit::{Foo, Foreign};
use std::sync::Arc;
// Implement an RPITIT from another crate.
-struct Local;
+pub struct Local;
impl Foo for Local {
+ #[expect(refining_impl_trait)]
+ fn bar(self) -> Arc<String> {
+ Arc::new(String::new())
+ }
+}
+
+struct LocalIgnoreRefining;
+impl Foo for LocalIgnoreRefining {
+ #[deny(refining_impl_trait)]
fn bar(self) -> Arc<String> {
Arc::new(String::new())
}
@@ -23,4 +34,5 @@ fn main() {
let &() = Foreign.bar();
let x: Arc<String> = Local.bar();
+ let x: Arc<String> = LocalIgnoreRefining.bar();
}
diff --git a/tests/ui/impl-trait/in-trait/issue-102140.stderr b/tests/ui/impl-trait/in-trait/issue-102140.stderr
index 5d55b9fa4..18bb63745 100644
--- a/tests/ui/impl-trait/in-trait/issue-102140.stderr
+++ b/tests/ui/impl-trait/in-trait/issue-102140.stderr
@@ -6,7 +6,11 @@ LL | MyTrait::foo(&self)
| |
| required by a bound introduced by this call
|
- = help: the trait `MyTrait` is implemented for `Outer`
+help: consider removing the leading `&`-reference
+ |
+LL - MyTrait::foo(&self)
+LL + MyTrait::foo(self)
+ |
error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
--> $DIR/issue-102140.rs:23:9
diff --git a/tests/ui/impl-trait/in-trait/issue-102571.rs b/tests/ui/impl-trait/in-trait/issue-102571.rs
index 61c91e644..ccb53031c 100644
--- a/tests/ui/impl-trait/in-trait/issue-102571.rs
+++ b/tests/ui/impl-trait/in-trait/issue-102571.rs
@@ -8,14 +8,6 @@ trait Foo {
fn bar(self) -> impl Deref<Target = impl Display + ?Sized>;
}
-struct A;
-
-impl Foo for A {
- fn bar(self) -> &'static str {
- "Hello, world"
- }
-}
-
fn foo<T: Foo>(t: T) {
let () = t.bar();
//~^ ERROR mismatched types
diff --git a/tests/ui/impl-trait/in-trait/issue-102571.stderr b/tests/ui/impl-trait/in-trait/issue-102571.stderr
index 87219941d..594b9ae9c 100644
--- a/tests/ui/impl-trait/in-trait/issue-102571.stderr
+++ b/tests/ui/impl-trait/in-trait/issue-102571.stderr
@@ -1,5 +1,5 @@
error[E0308]: mismatched types
- --> $DIR/issue-102571.rs:20:9
+ --> $DIR/issue-102571.rs:12:9
|
LL | let () = t.bar();
| ^^ ------- this expression has type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
diff --git a/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs b/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs
new file mode 100644
index 000000000..49d36d6c9
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/lifetime-in-associated-trait-bound.rs
@@ -0,0 +1,19 @@
+// check-pass
+
+#![feature(associated_type_bounds, return_position_impl_trait_in_trait)]
+
+trait Trait {
+ type Type;
+
+ fn method(&self) -> impl Trait<Type: '_>;
+}
+
+impl Trait for () {
+ type Type = ();
+
+ fn method(&self) -> impl Trait<Type: '_> {
+ ()
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/nested-rpitit.rs b/tests/ui/impl-trait/in-trait/nested-rpitit.rs
index 65285e3a3..58ba1acaf 100644
--- a/tests/ui/impl-trait/in-trait/nested-rpitit.rs
+++ b/tests/ui/impl-trait/in-trait/nested-rpitit.rs
@@ -1,26 +1,28 @@
// check-pass
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
#![allow(incomplete_features)]
use std::fmt::Display;
use std::ops::Deref;
-trait Foo {
+pub trait Foo {
fn bar(self) -> impl Deref<Target = impl Display + ?Sized>;
}
-struct A;
+pub struct A;
impl Foo for A {
+ #[expect(refining_impl_trait)]
fn bar(self) -> &'static str {
"Hello, world"
}
}
-struct B;
+pub struct B;
impl Foo for B {
+ #[expect(refining_impl_trait)]
fn bar(self) -> Box<i32> {
Box::new(42)
}
diff --git a/tests/ui/impl-trait/in-trait/object-safety-sized.rs b/tests/ui/impl-trait/in-trait/object-safety-sized.rs
new file mode 100644
index 000000000..f221cfbb1
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/object-safety-sized.rs
@@ -0,0 +1,23 @@
+// check-pass
+// revisions: current next
+//[next] compile-flags: -Ztrait-solver=next
+
+#![feature(return_position_impl_trait_in_trait)]
+
+fn main() {
+ let vec: Vec<Box<dyn Trait>> = Vec::new();
+
+ for i in vec {
+ i.fn_2();
+ }
+}
+
+trait OtherTrait {}
+
+trait Trait {
+ fn fn_1(&self) -> impl OtherTrait
+ where
+ Self: Sized;
+
+ fn fn_2(&self) -> bool;
+}
diff --git a/tests/ui/impl-trait/in-trait/object-safety.rs b/tests/ui/impl-trait/in-trait/object-safety.rs
index dd35b9a2d..d1c9fba4e 100644
--- a/tests/ui/impl-trait/in-trait/object-safety.rs
+++ b/tests/ui/impl-trait/in-trait/object-safety.rs
@@ -8,7 +8,7 @@ trait Foo {
}
impl Foo for u32 {
- fn baz(&self) -> u32 {
+ fn baz(&self) -> impl Debug {
32
}
}
@@ -19,4 +19,5 @@ fn main() {
//~| ERROR the trait `Foo` cannot be made into an object
let s = i.baz();
//~^ ERROR the trait `Foo` cannot be made into an object
+ //~| ERROR the trait `Foo` cannot be made into an object
}
diff --git a/tests/ui/impl-trait/in-trait/object-safety.stderr b/tests/ui/impl-trait/in-trait/object-safety.stderr
index 4a3b3b114..0170dc5d0 100644
--- a/tests/ui/impl-trait/in-trait/object-safety.stderr
+++ b/tests/ui/impl-trait/in-trait/object-safety.stderr
@@ -14,6 +14,21 @@ LL | fn baz(&self) -> impl Debug;
= help: consider moving `baz` to another trait
error[E0038]: the trait `Foo` cannot be made into an object
+ --> $DIR/object-safety.rs:20:15
+ |
+LL | let s = i.baz();
+ | ^^^ `Foo` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety.rs:7:22
+ |
+LL | trait Foo {
+ | --- this trait cannot be made into an object...
+LL | fn baz(&self) -> impl Debug;
+ | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
+ = help: consider moving `baz` to another trait
+
+error[E0038]: the trait `Foo` cannot be made into an object
--> $DIR/object-safety.rs:20:13
|
LL | let s = i.baz();
@@ -44,6 +59,6 @@ LL | fn baz(&self) -> impl Debug;
= help: consider moving `baz` to another trait
= note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/impl-trait/in-trait/refine.rs b/tests/ui/impl-trait/in-trait/refine.rs
new file mode 100644
index 000000000..a91f9b3e7
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/refine.rs
@@ -0,0 +1,48 @@
+#![feature(return_position_impl_trait_in_trait, async_fn_in_trait)]
+#![deny(refining_impl_trait)]
+
+pub trait Foo {
+ fn bar() -> impl Sized;
+}
+
+pub struct A;
+impl Foo for A {
+ fn bar() -> impl Copy {}
+ //~^ ERROR impl method signature does not match trait method signature
+}
+
+pub struct B;
+impl Foo for B {
+ fn bar() {}
+ //~^ ERROR impl method signature does not match trait method signature
+}
+
+pub struct C;
+impl Foo for C {
+ fn bar() -> () {}
+ //~^ ERROR impl method signature does not match trait method signature
+}
+
+struct Private;
+impl Foo for Private {
+ fn bar() -> () {}
+}
+
+pub trait Arg<A> {
+ fn bar() -> impl Sized;
+}
+impl Arg<Private> for A {
+ fn bar() -> () {}
+}
+
+pub trait Late {
+ fn bar<'a>(&'a self) -> impl Sized + 'a;
+}
+
+pub struct D;
+impl Late for D {
+ fn bar(&self) -> impl Copy + '_ {}
+ //~^ ERROR impl method signature does not match trait method signature
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/refine.stderr b/tests/ui/impl-trait/in-trait/refine.stderr
new file mode 100644
index 000000000..29aa08e25
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/refine.stderr
@@ -0,0 +1,67 @@
+error: impl trait in impl method signature does not match trait method signature
+ --> $DIR/refine.rs:10:22
+ |
+LL | fn bar() -> impl Sized;
+ | ---------- return type from trait method defined here
+...
+LL | fn bar() -> impl Copy {}
+ | ^^^^ this bound is stronger than that defined on the trait
+ |
+ = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
+note: the lint level is defined here
+ --> $DIR/refine.rs:2:9
+ |
+LL | #![deny(refining_impl_trait)]
+ | ^^^^^^^^^^^^^^^^^^^
+help: replace the return type so that it matches the trait
+ |
+LL | fn bar() -> impl Sized {}
+ | ~~~~~~~~~~
+
+error: impl trait in impl method signature does not match trait method signature
+ --> $DIR/refine.rs:16:5
+ |
+LL | fn bar() -> impl Sized;
+ | ---------- return type from trait method defined here
+...
+LL | fn bar() {}
+ | ^^^^^^^^
+ |
+ = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
+help: replace the return type so that it matches the trait
+ |
+LL | fn bar() -> impl Sized {}
+ | +++++++++++++
+
+error: impl trait in impl method signature does not match trait method signature
+ --> $DIR/refine.rs:22:17
+ |
+LL | fn bar() -> impl Sized;
+ | ---------- return type from trait method defined here
+...
+LL | fn bar() -> () {}
+ | ^^
+ |
+ = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
+help: replace the return type so that it matches the trait
+ |
+LL | fn bar() -> impl Sized {}
+ | ~~~~~~~~~~
+
+error: impl trait in impl method signature does not match trait method signature
+ --> $DIR/refine.rs:44:27
+ |
+LL | fn bar<'a>(&'a self) -> impl Sized + 'a;
+ | --------------- return type from trait method defined here
+...
+LL | fn bar(&self) -> impl Copy + '_ {}
+ | ^^^^ this bound is stronger than that defined on the trait
+ |
+ = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
+help: replace the return type so that it matches the trait
+ |
+LL | fn bar(&self) -> impl Sized + '_ {}
+ | ~~~~~~~~~~~~~~~
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/impl-trait/in-trait/reveal.rs b/tests/ui/impl-trait/in-trait/reveal.rs
index d6ede1cc4..b1b46d75b 100644
--- a/tests/ui/impl-trait/in-trait/reveal.rs
+++ b/tests/ui/impl-trait/in-trait/reveal.rs
@@ -1,13 +1,14 @@
// check-pass
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
#![allow(incomplete_features)]
-trait Foo {
+pub trait Foo {
fn f() -> Box<impl Sized>;
}
impl Foo for () {
+ #[expect(refining_impl_trait)]
fn f() -> Box<String> {
Box::new(String::new())
}
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs
new file mode 100644
index 000000000..5e14a7f8e
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs
@@ -0,0 +1,26 @@
+#![feature(return_position_impl_trait_in_trait)]
+
+trait Extend {
+ fn extend<'a: 'a>(_: &'a str) -> (impl Sized + 'a, &'static str);
+}
+
+impl Extend for () {
+ fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
+ //~^ ERROR in type `&'static &'a ()`, reference has a longer lifetime than the data it references
+ where
+ 'a: 'static,
+ {
+ (None, s)
+ }
+}
+
+// This indirection is not necessary for reproduction,
+// but it makes this test future-proof against #114936.
+fn extend<T: Extend>(s: &str) -> &'static str {
+ <T as Extend>::extend(s).1
+}
+
+fn main() {
+ let use_after_free = extend::<()>(&String::from("temporary"));
+ println!("{}", use_after_free);
+}
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr
new file mode 100644
index 000000000..1d947310e
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr
@@ -0,0 +1,16 @@
+error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references
+ --> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:8:38
+ |
+LL | fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the pointer is valid for the static lifetime
+note: but the referenced data is only valid for the lifetime `'a` as defined here
+ --> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:8:15
+ |
+LL | fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
+ | ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0491`.
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs
new file mode 100644
index 000000000..c1885af4e
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs
@@ -0,0 +1,23 @@
+#![feature(return_position_impl_trait_in_trait)]
+
+trait Extend {
+ fn extend(_: &str) -> (impl Sized + '_, &'static str);
+}
+
+impl Extend for () {
+ fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) {
+ //~^ ERROR in type `&'static &()`, reference has a longer lifetime than the data it references
+ (None, s)
+ }
+}
+
+// This indirection is not necessary for reproduction,
+// but it makes this test future-proof against #114936.
+fn extend<T: Extend>(s: &str) -> &'static str {
+ <T as Extend>::extend(s).1
+}
+
+fn main() {
+ let use_after_free = extend::<()>(&String::from("temporary"));
+ println!("{}", use_after_free);
+}
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr
new file mode 100644
index 000000000..7b63e72ac
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr
@@ -0,0 +1,16 @@
+error[E0491]: in type `&'static &()`, reference has a longer lifetime than the data it references
+ --> $DIR/rpitit-hidden-types-self-implied-wf.rs:8:27
+ |
+LL | fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: the pointer is valid for the static lifetime
+note: but the referenced data is only valid for the anonymous lifetime defined here
+ --> $DIR/rpitit-hidden-types-self-implied-wf.rs:8:18
+ |
+LL | fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) {
+ | ^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0491`.
diff --git a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs
index 7682884f8..44a2b4303 100644
--- a/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs
+++ b/tests/ui/impl-trait/in-trait/rpitit-shadowed-by-missing-adt.rs
@@ -1,6 +1,6 @@
// issue: 113903
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
use std::ops::Deref;
@@ -10,6 +10,7 @@ pub trait Tr {
}
impl Tr for () {
+ #[expect(refining_impl_trait)]
fn w() -> &'static () {
&()
}
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr
new file mode 100644
index 000000000..468cf12f1
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/signature-mismatch.failure.stderr
@@ -0,0 +1,14 @@
+error[E0623]: lifetime mismatch
+ --> $DIR/signature-mismatch.rs:79:10
+ |
+LL | &'a self,
+ | -------- this parameter and the return type are declared with different lifetimes...
+...
+LL | ) -> impl Future<Output = Vec<u8>> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | ...but data from `buff` is returned here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0623`.
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.rs b/tests/ui/impl-trait/in-trait/signature-mismatch.rs
index 1d63a6f3c..685c0f06e 100644
--- a/tests/ui/impl-trait/in-trait/signature-mismatch.rs
+++ b/tests/ui/impl-trait/in-trait/signature-mismatch.rs
@@ -1,26 +1,36 @@
// edition:2021
+// revisions: success failure
+//[success] check-pass
-#![feature(return_position_impl_trait_in_trait)]
-#![allow(incomplete_features)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
use std::future::Future;
-trait Captures<'a> {}
+pub trait Captures<'a> {}
impl<T> Captures<'_> for T {}
-trait Captures2<'a, 'b> {}
+pub trait Captures2<'a, 'b> {}
impl<T> Captures2<'_, '_> for T {}
pub trait AsyncTrait {
+ #[cfg(success)]
fn async_fn(&self, buff: &[u8]) -> impl Future<Output = Vec<u8>>;
+
+ #[cfg(success)]
fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>>;
+
+ #[cfg(success)]
fn async_fn_multiple<'a>(&'a self, buff: &[u8])
- -> impl Future<Output = Vec<u8>> + Captures<'a>;
+ -> impl Future<Output = Vec<u8>> + Captures<'a>;
+
+ #[cfg(failure)]
fn async_fn_reduce_outlive<'a, T>(
&'a self,
buff: &[u8],
t: T,
) -> impl Future<Output = Vec<u8>> + 'a;
+
+ #[cfg(success)]
fn async_fn_reduce<'a, T>(
&'a self,
buff: &[u8],
@@ -31,38 +41,52 @@ pub trait AsyncTrait {
pub struct Struct;
impl AsyncTrait for Struct {
+ // Does not capture more lifetimes that trait def'n, since trait def'n
+ // implicitly captures all in-scope lifetimes.
+ #[cfg(success)]
+ #[expect(refining_impl_trait)]
fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
- //~^ ERROR return type captures more lifetimes than trait definition
async move { buff.to_vec() }
}
+ // Does not capture more lifetimes that trait def'n, since trait def'n
+ // implicitly captures all in-scope lifetimes.
+ #[cfg(success)]
+ #[expect(refining_impl_trait)]
fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
- //~^ ERROR return type captures more lifetimes than trait definition
async move { buff.to_vec() }
}
+ // Does not capture more lifetimes that trait def'n, since trait def'n
+ // implicitly captures all in-scope lifetimes.
+ #[cfg(success)]
+ #[expect(refining_impl_trait)]
fn async_fn_multiple<'a, 'b>(
&'a self,
buff: &'b [u8],
) -> impl Future<Output = Vec<u8>> + Captures2<'a, 'b> {
- //~^ ERROR return type captures more lifetimes than trait definition
async move { buff.to_vec() }
}
+ // This error message is awkward, but `impl Future<Output = Vec<u8>>`
+ // cannot outlive `'a` (from the trait signature) because it captures
+ // both `T` and `'b`.
+ #[cfg(failure)]
fn async_fn_reduce_outlive<'a, 'b, T>(
&'a self,
buff: &'b [u8],
t: T,
) -> impl Future<Output = Vec<u8>> {
- //~^ ERROR the parameter type `T` may not live long enough
+ //[failure]~^ ERROR lifetime mismatch
async move {
let _t = t;
vec![]
}
}
- // OK: We remove the `Captures<'a>`, providing a guarantee that we don't capture `'a`,
- // but we still fulfill the `Captures<'a>` trait bound.
+ // Does not capture fewer lifetimes that trait def'n (not that it matters),
+ // since impl also captures all in-scope lifetimes.
+ #[cfg(success)]
fn async_fn_reduce<'a, 'b, T>(&'a self, buff: &'b [u8], t: T) -> impl Future<Output = Vec<u8>> {
async move {
let _t = t;
diff --git a/tests/ui/impl-trait/in-trait/signature-mismatch.stderr b/tests/ui/impl-trait/in-trait/signature-mismatch.stderr
deleted file mode 100644
index 616f1ac35..000000000
--- a/tests/ui/impl-trait/in-trait/signature-mismatch.stderr
+++ /dev/null
@@ -1,61 +0,0 @@
-error: return type captures more lifetimes than trait definition
- --> $DIR/signature-mismatch.rs:34:47
- |
-LL | fn async_fn<'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
- | -- this lifetime was captured ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: hidden type must only reference lifetimes captured by this impl trait
- --> $DIR/signature-mismatch.rs:15:40
- |
-LL | fn async_fn(&self, buff: &[u8]) -> impl Future<Output = Vec<u8>>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- = note: hidden type inferred to be `impl Future<Output = Vec<u8>> + 'a`
-
-error: return type captures more lifetimes than trait definition
- --> $DIR/signature-mismatch.rs:39:57
- |
-LL | fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>> + 'a {
- | -- this lifetime was captured ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: hidden type must only reference lifetimes captured by this impl trait
- --> $DIR/signature-mismatch.rs:16:57
- |
-LL | fn async_fn_early<'a: 'a>(&self, buff: &'a [u8]) -> impl Future<Output = Vec<u8>>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- = note: hidden type inferred to be `impl Future<Output = Vec<u8>> + 'a`
-
-error: return type captures more lifetimes than trait definition
- --> $DIR/signature-mismatch.rs:47:10
- |
-LL | fn async_fn_multiple<'a, 'b>(
- | -- this lifetime was captured
-...
-LL | ) -> impl Future<Output = Vec<u8>> + Captures2<'a, 'b> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- |
-note: hidden type must only reference lifetimes captured by this impl trait
- --> $DIR/signature-mismatch.rs:18:12
- |
-LL | -> impl Future<Output = Vec<u8>> + Captures<'a>;
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- = note: hidden type inferred to be `impl Future<Output = Vec<u8>> + Captures2<'a, 'b>`
-
-error[E0309]: the parameter type `T` may not live long enough
- --> $DIR/signature-mismatch.rs:56:10
- |
-LL | ) -> impl Future<Output = Vec<u8>> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `impl Future<Output = Vec<u8>>` will meet its required lifetime bounds...
- |
-note: ...that is required by this bound
- --> $DIR/signature-mismatch.rs:23:42
- |
-LL | ) -> impl Future<Output = Vec<u8>> + 'a;
- | ^^
-help: consider adding an explicit lifetime bound...
- |
-LL | fn async_fn_reduce_outlive<'a, 'b, T: 'a>(
- | ++++
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0309`.
diff --git a/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs b/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs
index c9ee877db..41fc28588 100644
--- a/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs
+++ b/tests/ui/impl-trait/in-trait/specialization-substs-remap.rs
@@ -1,10 +1,10 @@
// check-pass
#![feature(specialization)]
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
#![allow(incomplete_features)]
-trait Foo {
+pub trait Foo {
fn bar(&self) -> impl Sized;
}
@@ -12,6 +12,7 @@ impl<U> Foo for U
where
U: Copy,
{
+ #[expect(refining_impl_trait)]
fn bar(&self) -> U {
*self
}
diff --git a/tests/ui/impl-trait/in-trait/success.rs b/tests/ui/impl-trait/in-trait/success.rs
index 4cbe682b4..7d415ea17 100644
--- a/tests/ui/impl-trait/in-trait/success.rs
+++ b/tests/ui/impl-trait/in-trait/success.rs
@@ -1,29 +1,32 @@
// check-pass
-#![feature(return_position_impl_trait_in_trait)]
+#![feature(return_position_impl_trait_in_trait, lint_reasons)]
#![allow(incomplete_features)]
use std::fmt::Display;
-trait Foo {
+pub trait Foo {
fn bar(&self) -> impl Display;
}
impl Foo for i32 {
+ #[expect(refining_impl_trait)]
fn bar(&self) -> i32 {
*self
}
}
impl Foo for &'static str {
+ #[expect(refining_impl_trait)]
fn bar(&self) -> &'static str {
*self
}
}
-struct Yay;
+pub struct Yay;
impl Foo for Yay {
+ #[expect(refining_impl_trait)]
fn bar(&self) -> String {
String::from(":^)")
}
diff --git a/tests/ui/impl-trait/in-trait/variance.rs b/tests/ui/impl-trait/in-trait/variance.rs
new file mode 100644
index 000000000..f8e4ab88c
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/variance.rs
@@ -0,0 +1,20 @@
+#![feature(rustc_attrs, return_position_impl_trait_in_trait)]
+#![allow(internal_features)]
+#![rustc_variance_of_opaques]
+
+trait Captures<'a> {}
+impl<T> Captures<'_> for T {}
+
+trait Foo<'i> {
+ fn implicit_capture_early<'a: 'a>() -> impl Sized {}
+ //~^ [o, *, *, o, o]
+ // Self, 'i, 'a, 'i_duplicated, 'a_duplicated
+
+ fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {} //~ [o, *, *, o, o]
+
+ fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {} //~ [o, *, o, o]
+
+ fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {} //~ [o, *, o, o]
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/variance.stderr b/tests/ui/impl-trait/in-trait/variance.stderr
new file mode 100644
index 000000000..8cae5a92f
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/variance.stderr
@@ -0,0 +1,26 @@
+error: [o, *, *, o, o]
+ --> $DIR/variance.rs:9:44
+ |
+LL | fn implicit_capture_early<'a: 'a>() -> impl Sized {}
+ | ^^^^^^^^^^
+
+error: [o, *, *, o, o]
+ --> $DIR/variance.rs:13:44
+ |
+LL | fn explicit_capture_early<'a: 'a>() -> impl Sized + Captures<'a> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: [o, *, o, o]
+ --> $DIR/variance.rs:15:48
+ |
+LL | fn implicit_capture_late<'a>(_: &'a ()) -> impl Sized {}
+ | ^^^^^^^^^^
+
+error: [o, *, o, o]
+ --> $DIR/variance.rs:17:48
+ |
+LL | fn explicit_capture_late<'a>(_: &'a ()) -> impl Sized + Captures<'a> {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+