mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
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:
@@ -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();
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
Reference in New Issue
Block a user