Auto merge of #14643 - HKalbasi:dev3, r=HKalbasi
Fix panic in const eval and parameter destructing fix #14624
This commit is contained in:
commit
bc78ebd9d8
@ -714,13 +714,8 @@ pub enum Rvalue {
|
|||||||
|
|
||||||
/// Creates an array where each element is the value of the operand.
|
/// Creates an array where each element is the value of the operand.
|
||||||
///
|
///
|
||||||
/// This is the cause of a bug in the case where the repetition count is zero because the value
|
|
||||||
/// is not dropped, see [#74836].
|
|
||||||
///
|
|
||||||
/// Corresponds to source code like `[x; 32]`.
|
/// Corresponds to source code like `[x; 32]`.
|
||||||
///
|
Repeat(Operand, Const),
|
||||||
/// [#74836]: https://github.com/rust-lang/rust/issues/74836
|
|
||||||
//Repeat(Operand, ty::Const),
|
|
||||||
|
|
||||||
/// Creates a reference of the indicated kind to the place.
|
/// Creates a reference of the indicated kind to the place.
|
||||||
///
|
///
|
||||||
@ -932,6 +927,7 @@ fn for_operand(op: &mut Operand, f: &mut impl FnMut(&mut Place)) {
|
|||||||
Rvalue::ShallowInitBox(o, _)
|
Rvalue::ShallowInitBox(o, _)
|
||||||
| Rvalue::UnaryOp(_, o)
|
| Rvalue::UnaryOp(_, o)
|
||||||
| Rvalue::Cast(_, o, _)
|
| Rvalue::Cast(_, o, _)
|
||||||
|
| Rvalue::Repeat(o, _)
|
||||||
| Rvalue::Use(o) => for_operand(o, &mut f),
|
| Rvalue::Use(o) => for_operand(o, &mut f),
|
||||||
Rvalue::CopyForDeref(p)
|
Rvalue::CopyForDeref(p)
|
||||||
| Rvalue::Discriminant(p)
|
| Rvalue::Discriminant(p)
|
||||||
|
@ -769,6 +769,7 @@ fn eval_rvalue<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Rvalue::Repeat(_, _) => not_supported!("evaluating repeat rvalue"),
|
||||||
Rvalue::ShallowInitBox(_, _) => not_supported!("shallow init box"),
|
Rvalue::ShallowInitBox(_, _) => not_supported!("shallow init box"),
|
||||||
Rvalue::CopyForDeref(_) => not_supported!("copy for deref"),
|
Rvalue::CopyForDeref(_) => not_supported!("copy for deref"),
|
||||||
Rvalue::Aggregate(kind, values) => {
|
Rvalue::Aggregate(kind, values) => {
|
||||||
|
@ -964,7 +964,22 @@ fn lower_expr_to_place_without_adjust(
|
|||||||
self.push_assignment(current, place, r, expr_id.into());
|
self.push_assignment(current, place, r, expr_id.into());
|
||||||
Ok(Some(current))
|
Ok(Some(current))
|
||||||
}
|
}
|
||||||
Array::Repeat { .. } => not_supported!("array repeat"),
|
Array::Repeat { initializer, .. } => {
|
||||||
|
let Some((init, current)) = self.lower_expr_to_some_operand(*initializer, current)? else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
let len = match &self.expr_ty(expr_id).data(Interner).kind {
|
||||||
|
TyKind::Array(_, len) => len.clone(),
|
||||||
|
_ => {
|
||||||
|
return Err(MirLowerError::TypeError(
|
||||||
|
"Array repeat expression with non array type",
|
||||||
|
))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let r = Rvalue::Repeat(init, len);
|
||||||
|
self.push_assignment(current, place, r, expr_id.into());
|
||||||
|
Ok(Some(current))
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Expr::Literal(l) => {
|
Expr::Literal(l) => {
|
||||||
let ty = self.expr_ty(expr_id);
|
let ty = self.expr_ty(expr_id);
|
||||||
@ -1433,7 +1448,12 @@ fn lower_params_and_bindings(
|
|||||||
fn binding_local(&self, b: BindingId) -> Result<LocalId> {
|
fn binding_local(&self, b: BindingId) -> Result<LocalId> {
|
||||||
match self.result.binding_locals.get(b) {
|
match self.result.binding_locals.get(b) {
|
||||||
Some(x) => Ok(*x),
|
Some(x) => Ok(*x),
|
||||||
None => Err(MirLowerError::UnaccessableLocal),
|
None => {
|
||||||
|
// FIXME: It should never happens, but currently it will happen in `const_dependent_on_local` test, which
|
||||||
|
// is a hir lowering problem IMO.
|
||||||
|
// never!("Using unaccessable local for binding is always a bug");
|
||||||
|
Err(MirLowerError::UnaccessableLocal)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1588,14 +1608,23 @@ pub fn lower_to_mir(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 1 to param_len is for params
|
// 1 to param_len is for params
|
||||||
let current = if let DefWithBodyId::FunctionId(fid) = owner {
|
// FIXME: replace with let chain once it becomes stable
|
||||||
let substs = TyBuilder::placeholder_subst(db, fid);
|
let current = 'b: {
|
||||||
let callable_sig = db.callable_item_signature(fid.into()).substitute(Interner, &substs);
|
if body.body_expr == root_expr {
|
||||||
ctx.lower_params_and_bindings(
|
// otherwise it's an inline const, and has no parameter
|
||||||
body.params.iter().zip(callable_sig.params().iter()).map(|(x, y)| (*x, y.clone())),
|
if let DefWithBodyId::FunctionId(fid) = owner {
|
||||||
binding_picker,
|
let substs = TyBuilder::placeholder_subst(db, fid);
|
||||||
)?
|
let callable_sig =
|
||||||
} else {
|
db.callable_item_signature(fid.into()).substitute(Interner, &substs);
|
||||||
|
break 'b ctx.lower_params_and_bindings(
|
||||||
|
body.params
|
||||||
|
.iter()
|
||||||
|
.zip(callable_sig.params().iter())
|
||||||
|
.map(|(x, y)| (*x, y.clone())),
|
||||||
|
binding_picker,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
ctx.lower_params_and_bindings([].into_iter(), binding_picker)?
|
ctx.lower_params_and_bindings([].into_iter(), binding_picker)?
|
||||||
};
|
};
|
||||||
if let Some(b) = ctx.lower_expr_to_place(root_expr, return_slot().into(), current)? {
|
if let Some(b) = ctx.lower_expr_to_place(root_expr, return_slot().into(), current)? {
|
||||||
|
@ -129,7 +129,7 @@ pub(super) fn pattern_match(
|
|||||||
_ => not_supported!("expression path literal"),
|
_ => not_supported!("expression path literal"),
|
||||||
},
|
},
|
||||||
Pat::Bind { id, subpat } => {
|
Pat::Bind { id, subpat } => {
|
||||||
let target_place = self.result.binding_locals[*id];
|
let target_place = self.binding_local(*id)?;
|
||||||
let mode = self.body.bindings[*id].mode;
|
let mode = self.body.bindings[*id].mode;
|
||||||
if let Some(subpat) = subpat {
|
if let Some(subpat) = subpat {
|
||||||
(current, current_else) = self.pattern_match(
|
(current, current_else) = self.pattern_match(
|
||||||
|
@ -321,6 +321,11 @@ fn rvalue(&mut self, r: &Rvalue) {
|
|||||||
self.operand_list(x);
|
self.operand_list(x);
|
||||||
w!(self, "]");
|
w!(self, "]");
|
||||||
}
|
}
|
||||||
|
Rvalue::Repeat(op, len) => {
|
||||||
|
w!(self, "[");
|
||||||
|
self.operand(op);
|
||||||
|
w!(self, "; {}]", len.display(self.db));
|
||||||
|
}
|
||||||
Rvalue::Aggregate(AggregateKind::Adt(_, _), x) => {
|
Rvalue::Aggregate(AggregateKind::Adt(_, _), x) => {
|
||||||
w!(self, "Adt(");
|
w!(self, "Adt(");
|
||||||
self.operand_list(x);
|
self.operand_list(x);
|
||||||
|
@ -544,6 +544,15 @@ fn f(x: i32) {
|
|||||||
x = 5;
|
x = 5;
|
||||||
//^^^^^ 💡 error: cannot mutate immutable variable `x`
|
//^^^^^ 💡 error: cannot mutate immutable variable `x`
|
||||||
}
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
check_diagnostics(
|
||||||
|
r#"
|
||||||
|
fn f((x, y): (i32, i32)) {
|
||||||
|
let t = [0; 2];
|
||||||
|
x = 5;
|
||||||
|
//^^^^^ 💡 error: cannot mutate immutable variable `x`
|
||||||
|
}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user