From 972ee01b69378280b4911caaae0bd95ea8d790c3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 30 Oct 2023 13:38:54 +0000 Subject: [PATCH 1/4] Add regression test --- .../nested_impl_trait_in_assoc_ty.rs | 37 +++++++++++++++++++ .../nested_impl_trait_in_assoc_ty.stderr | 15 ++++++++ 2 files changed, 52 insertions(+) create mode 100644 tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs create mode 100644 tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.stderr diff --git a/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs b/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs new file mode 100644 index 0000000000000..859a6807c2caa --- /dev/null +++ b/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs @@ -0,0 +1,37 @@ +// edition: 2021 + +#![feature(impl_trait_in_assoc_type)] + +use std::future::Future; + +pub struct MemtableLocalStateStore { + mem_table: MemTable, +} + +impl LocalStateStore for MemtableLocalStateStore { + type IterStream<'a> = impl Sized + 'a where Self: 'a; + + fn iter(&self) -> impl Future> + '_ { + async move { merge_stream(self.mem_table.iter()) } + } +} + +trait LocalStateStore { + type IterStream<'a> + where + Self: 'a; + + fn iter(&self) -> impl Future> + '_; +} + +struct MemTable; + +impl MemTable { + fn iter<'a>(&'a self) -> impl Iterator { + std::iter::empty() + } +} + +pub(crate) async fn merge_stream<'a>(mem_table_iter: impl Iterator) {} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.stderr b/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.stderr new file mode 100644 index 0000000000000..30b3deca1e420 --- /dev/null +++ b/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.stderr @@ -0,0 +1,15 @@ +error[E0792]: non-defining opaque type use in defining scope + --> $DIR/nested_impl_trait_in_assoc_ty.rs:15:9 + | +LL | async move { merge_stream(self.mem_table.iter()) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument `'_` is not a generic parameter + | +note: for this opaque type + --> $DIR/nested_impl_trait_in_assoc_ty.rs:35:1 + | +LL | pub(crate) async fn merge_stream<'a>(mem_table_iter: impl Iterator) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0792`. From 8d03e1394f90c43c25c00bcb6ba2dd621215cac4 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 30 Oct 2023 13:46:44 +0000 Subject: [PATCH 2/4] Don't treat closures/coroutines as part of the public API --- compiler/rustc_ty_utils/src/opaque_types.rs | 1 + compiler/rustc_ty_utils/src/sig_types.rs | 29 +++++-------------- .../nested_impl_trait_in_assoc_ty.rs | 7 +++++ .../nested_impl_trait_in_assoc_ty.stderr | 15 ---------- 4 files changed, 16 insertions(+), 36 deletions(-) delete mode 100644 tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.stderr diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index f7d54566cb704..9242a1a751bc7 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -121,6 +121,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> { } impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for OpaqueTypeCollector<'tcx> { + #[instrument(skip(self), ret, level = "trace")] fn visit(&mut self, span: Span, value: impl TypeVisitable>) -> ControlFlow { self.visit_spanned(span, value); ControlFlow::Continue(()) diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 1ab39974e0f2a..5d4aee318c61f 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -4,7 +4,7 @@ use std::ops::ControlFlow; use rustc_hir::{def::DefKind, def_id::LocalDefId}; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::TyCtxt; use rustc_span::Span; use rustc_type_ir::visit::TypeVisitable; @@ -25,24 +25,9 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( let kind = tcx.def_kind(item); trace!(?kind); match kind { - DefKind::Coroutine => { - match tcx.type_of(item).instantiate_identity().kind() { - ty::Coroutine(_, args, _) => visitor.visit(tcx.def_span(item), args.as_coroutine().sig())?, - _ => bug!(), - } - for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { - visitor.visit(span, pred)?; - } - } - // Walk over the signature of the function-like - DefKind::Closure | DefKind::AssocFn | DefKind::Fn => { - let ty_sig = match kind { - DefKind::Closure => match tcx.type_of(item).instantiate_identity().kind() { - ty::Closure(_, args) => args.as_closure().sig(), - _ => bug!(), - }, - _ => tcx.fn_sig(item).instantiate_identity(), - }; + // Walk over the signature of the function + DefKind::AssocFn | DefKind::Fn => { + let ty_sig = tcx.fn_sig(item).instantiate_identity(); let hir_sig = tcx.hir().get_by_def_id(item).fn_decl().unwrap(); // Walk over the inputs and outputs manually in order to get good spans for them. visitor.visit(hir_sig.output.span(), ty_sig.output()); @@ -79,8 +64,10 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( visitor.visit(span, pred)?; } } - // Does not have a syntactical signature - DefKind::InlineConst => {} + // These are not part of a public API, they can only appear as hidden types, and there + // the interesting parts are solely in the signature of the containing item's opaque type + // or dyn type. + DefKind::InlineConst | DefKind::Closure | DefKind::Coroutine => {} DefKind::Impl { of_trait } => { if of_trait { let span = tcx.hir().get_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span; diff --git a/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs b/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs index 859a6807c2caa..5f3dbaa179891 100644 --- a/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs +++ b/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs @@ -1,4 +1,11 @@ +//! This test checks that we do not walk types in async blocks for +//! determining the opaque types that appear in a signature. async blocks, +//! all other coroutines and closures are always private and not part of +//! a signature. They become part of a signature via `dyn Trait` or `impl Trait`, +//! which is something that we process abstractly without looking at its hidden +//! types. // edition: 2021 +// check-pass #![feature(impl_trait_in_assoc_type)] diff --git a/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.stderr b/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.stderr deleted file mode 100644 index 30b3deca1e420..0000000000000 --- a/tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0792]: non-defining opaque type use in defining scope - --> $DIR/nested_impl_trait_in_assoc_ty.rs:15:9 - | -LL | async move { merge_stream(self.mem_table.iter()) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument `'_` is not a generic parameter - | -note: for this opaque type - --> $DIR/nested_impl_trait_in_assoc_ty.rs:35:1 - | -LL | pub(crate) async fn merge_stream<'a>(mem_table_iter: impl Iterator) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0792`. From 251021c1ab095e6448cfe060e1d43a4bab2711f5 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 30 Oct 2023 13:47:08 +0000 Subject: [PATCH 3/4] Merge two equal match arms --- compiler/rustc_ty_utils/src/sig_types.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 5d4aee318c61f..741ee8f0b0017 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -82,12 +82,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { visitor.visit(span, pred)?; }} - DefKind::Trait => { - for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { - visitor.visit(span, pred)?; - } - } - DefKind::TraitAlias => { + DefKind::TraitAlias | DefKind::Trait => { for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { visitor.visit(span, pred)?; } From 43ff2a7e5095a9d79a3c4acde1208df6aa7bf296 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 30 Oct 2023 13:48:34 +0000 Subject: [PATCH 4/4] Some manual rustfmt as rustfmt is broken on this file --- compiler/rustc_ty_utils/src/sig_types.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index 741ee8f0b0017..ccdc6120196ac 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -46,7 +46,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( Some(ty) => ty.span, _ => tcx.def_span(item), }; - visitor.visit(span, tcx.type_of(item).instantiate_identity()); + visitor.visit(span, tcx.type_of(item).instantiate_identity()); for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { visitor.visit(span, pred)?; } @@ -59,7 +59,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( // Look at field types DefKind::Struct | DefKind::Union | DefKind::Enum => { let span = tcx.def_ident_span(item).unwrap(); - visitor.visit(span, tcx.type_of(item).instantiate_identity()); + visitor.visit(span, tcx.type_of(item).instantiate_identity()); for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { visitor.visit(span, pred)?; } @@ -81,7 +81,8 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( visitor.visit(span, tcx.type_of(item).instantiate_identity()); for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { visitor.visit(span, pred)?; - }} + } + } DefKind::TraitAlias | DefKind::Trait => { for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) { visitor.visit(span, pred)?;