summaryrefslogtreecommitdiffstats
path: root/tests/ui/implied-bounds
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--tests/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr2
-rw-r--r--tests/ui/implied-bounds/auxiliary/bevy_ecs.rs18
-rw-r--r--tests/ui/implied-bounds/bevy_world_query.rs11
-rw-r--r--tests/ui/implied-bounds/from-trait-impl.rs24
-rw-r--r--tests/ui/implied-bounds/gluon_salsa.rs31
-rw-r--r--tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs2
-rw-r--r--tests/ui/implied-bounds/impl-header-unnormalized-types.stderr2
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs5
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr43
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs5
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr45
-rw-r--r--tests/ui/implied-bounds/issue-100690.stderr6
-rw-r--r--tests/ui/implied-bounds/issue-110161.stderr2
-rw-r--r--tests/ui/implied-bounds/normalization-nested.lifetime.stderr29
-rw-r--r--tests/ui/implied-bounds/normalization-nested.rs4
-rw-r--r--tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr15
-rw-r--r--tests/ui/implied-bounds/normalization-placeholder-leak.rs56
-rw-r--r--tests/ui/implied-bounds/normalization-preserve-equality.borrowck.stderr28
-rw-r--r--tests/ui/implied-bounds/normalization-preserve-equality.rs28
-rw-r--r--tests/ui/implied-bounds/references-err.stderr2
-rw-r--r--tests/ui/implied-bounds/sod_service_chain.rs37
21 files changed, 326 insertions, 69 deletions
diff --git a/tests/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr b/tests/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr
index 307899297..92284df41 100644
--- a/tests/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr
+++ b/tests/ui/implied-bounds/assoc-ty-wf-used-to-get-assoc-ty.stderr
@@ -12,6 +12,6 @@ LL | let _: &'static u8 = test(&x, &&3);
LL | }
| - `x` dropped here while still borrowed
-error: aborting due to previous error
+error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/implied-bounds/auxiliary/bevy_ecs.rs b/tests/ui/implied-bounds/auxiliary/bevy_ecs.rs
new file mode 100644
index 000000000..b373d39f4
--- /dev/null
+++ b/tests/ui/implied-bounds/auxiliary/bevy_ecs.rs
@@ -0,0 +1,18 @@
+// Related to Bevy regression #118553
+
+pub trait WorldQuery {}
+impl WorldQuery for &u8 {}
+
+pub struct Query<Q: WorldQuery>(Q);
+
+pub trait SystemParam {
+ type State;
+}
+impl<Q: WorldQuery + 'static> SystemParam for Query<Q> {
+ type State = ();
+ // `Q: 'static` is required because we need the TypeId of Q ...
+}
+
+pub struct ParamSet<T: SystemParam>(T)
+where
+ T::State: Sized;
diff --git a/tests/ui/implied-bounds/bevy_world_query.rs b/tests/ui/implied-bounds/bevy_world_query.rs
new file mode 100644
index 000000000..f8e646326
--- /dev/null
+++ b/tests/ui/implied-bounds/bevy_world_query.rs
@@ -0,0 +1,11 @@
+// aux-crate:bevy_ecs=bevy_ecs.rs
+// check-pass
+// Related to Bevy regression #118553
+
+extern crate bevy_ecs;
+
+use bevy_ecs::*;
+
+fn handler<'a>(_: ParamSet<Query<&'a u8>>) {}
+
+fn main() {}
diff --git a/tests/ui/implied-bounds/from-trait-impl.rs b/tests/ui/implied-bounds/from-trait-impl.rs
new file mode 100644
index 000000000..d13fddd9b
--- /dev/null
+++ b/tests/ui/implied-bounds/from-trait-impl.rs
@@ -0,0 +1,24 @@
+// check-pass
+// known-bug: #109628
+
+trait Trait {
+ type Assoc;
+}
+
+impl<X: 'static> Trait for (X,) {
+ type Assoc = ();
+}
+
+struct Foo<T: Trait>(T)
+where
+ T::Assoc: Clone; // any predicate using `T::Assoc` works here
+
+fn func1(foo: Foo<(&str,)>) {
+ let _: &'static str = foo.0.0;
+}
+
+trait TestTrait {}
+
+impl<X> TestTrait for [Foo<(X,)>; 1] {}
+
+fn main() {}
diff --git a/tests/ui/implied-bounds/gluon_salsa.rs b/tests/ui/implied-bounds/gluon_salsa.rs
new file mode 100644
index 000000000..98951af8a
--- /dev/null
+++ b/tests/ui/implied-bounds/gluon_salsa.rs
@@ -0,0 +1,31 @@
+// check-pass
+// Related to Bevy regression #118553
+
+pub trait QueryBase {
+ type Db;
+}
+
+pub trait AsyncQueryFunction<'f>: // 'f is important
+ QueryBase<Db = <Self as AsyncQueryFunction<'f>>::SendDb> // bound is important
+{
+ type SendDb;
+}
+
+pub struct QueryTable<'me, Q, DB> {
+ _q: Option<Q>,
+ _db: Option<DB>,
+ _marker: Option<&'me ()>,
+}
+
+impl<'me, Q> QueryTable<'me, Q, <Q as QueryBase>::Db>
+// projection is important
+// ^^^ removing 'me (and in QueryTable) gives a different error
+where
+ Q: for<'f> AsyncQueryFunction<'f>,
+{
+ pub fn get_async<'a>(&'a mut self) {
+ panic!();
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
index c177655c5..27c8f30ec 100644
--- a/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
+++ b/tests/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
@@ -1,5 +1,5 @@
// A test exploiting the bug behind #25860 except with
-// implied trait bounds which currently don't exist without `-Ztrait-solver=chalk`.
+// implied trait bounds which currently don't exist.
use std::marker::PhantomData;
struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>)
where
diff --git a/tests/ui/implied-bounds/impl-header-unnormalized-types.stderr b/tests/ui/implied-bounds/impl-header-unnormalized-types.stderr
index 88abd5f54..07cb0aecd 100644
--- a/tests/ui/implied-bounds/impl-header-unnormalized-types.stderr
+++ b/tests/ui/implied-bounds/impl-header-unnormalized-types.stderr
@@ -15,6 +15,6 @@ note: but the referenced data is only valid for the lifetime `'b` as defined her
LL | impl<'a, 'b> NeedsWf<'a, 'b> for Foo<<&'a &'b () as GoodBye>::Forget> {
| ^^
-error: aborting due to previous error
+error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0491`.
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs
index 6ccbb5bb2..280856805 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs
@@ -1,5 +1,3 @@
-#![deny(implied_bounds_entailment)]
-
trait Project {
type Ty;
}
@@ -11,8 +9,7 @@ trait Trait {
}
impl Trait for () {
fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
- //~^ ERROR impl method assumes more implied bounds than the corresponding trait method
- //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
s
}
}
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
index ebe07027d..c8d1614a7 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
@@ -1,31 +1,28 @@
-error: impl method assumes more implied bounds than the corresponding trait method
- --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:31
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
+ --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
|
LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `()`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = 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 #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
- --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:1:9
- |
-LL | #![deny(implied_bounds_entailment)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-Future incompatibility report: Future breakage diagnostic:
-error: impl method assumes more implied bounds than the corresponding trait method
- --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:31
+note: first, the lifetime cannot outlive the lifetime `'s` as defined here...
+ --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:12
|
LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `()`
+ | ^^
+note: ...so that the method type is compatible with trait
+ --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
|
- = 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 #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
- --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:1:9
+LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: expected `fn(&'s _, ()) -> &'static _`
+ found `fn(&_, ()) -> &'static _`
+ = note: but, the lifetime must be valid for the static lifetime...
+note: ...so that the reference type `&'static &()` does not outlive the data it points at
+ --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
|
-LL | #![deny(implied_bounds_entailment)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+For more information about this error, try `rustc --explain E0495`.
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs
index d097bc16a..7f3817b32 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs
@@ -1,5 +1,3 @@
-#![deny(implied_bounds_entailment)]
-
use std::cell::RefCell;
pub struct MessageListeners<'a> {
@@ -12,8 +10,7 @@ pub trait MessageListenersInterface {
impl<'a> MessageListenersInterface for MessageListeners<'a> {
fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
- //~^ ERROR impl method assumes more implied bounds than the corresponding trait method
- //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements
self
}
}
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr
index 43d3e058f..6a412eb5e 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr
@@ -1,31 +1,32 @@
-error: impl method assumes more implied bounds than the corresponding trait method
- --> $DIR/impl-implied-bounds-compatibility.rs:14:35
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements
+ --> $DIR/impl-implied-bounds-compatibility.rs:12:5
|
LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `&'b MessageListeners<'b>`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
- = 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 #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
- --> $DIR/impl-implied-bounds-compatibility.rs:1:9
+note: first, the lifetime cannot outlive the lifetime `'c` as defined here...
+ --> $DIR/impl-implied-bounds-compatibility.rs:12:5
|
-LL | #![deny(implied_bounds_entailment)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-Future incompatibility report: Future breakage diagnostic:
-error: impl method assumes more implied bounds than the corresponding trait method
- --> $DIR/impl-implied-bounds-compatibility.rs:14:35
+LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...so that the method type is compatible with trait
+ --> $DIR/impl-implied-bounds-compatibility.rs:12:5
|
LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
- | ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `&'b MessageListeners<'b>`
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ = note: expected `fn(&'c MessageListeners<'_>) -> &'c MessageListeners<'c>`
+ found `fn(&MessageListeners<'_>) -> &'a MessageListeners<'_>`
+note: but, the lifetime must be valid for the lifetime `'a` as defined here...
+ --> $DIR/impl-implied-bounds-compatibility.rs:11:6
|
- = 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 #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
- --> $DIR/impl-implied-bounds-compatibility.rs:1:9
+LL | impl<'a> MessageListenersInterface for MessageListeners<'a> {
+ | ^^
+note: ...so that the reference type `&'a MessageListeners<'_>` does not outlive the data it points at
+ --> $DIR/impl-implied-bounds-compatibility.rs:12:5
|
-LL | #![deny(implied_bounds_entailment)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+For more information about this error, try `rustc --explain E0495`.
diff --git a/tests/ui/implied-bounds/issue-100690.stderr b/tests/ui/implied-bounds/issue-100690.stderr
index ac9f7ab25..df069d875 100644
--- a/tests/ui/implied-bounds/issue-100690.stderr
+++ b/tests/ui/implied-bounds/issue-100690.stderr
@@ -6,8 +6,8 @@ LL | real_dispatch(f)
| |
| required by a bound introduced by this call
|
- = note: expected a closure with arguments `(&mut UIView<'a, T>,)`
- found a closure with arguments `(&mut UIView<'_, T>,)`
+ = note: expected a closure with arguments `(&mut UIView<'a, _>,)`
+ found a closure with arguments `(&mut UIView<'_, _>,)`
note: required by a bound in `real_dispatch`
--> $DIR/issue-100690.rs:9:8
|
@@ -17,6 +17,6 @@ LL | fn real_dispatch<T, F>(f: F) -> Result<(), io::Error>
LL | F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `real_dispatch`
-error: aborting due to previous error
+error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/implied-bounds/issue-110161.stderr b/tests/ui/implied-bounds/issue-110161.stderr
index 9e0188694..0b7363179 100644
--- a/tests/ui/implied-bounds/issue-110161.stderr
+++ b/tests/ui/implied-bounds/issue-110161.stderr
@@ -7,6 +7,6 @@ LL | type Ty;
LL | impl LtTrait for () {
| ^^^^^^^^^^^^^^^^^^^ missing `Ty` in implementation
-error: aborting due to previous error
+error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/implied-bounds/normalization-nested.lifetime.stderr b/tests/ui/implied-bounds/normalization-nested.lifetime.stderr
index 898e5e951..e020230d8 100644
--- a/tests/ui/implied-bounds/normalization-nested.lifetime.stderr
+++ b/tests/ui/implied-bounds/normalization-nested.lifetime.stderr
@@ -1,11 +1,11 @@
error[E0759]: `fn` parameter has lifetime `'x` but it needs to satisfy a `'static` lifetime requirement
- --> $DIR/normalization-nested.rs:35:20
+ --> $DIR/normalization-nested.rs:35:28
|
-LL | pub fn test<'x>(_: Map<Vec<&'x ()>>, s: &'x str) -> &'static str {
- | ^^^^^^^^^^^^^^^^
- | |
- | this data with lifetime `'x`...
- | ...is used and required to live as long as `'static` here
+LL | pub fn test_wfcheck<'x>(_: Map<Vec<&'x ()>>) {}
+ | ^^^^^^^^^^^^^^^^
+ | |
+ | this data with lifetime `'x`...
+ | ...is used and required to live as long as `'static` here
|
note: `'static` lifetime requirement introduced by this bound
--> $DIR/normalization-nested.rs:33:14
@@ -13,6 +13,21 @@ note: `'static` lifetime requirement introduced by this bound
LL | I::Item: 'static;
| ^^^^^^^
-error: aborting due to previous error
+error[E0759]: `fn` parameter has lifetime `'x` but it needs to satisfy a `'static` lifetime requirement
+ --> $DIR/normalization-nested.rs:37:29
+ |
+LL | pub fn test_borrowck<'x>(_: Map<Vec<&'x ()>>, s: &'x str) -> &'static str {
+ | ^^^^^^^^^^^^^^^^
+ | |
+ | this data with lifetime `'x`...
+ | ...is used and required to live as long as `'static` here
+ |
+note: `'static` lifetime requirement introduced by this bound
+ --> $DIR/normalization-nested.rs:33:14
+ |
+LL | I::Item: 'static;
+ | ^^^^^^^
+
+error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0759`.
diff --git a/tests/ui/implied-bounds/normalization-nested.rs b/tests/ui/implied-bounds/normalization-nested.rs
index 5f1cbb3f6..87903783a 100644
--- a/tests/ui/implied-bounds/normalization-nested.rs
+++ b/tests/ui/implied-bounds/normalization-nested.rs
@@ -32,7 +32,9 @@ where
I: Iter,
I::Item: 'static;
-pub fn test<'x>(_: Map<Vec<&'x ()>>, s: &'x str) -> &'static str {
+pub fn test_wfcheck<'x>(_: Map<Vec<&'x ()>>) {}
+
+pub fn test_borrowck<'x>(_: Map<Vec<&'x ()>>, s: &'x str) -> &'static str {
s
}
diff --git a/tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr b/tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr
new file mode 100644
index 000000000..a591d0f5d
--- /dev/null
+++ b/tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr
@@ -0,0 +1,15 @@
+error[E0477]: the type `&'lt u8` does not fulfill the required lifetime
+ --> $DIR/normalization-placeholder-leak.rs:31:40
+ |
+LL | fn test_lifetime<'lt, T: Trait>(_: Foo<&'lt u8>) {}
+ | ^^^^^^^^^^^^
+
+error[E0477]: the type `<T as AnotherTrait>::Ty2<'lt>` does not fulfill the required lifetime
+ --> $DIR/normalization-placeholder-leak.rs:36:44
+ |
+LL | fn test_alias<'lt, T: AnotherTrait>(_: Foo<T::Ty2::<'lt>>) {}
+ | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0477`.
diff --git a/tests/ui/implied-bounds/normalization-placeholder-leak.rs b/tests/ui/implied-bounds/normalization-placeholder-leak.rs
new file mode 100644
index 000000000..5350dcbb2
--- /dev/null
+++ b/tests/ui/implied-bounds/normalization-placeholder-leak.rs
@@ -0,0 +1,56 @@
+// Because of #109628, when we compute the implied bounds from `Foo<X>`,
+// we incorrectly get `X: placeholder('x)`.
+// Make sure we ignore these bogus bounds and not use them for anything useful.
+//
+// revisions: fail pass
+// [fail] check-fail
+// [pass] check-pass
+
+trait Trait {
+ type Ty<'a> where Self: 'a;
+}
+
+impl<T> Trait for T {
+ type Ty<'a> = () where Self: 'a;
+}
+
+struct Foo<T: Trait>(T)
+where
+ for<'x> T::Ty<'x>: Sized;
+
+trait AnotherTrait {
+ type Ty2<'a>: 'a;
+}
+
+#[cfg(fail)]
+mod fail {
+ use super::*;
+
+ // implied_bound: `'lt: placeholder('x)`.
+ // don't use the bound to prove `'lt: 'static`.
+ fn test_lifetime<'lt, T: Trait>(_: Foo<&'lt u8>) {}
+ //[fail]~^ ERROR `&'lt u8` does not fulfill the required lifetime
+
+ // implied bound: `T::Ty2<'lt>: placeholder('x)`.
+ // don't use the bound to prove `T::Ty2<'lt>: 'static`.
+ fn test_alias<'lt, T: AnotherTrait>(_: Foo<T::Ty2::<'lt>>) {}
+ //[fail]~^ ERROR `<T as AnotherTrait>::Ty2<'lt>` does not fulfill the required lifetime
+}
+
+
+mod pass {
+ use super::*;
+
+ // implied_bound: 'static: placeholder('x).
+ // don't ice.
+ fn test_lifetime<T: Trait>(_: Foo<&'static u8>) {}
+
+ // implied bound: T::Ty2<'static>: placeholder('x).
+ // don't add the bound to the environment,
+ // otherwise we would fail to infer a value for `'_`.
+ fn test_alias<T: AnotherTrait>(_: Foo<T::Ty2::<'static>>) {
+ None::<&'static T::Ty2<'_>>;
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/implied-bounds/normalization-preserve-equality.borrowck.stderr b/tests/ui/implied-bounds/normalization-preserve-equality.borrowck.stderr
new file mode 100644
index 000000000..96c76ca9a
--- /dev/null
+++ b/tests/ui/implied-bounds/normalization-preserve-equality.borrowck.stderr
@@ -0,0 +1,28 @@
+error: lifetime may not live long enough
+ --> $DIR/normalization-preserve-equality.rs:24:1
+ |
+LL | fn test_borrowck<'a, 'b>(_: (<Equal<'a, 'b> as Trait>::Ty, Equal<'a, 'b>)) {
+ | ^^^^^^^^^^^^^^^^^--^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | | | |
+ | | | lifetime `'b` defined here
+ | | lifetime `'a` defined here
+ | requires that `'a` must outlive `'b`
+ |
+ = help: consider adding the following bound: `'a: 'b`
+
+error: lifetime may not live long enough
+ --> $DIR/normalization-preserve-equality.rs:24:1
+ |
+LL | fn test_borrowck<'a, 'b>(_: (<Equal<'a, 'b> as Trait>::Ty, Equal<'a, 'b>)) {
+ | ^^^^^^^^^^^^^^^^^--^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ | | | |
+ | | | lifetime `'b` defined here
+ | | lifetime `'a` defined here
+ | requires that `'b` must outlive `'a`
+ |
+ = help: consider adding the following bound: `'b: 'a`
+
+help: `'a` and `'b` must be the same: replace one with the other
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/implied-bounds/normalization-preserve-equality.rs b/tests/ui/implied-bounds/normalization-preserve-equality.rs
new file mode 100644
index 000000000..557c171e5
--- /dev/null
+++ b/tests/ui/implied-bounds/normalization-preserve-equality.rs
@@ -0,0 +1,28 @@
+// Both revisions should pass. `borrowck` revision is a bug!
+//
+// revisions: wfcheck borrowck
+// [wfcheck] check-pass
+// [borrowck] check-fail
+// [borrowck] known-bug: #106569
+
+struct Equal<'a, 'b>(&'a &'b (), &'b &'a ()); // implies 'a == 'b
+
+trait Trait {
+ type Ty;
+}
+
+impl<'x> Trait for Equal<'x, 'x> {
+ type Ty = ();
+}
+
+trait WfCheckTrait {}
+
+#[cfg(wfcheck)]
+impl<'a, 'b> WfCheckTrait for (<Equal<'a, 'b> as Trait>::Ty, Equal<'a, 'b>) {}
+
+#[cfg(borrowck)]
+fn test_borrowck<'a, 'b>(_: (<Equal<'a, 'b> as Trait>::Ty, Equal<'a, 'b>)) {
+ let _ = None::<Equal<'a, 'b>>;
+}
+
+fn main() {}
diff --git a/tests/ui/implied-bounds/references-err.stderr b/tests/ui/implied-bounds/references-err.stderr
index 6076eea3c..df83fce3b 100644
--- a/tests/ui/implied-bounds/references-err.stderr
+++ b/tests/ui/implied-bounds/references-err.stderr
@@ -4,6 +4,6 @@ error[E0412]: cannot find type `DoesNotExist` in this scope
LL | type Assoc = DoesNotExist;
| ^^^^^^^^^^^^ not found in this scope
-error: aborting due to previous error
+error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/implied-bounds/sod_service_chain.rs b/tests/ui/implied-bounds/sod_service_chain.rs
new file mode 100644
index 000000000..f45ced71f
--- /dev/null
+++ b/tests/ui/implied-bounds/sod_service_chain.rs
@@ -0,0 +1,37 @@
+// check-pass
+// Related to crater regressions on #118553
+
+pub trait Debug {}
+
+pub trait Service {
+ type Input;
+ type Output;
+ type Error;
+}
+
+pub struct ServiceChain<P, S> {
+ prev: P,
+ service: S,
+}
+impl<P: Service, S: Service<Input = P::Output>> Service for ServiceChain<P, S>
+where
+ P::Error: 'static,
+ S::Error: 'static,
+{
+ type Input = P::Input;
+ type Output = S::Output;
+ type Error = ();
+}
+
+pub struct ServiceChainBuilder<P: Service, S: Service<Input = P::Output>> {
+ chain: ServiceChain<P, S>,
+}
+impl<P: Service, S: Service<Input = P::Output>> ServiceChainBuilder<P, S> {
+ pub fn next<NS: Service<Input = S::Output>>(
+ self,
+ ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> {
+ panic!();
+ }
+}
+
+fn main() {}