Skip to content

Commit 21d7bb4

Browse files
authored
Fix: Don't crash when someone uses a macro-rules macro to generate a for loop. (#2763)
1 parent b07d7b0 commit 21d7bb4

3 files changed

Lines changed: 32 additions & 0 deletions

File tree

source/rust_verify/src/fn_call_to_vir.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2852,6 +2852,14 @@ pub(crate) fn fix_node_substs<'tcx, 'a>(
28522852
let generic_arg1 = GenericArg::from(types.expr_ty_adjusted(&args[0]));
28532853
tcx.mk_args(&[generic_arg0, generic_arg1])
28542854
}
2855+
Some(RustItem::IntoIterFn) if node_substs.is_empty() => {
2856+
// A `for` loop produced by a `macro_rules!` expansion is not rewritten
2857+
// by the `verus!` macro, so it reaches rustc's native for-loop
2858+
// desugaring, which emits an `IntoIterator::into_iter` call whose
2859+
// node_substs is empty instead of carrying the Self type argument.
2860+
let generic_arg = GenericArg::from(types.expr_ty_adjusted(&args[0]));
2861+
tcx.mk_args(&[generic_arg])
2862+
}
28552863
_ => node_substs,
28562864
}
28572865
}

source/rust_verify/src/rust_to_vir_expr.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3422,6 +3422,17 @@ pub(crate) fn expr_to_vir_innermost<'tcx>(
34223422
Ok(ExprOrPlace::Place(p))
34233423
}
34243424
}
3425+
ExprKind::Loop(_, _, LoopSource::ForLoop, _) => {
3426+
// The `verus!` macro rewrites `for` loops internally before they
3427+
// reach rustc's native for-loop desugaring, so a `LoopSource::ForLoop`
3428+
// only shows up here when the `for` loop was not visited by `verus!`
3429+
unsupported_err!(
3430+
expr.span,
3431+
format!(
3432+
"`for` loops produced by a macro expansion (wrap the loop in the macro body with `verus_exec_expr! {{ ... }}`)"
3433+
)
3434+
)
3435+
}
34253436
ExprKind::Loop(..) => unsupported_err!(expr.span, format!("complex loop expressions")),
34263437
ExprKind::Break(..) => unsupported_err!(expr.span, format!("complex break expressions")),
34273438
ExprKind::AssignOp(op, lhs, rhs) => {

source/rust_verify_test/tests/loops.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,3 +1946,16 @@ test_verify_one_file! {
19461946
}
19471947
} => Err(err) => assert_fails(err, 1)
19481948
}
1949+
1950+
test_verify_one_file! {
1951+
// A `for` loop produced by a `macro_rules!` expansion is not rewritten by the
1952+
// `verus!` macro, so it reaches rustc's native for-loop desugaring.
1953+
#[test] macro_rules_for_loop_no_ice_issue2751 verus_code! {
1954+
fn f() {
1955+
macro_rules! m {
1956+
() => { for _ in 0..1 {} };
1957+
}
1958+
m!();
1959+
}
1960+
} => Err(err) => assert_vir_error_msg(err, "`for` loops produced by a macro expansion")
1961+
}

0 commit comments

Comments
 (0)