From 353683e4e9590d80e82902e5d538dff15e0f4663 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 30 Sep 2023 19:28:40 +0000 Subject: [PATCH] Only reachable traits --- compiler/rustc_lint/src/async_fn_in_trait.rs | 6 ++++++ tests/ui/async-await/in-trait/warn.rs | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_lint/src/async_fn_in_trait.rs b/compiler/rustc_lint/src/async_fn_in_trait.rs index 2ef9627eac54a..ba1a3b5eb16d5 100644 --- a/compiler/rustc_lint/src/async_fn_in_trait.rs +++ b/compiler/rustc_lint/src/async_fn_in_trait.rs @@ -92,10 +92,16 @@ impl<'tcx> LateLintPass<'tcx> for AsyncFnInTrait { if let hir::TraitItemKind::Fn(sig, body) = item.kind && let hir::IsAsync::Async(async_span) = sig.header.asyncness { + // RTN can be used to bound `async fn` in traits in a better way than "always" if cx.tcx.features().return_type_notation { return; } + // Only need to think about library implications of reachable traits + if !cx.tcx.effective_visibilities(()).is_reachable(item.owner_id.def_id) { + return; + } + let hir::FnRetTy::Return(hir::Ty { kind: hir::TyKind::OpaqueDef(def, ..), .. }) = sig.decl.output else { diff --git a/tests/ui/async-await/in-trait/warn.rs b/tests/ui/async-await/in-trait/warn.rs index defbdcffccd7f..4f981c31f5c06 100644 --- a/tests/ui/async-await/in-trait/warn.rs +++ b/tests/ui/async-await/in-trait/warn.rs @@ -3,9 +3,21 @@ #![feature(async_fn_in_trait)] #![deny(async_fn_in_trait)] -trait Foo { +pub trait Foo { async fn not_send(); - //~^ ERROR + //~^ ERROR use of `async fn` in public traits is discouraged +} + +mod private { + pub trait FooUnreachable { + async fn not_send(); + // No warning + } +} + +pub(crate) trait FooCrate { + async fn not_send(); + // No warning } fn main() {}