Skip to content

StableMIR: Add associated_items. #138826

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
Apr 5, 2025
Merged
Show file tree
Hide file tree
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
8 changes: 8 additions & 0 deletions compiler/rustc_smir/src/rustc_internal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_smir/src/rustc_smir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>>);
Expand Down
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
Expand Up @@ -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
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
16 changes: 15 additions & 1 deletion compiler/stable_mir/src/crate_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Up @@ -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]
Expand Down Expand Up @@ -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 {
Expand Down
12 changes: 11 additions & 1 deletion compiler/stable_mir/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)))
Expand Down
67 changes: 66 additions & 1 deletion compiler/stable_mir/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ 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;
Expand Down Expand Up @@ -910,6 +910,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))
Expand All @@ -932,6 +936,10 @@ crate_def! {
pub ImplDef;
}

impl_crate_def_items! {
ImplDef;
}

impl ImplDef {
/// Retrieve information about this implementation.
pub fn trait_impl(&self) -> ImplTrait {
Expand Down Expand Up @@ -1555,3 +1563,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
Loading