diff options
-rw-r--r-- | crates/ra_hir/src/ty.rs | 40 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests/data/bug_484.txt | 5 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop.rs | 2 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/main_loop/handlers.rs | 7 | ||||
-rw-r--r-- | crates/ra_lsp_server/src/project_model/sysroot.rs | 8 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar/items/nominal.rs | 10 | ||||
-rw-r--r-- | crates/ra_syntax/tests/data/parser/inline/ok/0115_pos_field_attrs.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/tests/data/parser/inline/ok/0115_pos_field_attrs.txt | 39 | ||||
-rw-r--r-- | crates/tools/src/main.rs | 4 | ||||
-rw-r--r-- | editors/README.md | 2 |
11 files changed, 120 insertions, 13 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 0c24a0652..2d533eb6a 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -18,6 +18,7 @@ mod primitive; | |||
18 | #[cfg(test)] | 18 | #[cfg(test)] |
19 | mod tests; | 19 | mod tests; |
20 | 20 | ||
21 | use std::borrow::Cow; | ||
21 | use std::ops::Index; | 22 | use std::ops::Index; |
22 | use std::sync::Arc; | 23 | use std::sync::Arc; |
23 | use std::{fmt, mem}; | 24 | use std::{fmt, mem}; |
@@ -671,7 +672,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
671 | } | 672 | } |
672 | 673 | ||
673 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { | 674 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { |
674 | match (ty1, ty2) { | 675 | // try to resolve type vars first |
676 | let ty1 = self.resolve_ty_shallow(ty1); | ||
677 | let ty2 = self.resolve_ty_shallow(ty2); | ||
678 | match (&*ty1, &*ty2) { | ||
675 | (Ty::Unknown, ..) => true, | 679 | (Ty::Unknown, ..) => true, |
676 | (.., Ty::Unknown) => true, | 680 | (.., Ty::Unknown) => true, |
677 | (Ty::Bool, _) | 681 | (Ty::Bool, _) |
@@ -698,10 +702,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
698 | .zip(ts2.iter()) | 702 | .zip(ts2.iter()) |
699 | .all(|(t1, t2)| self.unify(t1, t2)), | 703 | .all(|(t1, t2)| self.unify(t1, t2)), |
700 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) => { | 704 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) => { |
705 | // both type vars are unknown since we tried to resolve them | ||
701 | self.var_unification_table.union(*tv1, *tv2); | 706 | self.var_unification_table.union(*tv1, *tv2); |
702 | true | 707 | true |
703 | } | 708 | } |
704 | (Ty::Infer(InferTy::TypeVar(tv)), other) | (other, Ty::Infer(InferTy::TypeVar(tv))) => { | 709 | (Ty::Infer(InferTy::TypeVar(tv)), other) | (other, Ty::Infer(InferTy::TypeVar(tv))) => { |
710 | // the type var is unknown since we tried to resolve it | ||
705 | self.var_unification_table | 711 | self.var_unification_table |
706 | .union_value(*tv, TypeVarValue::Known(other.clone())); | 712 | .union_value(*tv, TypeVarValue::Known(other.clone())); |
707 | true | 713 | true |
@@ -746,6 +752,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
746 | }) | 752 | }) |
747 | } | 753 | } |
748 | 754 | ||
755 | /// If `ty` is a type variable with known type, returns that type; | ||
756 | /// otherwise, return ty. | ||
757 | fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { | ||
758 | match ty { | ||
759 | Ty::Infer(InferTy::TypeVar(tv)) => { | ||
760 | match self.var_unification_table.probe_value(*tv).known() { | ||
761 | Some(known_ty) => { | ||
762 | // The known_ty can't be a type var itself | ||
763 | Cow::Owned(known_ty.clone()) | ||
764 | } | ||
765 | _ => Cow::Borrowed(ty), | ||
766 | } | ||
767 | } | ||
768 | _ => Cow::Borrowed(ty), | ||
769 | } | ||
770 | } | ||
771 | |||
749 | /// Resolves the type completely; type variables without known type are | 772 | /// Resolves the type completely; type variables without known type are |
750 | /// replaced by Ty::Unknown. | 773 | /// replaced by Ty::Unknown. |
751 | fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { | 774 | fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { |
@@ -816,12 +839,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
816 | // if let is desugared to match, so this is always simple if | 839 | // if let is desugared to match, so this is always simple if |
817 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool))?; | 840 | self.infer_expr(*condition, &Expectation::has_type(Ty::Bool))?; |
818 | let then_ty = self.infer_expr(*then_branch, expected)?; | 841 | let then_ty = self.infer_expr(*then_branch, expected)?; |
819 | if let Some(else_branch) = else_branch { | 842 | match else_branch { |
820 | self.infer_expr(*else_branch, expected)?; | 843 | Some(else_branch) => { |
821 | } else { | 844 | self.infer_expr(*else_branch, expected)?; |
822 | // no else branch -> unit | 845 | } |
823 | self.unify(&expected.ty, &Ty::unit()); // actually coerce | 846 | None => { |
824 | } | 847 | // no else branch -> unit |
848 | self.unify(&then_ty, &Ty::unit()); // actually coerce | ||
849 | } | ||
850 | }; | ||
825 | then_ty | 851 | then_ty |
826 | } | 852 | } |
827 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected)?, | 853 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected)?, |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index d8c0af326..815aecda7 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -230,6 +230,18 @@ fn test2(a1: *const A, a2: *mut A) { | |||
230 | ); | 230 | ); |
231 | } | 231 | } |
232 | 232 | ||
233 | #[test] | ||
234 | fn infer_bug_484() { | ||
235 | check_inference( | ||
236 | r#" | ||
237 | fn test() { | ||
238 | let x = if true {}; | ||
239 | } | ||
240 | "#, | ||
241 | "bug_484.txt", | ||
242 | ); | ||
243 | } | ||
244 | |||
233 | fn infer(content: &str) -> String { | 245 | fn infer(content: &str) -> String { |
234 | let (db, _, file_id) = MockDatabase::with_single_file(content); | 246 | let (db, _, file_id) = MockDatabase::with_single_file(content); |
235 | let source_file = db.source_file(file_id); | 247 | let source_file = db.source_file(file_id); |
diff --git a/crates/ra_hir/src/ty/tests/data/bug_484.txt b/crates/ra_hir/src/ty/tests/data/bug_484.txt new file mode 100644 index 000000000..300530551 --- /dev/null +++ b/crates/ra_hir/src/ty/tests/data/bug_484.txt | |||
@@ -0,0 +1,5 @@ | |||
1 | [11; 37) '{ l... {}; }': () | ||
2 | [20; 21) 'x': () | ||
3 | [24; 34) 'if true {}': () | ||
4 | [27; 31) 'true': bool | ||
5 | [32; 34) '{}': () | ||
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 726c758aa..03c834dbc 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -65,7 +65,7 @@ pub fn main_loop( | |||
65 | let workspaces = match ws_worker.recv().unwrap() { | 65 | let workspaces = match ws_worker.recv().unwrap() { |
66 | Ok(ws) => vec![ws], | 66 | Ok(ws) => vec![ws], |
67 | Err(e) => { | 67 | Err(e) => { |
68 | log::warn!("loading workspace failed: {}", e); | 68 | log::error!("loading workspace failed: {}", e); |
69 | Vec::new() | 69 | Vec::new() |
70 | } | 70 | } |
71 | }; | 71 | }; |
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs index 7f6146b6c..a781df181 100644 --- a/crates/ra_lsp_server/src/main_loop/handlers.rs +++ b/crates/ra_lsp_server/src/main_loop/handlers.rs | |||
@@ -4,7 +4,7 @@ use gen_lsp_server::ErrorCode; | |||
4 | use languageserver_types::{ | 4 | use languageserver_types::{ |
5 | CodeActionResponse, Command, CodeLens, Diagnostic, DiagnosticSeverity, DocumentFormattingParams, | 5 | CodeActionResponse, Command, CodeLens, Diagnostic, DiagnosticSeverity, DocumentFormattingParams, |
6 | DocumentHighlight, DocumentSymbol, Documentation, FoldingRange, FoldingRangeKind, | 6 | DocumentHighlight, DocumentSymbol, Documentation, FoldingRange, FoldingRangeKind, |
7 | FoldingRangeParams, Hover, HoverContents, Location, MarkedString, MarkupContent, MarkupKind, | 7 | FoldingRangeParams, Hover, HoverContents, Location, MarkupContent, MarkupKind, |
8 | ParameterInformation, ParameterLabel, Position, PrepareRenameResponse, Range, RenameParams, | 8 | ParameterInformation, ParameterLabel, Position, PrepareRenameResponse, Range, RenameParams, |
9 | SignatureInformation, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit, | 9 | SignatureInformation, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit, |
10 | }; | 10 | }; |
@@ -422,7 +422,10 @@ pub fn handle_hover( | |||
422 | let line_index = world.analysis.file_line_index(position.file_id); | 422 | let line_index = world.analysis.file_line_index(position.file_id); |
423 | let range = info.range.conv_with(&line_index); | 423 | let range = info.range.conv_with(&line_index); |
424 | let res = Hover { | 424 | let res = Hover { |
425 | contents: HoverContents::Scalar(MarkedString::String(info.info)), | 425 | contents: HoverContents::Markup(MarkupContent { |
426 | kind: MarkupKind::Markdown, | ||
427 | value: info.info, | ||
428 | }), | ||
426 | range: Some(range), | 429 | range: Some(range), |
427 | }; | 430 | }; |
428 | Ok(Some(res)) | 431 | Ok(Some(res)) |
diff --git a/crates/ra_lsp_server/src/project_model/sysroot.rs b/crates/ra_lsp_server/src/project_model/sysroot.rs index 1dbab57f8..3b2fa070b 100644 --- a/crates/ra_lsp_server/src/project_model/sysroot.rs +++ b/crates/ra_lsp_server/src/project_model/sysroot.rs | |||
@@ -44,6 +44,14 @@ impl Sysroot { | |||
44 | let stdout = String::from_utf8(rustc_output.stdout)?; | 44 | let stdout = String::from_utf8(rustc_output.stdout)?; |
45 | let sysroot_path = Path::new(stdout.trim()); | 45 | let sysroot_path = Path::new(stdout.trim()); |
46 | let src = sysroot_path.join("lib/rustlib/src/rust/src"); | 46 | let src = sysroot_path.join("lib/rustlib/src/rust/src"); |
47 | if !src.exists() { | ||
48 | failure::bail!( | ||
49 | "can't load standard library from sysroot\n\ | ||
50 | {:?}\n\ | ||
51 | try running `rustup component add rust-src`", | ||
52 | src, | ||
53 | ); | ||
54 | } | ||
47 | 55 | ||
48 | let mut sysroot = Sysroot { | 56 | let mut sysroot = Sysroot { |
49 | crates: Arena::default(), | 57 | crates: Arena::default(), |
diff --git a/crates/ra_syntax/src/grammar/items/nominal.rs b/crates/ra_syntax/src/grammar/items/nominal.rs index 495462ca7..0784fb7b1 100644 --- a/crates/ra_syntax/src/grammar/items/nominal.rs +++ b/crates/ra_syntax/src/grammar/items/nominal.rs | |||
@@ -140,6 +140,16 @@ fn pos_field_list(p: &mut Parser) { | |||
140 | } | 140 | } |
141 | while !p.at(R_PAREN) && !p.at(EOF) { | 141 | while !p.at(R_PAREN) && !p.at(EOF) { |
142 | let m = p.start(); | 142 | let m = p.start(); |
143 | // test pos_field_attrs | ||
144 | // struct S ( | ||
145 | // #[serde(with = "url_serde")] | ||
146 | // pub Uri, | ||
147 | // ); | ||
148 | // | ||
149 | // enum S { | ||
150 | // Uri(#[serde(with = "url_serde")] Uri), | ||
151 | // } | ||
152 | attributes::outer_attributes(p); | ||
143 | opt_visibility(p); | 153 | opt_visibility(p); |
144 | if !p.at_ts(types::TYPE_FIRST) { | 154 | if !p.at_ts(types::TYPE_FIRST) { |
145 | p.error("expected a type"); | 155 | p.error("expected a type"); |
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0115_pos_field_attrs.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0115_pos_field_attrs.rs new file mode 100644 index 000000000..635b9ac21 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0115_pos_field_attrs.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | struct S ( | ||
2 | #[serde(with = "url_serde")] | ||
3 | pub Uri, | ||
4 | ); | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0115_pos_field_attrs.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0115_pos_field_attrs.txt new file mode 100644 index 000000000..99ec0755b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0115_pos_field_attrs.txt | |||
@@ -0,0 +1,39 @@ | |||
1 | SOURCE_FILE@[0; 60) | ||
2 | STRUCT_DEF@[0; 59) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "S" | ||
7 | WHITESPACE@[8; 9) | ||
8 | POS_FIELD_LIST@[9; 58) | ||
9 | L_PAREN@[9; 10) | ||
10 | WHITESPACE@[10; 15) | ||
11 | POS_FIELD@[15; 55) | ||
12 | ATTR@[15; 43) | ||
13 | POUND@[15; 16) | ||
14 | TOKEN_TREE@[16; 43) | ||
15 | L_BRACK@[16; 17) | ||
16 | IDENT@[17; 22) "serde" | ||
17 | TOKEN_TREE@[22; 42) | ||
18 | L_PAREN@[22; 23) | ||
19 | IDENT@[23; 27) "with" | ||
20 | WHITESPACE@[27; 28) | ||
21 | EQ@[28; 29) | ||
22 | WHITESPACE@[29; 30) | ||
23 | STRING@[30; 41) | ||
24 | R_PAREN@[41; 42) | ||
25 | R_BRACK@[42; 43) | ||
26 | WHITESPACE@[43; 48) | ||
27 | VISIBILITY@[48; 51) | ||
28 | PUB_KW@[48; 51) | ||
29 | WHITESPACE@[51; 52) | ||
30 | PATH_TYPE@[52; 55) | ||
31 | PATH@[52; 55) | ||
32 | PATH_SEGMENT@[52; 55) | ||
33 | NAME_REF@[52; 55) | ||
34 | IDENT@[52; 55) "Uri" | ||
35 | COMMA@[55; 56) | ||
36 | WHITESPACE@[56; 57) | ||
37 | R_PAREN@[57; 58) | ||
38 | SEMI@[58; 59) | ||
39 | WHITESPACE@[59; 60) | ||
diff --git a/crates/tools/src/main.rs b/crates/tools/src/main.rs index 9d73d57c4..5597aae5a 100644 --- a/crates/tools/src/main.rs +++ b/crates/tools/src/main.rs | |||
@@ -158,12 +158,12 @@ fn install_code_extension() -> Result<()> { | |||
158 | } | 158 | } |
159 | if cfg!(windows) { | 159 | if cfg!(windows) { |
160 | run( | 160 | run( |
161 | r"cmd.exe /c code.cmd --install-extension ./ra-lsp-0.0.1.vsix", | 161 | r"cmd.exe /c code.cmd --install-extension ./ra-lsp-0.0.1.vsix --force", |
162 | "./editors/code", | 162 | "./editors/code", |
163 | )?; | 163 | )?; |
164 | } else { | 164 | } else { |
165 | run( | 165 | run( |
166 | r"code --install-extension ./ra-lsp-0.0.1.vsix", | 166 | r"code --install-extension ./ra-lsp-0.0.1.vsix --force", |
167 | "./editors/code", | 167 | "./editors/code", |
168 | )?; | 168 | )?; |
169 | } | 169 | } |
diff --git a/editors/README.md b/editors/README.md index a63ced725..5b09750e6 100644 --- a/editors/README.md +++ b/editors/README.md | |||
@@ -1,7 +1,7 @@ | |||
1 | To install experimental VS Code plugin: | 1 | To install experimental VS Code plugin: |
2 | 2 | ||
3 | ``` | 3 | ``` |
4 | $ git clone https://github.com/rust-analyzer/rust-analyzer.git | 4 | $ git clone https://github.com/rust-analyzer/rust-analyzer.git --depth 1 |
5 | $ cd rust-analyzer | 5 | $ cd rust-analyzer |
6 | $ cargo install-code | 6 | $ cargo install-code |
7 | ``` | 7 | ``` |