Skip to content

Commit 0f4ff52

Browse files
committed
Implement and test monomorphization
1 parent 202fbed commit 0f4ff52

File tree

3 files changed

+92
-4
lines changed

3 files changed

+92
-4
lines changed

compiler/rustc_smir/src/stable_mir/fold.rs

+25-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use std::ops::ControlFlow;
33
use crate::rustc_internal::Opaque;
44

55
use super::ty::{
6-
Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
7-
Promoted, RigidTy, TermKind, Ty, UnevaluatedConst,
6+
Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind,
7+
GenericArgs, Promoted, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst,
88
};
99

1010
pub trait Folder: Sized {
@@ -205,3 +205,26 @@ impl Foldable for FnSig {
205205
})
206206
}
207207
}
208+
209+
pub enum Never {}
210+
211+
/// In order to instantiate a `Foldable`'s generic parameters with specific arguments,
212+
/// `GenericArgs` can be used as a `Folder` that replaces all mentions of generic params
213+
/// with the entries in its list.
214+
impl Folder for GenericArgs {
215+
type Break = Never;
216+
217+
fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
218+
ControlFlow::Continue(match ty.kind() {
219+
TyKind::Param(p) => self[p],
220+
_ => *ty,
221+
})
222+
}
223+
224+
fn fold_const(&mut self, c: &Const) -> ControlFlow<Self::Break, Const> {
225+
ControlFlow::Continue(match &c.literal {
226+
ConstantKind::Param(p) => self[p.clone()].clone(),
227+
_ => c.clone(),
228+
})
229+
}
230+
}

compiler/rustc_smir/src/stable_mir/ty.rs

+38
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,51 @@ pub struct ImplDef(pub(crate) DefId);
138138
#[derive(Clone, Debug)]
139139
pub struct GenericArgs(pub Vec<GenericArgKind>);
140140

141+
impl std::ops::Index<ParamTy> for GenericArgs {
142+
type Output = Ty;
143+
144+
fn index(&self, index: ParamTy) -> &Self::Output {
145+
self.0[index.index as usize].expect_ty()
146+
}
147+
}
148+
149+
impl std::ops::Index<ParamConst> for GenericArgs {
150+
type Output = Const;
151+
152+
fn index(&self, index: ParamConst) -> &Self::Output {
153+
self.0[index.index as usize].expect_const()
154+
}
155+
}
156+
141157
#[derive(Clone, Debug)]
142158
pub enum GenericArgKind {
143159
Lifetime(Region),
144160
Type(Ty),
145161
Const(Const),
146162
}
147163

164+
impl GenericArgKind {
165+
/// Panic if this generic argument is not a type, otherwise
166+
/// return the type.
167+
#[track_caller]
168+
pub fn expect_ty(&self) -> &Ty {
169+
match self {
170+
GenericArgKind::Type(ty) => ty,
171+
_ => panic!("{self:?}"),
172+
}
173+
}
174+
175+
/// Panic if this generic argument is not a const, otherwise
176+
/// return the const.
177+
#[track_caller]
178+
pub fn expect_const(&self) -> &Const {
179+
match self {
180+
GenericArgKind::Const(c) => c,
181+
_ => panic!("{self:?}"),
182+
}
183+
}
184+
}
185+
148186
#[derive(Clone, Debug)]
149187
pub enum TermKind {
150188
Type(Ty),

tests/ui-fulldeps/stable-mir/crate-info.rs

+29-2
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@
88

99
#![feature(rustc_private)]
1010
#![feature(assert_matches)]
11+
#![feature(control_flow_enum)]
1112

1213
extern crate rustc_hir;
1314
extern crate rustc_middle;
1415
extern crate rustc_smir;
1516

1617
use rustc_hir::def::DefKind;
1718
use rustc_middle::ty::TyCtxt;
18-
use rustc_smir::{rustc_internal, stable_mir};
19+
use rustc_smir::{
20+
rustc_internal,
21+
stable_mir::{self, fold::Foldable},
22+
};
1923
use std::assert_matches::assert_matches;
2024
use std::io::Write;
2125
use std::ops::ControlFlow;
@@ -116,7 +120,30 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
116120
stable_mir::mir::Terminator::Call { func, .. } => match func {
117121
stable_mir::mir::Operand::Constant(c) => match &c.literal.literal {
118122
stable_mir::ty::ConstantKind::Allocated(alloc) => {
119-
assert!(alloc.bytes.is_empty())
123+
assert!(alloc.bytes.is_empty());
124+
match c.literal.ty.kind() {
125+
stable_mir::ty::TyKind::RigidTy(stable_mir::ty::RigidTy::FnDef(
126+
def,
127+
mut args,
128+
)) => {
129+
let func = def.body();
130+
match func.locals[1]
131+
.fold(&mut args)
132+
.continue_value()
133+
.unwrap()
134+
.kind()
135+
{
136+
stable_mir::ty::TyKind::RigidTy(
137+
stable_mir::ty::RigidTy::Uint(_),
138+
) => {}
139+
stable_mir::ty::TyKind::RigidTy(
140+
stable_mir::ty::RigidTy::Tuple(_),
141+
) => {}
142+
other => panic!("{other:?}"),
143+
}
144+
}
145+
other => panic!("{other:?}"),
146+
}
120147
}
121148
other => panic!("{other:?}"),
122149
},

0 commit comments

Comments
 (0)