Rollup merge of #117396 - oli-obk:privacy_visitor_types, r=compiler-errors
Don't treat closures/coroutine types as part of the public API Fixes a regression from https://github.com/rust-lang/rust/pull/117076 r? `@compiler-errors`
This commit is contained in:
commit
e648f479d8
3 changed files with 56 additions and 28 deletions
|
@ -121,6 +121,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> super::sig_types::SpannedTypeVisitor<'tcx> for 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<!> {
|
fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> ControlFlow<!> {
|
||||||
self.visit_spanned(span, value);
|
self.visit_spanned(span, value);
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
use rustc_hir::{def::DefKind, def_id::LocalDefId};
|
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_span::Span;
|
||||||
use rustc_type_ir::visit::TypeVisitable;
|
use rustc_type_ir::visit::TypeVisitable;
|
||||||
|
|
||||||
|
@ -25,24 +25,9 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
|
||||||
let kind = tcx.def_kind(item);
|
let kind = tcx.def_kind(item);
|
||||||
trace!(?kind);
|
trace!(?kind);
|
||||||
match kind {
|
match kind {
|
||||||
DefKind::Coroutine => {
|
// Walk over the signature of the function
|
||||||
match tcx.type_of(item).instantiate_identity().kind() {
|
DefKind::AssocFn | DefKind::Fn => {
|
||||||
ty::Coroutine(_, args, _) => visitor.visit(tcx.def_span(item), args.as_coroutine().sig())?,
|
let ty_sig = tcx.fn_sig(item).instantiate_identity();
|
||||||
_ => 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(),
|
|
||||||
};
|
|
||||||
let hir_sig = tcx.hir().get_by_def_id(item).fn_decl().unwrap();
|
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.
|
// Walk over the inputs and outputs manually in order to get good spans for them.
|
||||||
visitor.visit(hir_sig.output.span(), ty_sig.output());
|
visitor.visit(hir_sig.output.span(), ty_sig.output());
|
||||||
|
@ -61,7 +46,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
|
||||||
Some(ty) => ty.span,
|
Some(ty) => ty.span,
|
||||||
_ => tcx.def_span(item),
|
_ => 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) {
|
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
|
||||||
visitor.visit(span, pred)?;
|
visitor.visit(span, pred)?;
|
||||||
}
|
}
|
||||||
|
@ -74,13 +59,15 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
|
||||||
// Look at field types
|
// Look at field types
|
||||||
DefKind::Struct | DefKind::Union | DefKind::Enum => {
|
DefKind::Struct | DefKind::Union | DefKind::Enum => {
|
||||||
let span = tcx.def_ident_span(item).unwrap();
|
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) {
|
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
|
||||||
visitor.visit(span, pred)?;
|
visitor.visit(span, pred)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Does not have a syntactical signature
|
// These are not part of a public API, they can only appear as hidden types, and there
|
||||||
DefKind::InlineConst => {}
|
// 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 } => {
|
DefKind::Impl { of_trait } => {
|
||||||
if of_trait {
|
if of_trait {
|
||||||
let span = tcx.hir().get_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span;
|
let span = tcx.hir().get_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span;
|
||||||
|
@ -92,15 +79,11 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
|
||||||
_ => tcx.def_span(item),
|
_ => 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)?;
|
|
||||||
}}
|
|
||||||
DefKind::Trait => {
|
|
||||||
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
|
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
|
||||||
visitor.visit(span, pred)?;
|
visitor.visit(span, pred)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefKind::TraitAlias => {
|
DefKind::TraitAlias | DefKind::Trait => {
|
||||||
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
|
for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
|
||||||
visitor.visit(span, pred)?;
|
visitor.visit(span, pred)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {}
|
Loading…
Add table
Add a link
Reference in a new issue