Implement type inference for boolean operators
This commit is contained in:
parent
3e42a15878
commit
4fc233a02e
@ -26,7 +26,7 @@ use ena::unify::{InPlaceUnificationTable, UnifyKey, UnifyValue, NoError};
|
||||
|
||||
use ra_db::{LocalSyntaxPtr, Cancelable};
|
||||
use ra_syntax::{
|
||||
ast::{self, AstNode, LoopBodyOwner, ArgListOwner, PrefixOp},
|
||||
ast::{self, AstNode, LoopBodyOwner, ArgListOwner, PrefixOp, BinOp},
|
||||
SyntaxNodeRef
|
||||
};
|
||||
|
||||
@ -906,7 +906,16 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
||||
}
|
||||
}
|
||||
ast::Expr::RangeExpr(_e) => Ty::Unknown,
|
||||
ast::Expr::BinExpr(_e) => Ty::Unknown,
|
||||
ast::Expr::BinExpr(e) => match e.op() {
|
||||
Some(BinOp::BooleanOr)
|
||||
| Some(BinOp::BooleanAnd)
|
||||
| Some(BinOp::EqualityTest)
|
||||
| Some(BinOp::LesserEqualTest)
|
||||
| Some(BinOp::GreaterEqualTest)
|
||||
| Some(BinOp::LesserTest)
|
||||
| Some(BinOp::GreaterTest) => Ty::Bool,
|
||||
_ => Ty::Unknown,
|
||||
},
|
||||
ast::Expr::Literal(_e) => Ty::Unknown,
|
||||
};
|
||||
// use a new type variable if we got Ty::Unknown here
|
||||
|
@ -153,6 +153,23 @@ impl S {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_boolean_op() {
|
||||
check_inference(
|
||||
r#"
|
||||
fn test() {
|
||||
let x = a && b;
|
||||
let y = true || false;
|
||||
let z = x == y;
|
||||
let h = CONST_1 <= CONST_2;
|
||||
|
||||
10 < 3
|
||||
}
|
||||
"#,
|
||||
"0008_boolean_op.txt",
|
||||
);
|
||||
}
|
||||
|
||||
fn infer(content: &str) -> String {
|
||||
let (db, _, file_id) = MockDatabase::with_single_file(content);
|
||||
let source_file = db.source_file(file_id);
|
||||
|
10
crates/ra_hir/src/ty/tests/data/0008_boolean_op.txt
Normal file
10
crates/ra_hir/src/ty/tests/data/0008_boolean_op.txt
Normal file
@ -0,0 +1,10 @@
|
||||
[21; 22) 'x': bool
|
||||
[68; 69) 'z': bool
|
||||
[72; 78) 'x == y': bool
|
||||
[45; 58) 'true || false': bool
|
||||
[11; 125) '{ ... < 3 }': bool
|
||||
[117; 123) '10 < 3': bool
|
||||
[88; 89) 'h': bool
|
||||
[41; 42) 'y': bool
|
||||
[92; 110) 'CONST_...ONST_2': bool
|
||||
[25; 31) 'a && b': bool
|
@ -488,6 +488,45 @@ impl<'a> PrefixExpr<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum BinOp {
|
||||
/// The `||` operator for boolean OR
|
||||
BooleanOr,
|
||||
/// The `&&` operator for boolean AND
|
||||
BooleanAnd,
|
||||
/// The `==` operator for equality testing
|
||||
EqualityTest,
|
||||
/// The `<=` operator for lesser-equal testing
|
||||
LesserEqualTest,
|
||||
/// The `>=` operator for greater-equal testing
|
||||
GreaterEqualTest,
|
||||
/// The `<` operator for comparison
|
||||
LesserTest,
|
||||
/// The `>` operator for comparison
|
||||
GreaterTest,
|
||||
// TODO: lots of others
|
||||
}
|
||||
|
||||
impl<'a> BinExpr<'a> {
|
||||
pub fn op(&self) -> Option<BinOp> {
|
||||
self.syntax()
|
||||
.children()
|
||||
.filter_map(|c| {
|
||||
match c.kind() {
|
||||
PIPEPIPE => Some(BinOp::BooleanOr),
|
||||
AMPAMP => Some(BinOp::BooleanAnd),
|
||||
EQEQ => Some(BinOp::EqualityTest),
|
||||
LTEQ => Some(BinOp::LesserEqualTest),
|
||||
GTEQ => Some(BinOp::GreaterEqualTest),
|
||||
L_ANGLE => Some(BinOp::LesserTest),
|
||||
R_ANGLE => Some(BinOp::GreaterTest),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.next()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum SelfParamFlavor {
|
||||
/// self
|
||||
|
@ -217,7 +217,15 @@ impl<R: TreeRoot<RaTypes>> BinExprNode<R> {
|
||||
}
|
||||
|
||||
|
||||
impl<'a> BinExpr<'a> {}
|
||||
impl<'a> BinExpr<'a> {
|
||||
pub fn lhs(self) -> Option<Expr<'a>> {
|
||||
super::child_opt(self)
|
||||
}
|
||||
|
||||
pub fn rhs(self) -> Option<Expr<'a>> {
|
||||
super::child_opt(self)
|
||||
}
|
||||
}
|
||||
|
||||
// BindPat
|
||||
#[derive(Debug, Clone, Copy,)]
|
||||
|
@ -422,7 +422,12 @@ Grammar(
|
||||
"RefExpr": (options: ["Expr"]),
|
||||
"PrefixExpr": (options: ["Expr"]),
|
||||
"RangeExpr": (),
|
||||
"BinExpr": (),
|
||||
"BinExpr": (
|
||||
options: [
|
||||
["lhs", "Expr"],
|
||||
["rhs", "Expr"]
|
||||
]
|
||||
),
|
||||
"String": (),
|
||||
"Byte": (),
|
||||
"ByteString": (),
|
||||
|
Loading…
x
Reference in New Issue
Block a user