diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-01-26 14:43:32 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-26 14:43:32 +0100 |
| commit | b4b483574f8597ab40d4e4be6adb10a3a91174ec (patch) | |
| tree | 930a676778f8291a4987665266c15bca9624bbd4 | |
| parent | 37b9022ceff4ee6d90ffcba513afe3324a964299 (diff) | |
| parent | 2aa746913bda5c52b3efeefb756e13c72618f793 (diff) | |
| download | rust-b4b483574f8597ab40d4e4be6adb10a3a91174ec.tar.gz rust-b4b483574f8597ab40d4e4be6adb10a3a91174ec.zip | |
Rollup merge of #120360 - compiler-errors:afit-sized-lol, r=lcnr
Don't fire `OPAQUE_HIDDEN_INFERRED_BOUND` on sized return of AFIT
Conceptually, we should probably not fire `OPAQUE_HIDDEN_INFERRED_BOUND` for methods like:
```
trait Foo { async fn bar() -> Self; }
```
Even though we technically cannot prove that `Self: Sized`, which is one of the item bounds of the `Output` type in the `-> impl Future<Output = Sized>` from the async desugaring.
This is somewhat justifiable along the same lines as how we allow regular methods to return `-> Self` even though `Self` isn't sized.
Fixes #113538
(side-note: some days i wonder if we should just remove the `OPAQUE_HIDDEN_INFERRED_BOUND` lint... it does make me sad that we have non-well-formed types in signatures, though.)
| -rw-r--r-- | compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs | 13 | ||||
| -rw-r--r-- | tests/ui/async-await/in-trait/returning-possibly-unsized-self.rs | 18 |
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() {} |
