Skip to content

Commit bc78ebd

Browse files
committed
Auto merge of rust-lang#14643 - HKalbasi:dev3, r=HKalbasi
Fix panic in const eval and parameter destructing fix rust-lang#14624
2 parents 2feabc4 + 01c1b3d commit bc78ebd

File tree

6 files changed

+57
-17
lines changed

6 files changed

+57
-17
lines changed

crates/hir-ty/src/mir.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -714,13 +714,8 @@ pub enum Rvalue {
714714

715715
/// Creates an array where each element is the value of the operand.
716716
///
717-
/// This is the cause of a bug in the case where the repetition count is zero because the value
718-
/// is not dropped, see [#74836].
719-
///
720717
/// Corresponds to source code like `[x; 32]`.
721-
///
722-
/// [#74836]: https://github.com/rust-lang/rust/issues/74836
723-
//Repeat(Operand, ty::Const),
718+
Repeat(Operand, Const),
724719

725720
/// Creates a reference of the indicated kind to the place.
726721
///
@@ -932,6 +927,7 @@ impl MirBody {
932927
Rvalue::ShallowInitBox(o, _)
933928
| Rvalue::UnaryOp(_, o)
934929
| Rvalue::Cast(_, o, _)
930+
| Rvalue::Repeat(o, _)
935931
| Rvalue::Use(o) => for_operand(o, &mut f),
936932
Rvalue::CopyForDeref(p)
937933
| Rvalue::Discriminant(p)

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

+1
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,7 @@ impl Evaluator<'_> {
769769
}
770770
}
771771
}
772+
Rvalue::Repeat(_, _) => not_supported!("evaluating repeat rvalue"),
772773
Rvalue::ShallowInitBox(_, _) => not_supported!("shallow init box"),
773774
Rvalue::CopyForDeref(_) => not_supported!("copy for deref"),
774775
Rvalue::Aggregate(kind, values) => {

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

+39-10
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,22 @@ impl<'ctx> MirLowerCtx<'ctx> {
964964
self.push_assignment(current, place, r, expr_id.into());
965965
Ok(Some(current))
966966
}
967-
Array::Repeat { .. } => not_supported!("array repeat"),
967+
Array::Repeat { initializer, .. } => {
968+
let Some((init, current)) = self.lower_expr_to_some_operand(*initializer, current)? else {
969+
return Ok(None);
970+
};
971+
let len = match &self.expr_ty(expr_id).data(Interner).kind {
972+
TyKind::Array(_, len) => len.clone(),
973+
_ => {
974+
return Err(MirLowerError::TypeError(
975+
"Array repeat expression with non array type",
976+
))
977+
}
978+
};
979+
let r = Rvalue::Repeat(init, len);
980+
self.push_assignment(current, place, r, expr_id.into());
981+
Ok(Some(current))
982+
},
968983
},
969984
Expr::Literal(l) => {
970985
let ty = self.expr_ty(expr_id);
@@ -1433,7 +1448,12 @@ impl<'ctx> MirLowerCtx<'ctx> {
14331448
fn binding_local(&self, b: BindingId) -> Result<LocalId> {
14341449
match self.result.binding_locals.get(b) {
14351450
Some(x) => Ok(*x),
1436-
None => Err(MirLowerError::UnaccessableLocal),
1451+
None => {
1452+
// FIXME: It should never happens, but currently it will happen in `const_dependent_on_local` test, which
1453+
// is a hir lowering problem IMO.
1454+
// never!("Using unaccessable local for binding is always a bug");
1455+
Err(MirLowerError::UnaccessableLocal)
1456+
}
14371457
}
14381458
}
14391459
}
@@ -1588,14 +1608,23 @@ pub fn lower_to_mir(
15881608
}
15891609
};
15901610
// 1 to param_len is for params
1591-
let current = if let DefWithBodyId::FunctionId(fid) = owner {
1592-
let substs = TyBuilder::placeholder_subst(db, fid);
1593-
let callable_sig = db.callable_item_signature(fid.into()).substitute(Interner, &substs);
1594-
ctx.lower_params_and_bindings(
1595-
body.params.iter().zip(callable_sig.params().iter()).map(|(x, y)| (*x, y.clone())),
1596-
binding_picker,
1597-
)?
1598-
} else {
1611+
// FIXME: replace with let chain once it becomes stable
1612+
let current = 'b: {
1613+
if body.body_expr == root_expr {
1614+
// otherwise it's an inline const, and has no parameter
1615+
if let DefWithBodyId::FunctionId(fid) = owner {
1616+
let substs = TyBuilder::placeholder_subst(db, fid);
1617+
let callable_sig =
1618+
db.callable_item_signature(fid.into()).substitute(Interner, &substs);
1619+
break 'b ctx.lower_params_and_bindings(
1620+
body.params
1621+
.iter()
1622+
.zip(callable_sig.params().iter())
1623+
.map(|(x, y)| (*x, y.clone())),
1624+
binding_picker,
1625+
)?;
1626+
}
1627+
}
15991628
ctx.lower_params_and_bindings([].into_iter(), binding_picker)?
16001629
};
16011630
if let Some(b) = ctx.lower_expr_to_place(root_expr, return_slot().into(), current)? {

crates/hir-ty/src/mir/lower/pattern_matching.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ impl MirLowerCtx<'_> {
129129
_ => not_supported!("expression path literal"),
130130
},
131131
Pat::Bind { id, subpat } => {
132-
let target_place = self.result.binding_locals[*id];
132+
let target_place = self.binding_local(*id)?;
133133
let mode = self.body.bindings[*id].mode;
134134
if let Some(subpat) = subpat {
135135
(current, current_else) = self.pattern_match(

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

+5
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,11 @@ impl<'a> MirPrettyCtx<'a> {
321321
self.operand_list(x);
322322
w!(self, "]");
323323
}
324+
Rvalue::Repeat(op, len) => {
325+
w!(self, "[");
326+
self.operand(op);
327+
w!(self, "; {}]", len.display(self.db));
328+
}
324329
Rvalue::Aggregate(AggregateKind::Adt(_, _), x) => {
325330
w!(self, "Adt(");
326331
self.operand_list(x);

crates/ide-diagnostics/src/handlers/mutability_errors.rs

+9
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,15 @@ fn f(x: i32) {
544544
x = 5;
545545
//^^^^^ 💡 error: cannot mutate immutable variable `x`
546546
}
547+
"#,
548+
);
549+
check_diagnostics(
550+
r#"
551+
fn f((x, y): (i32, i32)) {
552+
let t = [0; 2];
553+
x = 5;
554+
//^^^^^ 💡 error: cannot mutate immutable variable `x`
555+
}
547556
"#,
548557
);
549558
}

0 commit comments

Comments
 (0)