Skip to content

Commit 6de838c

Browse files
committed
Implement BeginPanic for mir eval
1 parent a9140e1 commit 6de838c

File tree

4 files changed

+44
-7
lines changed

4 files changed

+44
-7
lines changed

crates/hir-ty/src/chalk_ext.rs

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub trait TyExt {
2727
fn is_scalar(&self) -> bool;
2828
fn is_floating_point(&self) -> bool;
2929
fn is_never(&self) -> bool;
30+
fn is_str(&self) -> bool;
3031
fn is_unknown(&self) -> bool;
3132
fn contains_unknown(&self) -> bool;
3233
fn is_ty_var(&self) -> bool;
@@ -87,6 +88,10 @@ impl TyExt for Ty {
8788
matches!(self.kind(Interner), TyKind::Never)
8889
}
8990

91+
fn is_str(&self) -> bool {
92+
matches!(self.kind(Interner), TyKind::Str)
93+
}
94+
9095
fn is_unknown(&self) -> bool {
9196
matches!(self.kind(Interner), TyKind::Error)
9297
}

crates/hir-ty/src/mir/eval.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1138,7 +1138,7 @@ impl Evaluator<'_> {
11381138
let mut ty = self.operand_ty(lhs, locals)?;
11391139
while let TyKind::Ref(_, _, z) = ty.kind(Interner) {
11401140
ty = z.clone();
1141-
let size = if ty.kind(Interner) == &TyKind::Str {
1141+
let size = if ty.is_str() {
11421142
if *op != BinOp::Eq {
11431143
never!("Only eq is builtin for `str`");
11441144
}

crates/hir-ty/src/mir/eval/shim.rs

+38-5
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,7 @@ impl Evaluator<'_> {
132132
return Ok(true);
133133
}
134134
if let Some(it) = self.detect_lang_function(def) {
135-
let arg_bytes =
136-
args.iter().map(|it| Ok(it.get(self)?.to_owned())).collect::<Result<Vec<_>>>()?;
137-
let result = self.exec_lang_item(it, generic_args, &arg_bytes, locals, span)?;
135+
let result = self.exec_lang_item(it, generic_args, args, locals, span)?;
138136
destination.write_from_bytes(self, &result)?;
139137
return Ok(true);
140138
}
@@ -333,18 +331,52 @@ impl Evaluator<'_> {
333331
&mut self,
334332
it: LangItem,
335333
generic_args: &Substitution,
336-
args: &[Vec<u8>],
334+
args: &[IntervalAndTy],
337335
locals: &Locals,
338336
span: MirSpan,
339337
) -> Result<Vec<u8>> {
340338
use LangItem::*;
341339
let mut args = args.iter();
342340
match it {
343-
BeginPanic => Err(MirEvalError::Panic("<unknown-panic-payload>".to_owned())),
341+
BeginPanic => {
342+
let mut arg = args
343+
.next()
344+
.ok_or(MirEvalError::InternalError(
345+
"argument of BeginPanic is not provided".into(),
346+
))?
347+
.clone();
348+
while let TyKind::Ref(_, _, ty) = arg.ty.kind(Interner) {
349+
if ty.is_str() {
350+
let (pointee, metadata) = arg.interval.get(self)?.split_at(self.ptr_size());
351+
let len = from_bytes!(usize, metadata);
352+
353+
return {
354+
Err(MirEvalError::Panic(
355+
std::str::from_utf8(
356+
self.read_memory(Address::from_bytes(pointee)?, len)?,
357+
)
358+
.unwrap()
359+
.to_owned(),
360+
))
361+
};
362+
}
363+
let size = self.size_of_sized(&ty, locals, "begin panic arg")?;
364+
let pointee = arg.interval.get(self)?;
365+
arg = IntervalAndTy {
366+
interval: Interval::new(Address::from_bytes(pointee)?, size),
367+
ty: ty.clone(),
368+
};
369+
}
370+
Err(MirEvalError::Panic(format!(
371+
"unknown-panic-payload: {:?}",
372+
arg.ty.kind(Interner)
373+
)))
374+
}
344375
SliceLen => {
345376
let arg = args.next().ok_or(MirEvalError::InternalError(
346377
"argument of <[T]>::len() is not provided".into(),
347378
))?;
379+
let arg = arg.get(self)?;
348380
let ptr_size = arg.len() / 2;
349381
Ok(arg[ptr_size..].into())
350382
}
@@ -358,6 +390,7 @@ impl Evaluator<'_> {
358390
let arg = args.next().ok_or(MirEvalError::InternalError(
359391
"argument of drop_in_place is not provided".into(),
360392
))?;
393+
let arg = arg.interval.get(self)?.to_owned();
361394
self.run_drop_glue_deep(
362395
ty.clone(),
363396
locals,

crates/hir-ty/src/mir/eval/tests.rs

-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ fn main() {
104104
}
105105
"#,
106106
);
107-
panic!("a");
108107
}
109108

110109
#[test]

0 commit comments

Comments
 (0)