svlog: typeck: Avoid casting lvalues
@@ -458,6 +458,10 @@ fn cast_expr_type<'gcx>(
);
// If there is no type context which we have to cast to, return.
+ if expr_is_lvalue(cx, expr.id, env) {
+ trace!(" Not casting lvalue");
+ return inferred.into();
+ }
let context = match context {
Some(c) => c,
None => return inferred.into(),
@@ -1405,3 +1409,29 @@ impl std::fmt::Display for CastType<'_> {
Ok(())
}
}
+
+/// Check if an expression is in lvalue position.
+pub(crate) fn expr_is_lvalue<'gcx>(cx: &impl Context<'gcx>, onto: NodeId, _env: ParamEnv) -> bool {
+ let hir = match cx.hir_of(cx.parent_node_id(onto).unwrap()) {
+ Ok(x) => x,
+ Err(()) => return false,
+ };
+ match hir {
+ HirNode::Expr(e) => match e.kind {
+ hir::ExprKind::Unary(op, _) => match op {
+ hir::UnaryOp::PreInc
+ | hir::UnaryOp::PreDec
+ | hir::UnaryOp::PostInc
+ | hir::UnaryOp::PostDec => true,
+ _ => false,
+ },
+ _ => false,
+ },
+ HirNode::Stmt(s) => match s.kind {
+ hir::StmtKind::Assign { lhs, .. } => lhs == onto,
+ _ => false,
+ },
+ HirNode::Assign(a) => a.lhs == onto,
+ _ => false,
+ }
+}
