mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-27 20:35:09 +00:00
Merge #544
544: Implement rudimentary type inference for unary operators r=marcusklaas a=marcusklaas Co-authored-by: Marcus Klaas de Vries <mail@marcusklaas.nl>
This commit is contained in:
commit
68d320a680
4 changed files with 72 additions and 5 deletions
|
@ -182,7 +182,7 @@ pub enum Expr {
|
||||||
},
|
},
|
||||||
UnaryOp {
|
UnaryOp {
|
||||||
expr: ExprId,
|
expr: ExprId,
|
||||||
op: Option<UnaryOp>,
|
op: UnaryOp,
|
||||||
},
|
},
|
||||||
BinaryOp {
|
BinaryOp {
|
||||||
lhs: ExprId,
|
lhs: ExprId,
|
||||||
|
@ -612,8 +612,11 @@ impl ExprCollector {
|
||||||
}
|
}
|
||||||
ast::ExprKind::PrefixExpr(e) => {
|
ast::ExprKind::PrefixExpr(e) => {
|
||||||
let expr = self.collect_expr_opt(e.expr());
|
let expr = self.collect_expr_opt(e.expr());
|
||||||
let op = e.op();
|
if let Some(op) = e.op() {
|
||||||
self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr)
|
self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr)
|
||||||
|
} else {
|
||||||
|
self.alloc_expr(Expr::Missing, syntax_ptr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ast::ExprKind::LambdaExpr(e) => {
|
ast::ExprKind::LambdaExpr(e) => {
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
|
|
|
@ -1051,7 +1051,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
Expr::UnaryOp { expr, op } => {
|
Expr::UnaryOp { expr, op } => {
|
||||||
let inner_ty = self.infer_expr(*expr, &Expectation::none());
|
let inner_ty = self.infer_expr(*expr, &Expectation::none());
|
||||||
match op {
|
match op {
|
||||||
Some(UnaryOp::Deref) => {
|
UnaryOp::Deref => {
|
||||||
if let Some(derefed_ty) = inner_ty.builtin_deref() {
|
if let Some(derefed_ty) = inner_ty.builtin_deref() {
|
||||||
derefed_ty
|
derefed_ty
|
||||||
} else {
|
} else {
|
||||||
|
@ -1059,7 +1059,20 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||||
Ty::Unknown
|
Ty::Unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Ty::Unknown,
|
UnaryOp::Neg => {
|
||||||
|
match inner_ty {
|
||||||
|
Ty::Int(primitive::UncertainIntTy::Unknown)
|
||||||
|
| Ty::Int(primitive::UncertainIntTy::Signed(..))
|
||||||
|
| Ty::Infer(InferTy::IntVar(..))
|
||||||
|
| Ty::Infer(InferTy::FloatVar(..))
|
||||||
|
| Ty::Float(..) => inner_ty,
|
||||||
|
// TODO: resolve ops::Neg trait
|
||||||
|
_ => Ty::Unknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnaryOp::Not if inner_ty == Ty::Bool => Ty::Bool,
|
||||||
|
// TODO: resolve ops::Not trait for inner_ty
|
||||||
|
UnaryOp::Not => Ty::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::BinaryOp { lhs, rhs, op } => match op {
|
Expr::BinaryOp { lhs, rhs, op } => match op {
|
||||||
|
|
|
@ -158,6 +158,29 @@ fn test() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn infer_unary_op() {
|
||||||
|
check_inference(
|
||||||
|
r#"
|
||||||
|
enum SomeType {}
|
||||||
|
|
||||||
|
fn test(x: SomeType) {
|
||||||
|
let b = false;
|
||||||
|
let c = !b;
|
||||||
|
let a = 100;
|
||||||
|
let d: i128 = -a;
|
||||||
|
let e = -100;
|
||||||
|
let f = !!!true;
|
||||||
|
-3.14;
|
||||||
|
-x;
|
||||||
|
!x;
|
||||||
|
-"hello";
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
"unary_op.txt",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn infer_backwards() {
|
fn infer_backwards() {
|
||||||
check_inference(
|
check_inference(
|
||||||
|
|
28
crates/ra_hir/src/ty/tests/data/unary_op.txt
Normal file
28
crates/ra_hir/src/ty/tests/data/unary_op.txt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
[27; 28) 'x': SomeType
|
||||||
|
[40; 197) '{ ...lo"; }': ()
|
||||||
|
[50; 51) 'b': bool
|
||||||
|
[54; 59) 'false': bool
|
||||||
|
[69; 70) 'c': bool
|
||||||
|
[73; 75) '!b': bool
|
||||||
|
[74; 75) 'b': bool
|
||||||
|
[85; 86) 'a': i128
|
||||||
|
[89; 92) '100': i128
|
||||||
|
[102; 103) 'd': i128
|
||||||
|
[112; 114) '-a': i128
|
||||||
|
[113; 114) 'a': i128
|
||||||
|
[124; 125) 'e': i32
|
||||||
|
[128; 132) '-100': i32
|
||||||
|
[129; 132) '100': i32
|
||||||
|
[142; 143) 'f': bool
|
||||||
|
[146; 153) '!!!true': bool
|
||||||
|
[147; 153) '!!true': bool
|
||||||
|
[148; 153) '!true': bool
|
||||||
|
[149; 153) 'true': bool
|
||||||
|
[159; 164) '-3.14': f64
|
||||||
|
[160; 164) '3.14': f64
|
||||||
|
[170; 172) '-x': [unknown]
|
||||||
|
[171; 172) 'x': SomeType
|
||||||
|
[178; 180) '!x': [unknown]
|
||||||
|
[179; 180) 'x': SomeType
|
||||||
|
[186; 194) '-"hello"': [unknown]
|
||||||
|
[187; 194) '"hello"': &str
|
Loading…
Reference in a new issue