diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index 71c07f31bc952..5e0961b30657f 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -254,6 +254,10 @@ where
             .handle_opaque_type(a, b, true, &cause, self.delegate.param_env())?
             .obligations;
         self.delegate.register_obligations(obligations);
+        self.register_predicates([
+            ty::ClauseKind::WellFormed(a.into()),
+            ty::ClauseKind::WellFormed(b.into()),
+        ]);
         trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated");
         Ok(a)
     }
@@ -687,6 +691,10 @@ where
     }
 
     fn register_type_relate_obligation(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) {
+        self.register_predicates([
+            ty::ClauseKind::WellFormed(a.into()),
+            ty::ClauseKind::WellFormed(b.into()),
+        ]);
         self.register_predicates([ty::Binder::dummy(match self.ambient_variance {
             ty::Variance::Covariant => ty::PredicateKind::AliasRelate(
                 a.into(),
diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs
index 73362d823065a..93dc422491b06 100644
--- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs
+++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs
@@ -134,6 +134,11 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                     Invert::Yes => (other, fresh),
                 };
                 self.sub(param_env, sub, sup)?;
+                self.add_goal(Goal::new(
+                    self.tcx(),
+                    param_env,
+                    ty::ClauseKind::WellFormed(fresh.into()),
+                ));
                 fresh
             }
         };
diff --git a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs
index addbe5d658aee..6c354d89ec89e 100644
--- a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs
+++ b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs
@@ -18,6 +18,7 @@ where
 {
     async move { c.connect().await }
     //~^ ERROR `C` does not live long enough
+    //~| ERROR `C` may not live long enough
 }
 
 fn main() {}
diff --git a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr
index 53abe3dc9521d..8d4d04b72b102 100644
--- a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr
+++ b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr
@@ -19,6 +19,18 @@ error: `C` does not live long enough
 LL |     async move { c.connect().await }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error[E0310]: the parameter type `C` may not live long enough
+  --> $DIR/erase-error-in-mir-drop-tracking.rs:19:5
+   |
+LL |     async move { c.connect().await }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound...
+   |
+LL |     C: Client + Send + Sync + 'static,
+   |                             +++++++++
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0261`.
+Some errors have detailed explanations: E0261, E0310.
+For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/impl-trait/wf-check-hidden-type.rs b/tests/ui/impl-trait/wf-check-hidden-type.rs
new file mode 100644
index 0000000000000..d82f30cc4666e
--- /dev/null
+++ b/tests/ui/impl-trait/wf-check-hidden-type.rs
@@ -0,0 +1,21 @@
+//! Regression test for #114728.
+
+trait Extend<'a, 'b> {
+    fn extend(self, _: &'a str) -> &'b str;
+}
+
+impl<'a, 'b> Extend<'a, 'b> for Option<&'b &'a ()> {
+    fn extend(self, s: &'a str) -> &'b str {
+        s
+    }
+}
+
+fn boom<'a, 'b>() -> impl Extend<'a, 'b> {
+    None::<&'_ &'_ ()>
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {
+    let y = boom().extend(&String::from("temporary"));
+    println!("{}", y);
+}
diff --git a/tests/ui/impl-trait/wf-check-hidden-type.stderr b/tests/ui/impl-trait/wf-check-hidden-type.stderr
new file mode 100644
index 0000000000000..eb5b4fab8b5e1
--- /dev/null
+++ b/tests/ui/impl-trait/wf-check-hidden-type.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+  --> $DIR/wf-check-hidden-type.rs:14:5
+   |
+LL | fn boom<'a, 'b>() -> impl Extend<'a, 'b> {
+   |         --  -- lifetime `'b` defined here
+   |         |
+   |         lifetime `'a` defined here
+LL |     None::<&'_ &'_ ()>
+   |     ^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
index 4aefdd6bb0735..8becb26870799 100644
--- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
+++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely
-  --> $DIR/auto-with-drop_tracking_mir.rs:25:13
+  --> $DIR/auto-with-drop_tracking_mir.rs:28:13
    |
 LL |     is_send(foo());
    |     ------- ^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely
@@ -8,7 +8,7 @@ LL |     is_send(foo());
    |
    = help: the trait `Send` is not implemented for `impl Future<Output = ()>`
 note: required by a bound in `is_send`
-  --> $DIR/auto-with-drop_tracking_mir.rs:24:24
+  --> $DIR/auto-with-drop_tracking_mir.rs:27:24
    |
 LL |     fn is_send(_: impl Send) {}
    |                        ^^^^ required by this bound in `is_send`
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
index e311a4af2f4ea..ecfa18a2577b9 100644
--- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
+++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
@@ -1,7 +1,8 @@
 // compile-flags: -Ztrait-solver=next -Zdrop-tracking-mir
 // edition: 2021
 // revisions: pass fail
-//[pass] check-pass
+//[pass] check-fail
+// WARN new-solver BUG.
 
 #![feature(negative_impls)]
 
@@ -9,6 +10,7 @@ struct NotSync;
 impl !Sync for NotSync {}
 
 async fn foo() {
+//[pass]~^ ERROR type mismatch
     #[cfg(pass)]
     let x = &();
     #[cfg(fail)]
@@ -19,6 +21,7 @@ async fn foo() {
 }
 
 async fn bar() {}
+//[pass]~^ ERROR type mismatch
 
 fn main() {
     fn is_send(_: impl Send) {}
diff --git a/tests/ui/type-alias-impl-trait/wf-check-definition-site.rs b/tests/ui/type-alias-impl-trait/wf-check-definition-site.rs
new file mode 100644
index 0000000000000..a67fb4f2c3d16
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/wf-check-definition-site.rs
@@ -0,0 +1,31 @@
+//! Regression test for #114572.
+//! We were inferring an ill-formed type:
+//! `Opaque<'a> = Static<&'a str>`, vs
+//! `Opaque<'a> = Static<&'static str>`.
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+
+struct Static<T: 'static>(T);
+
+type OpaqueRet<'a> = impl Sized + 'a;
+fn test_return<'a>(msg: Static<&'static u8>) -> OpaqueRet<'a> {
+    msg
+}
+
+type OpaqueAssign<'a> = impl Sized + 'a;
+fn test_assign<'a>(msg: Static<&'static u8>) -> Option<OpaqueAssign<'a>> {
+    let _: OpaqueAssign<'a> = msg;
+    None
+}
+
+// `OpaqueRef<'a, T> = Ref<'a, T>`, vs
+// `OpaqueRef<'a, T> = Ref<'static, T>`.
+trait RefAt<'a>: 'a {}
+struct Ref<'a, T: RefAt<'a>>(&'a T);
+type OpaqueRef<'a, T: RefAt<'static>> = impl Sized + 'a;
+fn test_trait<'a, T: RefAt<'static>>(msg: Ref<'static, T>) -> OpaqueRef<'a, T> {
+    msg
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr b/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr
index 753a46e882eda..4c398262359e5 100644
--- a/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr
+++ b/tests/ui/type-alias-impl-trait/wf-nested.fail.stderr
@@ -1,5 +1,5 @@
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/wf-nested.rs:55:27
+  --> $DIR/wf-nested.rs:57:27
    |
 LL |     type InnerOpaque<T> = impl Sized;
    |                           ^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
diff --git a/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr b/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr
index 9ab6685a7f73f..fed11fc8a8640 100644
--- a/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr
+++ b/tests/ui/type-alias-impl-trait/wf-nested.pass_sound.stderr
@@ -1,5 +1,5 @@
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/wf-nested.rs:46:17
+  --> $DIR/wf-nested.rs:48:17
    |
 LL |         let _ = outer.get();
    |                 ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
diff --git a/tests/ui/type-alias-impl-trait/wf-nested.rs b/tests/ui/type-alias-impl-trait/wf-nested.rs
index de38832948918..f51ee3cfc319a 100644
--- a/tests/ui/type-alias-impl-trait/wf-nested.rs
+++ b/tests/ui/type-alias-impl-trait/wf-nested.rs
@@ -32,6 +32,8 @@ mod pass {
     use super::*;
     type OuterOpaque<T> = impl Trait<&'static T, Out = impl Sized>;
     fn define<T>() -> OuterOpaque<T> {}
+
+    fn define_rpit<T>() -> impl Trait<&'static T, Out = impl Sized> {}
 }
 
 // Test the soundness of `pass` - We should require `T: 'static` at the use site.