Rollup merge of #155629 - cijiugechu:fn_constness, r=makai410

rustc_public: Add `constness` & `asyncness` in `FnDef`

Resolves [https://github.com/rust-lang/project-stable-mir/issues/111](https://github.com/rust-lang/project-stable-mir/issues/111).
This commit is contained in:
Jonathan Brouwer
2026-04-22 19:18:31 +02:00
committed by GitHub
6 changed files with 210 additions and 7 deletions
@@ -17,11 +17,11 @@
use crate::mir::{BinOp, Body, Place, UnOp};
use crate::target::{MachineInfo, MachineSize};
use crate::ty::{
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, CoroutineDef, Discr, FieldDef, FnDef,
ForeignDef, ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates,
Generics, ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span,
TraitDecl, TraitDef, TraitRef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef, VariantIdx,
VtblEntry,
AdtDef, AdtKind, Allocation, Asyncness, ClosureDef, ClosureKind, Constness, CoroutineDef,
Discr, FieldDef, FnDef, ForeignDef, ForeignItemKind, ForeignModule, ForeignModuleDef,
GenericArgs, GenericPredicates, Generics, ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst,
PolyFnSig, RigidTy, Span, TraitDecl, TraitDef, TraitRef, Ty, TyConst, TyConstId, TyKind,
UintTy, VariantDef, VariantIdx, VtblEntry,
};
use crate::unstable::{RustcInternal, Stable, new_item_kind};
use crate::{
@@ -388,6 +388,22 @@ pub(crate) fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig {
cx.fn_sig(def_id, args_ref).stable(&mut *tables, cx)
}
/// Retrieve the constness for the given function definition.
pub(crate) fn constness(&self, def: FnDef) -> Constness {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let def_id = def.0.internal(&mut *tables, cx.tcx);
cx.constness(def_id).stable(&mut *tables, cx)
}
/// Retrieve the asyncness for the given function definition.
pub(crate) fn asyncness(&self, def: FnDef) -> Asyncness {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let def_id = def.0.internal(&mut *tables, cx.tcx);
cx.asyncness(def_id).stable(&mut *tables, cx)
}
/// Retrieve the intrinsic definition if the item corresponds one.
pub(crate) fn intrinsic(&self, item: DefId) -> Option<IntrinsicDef> {
let mut tables = self.tables.borrow_mut();
+34
View File
@@ -710,6 +710,16 @@ pub fn is_intrinsic(&self) -> bool {
self.as_intrinsic().is_some()
}
/// Get the constness of this function definition.
pub fn constness(&self) -> Constness {
with(|cx| cx.constness(*self))
}
/// Get the asyncness of this function definition.
pub fn asyncness(&self) -> Asyncness {
with(|cx| cx.asyncness(*self))
}
/// Get the function signature for this function definition.
pub fn fn_sig(&self) -> PolyFnSig {
let kind = self.ty().kind();
@@ -1103,6 +1113,30 @@ pub fn inputs(&self) -> &[Ty] {
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum Constness {
Const,
NotConst,
}
impl Constness {
pub fn is_const(self) -> bool {
matches!(self, Constness::Const)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
pub enum Asyncness {
Async,
NotAsync,
}
impl Asyncness {
pub fn is_async(self) -> bool {
matches!(self, Asyncness::Async)
}
}
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
pub enum Abi {
Rust,
@@ -14,8 +14,8 @@
use crate::mir::mono::{Instance, MonoItem, StaticDef};
use crate::mir::{BinOp, Mutability, Place, ProjectionElem, RawPtrKind, Safety, UnOp};
use crate::ty::{
Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind,
ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig,
Abi, AdtDef, Asyncness, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind,
Constness, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig,
GenericArgKind, GenericArgs, IntTy, MirConst, Movability, Pattern, Region, RigidTy, Span,
TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx,
};
@@ -637,6 +637,36 @@ fn internal<'tcx>(
}
}
}
impl RustcInternal for Constness {
type T<'tcx> = rustc_hir::Constness;
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
Constness::Const => rustc_hir::Constness::Const,
Constness::NotConst => rustc_hir::Constness::NotConst,
}
}
}
impl RustcInternal for Asyncness {
type T<'tcx> = rustc_ty::Asyncness;
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
Asyncness::Async => rustc_ty::Asyncness::Yes,
Asyncness::NotAsync => rustc_ty::Asyncness::No,
}
}
}
impl RustcInternal for Span {
type T<'tcx> = rustc_span::Span;
@@ -21,6 +21,26 @@ fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>)
}
}
impl<'tcx> Stable<'tcx> for rustc_hir::Constness {
type T = crate::ty::Constness;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
rustc_hir::Constness::Const => crate::ty::Constness::Const,
rustc_hir::Constness::NotConst => crate::ty::Constness::NotConst,
}
}
}
impl<'tcx> Stable<'tcx> for rustc_middle::ty::Asyncness {
type T = crate::ty::Asyncness;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
match self {
rustc_middle::ty::Asyncness::Yes => crate::ty::Asyncness::Async,
rustc_middle::ty::Asyncness::No => crate::ty::Asyncness::NotAsync,
}
}
}
impl<'tcx> Stable<'tcx> for FieldIdx {
type T = usize;
fn stable(&self, _: &mut Tables<'_, BridgeTys>, _: &CompilerCtxt<'_, BridgeTys>) -> Self::T {
@@ -383,6 +383,16 @@ pub fn fn_sig(
sig
}
/// Retrieve the constness for the given function definition.
pub fn constness(&self, def_id: DefId) -> rustc_hir::Constness {
self.tcx.constness(def_id)
}
/// Retrieve the asyncness for the given function definition.
pub fn asyncness(&self, def_id: DefId) -> ty::Asyncness {
self.tcx.asyncness(def_id)
}
/// Retrieve the intrinsic definition if the item corresponds one.
pub fn intrinsic(&self, def_id: DefId) -> Option<IntrinsicDef> {
let intrinsic = self.tcx.intrinsic_raw(def_id);
@@ -0,0 +1,93 @@
//@ run-pass
//! Test that users are able to query function-level constness and asyncness.
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ edition: 2021
#![feature(rustc_private)]
extern crate rustc_driver;
extern crate rustc_interface;
extern crate rustc_middle;
#[macro_use]
extern crate rustc_public;
use rustc_public::crate_def::CrateDef;
use rustc_public::ty::{Asyncness, Constness, FnDef};
use std::io::Write;
use std::ops::ControlFlow;
const CRATE_NAME: &str = "input";
fn test_stable_mir() -> ControlFlow<()> {
let fns = rustc_public::local_crate().fn_defs();
check_fn(&fns, "input::const_sync", Constness::Const, Asyncness::NotAsync);
check_fn(&fns, "input::async_fn", Constness::NotConst, Asyncness::Async);
check_fn(&fns, "input::plain", Constness::NotConst, Asyncness::NotAsync);
check_fn(&fns, "input::Widget::assoc_const", Constness::Const, Asyncness::NotAsync);
check_fn(&fns, "input::Widget::assoc_async", Constness::NotConst, Asyncness::Async);
check_fn(&fns, "input::Widget::assoc_plain", Constness::NotConst, Asyncness::NotAsync);
ControlFlow::Continue(())
}
fn check_fn(fns: &[FnDef], name: &str, constness: Constness, asyncness: Asyncness) {
let fn_def =
fns.iter().find(|def| def.name() == name).unwrap_or_else(|| panic!("missing {name}"));
assert_eq!(fn_def.constness(), constness, "wrong constness for {}", fn_def.name());
assert_eq!(fn_def.asyncness(), asyncness, "wrong asyncness for {}", fn_def.name());
}
fn main() {
let path = "fn_attrs_input.rs";
generate_input(&path).unwrap();
let args = &[
"rustc".to_string(),
"--edition=2021".to_string(),
"--crate-type=lib".to_string(),
"--crate-name".to_string(),
CRATE_NAME.to_string(),
path.to_string(),
];
run!(args, test_stable_mir).unwrap();
}
fn generate_input(path: &str) -> std::io::Result<()> {
let mut file = std::fs::File::create(path)?;
write!(
file,
r#"
pub const fn const_sync() -> u32 {{
1
}}
pub async fn async_fn() -> u32 {{
2
}}
pub fn plain() -> u32 {{
3
}}
pub struct Widget;
impl Widget {{
pub const fn assoc_const() -> u32 {{
4
}}
pub async fn assoc_async() -> u32 {{
5
}}
pub fn assoc_plain() -> u32 {{
6
}}
}}
"#
)?;
Ok(())
}