mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 14:13:58 +00:00
Add info whether it's assignee expr to relevant HIR Expr
variants
This commit is contained in:
parent
fb063d360c
commit
64758bd481
3 changed files with 48 additions and 20 deletions
|
@ -96,6 +96,7 @@ pub(super) fn lower(
|
||||||
expander,
|
expander,
|
||||||
name_to_pat_grouping: Default::default(),
|
name_to_pat_grouping: Default::default(),
|
||||||
is_lowering_inside_or_pat: false,
|
is_lowering_inside_or_pat: false,
|
||||||
|
is_lowering_assignee_expr: false,
|
||||||
}
|
}
|
||||||
.collect(params, body)
|
.collect(params, body)
|
||||||
}
|
}
|
||||||
|
@ -109,6 +110,7 @@ struct ExprCollector<'a> {
|
||||||
// a poor-mans union-find?
|
// a poor-mans union-find?
|
||||||
name_to_pat_grouping: FxHashMap<Name, Vec<PatId>>,
|
name_to_pat_grouping: FxHashMap<Name, Vec<PatId>>,
|
||||||
is_lowering_inside_or_pat: bool,
|
is_lowering_inside_or_pat: bool,
|
||||||
|
is_lowering_assignee_expr: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExprCollector<'_> {
|
impl ExprCollector<'_> {
|
||||||
|
@ -283,7 +285,10 @@ impl ExprCollector<'_> {
|
||||||
} else {
|
} else {
|
||||||
Box::default()
|
Box::default()
|
||||||
};
|
};
|
||||||
self.alloc_expr(Expr::Call { callee, args }, syntax_ptr)
|
self.alloc_expr(
|
||||||
|
Expr::Call { callee, args, is_assignee_expr: self.is_lowering_assignee_expr },
|
||||||
|
syntax_ptr,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
ast::Expr::MethodCallExpr(e) => {
|
ast::Expr::MethodCallExpr(e) => {
|
||||||
let receiver = self.collect_expr_opt(e.receiver());
|
let receiver = self.collect_expr_opt(e.receiver());
|
||||||
|
@ -359,6 +364,7 @@ impl ExprCollector<'_> {
|
||||||
ast::Expr::RecordExpr(e) => {
|
ast::Expr::RecordExpr(e) => {
|
||||||
let path =
|
let path =
|
||||||
e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
|
e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
|
||||||
|
let is_assignee_expr = self.is_lowering_assignee_expr;
|
||||||
let record_lit = if let Some(nfl) = e.record_expr_field_list() {
|
let record_lit = if let Some(nfl) = e.record_expr_field_list() {
|
||||||
let fields = nfl
|
let fields = nfl
|
||||||
.fields()
|
.fields()
|
||||||
|
@ -379,9 +385,15 @@ impl ExprCollector<'_> {
|
||||||
.collect();
|
.collect();
|
||||||
let spread = nfl.spread().map(|s| self.collect_expr(s));
|
let spread = nfl.spread().map(|s| self.collect_expr(s));
|
||||||
let ellipsis = nfl.dotdot_token().is_some();
|
let ellipsis = nfl.dotdot_token().is_some();
|
||||||
Expr::RecordLit { path, fields, spread, ellipsis }
|
Expr::RecordLit { path, fields, spread, ellipsis, is_assignee_expr }
|
||||||
} else {
|
} else {
|
||||||
Expr::RecordLit { path, fields: Box::default(), spread: None, ellipsis: false }
|
Expr::RecordLit {
|
||||||
|
path,
|
||||||
|
fields: Box::default(),
|
||||||
|
spread: None,
|
||||||
|
ellipsis: false,
|
||||||
|
is_assignee_expr,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.alloc_expr(record_lit, syntax_ptr)
|
self.alloc_expr(record_lit, syntax_ptr)
|
||||||
|
@ -459,14 +471,21 @@ impl ExprCollector<'_> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ast::Expr::BinExpr(e) => {
|
ast::Expr::BinExpr(e) => {
|
||||||
let lhs = self.collect_expr_opt(e.lhs());
|
|
||||||
let rhs = self.collect_expr_opt(e.rhs());
|
|
||||||
let op = e.op_kind();
|
let op = e.op_kind();
|
||||||
|
if let Some(ast::BinaryOp::Assignment { op: None }) = op {
|
||||||
|
self.is_lowering_assignee_expr = true;
|
||||||
|
}
|
||||||
|
let lhs = self.collect_expr_opt(e.lhs());
|
||||||
|
self.is_lowering_assignee_expr = false;
|
||||||
|
let rhs = self.collect_expr_opt(e.rhs());
|
||||||
self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr)
|
self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr)
|
||||||
}
|
}
|
||||||
ast::Expr::TupleExpr(e) => {
|
ast::Expr::TupleExpr(e) => {
|
||||||
let exprs = e.fields().map(|expr| self.collect_expr(expr)).collect();
|
let exprs = e.fields().map(|expr| self.collect_expr(expr)).collect();
|
||||||
self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
|
self.alloc_expr(
|
||||||
|
Expr::Tuple { exprs, is_assignee_expr: self.is_lowering_assignee_expr },
|
||||||
|
syntax_ptr,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
ast::Expr::BoxExpr(e) => {
|
ast::Expr::BoxExpr(e) => {
|
||||||
let expr = self.collect_expr_opt(e.expr());
|
let expr = self.collect_expr_opt(e.expr());
|
||||||
|
@ -478,8 +497,14 @@ impl ExprCollector<'_> {
|
||||||
|
|
||||||
match kind {
|
match kind {
|
||||||
ArrayExprKind::ElementList(e) => {
|
ArrayExprKind::ElementList(e) => {
|
||||||
let exprs = e.map(|expr| self.collect_expr(expr)).collect();
|
let elements = e.map(|expr| self.collect_expr(expr)).collect();
|
||||||
self.alloc_expr(Expr::Array(Array::ElementList(exprs)), syntax_ptr)
|
self.alloc_expr(
|
||||||
|
Expr::Array(Array::ElementList {
|
||||||
|
elements,
|
||||||
|
is_assignee_expr: self.is_lowering_assignee_expr,
|
||||||
|
}),
|
||||||
|
syntax_ptr,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
ArrayExprKind::Repeat { initializer, repeat } => {
|
ArrayExprKind::Repeat { initializer, repeat } => {
|
||||||
let initializer = self.collect_expr_opt(initializer);
|
let initializer = self.collect_expr_opt(initializer);
|
||||||
|
|
|
@ -110,6 +110,7 @@ pub enum Expr {
|
||||||
Call {
|
Call {
|
||||||
callee: ExprId,
|
callee: ExprId,
|
||||||
args: Box<[ExprId]>,
|
args: Box<[ExprId]>,
|
||||||
|
is_assignee_expr: bool,
|
||||||
},
|
},
|
||||||
MethodCall {
|
MethodCall {
|
||||||
receiver: ExprId,
|
receiver: ExprId,
|
||||||
|
@ -139,6 +140,7 @@ pub enum Expr {
|
||||||
fields: Box<[RecordLitField]>,
|
fields: Box<[RecordLitField]>,
|
||||||
spread: Option<ExprId>,
|
spread: Option<ExprId>,
|
||||||
ellipsis: bool,
|
ellipsis: bool,
|
||||||
|
is_assignee_expr: bool,
|
||||||
},
|
},
|
||||||
Field {
|
Field {
|
||||||
expr: ExprId,
|
expr: ExprId,
|
||||||
|
@ -197,6 +199,7 @@ pub enum Expr {
|
||||||
},
|
},
|
||||||
Tuple {
|
Tuple {
|
||||||
exprs: Box<[ExprId]>,
|
exprs: Box<[ExprId]>,
|
||||||
|
is_assignee_expr: bool,
|
||||||
},
|
},
|
||||||
Unsafe {
|
Unsafe {
|
||||||
body: ExprId,
|
body: ExprId,
|
||||||
|
@ -212,7 +215,7 @@ pub enum Expr {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||||
pub enum Array {
|
pub enum Array {
|
||||||
ElementList(Box<[ExprId]>),
|
ElementList { elements: Box<[ExprId]>, is_assignee_expr: bool },
|
||||||
Repeat { initializer: ExprId, repeat: ExprId },
|
Repeat { initializer: ExprId, repeat: ExprId },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +289,7 @@ impl Expr {
|
||||||
f(*iterable);
|
f(*iterable);
|
||||||
f(*body);
|
f(*body);
|
||||||
}
|
}
|
||||||
Expr::Call { callee, args } => {
|
Expr::Call { callee, args, .. } => {
|
||||||
f(*callee);
|
f(*callee);
|
||||||
args.iter().copied().for_each(f);
|
args.iter().copied().for_each(f);
|
||||||
}
|
}
|
||||||
|
@ -340,9 +343,9 @@ impl Expr {
|
||||||
| Expr::Box { expr } => {
|
| Expr::Box { expr } => {
|
||||||
f(*expr);
|
f(*expr);
|
||||||
}
|
}
|
||||||
Expr::Tuple { exprs } => exprs.iter().copied().for_each(f),
|
Expr::Tuple { exprs, .. } => exprs.iter().copied().for_each(f),
|
||||||
Expr::Array(a) => match a {
|
Expr::Array(a) => match a {
|
||||||
Array::ElementList(exprs) => exprs.iter().copied().for_each(f),
|
Array::ElementList { elements, .. } => elements.iter().copied().for_each(f),
|
||||||
Array::Repeat { initializer, repeat } => {
|
Array::Repeat { initializer, repeat } => {
|
||||||
f(*initializer);
|
f(*initializer);
|
||||||
f(*repeat)
|
f(*repeat)
|
||||||
|
|
|
@ -276,7 +276,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
|
|
||||||
closure_ty
|
closure_ty
|
||||||
}
|
}
|
||||||
Expr::Call { callee, args } => {
|
Expr::Call { callee, args, .. } => {
|
||||||
let callee_ty = self.infer_expr(*callee, &Expectation::none());
|
let callee_ty = self.infer_expr(*callee, &Expectation::none());
|
||||||
let mut derefs = Autoderef::new(&mut self.table, callee_ty.clone());
|
let mut derefs = Autoderef::new(&mut self.table, callee_ty.clone());
|
||||||
let mut res = None;
|
let mut res = None;
|
||||||
|
@ -693,7 +693,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
self.err_ty()
|
self.err_ty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::Tuple { exprs } => {
|
Expr::Tuple { exprs, .. } => {
|
||||||
let mut tys = match expected
|
let mut tys = match expected
|
||||||
.only_has_type(&mut self.table)
|
.only_has_type(&mut self.table)
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -724,12 +724,12 @@ impl<'a> InferenceContext<'a> {
|
||||||
|
|
||||||
let expected = Expectation::has_type(elem_ty.clone());
|
let expected = Expectation::has_type(elem_ty.clone());
|
||||||
let len = match array {
|
let len = match array {
|
||||||
Array::ElementList(items) => {
|
Array::ElementList { elements, .. } => {
|
||||||
for &expr in items.iter() {
|
for &expr in elements.iter() {
|
||||||
let cur_elem_ty = self.infer_expr_inner(expr, &expected);
|
let cur_elem_ty = self.infer_expr_inner(expr, &expected);
|
||||||
coerce.coerce(self, Some(expr), &cur_elem_ty);
|
coerce.coerce(self, Some(expr), &cur_elem_ty);
|
||||||
}
|
}
|
||||||
consteval::usize_const(Some(items.len() as u128))
|
consteval::usize_const(Some(elements.len() as u128))
|
||||||
}
|
}
|
||||||
&Array::Repeat { initializer, repeat } => {
|
&Array::Repeat { initializer, repeat } => {
|
||||||
self.infer_expr_coerce(initializer, &Expectation::has_type(elem_ty));
|
self.infer_expr_coerce(initializer, &Expectation::has_type(elem_ty));
|
||||||
|
@ -850,7 +850,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
let rhs_ty = self.resolve_ty_shallow(rhs_ty);
|
let rhs_ty = self.resolve_ty_shallow(rhs_ty);
|
||||||
|
|
||||||
let ty = match &self.body[lhs] {
|
let ty = match &self.body[lhs] {
|
||||||
Expr::Tuple { exprs } => {
|
Expr::Tuple { exprs, .. } => {
|
||||||
// We don't consider multiple ellipses. This is analogous to
|
// We don't consider multiple ellipses. This is analogous to
|
||||||
// `hir_def::body::lower::ExprCollector::collect_tuple_pat()`.
|
// `hir_def::body::lower::ExprCollector::collect_tuple_pat()`.
|
||||||
let ellipsis = exprs.iter().position(|e| is_rest_expr(*e));
|
let ellipsis = exprs.iter().position(|e| is_rest_expr(*e));
|
||||||
|
@ -858,7 +858,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
|
|
||||||
self.infer_tuple_pat_like(&rhs_ty, (), ellipsis, &exprs)
|
self.infer_tuple_pat_like(&rhs_ty, (), ellipsis, &exprs)
|
||||||
}
|
}
|
||||||
Expr::Call { callee, args } => {
|
Expr::Call { callee, args, .. } => {
|
||||||
// Tuple structs
|
// Tuple structs
|
||||||
let path = match &self.body[*callee] {
|
let path = match &self.body[*callee] {
|
||||||
Expr::Path(path) => Some(path),
|
Expr::Path(path) => Some(path),
|
||||||
|
@ -872,7 +872,7 @@ impl<'a> InferenceContext<'a> {
|
||||||
|
|
||||||
self.infer_tuple_struct_pat_like(path, &rhs_ty, (), lhs, ellipsis, &args)
|
self.infer_tuple_struct_pat_like(path, &rhs_ty, (), lhs, ellipsis, &args)
|
||||||
}
|
}
|
||||||
Expr::Array(Array::ElementList(elements)) => {
|
Expr::Array(Array::ElementList { elements, .. }) => {
|
||||||
let elem_ty = match rhs_ty.kind(Interner) {
|
let elem_ty = match rhs_ty.kind(Interner) {
|
||||||
TyKind::Array(st, _) => st.clone(),
|
TyKind::Array(st, _) => st.clone(),
|
||||||
_ => self.err_ty(),
|
_ => self.err_ty(),
|
||||||
|
|
Loading…
Reference in a new issue