about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs13
-rw-r--r--tests/ui/async-await/in-trait/returning-possibly-unsized-self.rs18
2 files changed, 30 insertions, 1 deletions
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index f64509fe8bc..bed5d3c80c0 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -4,7 +4,7 @@ use rustc_macros::{LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::{
     self, fold::BottomUpFolder, print::TraitPredPrintModifiersAndPath, Ty, TypeFoldable,
 };
-use rustc_span::Span;
+use rustc_span::{symbol::kw, Span};
 use rustc_trait_selection::traits;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 
@@ -96,6 +96,17 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
                 continue;
             }
 
+            // HACK: `async fn() -> Self` in traits is "ok"...
+            // This is not really that great, but it's similar to why the `-> Self`
+            // return type is well-formed in traits even when `Self` isn't sized.
+            if let ty::Param(param_ty) = *proj_term.kind()
+                && param_ty.name == kw::SelfUpper
+                && matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(_))
+                && opaque.in_trait
+            {
+                continue;
+            }
+
             let proj_ty =
                 Ty::new_projection(cx.tcx, proj.projection_ty.def_id, proj.projection_ty.args);
             // For every instance of the projection type in the bounds,
diff --git a/tests/ui/async-await/in-trait/returning-possibly-unsized-self.rs b/tests/ui/async-await/in-trait/returning-possibly-unsized-self.rs
new file mode 100644
index 00000000000..72f02679d77
--- /dev/null
+++ b/tests/ui/async-await/in-trait/returning-possibly-unsized-self.rs
@@ -0,0 +1,18 @@
+// check-pass
+// edition:2021
+
+#![deny(opaque_hidden_inferred_bound)]
+
+trait Repository /* : ?Sized */ {
+    async fn new() -> Self;
+}
+
+struct MyRepository {}
+
+impl Repository for MyRepository {
+    async fn new() -> Self {
+        todo!()
+    }
+}
+
+fn main() {}