Skip to content

Commit 9bae00d

Browse files
Begin to abstract rustc_type_ir for rust-analyzer
1 parent cc705b8 commit 9bae00d

File tree

15 files changed

+199
-76
lines changed

15 files changed

+199
-76
lines changed

Cargo.lock

+11
Original file line numberDiff line numberDiff line change
@@ -3967,11 +3967,22 @@ name = "rustc_index"
39673967
version = "0.0.0"
39683968
dependencies = [
39693969
"arrayvec",
3970+
"rustc_index_macros",
39703971
"rustc_macros",
39713972
"rustc_serialize",
39723973
"smallvec",
39733974
]
39743975

3976+
[[package]]
3977+
name = "rustc_index_macros"
3978+
version = "0.0.0"
3979+
dependencies = [
3980+
"proc-macro2",
3981+
"quote",
3982+
"syn 2.0.29",
3983+
"synstructure 0.13.0",
3984+
]
3985+
39753986
[[package]]
39763987
name = "rustc_infer"
39773988
version = "0.0.0"

compiler/rustc_index/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ edition = "2021"
88
[dependencies]
99
arrayvec = { version = "0.7", default-features = false }
1010
rustc_serialize = { path = "../rustc_serialize", optional = true }
11+
rustc_index_macros = { path = "../rustc_index_macros" }
1112
rustc_macros = { path = "../rustc_macros", optional = true }
1213
smallvec = "1.8.1"
1314

1415
[features]
1516
default = ["nightly"]
16-
nightly = ["rustc_serialize", "rustc_macros"]
17+
nightly = ["rustc_serialize", "rustc_macros", "rustc_index_macros/nightly"]

compiler/rustc_index/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ mod vec;
2525

2626
pub use {idx::Idx, slice::IndexSlice, vec::IndexVec};
2727

28-
#[cfg(feature = "rustc_macros")]
29-
pub use rustc_macros::newtype_index;
28+
pub use rustc_index_macros::newtype_index;
3029

3130
/// Type size assertion. The first argument is a type and the second argument is its expected size.
3231
///
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "rustc_index_macros"
3+
version = "0.0.0"
4+
edition = "2021"
5+
6+
[lib]
7+
proc-macro = true
8+
9+
[dependencies]
10+
synstructure = "0.13.0"
11+
syn = { version = "2.0.9", features = ["full"] }
12+
proc-macro2 = "1"
13+
quote = "1"
14+
15+
[features]
16+
default = ["nightly"]
17+
nightly = []
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#![cfg_attr(feature = "nightly", feature(allow_internal_unstable))]
2+
#![cfg_attr(feature = "nightly", allow(internal_features))]
3+
4+
use proc_macro::TokenStream;
5+
6+
mod newtype;
7+
8+
/// Creates a struct type `S` that can be used as an index with
9+
/// `IndexVec` and so on.
10+
///
11+
/// There are two ways of interacting with these indices:
12+
///
13+
/// - The `From` impls are the preferred way. So you can do
14+
/// `S::from(v)` with a `usize` or `u32`. And you can convert back
15+
/// to an integer with `u32::from(s)`.
16+
///
17+
/// - Alternatively, you can use the methods `S::new(v)` and `s.index()`
18+
/// to create/return a value.
19+
///
20+
/// Internally, the index uses a u32, so the index must not exceed
21+
/// `u32::MAX`. You can also customize things like the `Debug` impl,
22+
/// what traits are derived, and so forth via the macro.
23+
#[proc_macro]
24+
#[cfg_attr(
25+
feature = "nightly",
26+
allow_internal_unstable(step_trait, rustc_attrs, trusted_step, spec_option_partial_eq)
27+
)]
28+
pub fn newtype_index(input: TokenStream) -> TokenStream {
29+
newtype::newtype(input)
30+
}

compiler/rustc_macros/src/newtype.rs renamed to compiler/rustc_index_macros/src/newtype.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,16 @@ impl Parse for Newtype {
2424
let mut consts = Vec::new();
2525
let mut encodable = true;
2626
let mut ord = true;
27+
let mut gate_rustc_only = quote! {};
28+
let mut gate_rustc_only_cfg = quote! { all() };
2729

2830
attrs.retain(|attr| match attr.path().get_ident() {
2931
Some(ident) => match &*ident.to_string() {
32+
"gate_rustc_only" => {
33+
gate_rustc_only = quote! { #[cfg(feature = "nightly")] };
34+
gate_rustc_only_cfg = quote! { feature = "nightly" };
35+
false
36+
}
3037
"custom_encodable" => {
3138
encodable = false;
3239
false
@@ -88,11 +95,13 @@ impl Parse for Newtype {
8895

8996
let encodable_impls = if encodable {
9097
quote! {
98+
#gate_rustc_only
9199
impl<D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<D> for #name {
92100
fn decode(d: &mut D) -> Self {
93101
Self::from_u32(d.read_u32())
94102
}
95103
}
104+
#gate_rustc_only
96105
impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> for #name {
97106
fn encode(&self, e: &mut E) {
98107
e.emit_u32(self.private);
@@ -110,6 +119,7 @@ impl Parse for Newtype {
110119

111120
let step = if ord {
112121
quote! {
122+
#gate_rustc_only
113123
impl ::std::iter::Step for #name {
114124
#[inline]
115125
fn steps_between(start: &Self, end: &Self) -> Option<usize> {
@@ -131,6 +141,7 @@ impl Parse for Newtype {
131141
}
132142

133143
// Safety: The implementation of `Step` upholds all invariants.
144+
#gate_rustc_only
134145
unsafe impl ::std::iter::TrustedStep for #name {}
135146
}
136147
} else {
@@ -148,6 +159,7 @@ impl Parse for Newtype {
148159
let spec_partial_eq_impl = if let Lit::Int(max) = &max {
149160
if let Ok(max_val) = max.base10_parse::<u32>() {
150161
quote! {
162+
#gate_rustc_only
151163
impl core::option::SpecOptionPartialEq for #name {
152164
#[inline]
153165
fn eq(l: &Option<Self>, r: &Option<Self>) -> bool {
@@ -173,8 +185,8 @@ impl Parse for Newtype {
173185
Ok(Self(quote! {
174186
#(#attrs)*
175187
#[derive(Clone, Copy, PartialEq, Eq, Hash, #(#derive_paths),*)]
176-
#[rustc_layout_scalar_valid_range_end(#max)]
177-
#[rustc_pass_by_value]
188+
#[cfg_attr(#gate_rustc_only_cfg, rustc_layout_scalar_valid_range_end(#max))]
189+
#[cfg_attr(#gate_rustc_only_cfg, rustc_pass_by_value)]
178190
#vis struct #name {
179191
private: u32,
180192
}

compiler/rustc_macros/src/lib.rs

-22
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use proc_macro::TokenStream;
1717
mod diagnostics;
1818
mod hash_stable;
1919
mod lift;
20-
mod newtype;
2120
mod query;
2221
mod serialize;
2322
mod symbols;
@@ -34,27 +33,6 @@ pub fn symbols(input: TokenStream) -> TokenStream {
3433
symbols::symbols(input.into()).into()
3534
}
3635

37-
/// Creates a struct type `S` that can be used as an index with
38-
/// `IndexVec` and so on.
39-
///
40-
/// There are two ways of interacting with these indices:
41-
///
42-
/// - The `From` impls are the preferred way. So you can do
43-
/// `S::from(v)` with a `usize` or `u32`. And you can convert back
44-
/// to an integer with `u32::from(s)`.
45-
///
46-
/// - Alternatively, you can use the methods `S::new(v)` and `s.index()`
47-
/// to create/return a value.
48-
///
49-
/// Internally, the index uses a u32, so the index must not exceed
50-
/// `u32::MAX`. You can also customize things like the `Debug` impl,
51-
/// what traits are derived, and so forth via the macro.
52-
#[proc_macro]
53-
#[allow_internal_unstable(step_trait, rustc_attrs, trusted_step, spec_option_partial_eq)]
54-
pub fn newtype_index(input: TokenStream) -> TokenStream {
55-
newtype::newtype(input)
56-
}
57-
5836
decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
5937
decl_derive!(
6038
[HashStable_Generic, attributes(stable_hasher)] =>

compiler/rustc_mir_transform/src/gvn.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@
5656
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
5757
use rustc_data_structures::graph::dominators::Dominators;
5858
use rustc_index::bit_set::BitSet;
59+
use rustc_index::newtype_index;
5960
use rustc_index::IndexVec;
60-
use rustc_macros::newtype_index;
6161
use rustc_middle::mir::visit::*;
6262
use rustc_middle::mir::*;
6363
use rustc_middle::ty::{self, Ty, TyCtxt};

compiler/rustc_type_ir/Cargo.toml

+16-5
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,19 @@ edition = "2021"
77

88
[dependencies]
99
bitflags = "1.2.1"
10-
rustc_index = { path = "../rustc_index" }
11-
rustc_serialize = { path = "../rustc_serialize" }
12-
rustc_data_structures = { path = "../rustc_data_structures" }
13-
rustc_macros = { path = "../rustc_macros" }
14-
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
10+
rustc_index = { path = "../rustc_index", default-features = false }
11+
rustc_serialize = { path = "../rustc_serialize", optional = true }
12+
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
13+
rustc_macros = { path = "../rustc_macros", optional = true }
14+
smallvec = { version = "1.8.1" }
15+
16+
[features]
17+
default = ["nightly"]
18+
nightly = [
19+
"smallvec/may_dangle",
20+
"smallvec/union",
21+
"rustc_index/nightly",
22+
"rustc_serialize",
23+
"rustc_data_structures",
24+
"rustc_macros",
25+
]

compiler/rustc_type_ir/src/fold.rs

+21-9
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@
4646
//! ```
4747
use crate::{visit::TypeVisitable, Interner};
4848

49+
#[cfg(feature = "nightly")]
50+
type Never = !;
51+
52+
#[cfg(not(feature = "nightly"))]
53+
type Never = std::convert::Infallible;
54+
4955
/// This trait is implemented for every type that can be folded,
5056
/// providing the skeleton of the traversal.
5157
///
@@ -74,7 +80,10 @@ pub trait TypeFoldable<I: Interner>: TypeVisitable<I> {
7480
/// folders. Do not override this method, to ensure coherence with
7581
/// `try_fold_with`.
7682
fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
77-
self.try_fold_with(folder).into_ok()
83+
match self.try_fold_with(folder) {
84+
Ok(t) => t,
85+
Err(e) => match e {},
86+
}
7887
}
7988
}
8089

@@ -95,7 +104,10 @@ pub trait TypeSuperFoldable<I: Interner>: TypeFoldable<I> {
95104
/// infallible folders. Do not override this method, to ensure coherence
96105
/// with `try_super_fold_with`.
97106
fn super_fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
98-
self.try_super_fold_with(folder).into_ok()
107+
match self.try_super_fold_with(folder) {
108+
Ok(t) => t,
109+
Err(e) => match e {},
110+
}
99111
}
100112
}
101113

@@ -108,7 +120,7 @@ pub trait TypeSuperFoldable<I: Interner>: TypeFoldable<I> {
108120
/// A blanket implementation of [`FallibleTypeFolder`] will defer to
109121
/// the infallible methods of this trait to ensure that the two APIs
110122
/// are coherent.
111-
pub trait TypeFolder<I: Interner>: FallibleTypeFolder<I, Error = !> {
123+
pub trait TypeFolder<I: Interner>: FallibleTypeFolder<I, Error = Never> {
112124
fn interner(&self) -> I;
113125

114126
fn fold_binder<T>(&mut self, t: I::Binder<T>) -> I::Binder<T>
@@ -203,39 +215,39 @@ impl<I: Interner, F> FallibleTypeFolder<I> for F
203215
where
204216
F: TypeFolder<I>,
205217
{
206-
type Error = !;
218+
type Error = Never;
207219

208220
fn interner(&self) -> I {
209221
TypeFolder::interner(self)
210222
}
211223

212-
fn try_fold_binder<T>(&mut self, t: I::Binder<T>) -> Result<I::Binder<T>, !>
224+
fn try_fold_binder<T>(&mut self, t: I::Binder<T>) -> Result<I::Binder<T>, Never>
213225
where
214226
T: TypeFoldable<I>,
215227
I::Binder<T>: TypeSuperFoldable<I>,
216228
{
217229
Ok(self.fold_binder(t))
218230
}
219231

220-
fn try_fold_ty(&mut self, t: I::Ty) -> Result<I::Ty, !>
232+
fn try_fold_ty(&mut self, t: I::Ty) -> Result<I::Ty, Never>
221233
where
222234
I::Ty: TypeSuperFoldable<I>,
223235
{
224236
Ok(self.fold_ty(t))
225237
}
226238

227-
fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, !> {
239+
fn try_fold_region(&mut self, r: I::Region) -> Result<I::Region, Never> {
228240
Ok(self.fold_region(r))
229241
}
230242

231-
fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, !>
243+
fn try_fold_const(&mut self, c: I::Const) -> Result<I::Const, Never>
232244
where
233245
I::Const: TypeSuperFoldable<I>,
234246
{
235247
Ok(self.fold_const(c))
236248
}
237249

238-
fn try_fold_predicate(&mut self, p: I::Predicate) -> Result<I::Predicate, !>
250+
fn try_fold_predicate(&mut self, p: I::Predicate) -> Result<I::Predicate, Never>
239251
where
240252
I::Predicate: TypeSuperFoldable<I>,
241253
{

0 commit comments

Comments
 (0)