Skip to content

Commit

Permalink
Rollup merge of rust-lang#117396 - oli-obk:privacy_visitor_types, r=c…
Browse files Browse the repository at this point in the history
…ompiler-errors

Don't treat closures/coroutine types as part of the public API

Fixes a regression from rust-lang#117076

r? `@compiler-errors`
  • Loading branch information
matthiaskrgr authored Oct 30, 2023
2 parents 7730b41 + 43ff2a7 commit 3f4edea
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 28 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_ty_utils/src/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<TyCtxt<'tcx>>) -> ControlFlow<!> {
self.visit_spanned(span, value);
ControlFlow::Continue(())
Expand Down
39 changes: 11 additions & 28 deletions compiler/rustc_ty_utils/src/sig_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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());
Expand All @@ -61,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)?;
}
Expand All @@ -74,13 +59,15 @@ 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)?;
}
}
// 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;
Expand All @@ -92,15 +79,11 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
_ => tcx.def_span(item),
};
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::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)?;
}
Expand Down
44 changes: 44 additions & 0 deletions tests/ui/type-alias-impl-trait/nested_impl_trait_in_assoc_ty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//! 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)]

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<Output = Self::IterStream<'_>> + '_ {
async move { merge_stream(self.mem_table.iter()) }
}
}

trait LocalStateStore {
type IterStream<'a>
where
Self: 'a;

fn iter(&self) -> impl Future<Output = Self::IterStream<'_>> + '_;
}

struct MemTable;

impl MemTable {
fn iter<'a>(&'a self) -> impl Iterator<Item = &'a ()> {
std::iter::empty()
}
}

pub(crate) async fn merge_stream<'a>(mem_table_iter: impl Iterator<Item = &'a ()>) {}

fn main() {}

0 comments on commit 3f4edea

Please sign in to comment.