Skip to content

Commit 7e6dacf

Browse files
Rollup merge of rust-lang#155034 - ChayimFriedman2:ra-fixes, r=lcnr
Implement `GenericTypeVisitable` for some types This is required for rust-analyzer. r? types
2 parents 8b5d547 + 6cd5315 commit 7e6dacf

3 files changed

Lines changed: 20 additions & 55 deletions

File tree

compiler/rustc_type_ir/src/binder.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ pub enum BoundVarIndexKind {
956956
/// identified by both a universe, as well as a name residing within that universe. Distinct bound
957957
/// regions/types/consts within the same universe simply have an unknown relationship to one
958958
#[derive_where(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash; I: Interner, T)]
959-
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
959+
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, GenericTypeVisitable)]
960960
#[cfg_attr(
961961
feature = "nightly",
962962
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
@@ -995,7 +995,7 @@ where
995995
}
996996

997997
#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
998-
#[derive(Lift_Generic)]
998+
#[derive(Lift_Generic, GenericTypeVisitable)]
999999
#[cfg_attr(
10001000
feature = "nightly",
10011001
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
@@ -1058,7 +1058,7 @@ impl<I: Interner> BoundRegionKind<I> {
10581058
}
10591059

10601060
#[derive_where(Clone, Copy, PartialEq, Eq, Debug, Hash; I: Interner)]
1061-
#[derive(Lift_Generic)]
1061+
#[derive(Lift_Generic, GenericTypeVisitable)]
10621062
#[cfg_attr(
10631063
feature = "nightly",
10641064
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
@@ -1069,7 +1069,7 @@ pub enum BoundTyKind<I: Interner> {
10691069
}
10701070

10711071
#[derive_where(Clone, Copy, PartialEq, Eq, Debug, Hash; I: Interner)]
1072-
#[derive(Lift_Generic)]
1072+
#[derive(Lift_Generic, GenericTypeVisitable)]
10731073
#[cfg_attr(
10741074
feature = "nightly",
10751075
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
@@ -1104,6 +1104,7 @@ impl<I: Interner> BoundVariableKind<I> {
11041104
}
11051105

11061106
#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
1107+
#[derive(GenericTypeVisitable)]
11071108
#[cfg_attr(
11081109
feature = "nightly",
11091110
derive(Encodable_NoContext, HashStable_NoContext, Decodable_NoContext)
@@ -1164,6 +1165,7 @@ impl<I: Interner> PlaceholderRegion<I> {
11641165
}
11651166

11661167
#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
1168+
#[derive(GenericTypeVisitable)]
11671169
#[cfg_attr(
11681170
feature = "nightly",
11691171
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)
@@ -1229,6 +1231,7 @@ impl<I: Interner> PlaceholderType<I> {
12291231
}
12301232

12311233
#[derive_where(Clone, Copy, PartialEq, Debug, Eq, Hash; I: Interner)]
1234+
#[derive(GenericTypeVisitable)]
12321235
#[cfg_attr(
12331236
feature = "nightly",
12341237
derive(Encodable_NoContext, Decodable_NoContext, HashStable_NoContext)

compiler/rustc_type_ir/src/const_kind.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ impl<Hcx> HashStable<Hcx> for InferConst {
141141
/// `ValTree` does not have this problem with representation, as it only contains integers or
142142
/// lists of (nested) `ty::Const`s (which may indirectly contain more `ValTree`s).
143143
#[derive_where(Clone, Copy, Debug, Hash, Eq, PartialEq; I: Interner)]
144-
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
144+
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, GenericTypeVisitable)]
145145
#[cfg_attr(
146146
feature = "nightly",
147147
derive(Decodable_NoContext, Encodable_NoContext, HashStable_NoContext)

compiler/rustc_type_ir/src/generic_visit.rs

Lines changed: 12 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,13 @@
1-
//! A visiting traversal mechanism for complex data structures that contain type
2-
//! information.
1+
//! Special visiting used by rust-analyzer only.
32
//!
4-
//! This is a read-only traversal of the data structure.
3+
//! It is different from `TypeVisitable` in two ways:
54
//!
6-
//! This traversal has limited flexibility. Only a small number of "types of
7-
//! interest" within the complex data structures can receive custom
8-
//! visitation. These are the ones containing the most important type-related
9-
//! information, such as `Ty`, `Predicate`, `Region`, and `Const`.
10-
//!
11-
//! There are three traits involved in each traversal.
12-
//! - `GenericTypeVisitable`. This is implemented once for many types, including:
13-
//! - Types of interest, for which the methods delegate to the visitor.
14-
//! - All other types, including generic containers like `Vec` and `Option`.
15-
//! It defines a "skeleton" of how they should be visited.
16-
//! - `TypeSuperVisitable`. This is implemented only for recursive types of
17-
//! interest, and defines the visiting "skeleton" for these types. (This
18-
//! excludes `Region` because it is non-recursive, i.e. it never contains
19-
//! other types of interest.)
20-
//! - `CustomizableTypeVisitor`. This is implemented for each visitor. This defines how
21-
//! types of interest are visited.
22-
//!
23-
//! This means each visit is a mixture of (a) generic visiting operations, and (b)
24-
//! custom visit operations that are specific to the visitor.
25-
//! - The `GenericTypeVisitable` impls handle most of the traversal, and call into
26-
//! `CustomizableTypeVisitor` when they encounter a type of interest.
27-
//! - A `CustomizableTypeVisitor` may call into another `GenericTypeVisitable` impl, because some of
28-
//! the types of interest are recursive and can contain other types of interest.
29-
//! - A `CustomizableTypeVisitor` may also call into a `TypeSuperVisitable` impl, because each
30-
//! visitor might provide custom handling only for some types of interest, or
31-
//! only for some variants of each type of interest, and then use default
32-
//! traversal for the remaining cases.
33-
//!
34-
//! For example, if you have `struct S(Ty, U)` where `S: GenericTypeVisitable` and `U:
35-
//! GenericTypeVisitable`, and an instance `s = S(ty, u)`, it would be visited like so:
36-
//! ```text
37-
//! s.generic_visit_with(visitor) calls
38-
//! - ty.generic_visit_with(visitor) calls
39-
//! - visitor.visit_ty(ty) may call
40-
//! - ty.super_generic_visit_with(visitor)
41-
//! - u.generic_visit_with(visitor)
42-
//! ```
5+
//! - The visitor is a generic of the trait and not the method, allowing types to attach
6+
//! special behavior to visitors (as long as they know it; we don't use this capability
7+
//! in rustc crates, but rust-analyzer needs it).
8+
//! - It **must visit** every field. This is why we don't have an attribute like `#[type_visitable(ignore)]`
9+
//! for this visit. The reason for this is soundness: rust-analyzer uses this visit to
10+
//! garbage collect types, so a missing field can mean a use after free
4311
4412
use std::sync::Arc;
4513

@@ -53,16 +21,6 @@ use thin_vec::ThinVec;
5321
/// To implement this conveniently, use the derive macro located in
5422
/// `rustc_macros`.
5523
pub trait GenericTypeVisitable<V> {
56-
/// The entry point for visiting. To visit a value `t` with a visitor `v`
57-
/// call: `t.generic_visit_with(v)`.
58-
///
59-
/// For most types, this just traverses the value, calling `generic_visit_with` on
60-
/// each field/element.
61-
///
62-
/// For types of interest (such as `Ty`), the implementation of this method
63-
/// that calls a visitor method specifically for that type (such as
64-
/// `V::visit_ty`). This is where control transfers from `GenericTypeVisitable` to
65-
/// `CustomizableTypeVisitor`.
6624
fn generic_visit_with(&self, visitor: &mut V);
6725
}
6826

@@ -216,6 +174,10 @@ macro_rules! trivial_impls {
216174
};
217175
}
218176

177+
impl<T: ?Sized, V> GenericTypeVisitable<V> for std::marker::PhantomData<T> {
178+
fn generic_visit_with(&self, _visitor: &mut V) {}
179+
}
180+
219181
trivial_impls!(
220182
(),
221183
rustc_ast_ir::Mutability,

0 commit comments

Comments
 (0)