Skip to content

Commit 64758bd

Browse files
committed
Add info whether it's assignee expr to relevant HIR Expr variants
1 parent fb063d3 commit 64758bd

File tree

3 files changed

+47
-19
lines changed

3 files changed

+47
-19
lines changed

crates/hir-def/src/body/lower.rs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ pub(super) fn lower(
9696
expander,
9797
name_to_pat_grouping: Default::default(),
9898
is_lowering_inside_or_pat: false,
99+
is_lowering_assignee_expr: false,
99100
}
100101
.collect(params, body)
101102
}
@@ -109,6 +110,7 @@ struct ExprCollector<'a> {
109110
// a poor-mans union-find?
110111
name_to_pat_grouping: FxHashMap<Name, Vec<PatId>>,
111112
is_lowering_inside_or_pat: bool,
113+
is_lowering_assignee_expr: bool,
112114
}
113115

114116
impl ExprCollector<'_> {
@@ -283,7 +285,10 @@ impl ExprCollector<'_> {
283285
} else {
284286
Box::default()
285287
};
286-
self.alloc_expr(Expr::Call { callee, args }, syntax_ptr)
288+
self.alloc_expr(
289+
Expr::Call { callee, args, is_assignee_expr: self.is_lowering_assignee_expr },
290+
syntax_ptr,
291+
)
287292
}
288293
ast::Expr::MethodCallExpr(e) => {
289294
let receiver = self.collect_expr_opt(e.receiver());
@@ -359,6 +364,7 @@ impl ExprCollector<'_> {
359364
ast::Expr::RecordExpr(e) => {
360365
let path =
361366
e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
367+
let is_assignee_expr = self.is_lowering_assignee_expr;
362368
let record_lit = if let Some(nfl) = e.record_expr_field_list() {
363369
let fields = nfl
364370
.fields()
@@ -379,9 +385,15 @@ impl ExprCollector<'_> {
379385
.collect();
380386
let spread = nfl.spread().map(|s| self.collect_expr(s));
381387
let ellipsis = nfl.dotdot_token().is_some();
382-
Expr::RecordLit { path, fields, spread, ellipsis }
388+
Expr::RecordLit { path, fields, spread, ellipsis, is_assignee_expr }
383389
} else {
384-
Expr::RecordLit { path, fields: Box::default(), spread: None, ellipsis: false }
390+
Expr::RecordLit {
391+
path,
392+
fields: Box::default(),
393+
spread: None,
394+
ellipsis: false,
395+
is_assignee_expr,
396+
}
385397
};
386398

387399
self.alloc_expr(record_lit, syntax_ptr)
@@ -459,14 +471,21 @@ impl ExprCollector<'_> {
459471
)
460472
}
461473
ast::Expr::BinExpr(e) => {
474+
let op = e.op_kind();
475+
if let Some(ast::BinaryOp::Assignment { op: None }) = op {
476+
self.is_lowering_assignee_expr = true;
477+
}
462478
let lhs = self.collect_expr_opt(e.lhs());
479+
self.is_lowering_assignee_expr = false;
463480
let rhs = self.collect_expr_opt(e.rhs());
464-
let op = e.op_kind();
465481
self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr)
466482
}
467483
ast::Expr::TupleExpr(e) => {
468484
let exprs = e.fields().map(|expr| self.collect_expr(expr)).collect();
469-
self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
485+
self.alloc_expr(
486+
Expr::Tuple { exprs, is_assignee_expr: self.is_lowering_assignee_expr },
487+
syntax_ptr,
488+
)
470489
}
471490
ast::Expr::BoxExpr(e) => {
472491
let expr = self.collect_expr_opt(e.expr());
@@ -478,8 +497,14 @@ impl ExprCollector<'_> {
478497

479498
match kind {
480499
ArrayExprKind::ElementList(e) => {
481-
let exprs = e.map(|expr| self.collect_expr(expr)).collect();
482-
self.alloc_expr(Expr::Array(Array::ElementList(exprs)), syntax_ptr)
500+
let elements = e.map(|expr| self.collect_expr(expr)).collect();
501+
self.alloc_expr(
502+
Expr::Array(Array::ElementList {
503+
elements,
504+
is_assignee_expr: self.is_lowering_assignee_expr,
505+
}),
506+
syntax_ptr,
507+
)
483508
}
484509
ArrayExprKind::Repeat { initializer, repeat } => {
485510
let initializer = self.collect_expr_opt(initializer);

crates/hir-def/src/expr.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ pub enum Expr {
110110
Call {
111111
callee: ExprId,
112112
args: Box<[ExprId]>,
113+
is_assignee_expr: bool,
113114
},
114115
MethodCall {
115116
receiver: ExprId,
@@ -139,6 +140,7 @@ pub enum Expr {
139140
fields: Box<[RecordLitField]>,
140141
spread: Option<ExprId>,
141142
ellipsis: bool,
143+
is_assignee_expr: bool,
142144
},
143145
Field {
144146
expr: ExprId,
@@ -197,6 +199,7 @@ pub enum Expr {
197199
},
198200
Tuple {
199201
exprs: Box<[ExprId]>,
202+
is_assignee_expr: bool,
200203
},
201204
Unsafe {
202205
body: ExprId,
@@ -212,7 +215,7 @@ pub enum Expr {
212215

213216
#[derive(Debug, Clone, Eq, PartialEq)]
214217
pub enum Array {
215-
ElementList(Box<[ExprId]>),
218+
ElementList { elements: Box<[ExprId]>, is_assignee_expr: bool },
216219
Repeat { initializer: ExprId, repeat: ExprId },
217220
}
218221

@@ -286,7 +289,7 @@ impl Expr {
286289
f(*iterable);
287290
f(*body);
288291
}
289-
Expr::Call { callee, args } => {
292+
Expr::Call { callee, args, .. } => {
290293
f(*callee);
291294
args.iter().copied().for_each(f);
292295
}
@@ -340,9 +343,9 @@ impl Expr {
340343
| Expr::Box { expr } => {
341344
f(*expr);
342345
}
343-
Expr::Tuple { exprs } => exprs.iter().copied().for_each(f),
346+
Expr::Tuple { exprs, .. } => exprs.iter().copied().for_each(f),
344347
Expr::Array(a) => match a {
345-
Array::ElementList(exprs) => exprs.iter().copied().for_each(f),
348+
Array::ElementList { elements, .. } => elements.iter().copied().for_each(f),
346349
Array::Repeat { initializer, repeat } => {
347350
f(*initializer);
348351
f(*repeat)

crates/hir-ty/src/infer/expr.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ impl<'a> InferenceContext<'a> {
276276

277277
closure_ty
278278
}
279-
Expr::Call { callee, args } => {
279+
Expr::Call { callee, args, .. } => {
280280
let callee_ty = self.infer_expr(*callee, &Expectation::none());
281281
let mut derefs = Autoderef::new(&mut self.table, callee_ty.clone());
282282
let mut res = None;
@@ -693,7 +693,7 @@ impl<'a> InferenceContext<'a> {
693693
self.err_ty()
694694
}
695695
}
696-
Expr::Tuple { exprs } => {
696+
Expr::Tuple { exprs, .. } => {
697697
let mut tys = match expected
698698
.only_has_type(&mut self.table)
699699
.as_ref()
@@ -724,12 +724,12 @@ impl<'a> InferenceContext<'a> {
724724

725725
let expected = Expectation::has_type(elem_ty.clone());
726726
let len = match array {
727-
Array::ElementList(items) => {
728-
for &expr in items.iter() {
727+
Array::ElementList { elements, .. } => {
728+
for &expr in elements.iter() {
729729
let cur_elem_ty = self.infer_expr_inner(expr, &expected);
730730
coerce.coerce(self, Some(expr), &cur_elem_ty);
731731
}
732-
consteval::usize_const(Some(items.len() as u128))
732+
consteval::usize_const(Some(elements.len() as u128))
733733
}
734734
&Array::Repeat { initializer, repeat } => {
735735
self.infer_expr_coerce(initializer, &Expectation::has_type(elem_ty));
@@ -850,15 +850,15 @@ impl<'a> InferenceContext<'a> {
850850
let rhs_ty = self.resolve_ty_shallow(rhs_ty);
851851

852852
let ty = match &self.body[lhs] {
853-
Expr::Tuple { exprs } => {
853+
Expr::Tuple { exprs, .. } => {
854854
// We don't consider multiple ellipses. This is analogous to
855855
// `hir_def::body::lower::ExprCollector::collect_tuple_pat()`.
856856
let ellipsis = exprs.iter().position(|e| is_rest_expr(*e));
857857
let exprs: Vec<_> = exprs.iter().filter(|e| !is_rest_expr(**e)).copied().collect();
858858

859859
self.infer_tuple_pat_like(&rhs_ty, (), ellipsis, &exprs)
860860
}
861-
Expr::Call { callee, args } => {
861+
Expr::Call { callee, args, .. } => {
862862
// Tuple structs
863863
let path = match &self.body[*callee] {
864864
Expr::Path(path) => Some(path),
@@ -872,7 +872,7 @@ impl<'a> InferenceContext<'a> {
872872

873873
self.infer_tuple_struct_pat_like(path, &rhs_ty, (), lhs, ellipsis, &args)
874874
}
875-
Expr::Array(Array::ElementList(elements)) => {
875+
Expr::Array(Array::ElementList { elements, .. }) => {
876876
let elem_ty = match rhs_ty.kind(Interner) {
877877
TyKind::Array(st, _) => st.clone(),
878878
_ => self.err_ty(),

0 commit comments

Comments
 (0)