Skip to content
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

StableMIR: Add associated_items. #138826

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
2 changes: 2 additions & 0 deletions compiler/rustc_middle/src/ty/assoc.rs
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ use rustc_span::{Ident, Symbol, sym};
use super::{TyCtxt, Visibility};
use crate::ty;

/// Indicates whether an associated item is defined in a trait or an impl block.
#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Hash, Encodable, Decodable)]
pub enum AssocItemContainer {
Trait,
@@ -128,6 +129,7 @@ impl AssocItem {
}
}

/// Represents the kind of an associated item.
#[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)]
pub enum AssocKind {
Const,
68 changes: 64 additions & 4 deletions compiler/rustc_smir/src/rustc_internal/internal.rs
Original file line number Diff line number Diff line change
@@ -12,10 +12,11 @@ use stable_mir::mir::alloc::AllocId;
use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, RawPtrKind, Safety, UnOp};
use stable_mir::ty::{
Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, DynKind,
ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig,
GenericArgKind, GenericArgs, IndexedVal, IntTy, MirConst, Movability, Pattern, Region, RigidTy,
Span, TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx,
Abi, AdtDef, AssocItem, AssocItemContainer, AssocKind, Binder, BoundRegionKind, BoundTyKind,
BoundVariableKind, ClosureKind, DynKind, ExistentialPredicate, ExistentialProjection,
ExistentialTraitRef, FloatTy, FnSig, GenericArgKind, GenericArgs, ImplTraitInTraitData,
IndexedVal, IntTy, MirConst, Movability, Pattern, Region, RigidTy, Span, TermKind, TraitRef,
Ty, TyConst, UintTy, VariantDef, VariantIdx,
};
use stable_mir::{CrateItem, CrateNum, DefId};

@@ -570,6 +571,65 @@ impl RustcInternal for ProjectionElem {
}
}

impl RustcInternal for AssocItem {
type T<'tcx> = rustc_middle::ty::AssocItem;

fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
rustc_middle::ty::AssocItem {
def_id: self.def_id.0.internal(tables, tcx),
name: Symbol::intern(&self.name),
kind: self.kind.internal(tables, tcx),
container: self.container.internal(tables, tcx),
trait_item_def_id: self.trait_item_def_id.map(|did| did.0.internal(tables, tcx)),
fn_has_self_parameter: self.fn_has_self_parameter,
opt_rpitit_info: self.opt_rpitit_info.map(|did| did.internal(tables, tcx)),
}
}
}

impl RustcInternal for AssocItemContainer {
type T<'tcx> = rustc_middle::ty::AssocItemContainer;

fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
match self {
AssocItemContainer::Trait => rustc_middle::ty::AssocItemContainer::Trait,
AssocItemContainer::Impl => rustc_middle::ty::AssocItemContainer::Impl,
}
}
}

impl RustcInternal for AssocKind {
type T<'tcx> = rustc_middle::ty::AssocKind;

fn internal<'tcx>(&self, _tables: &mut Tables<'_>, _tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
match self {
AssocKind::Const => rustc_middle::ty::AssocKind::Const,
AssocKind::Fn => rustc_middle::ty::AssocKind::Fn,
AssocKind::Type => rustc_middle::ty::AssocKind::Type,
}
}
}

impl RustcInternal for ImplTraitInTraitData {
type T<'tcx> = rustc_middle::ty::ImplTraitInTraitData;

fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
match self {
ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id } => {
rustc_middle::ty::ImplTraitInTraitData::Trait {
fn_def_id: fn_def_id.0.internal(tables, tcx),
opaque_def_id: opaque_def_id.0.internal(tables, tcx),
}
}
ImplTraitInTraitData::Impl { fn_def_id } => {
rustc_middle::ty::ImplTraitInTraitData::Impl {
fn_def_id: fn_def_id.0.internal(tables, tcx),
}
}
}
}
}

impl RustcInternal for BinOp {
type T<'tcx> = rustc_middle::mir::BinOp;

8 changes: 8 additions & 0 deletions compiler/rustc_smir/src/rustc_internal/mod.rs
Original file line number Diff line number Diff line change
@@ -147,6 +147,14 @@ impl<'tcx> Tables<'tcx> {
stable_mir::ty::CoroutineWitnessDef(self.create_def_id(did))
}

pub fn assoc_def(&mut self, did: DefId) -> stable_mir::ty::AssocDef {
stable_mir::ty::AssocDef(self.create_def_id(did))
}

pub fn opaque_def(&mut self, did: DefId) -> stable_mir::ty::OpaqueDef {
stable_mir::ty::OpaqueDef(self.create_def_id(did))
}

pub fn prov(&mut self, aid: AllocId) -> stable_mir::ty::Prov {
stable_mir::ty::Prov(self.create_alloc_id(aid))
}
15 changes: 15 additions & 0 deletions compiler/rustc_smir/src/rustc_smir/context.rs
Original file line number Diff line number Diff line change
@@ -822,6 +822,21 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
let ty = un_op.internal(&mut *tables, tcx).ty(tcx, arg_internal);
ty.stable(&mut *tables)
}

fn associated_items(&self, def_id: stable_mir::DefId) -> stable_mir::AssocItems {
let mut tables = self.0.borrow_mut();
let tcx = tables.tcx;
let def_id = tables[def_id];
let assoc_items = if tcx.is_trait_alias(def_id) {
Vec::new()
} else {
tcx.associated_item_def_ids(def_id)
.iter()
.map(|did| tcx.associated_item(*did).stable(&mut *tables))
.collect()
};
assoc_items
}
}

pub(crate) struct TablesWrapper<'tcx>(pub RefCell<Tables<'tcx>>);
60 changes: 60 additions & 0 deletions compiler/rustc_smir/src/rustc_smir/convert/ty.rs
Original file line number Diff line number Diff line change
@@ -890,3 +890,63 @@ impl<'tcx> Stable<'tcx> for rustc_session::cstore::ForeignModule {
}
}
}

impl<'tcx> Stable<'tcx> for ty::AssocKind {
type T = stable_mir::ty::AssocKind;

fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
use stable_mir::ty::AssocKind;
match self {
ty::AssocKind::Const => AssocKind::Const,
ty::AssocKind::Fn => AssocKind::Fn,
ty::AssocKind::Type => AssocKind::Type,
}
}
}

impl<'tcx> Stable<'tcx> for ty::AssocItemContainer {
type T = stable_mir::ty::AssocItemContainer;

fn stable(&self, _tables: &mut Tables<'_>) -> Self::T {
use stable_mir::ty::AssocItemContainer;
match self {
ty::AssocItemContainer::Trait => AssocItemContainer::Trait,
ty::AssocItemContainer::Impl => AssocItemContainer::Impl,
}
}
}

impl<'tcx> Stable<'tcx> for ty::AssocItem {
type T = stable_mir::ty::AssocItem;

fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
stable_mir::ty::AssocItem {
def_id: tables.assoc_def(self.def_id),
name: self.name.to_string(),
kind: self.kind.stable(tables),
container: self.container.stable(tables),
trait_item_def_id: self.trait_item_def_id.map(|did| tables.assoc_def(did)),
fn_has_self_parameter: self.fn_has_self_parameter,
opt_rpitit_info: self.opt_rpitit_info.map(|rpitit| rpitit.stable(tables)),
}
}
}

impl<'tcx> Stable<'tcx> for ty::ImplTraitInTraitData {
type T = stable_mir::ty::ImplTraitInTraitData;

fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
use stable_mir::ty::ImplTraitInTraitData;
match self {
ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id } => {
ImplTraitInTraitData::Trait {
fn_def_id: tables.fn_def(*fn_def_id),
opaque_def_id: tables.opaque_def(*opaque_def_id),
}
}
ty::ImplTraitInTraitData::Impl { fn_def_id } => {
ImplTraitInTraitData::Impl { fn_def_id: tables.fn_def(*fn_def_id) }
}
}
}
}
7 changes: 5 additions & 2 deletions compiler/stable_mir/src/compiler_interface.rs
Original file line number Diff line number Diff line change
@@ -18,8 +18,8 @@ use crate::ty::{
TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef,
};
use crate::{
Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, ItemKind,
Symbol, TraitDecls, mir,
AssocItems, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls,
ItemKind, Symbol, TraitDecls, mir,
};

/// This trait defines the interface between stable_mir and the Rust compiler.
@@ -251,6 +251,9 @@ pub trait Context {

/// Get the resulting type of unary operation.
fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty;

/// Get all associated items of a definition.
fn associated_items(&self, def_id: DefId) -> AssocItems;
}

// A thread local variable that stores a pointer to the tables mapping between TyCtxt
16 changes: 15 additions & 1 deletion compiler/stable_mir/src/crate_def.rs
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@
use serde::Serialize;

use crate::ty::{GenericArgs, Span, Ty};
use crate::{Crate, Symbol, with};
use crate::{AssocItems, Crate, Symbol, with};

/// A unique identification number for each item accessible for the current compilation unit.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
@@ -103,6 +103,14 @@ pub trait CrateDefType: CrateDef {
}
}

/// A trait for retrieving all items from a definition within a crate.
pub trait CrateDefItems: CrateDef {
/// Retrieve all associated items from a definition.
fn associated_items(&self) -> AssocItems {
with(|cx| cx.associated_items(self.def_id()))
}
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Attribute {
value: String,
@@ -158,3 +166,9 @@ macro_rules! crate_def_with_ty {
impl CrateDefType for $name {}
};
}

macro_rules! impl_crate_def_items {
( $name:ident $(;)? ) => {
impl CrateDefItems for $name {}
};
}
7 changes: 5 additions & 2 deletions compiler/stable_mir/src/lib.rs
Original file line number Diff line number Diff line change
@@ -23,11 +23,11 @@ use std::{fmt, io};
use serde::Serialize;

use crate::compiler_interface::with;
pub use crate::crate_def::{CrateDef, CrateDefType, DefId};
pub use crate::crate_def::{CrateDef, CrateDefItems, CrateDefType, DefId};
pub use crate::error::*;
use crate::mir::mono::StaticDef;
use crate::mir::{Body, Mutability};
use crate::ty::{FnDef, ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
use crate::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};

pub mod abi;
#[macro_use]
@@ -71,6 +71,9 @@ pub type TraitDecls = Vec<TraitDef>;
/// A list of impl trait decls.
pub type ImplTraitDecls = Vec<ImplDef>;

/// A list of associated items.
pub type AssocItems = Vec<AssocItem>;

/// Holds information about a crate.
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
pub struct Crate {
12 changes: 11 additions & 1 deletion compiler/stable_mir/src/mir/pretty.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, Ter
use crate::mir::{
Operand, Place, RawPtrKind, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents,
};
use crate::ty::{AdtKind, IndexedVal, MirConst, Ty, TyConst};
use crate::ty::{AdtKind, AssocKind, IndexedVal, MirConst, Ty, TyConst};
use crate::{Body, CrateDef, Mutability, with};

impl Display for Ty {
@@ -18,6 +18,16 @@ impl Display for Ty {
}
}

impl Display for AssocKind {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
AssocKind::Fn => write!(f, "method"),
AssocKind::Const => write!(f, "associated const"),
AssocKind::Type => write!(f, "associated type"),
}
}
}

impl Debug for Place {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
with(|ctx| write!(f, "{}", ctx.place_pretty(self)))
78 changes: 76 additions & 2 deletions compiler/stable_mir/src/ty.rs
Original file line number Diff line number Diff line change
@@ -6,11 +6,11 @@ use serde::Serialize;
use super::mir::{Body, Mutability, Safety};
use super::{DefId, Error, Symbol, with};
use crate::abi::{FnAbi, Layout};
use crate::crate_def::{CrateDef, CrateDefType};
use crate::crate_def::{CrateDef, CrateDefItems, CrateDefType};
use crate::mir::alloc::{AllocId, read_target_int, read_target_uint};
use crate::mir::mono::StaticDef;
use crate::target::MachineInfo;
use crate::{Filename, Opaque};
use crate::{AssocItems, Filename, Opaque};

#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)]
pub struct Ty(usize);
@@ -773,6 +773,15 @@ pub enum AdtKind {
Struct,
}

impl CrateDefItems for AdtDef {
fn associated_items(&self) -> AssocItems {
match &self.kind() {
AdtKind::Enum | AdtKind::Struct => with(|cx| cx.associated_items(self.def_id())),
AdtKind::Union => Vec::new(),
}
}
}

impl AdtDef {
pub fn kind(&self) -> AdtKind {
with(|cx| cx.adt_kind(*self))
@@ -910,6 +919,10 @@ crate_def! {
pub TraitDef;
}

impl_crate_def_items! {
TraitDef;
}

impl TraitDef {
pub fn declaration(trait_def: &TraitDef) -> TraitDecl {
with(|cx| cx.trait_decl(trait_def))
@@ -932,6 +945,10 @@ crate_def! {
pub ImplDef;
}

impl_crate_def_items! {
ImplDef;
}

impl ImplDef {
/// Retrieve information about this implementation.
pub fn trait_impl(&self) -> ImplTrait {
@@ -1555,3 +1572,60 @@ index_impl!(Span);
pub struct VariantIdx(usize);

index_impl!(VariantIdx);

crate_def! {
/// Hold infomation about an Opaque definition, particularly useful in `RPITIT`.
#[derive(Serialize)]
pub OpaqueDef;
}

crate_def! {
#[derive(Serialize)]
pub AssocDef;
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct AssocItem {
pub def_id: AssocDef,
pub name: Symbol,
pub kind: AssocKind,
pub container: AssocItemContainer,

/// If this is an item in an impl of a trait then this is the `DefId` of
/// the associated item on the trait that this implements.
pub trait_item_def_id: Option<AssocDef>,

/// Whether this is a method with an explicit self
/// as its first parameter, allowing method calls.
pub fn_has_self_parameter: bool,

/// `Some` if the associated item (an associated type) comes from the
/// return-position `impl Trait` in trait desugaring. The `ImplTraitInTraitData`
/// provides additional information about its source.
pub opt_rpitit_info: Option<ImplTraitInTraitData>,
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum AssocKind {
Const,
Fn,
Type,
}

#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub enum AssocItemContainer {
Trait,
Impl,
}

#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum ImplTraitInTraitData {
Trait { fn_def_id: FnDef, opaque_def_id: OpaqueDef },
Impl { fn_def_id: FnDef },
}

impl AssocItem {
pub fn is_impl_trait_in_trait(&self) -> bool {
self.opt_rpitit_info.is_some()
}
}
Loading