Skip to content

Commit 514df15

Browse files
author
TomasKralCZ
committed
2 parents c3b9a19 + 3a7724e commit 514df15

File tree

15 files changed

+181
-86
lines changed

15 files changed

+181
-86
lines changed

Cargo.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_hir_ty/src/infer/expr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
386386
let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
387387
// FIXME: find implementation of trait corresponding to operation
388388
// symbol and resolve associated `Output` type
389-
let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty);
389+
let rhs_expectation = op::binary_op_rhs_expectation(*op, lhs_ty.clone());
390390
let rhs_ty = self.infer_expr(*rhs, &Expectation::has_type(rhs_expectation));
391391

392392
// FIXME: similar as above, return ty is often associated trait type
393-
op::binary_op_return_ty(*op, rhs_ty)
393+
op::binary_op_return_ty(*op, lhs_ty, rhs_ty)
394394
}
395395
_ => Ty::Unknown,
396396
},

crates/ra_hir_ty/src/op.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
1-
//! FIXME: write short doc here
2-
use hir_def::expr::{BinaryOp, CmpOp};
1+
//! Helper functions for binary operator type inference.
2+
use hir_def::expr::{ArithOp, BinaryOp, CmpOp};
33

44
use super::{InferTy, Ty, TypeCtor};
55
use crate::ApplicationTy;
66

7-
pub(super) fn binary_op_return_ty(op: BinaryOp, rhs_ty: Ty) -> Ty {
7+
pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
88
match op {
99
BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Bool),
1010
BinaryOp::Assignment { .. } => Ty::unit(),
11+
BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty {
12+
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
13+
TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty,
14+
_ => Ty::Unknown,
15+
},
16+
Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
17+
_ => Ty::Unknown,
18+
},
1119
BinaryOp::ArithOp(_) => match rhs_ty {
1220
Ty::Apply(ApplicationTy { ctor, .. }) => match ctor {
1321
TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty,
@@ -36,6 +44,7 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
3644
_ => Ty::Unknown,
3745
}
3846
}
47+
BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown,
3948
BinaryOp::CmpOp(CmpOp::Ord { .. })
4049
| BinaryOp::Assignment { op: Some(_) }
4150
| BinaryOp::ArithOp(_) => match lhs_ty {

crates/ra_hir_ty/src/tests/simple.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,27 @@ fn test() -> bool {
613613
);
614614
}
615615

616+
#[test]
617+
fn infer_shift_op() {
618+
assert_snapshot!(
619+
infer(r#"
620+
fn test() {
621+
1u32 << 5u8;
622+
1u32 >> 5u8;
623+
}
624+
"#),
625+
@r###"
626+
[11; 48) '{ ...5u8; }': ()
627+
[17; 21) '1u32': u32
628+
[17; 28) '1u32 << 5u8': u32
629+
[25; 28) '5u8': u8
630+
[34; 38) '1u32': u32
631+
[34; 45) '1u32 >> 5u8': u32
632+
[42; 45) '5u8': u8
633+
"###
634+
);
635+
}
636+
616637
#[test]
617638
fn infer_field_autoderef() {
618639
assert_snapshot!(

crates/ra_ide/src/display/function_signature.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,22 @@ impl From<&'_ ast::FnDef> for FunctionSignature {
169169
res.push(self_param.syntax().text().to_string())
170170
}
171171

172-
res.extend(param_list.params().map(|param| {
173-
param.pat().map(|pat| pat.syntax().text().to_string()).unwrap_or_default()
174-
}));
172+
res.extend(
173+
param_list
174+
.params()
175+
.map(|param| {
176+
Some(
177+
param
178+
.pat()?
179+
.syntax()
180+
.descendants()
181+
.find_map(ast::Name::cast)?
182+
.text()
183+
.to_string(),
184+
)
185+
})
186+
.map(|param| param.unwrap_or_default()),
187+
);
175188
}
176189
res
177190
}

crates/ra_ide/src/inlay_hints.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ fn get_param_name_hints(
116116
let hints = parameters
117117
.zip(args)
118118
.filter_map(|(param, arg)| {
119-
if arg.syntax().kind() == SyntaxKind::LITERAL {
119+
if arg.syntax().kind() == SyntaxKind::LITERAL && !param.is_empty() {
120120
Some((arg.syntax().text_range(), param))
121121
} else {
122122
None
@@ -683,12 +683,12 @@ fn main() {
683683
struct Test {}
684684
685685
impl Test {
686-
fn method(&self, param: i32) -> i32 {
686+
fn method(&self, mut param: i32) -> i32 {
687687
param * 2
688688
}
689689
}
690690
691-
fn test_func(foo: i32, bar: i32, msg: &str, _: i32, last: i32) -> i32 {
691+
fn test_func(mut foo: i32, bar: i32, msg: &str, _: i32, last: i32) -> i32 {
692692
foo + bar
693693
}
694694
@@ -704,37 +704,32 @@ fn main() {
704704
assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###"
705705
[
706706
InlayHint {
707-
range: [207; 218),
707+
range: [215; 226),
708708
kind: TypeHint,
709709
label: "i32",
710710
},
711711
InlayHint {
712-
range: [251; 252),
712+
range: [259; 260),
713713
kind: ParameterHint,
714714
label: "foo",
715715
},
716716
InlayHint {
717-
range: [254; 255),
717+
range: [262; 263),
718718
kind: ParameterHint,
719719
label: "bar",
720720
},
721721
InlayHint {
722-
range: [257; 264),
722+
range: [265; 272),
723723
kind: ParameterHint,
724724
label: "msg",
725725
},
726726
InlayHint {
727-
range: [266; 267),
728-
kind: ParameterHint,
729-
label: "_",
730-
},
731-
InlayHint {
732-
range: [323; 326),
727+
range: [331; 334),
733728
kind: ParameterHint,
734729
label: "param",
735730
},
736731
InlayHint {
737-
range: [350; 354),
732+
range: [358; 362),
738733
kind: ParameterHint,
739734
label: "param",
740735
},

crates/ra_parser/src/grammar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! This is the actual "grammar" of the Rust language.
22
//!
33
//! Each function in this module and its children corresponds
4-
//! to a production of the format grammar. Submodules roughly
4+
//! to a production of the formal grammar. Submodules roughly
55
//! correspond to different *areas* of the grammar. By convention,
66
//! each submodule starts with `use super::*` import and exports
77
//! "public" productions via `pub(super)`.

crates/ra_parser/src/grammar/expressions.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,26 @@ pub(super) fn expr(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) {
1919
expr_bp(p, r, 1)
2020
}
2121

22+
pub(super) fn expr_with_attrs(p: &mut Parser) -> bool {
23+
let m = p.start();
24+
let has_attrs = p.at(T![#]);
25+
attributes::outer_attributes(p);
26+
27+
let (cm, _block_like) = expr(p);
28+
let success = cm.is_some();
29+
30+
match (has_attrs, cm) {
31+
(true, Some(cm)) => {
32+
let kind = cm.kind();
33+
cm.undo_completion(p).abandon(p);
34+
m.complete(p, kind);
35+
}
36+
_ => m.abandon(p),
37+
}
38+
39+
success
40+
}
41+
2242
pub(super) fn expr_stmt(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) {
2343
let r = Restrictions { forbid_structs: false, prefer_stmt: true };
2444
expr_bp(p, r, 1)
@@ -540,11 +560,13 @@ fn arg_list(p: &mut Parser) {
540560
let m = p.start();
541561
p.bump(T!['(']);
542562
while !p.at(T![')']) && !p.at(EOF) {
543-
if !p.at_ts(EXPR_FIRST) {
544-
p.error("expected expression");
563+
// test arg_with_attr
564+
// fn main() {
565+
// foo(#[attr] 92)
566+
// }
567+
if !expr_with_attrs(p) {
545568
break;
546569
}
547-
expr(p);
548570
if !p.at(T![')']) && !p.expect(T![,]) {
549571
break;
550572
}

crates/ra_parser/src/grammar/expressions/atom.rs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -191,19 +191,8 @@ fn array_expr(p: &mut Parser) -> CompletedMarker {
191191

192192
// test array_attrs
193193
// const A: &[i64] = &[1, #[cfg(test)] 2];
194-
let m = p.start();
195-
let has_attrs = p.at(T![#]);
196-
attributes::outer_attributes(p);
197-
198-
let cm = expr(p).0;
199-
200-
match (has_attrs, cm) {
201-
(true, Some(cm)) => {
202-
let kind = cm.kind();
203-
cm.undo_completion(p).abandon(p);
204-
m.complete(p, kind);
205-
}
206-
_ => m.abandon(p),
194+
if !expr_with_attrs(p) {
195+
break;
207196
}
208197

209198
if n_exprs == 1 && p.eat(T![;]) {

0 commit comments

Comments
 (0)