Skip to content

Begin to abstract rustc_type_ir for rust-analyzer #116828

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 20, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
@@ -4041,11 +4041,22 @@ name = "rustc_index"
version = "0.0.0"
dependencies = [
"arrayvec",
"rustc_index_macros",
"rustc_macros",
"rustc_serialize",
"smallvec",
]

[[package]]
name = "rustc_index_macros"
version = "0.0.0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.29",
"synstructure",
]

[[package]]
name = "rustc_infer"
version = "0.0.0"
3 changes: 2 additions & 1 deletion compiler/rustc_index/Cargo.toml
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@ edition = "2021"
[dependencies]
# tidy-alphabetical-start
arrayvec = { version = "0.7", default-features = false }
rustc_index_macros = { path = "../rustc_index_macros", default-features = false }
rustc_macros = { path = "../rustc_macros", optional = true }
rustc_serialize = { path = "../rustc_serialize", optional = true }
smallvec = "1.8.1"
@@ -14,5 +15,5 @@ smallvec = "1.8.1"
[features]
# tidy-alphabetical-start
default = ["nightly"]
nightly = ["rustc_serialize", "rustc_macros"]
nightly = ["rustc_serialize", "rustc_macros", "rustc_index_macros/nightly"]
# tidy-alphabetical-end
3 changes: 1 addition & 2 deletions compiler/rustc_index/src/lib.rs
Original file line number Diff line number Diff line change
@@ -25,8 +25,7 @@ mod vec;

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

#[cfg(feature = "rustc_macros")]
pub use rustc_macros::newtype_index;
pub use rustc_index_macros::newtype_index;

/// Type size assertion. The first argument is a type and the second argument is its expected size.
///
2 changes: 1 addition & 1 deletion compiler/rustc_index/src/vec/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Allows the macro invocation below to work
use crate as rustc_index;

rustc_macros::newtype_index! {
crate::newtype_index! {
#[max = 0xFFFF_FFFA]
struct MyIdx {}
}
17 changes: 17 additions & 0 deletions compiler/rustc_index_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "rustc_index_macros"
version = "0.0.0"
edition = "2021"

[lib]
proc-macro = true

[dependencies]
synstructure = "0.13.0"
syn = { version = "2.0.9", features = ["full"] }
proc-macro2 = "1"
quote = "1"

[features]
default = ["nightly"]
nightly = []
30 changes: 30 additions & 0 deletions compiler/rustc_index_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#![cfg_attr(feature = "nightly", feature(allow_internal_unstable))]
#![cfg_attr(feature = "nightly", allow(internal_features))]

use proc_macro::TokenStream;

mod newtype;

/// Creates a struct type `S` that can be used as an index with
/// `IndexVec` and so on.
///
/// There are two ways of interacting with these indices:
///
/// - The `From` impls are the preferred way. So you can do
/// `S::from(v)` with a `usize` or `u32`. And you can convert back
/// to an integer with `u32::from(s)`.
///
/// - Alternatively, you can use the methods `S::new(v)` and `s.index()`
/// to create/return a value.
///
/// Internally, the index uses a u32, so the index must not exceed
/// `u32::MAX`. You can also customize things like the `Debug` impl,
/// what traits are derived, and so forth via the macro.
#[proc_macro]
#[cfg_attr(
feature = "nightly",
allow_internal_unstable(step_trait, rustc_attrs, trusted_step, spec_option_partial_eq)
)]
pub fn newtype_index(input: TokenStream) -> TokenStream {
newtype::newtype(input)
}
Original file line number Diff line number Diff line change
@@ -24,9 +24,16 @@ impl Parse for Newtype {
let mut consts = Vec::new();
let mut encodable = true;
let mut ord = true;
let mut gate_rustc_only = quote! {};
let mut gate_rustc_only_cfg = quote! { all() };

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

let encodable_impls = if encodable {
quote! {
#gate_rustc_only
impl<D: ::rustc_serialize::Decoder> ::rustc_serialize::Decodable<D> for #name {
fn decode(d: &mut D) -> Self {
Self::from_u32(d.read_u32())
}
}
#gate_rustc_only
impl<E: ::rustc_serialize::Encoder> ::rustc_serialize::Encodable<E> for #name {
fn encode(&self, e: &mut E) {
e.emit_u32(self.private);
@@ -110,6 +119,7 @@ impl Parse for Newtype {

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

// Safety: The implementation of `Step` upholds all invariants.
#gate_rustc_only
unsafe impl ::std::iter::TrustedStep for #name {}
}
} else {
@@ -148,6 +159,7 @@ impl Parse for Newtype {
let spec_partial_eq_impl = if let Lit::Int(max) = &max {
if let Ok(max_val) = max.base10_parse::<u32>() {
quote! {
#gate_rustc_only
impl core::option::SpecOptionPartialEq for #name {
#[inline]
fn eq(l: &Option<Self>, r: &Option<Self>) -> bool {
@@ -173,8 +185,8 @@ impl Parse for Newtype {
Ok(Self(quote! {
#(#attrs)*
#[derive(Clone, Copy, PartialEq, Eq, Hash, #(#derive_paths),*)]
#[rustc_layout_scalar_valid_range_end(#max)]
#[rustc_pass_by_value]
#[cfg_attr(#gate_rustc_only_cfg, rustc_layout_scalar_valid_range_end(#max))]
#[cfg_attr(#gate_rustc_only_cfg, rustc_pass_by_value)]
#vis struct #name {
private: u32,
}
22 changes: 0 additions & 22 deletions compiler/rustc_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -19,7 +19,6 @@ mod current_version;
mod diagnostics;
mod hash_stable;
mod lift;
mod newtype;
mod query;
mod serialize;
mod symbols;
@@ -44,27 +43,6 @@ pub fn symbols(input: TokenStream) -> TokenStream {
symbols::symbols(input.into()).into()
}

/// Creates a struct type `S` that can be used as an index with
/// `IndexVec` and so on.
///
/// There are two ways of interacting with these indices:
///
/// - The `From` impls are the preferred way. So you can do
/// `S::from(v)` with a `usize` or `u32`. And you can convert back
/// to an integer with `u32::from(s)`.
///
/// - Alternatively, you can use the methods `S::new(v)` and `s.index()`
/// to create/return a value.
///
/// Internally, the index uses a u32, so the index must not exceed
/// `u32::MAX`. You can also customize things like the `Debug` impl,
/// what traits are derived, and so forth via the macro.
#[proc_macro]
#[allow_internal_unstable(step_trait, rustc_attrs, trusted_step, spec_option_partial_eq)]
pub fn newtype_index(input: TokenStream) -> TokenStream {
newtype::newtype(input)
}

decl_derive!([HashStable, attributes(stable_hasher)] => hash_stable::hash_stable_derive);
decl_derive!(
[HashStable_Generic, attributes(stable_hasher)] =>
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
@@ -88,8 +88,8 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::graph::dominators::Dominators;
use rustc_hir::def::DefKind;
use rustc_index::bit_set::BitSet;
use rustc_index::newtype_index;
use rustc_index::IndexVec;
use rustc_macros::newtype_index;
use rustc_middle::mir::interpret::GlobalAlloc;
use rustc_middle::mir::visit::*;
use rustc_middle::mir::*;
21 changes: 16 additions & 5 deletions compiler/rustc_type_ir/Cargo.toml
Original file line number Diff line number Diff line change
@@ -7,9 +7,20 @@ edition = "2021"
# tidy-alphabetical-start
bitflags = "1.2.1"
derivative = "2.2.0"
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" }
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
rustc_index = { path = "../rustc_index", default-features = false }
rustc_macros = { path = "../rustc_macros", optional = true }
rustc_serialize = { path = "../rustc_serialize", optional = true }
smallvec = { version = "1.8.1" }
# tidy-alphabetical-end

[features]
default = ["nightly"]
nightly = [
"smallvec/may_dangle",
"smallvec/union",
"rustc_index/nightly",
"rustc_serialize",
"rustc_data_structures",
"rustc_macros",
]
9 changes: 6 additions & 3 deletions compiler/rustc_type_ir/src/canonical.rs
Original file line number Diff line number Diff line change
@@ -2,18 +2,19 @@ use std::fmt;
use std::hash::Hash;
use std::ops::ControlFlow;

#[cfg(feature = "nightly")]
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};

use crate::fold::{FallibleTypeFolder, TypeFoldable};
use crate::visit::{TypeVisitable, TypeVisitor};
use crate::{HashStableContext, Interner, UniverseIndex};
use crate::{Interner, UniverseIndex};

/// A "canonicalized" type `V` is one where all free inference
/// variables have been rewritten to "canonical vars". These are
/// numbered starting from 0 in order of first appearance.
#[derive(derivative::Derivative)]
#[derivative(Clone(bound = "V: Clone"), Hash(bound = "V: Hash"))]
#[derive(TyEncodable, TyDecodable)]
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))]
pub struct Canonical<I: Interner, V> {
pub value: V,
pub max_universe: UniverseIndex,
@@ -60,7 +61,9 @@ impl<I: Interner, V> Canonical<I, V> {
}
}

impl<CTX: HashStableContext, I: Interner, V: HashStable<CTX>> HashStable<CTX> for Canonical<I, V>
#[cfg(feature = "nightly")]
impl<CTX: crate::HashStableContext, I: Interner, V: HashStable<CTX>> HashStable<CTX>
for Canonical<I, V>
where
I::CanonicalVars: HashStable<CTX>,
{
12 changes: 7 additions & 5 deletions compiler/rustc_type_ir/src/const_kind.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use rustc_data_structures::stable_hasher::HashStable;
use rustc_data_structures::stable_hasher::StableHasher;
#[cfg(feature = "nightly")]
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use std::fmt;

use crate::{DebruijnIndex, DebugWithInfcx, HashStableContext, InferCtxtLike, Interner, WithInfcx};
use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx};

use self::ConstKind::*;

@@ -16,7 +16,7 @@ use self::ConstKind::*;
Ord = "feature_allow_slow_enum",
Hash(bound = "")
)]
#[derive(TyEncodable, TyDecodable)]
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))]
pub enum ConstKind<I: Interner> {
/// A const generic parameter.
Param(I::ParamConst),
@@ -47,6 +47,7 @@ pub enum ConstKind<I: Interner> {
Expr(I::ExprConst),
}

#[cfg(feature = "nightly")]
const fn const_kind_discriminant<I: Interner>(value: &ConstKind<I>) -> usize {
match value {
Param(_) => 0,
@@ -60,7 +61,8 @@ const fn const_kind_discriminant<I: Interner>(value: &ConstKind<I>) -> usize {
}
}

impl<CTX: HashStableContext, I: Interner> HashStable<CTX> for ConstKind<I>
#[cfg(feature = "nightly")]
impl<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for ConstKind<I>
where
I::ParamConst: HashStable<CTX>,
I::InferConst: HashStable<CTX>,
Loading