aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/ast_transform.rs7
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs36
-rw-r--r--crates/ra_hir_def/src/path/lower.rs8
-rw-r--r--crates/ra_hir_def/src/path/lower/lower_use.rs11
-rw-r--r--crates/ra_hir_ty/src/infer/pat.rs17
-rw-r--r--crates/ra_hir_ty/src/tests/patterns.rs93
-rw-r--r--crates/ra_ide/src/completion/complete_dot.rs39
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs4
-rw-r--r--xtask/src/install.rs3
9 files changed, 208 insertions, 10 deletions
diff --git a/crates/ra_assists/src/ast_transform.rs b/crates/ra_assists/src/ast_transform.rs
index 0e53c1eee..42856f0ca 100644
--- a/crates/ra_assists/src/ast_transform.rs
+++ b/crates/ra_assists/src/ast_transform.rs
@@ -178,5 +178,10 @@ impl<'a> AstTransform<'a> for QualifyPaths<'a> {
178 178
179pub(crate) fn path_to_ast(path: hir::ModPath) -> ast::Path { 179pub(crate) fn path_to_ast(path: hir::ModPath) -> ast::Path {
180 let parse = ast::SourceFile::parse(&path.to_string()); 180 let parse = ast::SourceFile::parse(&path.to_string());
181 parse.tree().syntax().descendants().find_map(ast::Path::cast).unwrap() 181 parse
182 .tree()
183 .syntax()
184 .descendants()
185 .find_map(ast::Path::cast)
186 .unwrap_or_else(|| panic!("failed to parse path {:?}, `{}`", path, path))
182} 187}
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index 82f0f835c..dda5ed699 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -66,6 +66,42 @@ fn crate_def_map_smoke_test() {
66} 66}
67 67
68#[test] 68#[test]
69fn crate_def_map_super_super() {
70 let map = def_map(
71 "
72 //- /lib.rs
73 mod a {
74 const A: usize = 0;
75
76 mod b {
77 const B: usize = 0;
78
79 mod c {
80 use super::super::*;
81 }
82 }
83 }
84 ",
85 );
86 assert_snapshot!(map, @r###"
87 ⋮crate
88 ⋮a: t
89
90 ⋮crate::a
91 ⋮A: v
92 ⋮b: t
93
94 ⋮crate::a::b
95 ⋮B: v
96 ⋮c: t
97
98 ⋮crate::a::b::c
99 ⋮A: v
100 ⋮b: t
101 "###)
102}
103
104#[test]
69fn bogus_paths() { 105fn bogus_paths() {
70 covers!(bogus_paths); 106 covers!(bogus_paths);
71 let map = def_map( 107 let map = def_map(
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs
index 62aafd508..0934520d7 100644
--- a/crates/ra_hir_def/src/path/lower.rs
+++ b/crates/ra_hir_def/src/path/lower.rs
@@ -101,8 +101,12 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
101 break; 101 break;
102 } 102 }
103 ast::PathSegmentKind::SuperKw => { 103 ast::PathSegmentKind::SuperKw => {
104 kind = PathKind::Super(1); 104 let nested_super_count = if let PathKind::Super(n) = kind {
105 break; 105 n
106 } else {
107 0
108 };
109 kind = PathKind::Super(nested_super_count + 1);
106 } 110 }
107 } 111 }
108 path = match qualifier(&path) { 112 path = match qualifier(&path) {
diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs
index b6d1125e2..278d5196e 100644
--- a/crates/ra_hir_def/src/path/lower/lower_use.rs
+++ b/crates/ra_hir_def/src/path/lower/lower_use.rs
@@ -103,10 +103,13 @@ fn convert_path(prefix: Option<ModPath>, path: ast::Path, hygiene: &Hygiene) ->
103 ModPath::from_segments(PathKind::Super(0), iter::empty()) 103 ModPath::from_segments(PathKind::Super(0), iter::empty())
104 } 104 }
105 ast::PathSegmentKind::SuperKw => { 105 ast::PathSegmentKind::SuperKw => {
106 if prefix.is_some() { 106 let nested_super_count = match prefix.map(|p| p.kind) {
107 return None; 107 Some(PathKind::Super(n)) => n,
108 } 108 Some(_) => return None,
109 ModPath::from_segments(PathKind::Super(1), iter::empty()) 109 None => 0,
110 };
111
112 ModPath::from_segments(PathKind::Super(nested_super_count + 1), iter::empty())
110 } 113 }
111 ast::PathSegmentKind::Type { .. } => { 114 ast::PathSegmentKind::Type { .. } => {
112 // not allowed in imports 115 // not allowed in imports
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs
index bf8ea192b..623e52599 100644
--- a/crates/ra_hir_ty/src/infer/pat.rs
+++ b/crates/ra_hir_ty/src/infer/pat.rs
@@ -185,6 +185,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
185 self.write_pat_ty(pat, bound_ty); 185 self.write_pat_ty(pat, bound_ty);
186 return inner_ty; 186 return inner_ty;
187 } 187 }
188 Pat::Slice { prefix, slice: _slice, suffix } => {
189 let (container_ty, elem_ty) = match &expected {
190 ty_app!(TypeCtor::Array, st) => {
191 (TypeCtor::Array, st.as_single().clone())
192 },
193 ty_app!(TypeCtor::Slice, st) => {
194 (TypeCtor::Slice, st.as_single().clone())
195 },
196 _ => (TypeCtor::Slice, Ty::Unknown),
197 };
198
199 for pat_id in prefix.iter().chain(suffix) {
200 self.infer_pat(*pat_id, &elem_ty, default_bm);
201 }
202
203 Ty::apply_one(container_ty, elem_ty)
204 }
188 _ => Ty::Unknown, 205 _ => Ty::Unknown,
189 }; 206 };
190 // use a new type variable if we got Ty::Unknown here 207 // use a new type variable if we got Ty::Unknown here
diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs
index 81d00c2af..76aa32024 100644
--- a/crates/ra_hir_ty/src/tests/patterns.rs
+++ b/crates/ra_hir_ty/src/tests/patterns.rs
@@ -53,8 +53,9 @@ fn test(x: &i32) {
53 [140; 141) 'g': {unknown} 53 [140; 141) 'g': {unknown}
54 [144; 145) 'e': {unknown} 54 [144; 145) 'e': {unknown}
55 [158; 205) 'if let... }': () 55 [158; 205) 'if let... }': ()
56 [165; 170) '[val]': {unknown} 56 [165; 170) '[val]': [{unknown}]
57 [173; 176) 'opt': {unknown} 57 [166; 169) 'val': {unknown}
58 [173; 176) 'opt': [{unknown}]
58 [177; 205) '{ ... }': () 59 [177; 205) '{ ... }': ()
59 [191; 192) 'h': {unknown} 60 [191; 192) 'h': {unknown}
60 [195; 198) 'val': {unknown} 61 [195; 198) 'val': {unknown}
@@ -137,6 +138,94 @@ fn test() {
137} 138}
138 139
139#[test] 140#[test]
141fn infer_pattern_match_slice() {
142 assert_snapshot!(
143 infer(r#"
144fn test() {
145 let slice: &[f64] = &[0.0];
146 match slice {
147 &[] => {},
148 &[a] => {
149 a;
150 },
151 &[b, c] => {
152 b;
153 c;
154 }
155 _ => {}
156 }
157}
158"#),
159 @r###"
160 [11; 210) '{ ... } }': ()
161 [21; 26) 'slice': &[f64]
162 [37; 43) '&[0.0]': &[f64; _]
163 [38; 43) '[0.0]': [f64; _]
164 [39; 42) '0.0': f64
165 [49; 208) 'match ... }': ()
166 [55; 60) 'slice': &[f64]
167 [71; 74) '&[]': &[f64]
168 [72; 74) '[]': [f64]
169 [78; 80) '{}': ()
170 [90; 94) '&[a]': &[f64]
171 [91; 94) '[a]': [f64]
172 [92; 93) 'a': f64
173 [98; 124) '{ ... }': ()
174 [112; 113) 'a': f64
175 [134; 141) '&[b, c]': &[f64]
176 [135; 141) '[b, c]': [f64]
177 [136; 137) 'b': f64
178 [139; 140) 'c': f64
179 [145; 186) '{ ... }': ()
180 [159; 160) 'b': f64
181 [174; 175) 'c': f64
182 [195; 196) '_': &[f64]
183 [200; 202) '{}': ()
184 "###
185 );
186}
187
188#[test]
189fn infer_pattern_match_arr() {
190 assert_snapshot!(
191 infer(r#"
192fn test() {
193 let arr: [f64; 2] = [0.0, 1.0];
194 match arr {
195 [1.0, a] => {
196 a;
197 },
198 [b, c] => {
199 b;
200 c;
201 }
202 }
203}
204"#),
205 @r###"
206 [11; 180) '{ ... } }': ()
207 [21; 24) 'arr': [f64; _]
208 [37; 47) '[0.0, 1.0]': [f64; _]
209 [38; 41) '0.0': f64
210 [43; 46) '1.0': f64
211 [53; 178) 'match ... }': ()
212 [59; 62) 'arr': [f64; _]
213 [73; 81) '[1.0, a]': [f64; _]
214 [74; 77) '1.0': f64
215 [79; 80) 'a': f64
216 [85; 111) '{ ... }': ()
217 [99; 100) 'a': f64
218 [121; 127) '[b, c]': [f64; _]
219 [122; 123) 'b': f64
220 [125; 126) 'c': f64
221 [131; 172) '{ ... }': ()
222 [145; 146) 'b': f64
223 [160; 161) 'c': f64
224 "###
225 );
226}
227
228#[test]
140fn infer_adt_pattern() { 229fn infer_adt_pattern() {
141 assert_snapshot!( 230 assert_snapshot!(
142 infer(r#" 231 infer(r#"
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index a6e0158b2..9145aa183 100644
--- a/crates/ra_ide/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -545,4 +545,43 @@ mod tests {
545 "### 545 "###
546 ) 546 )
547 } 547 }
548
549 #[test]
550 fn test_super_super_completion() {
551 assert_debug_snapshot!(
552 do_ref_completion(
553 r"
554 mod a {
555 const A: usize = 0;
556
557 mod b {
558 const B: usize = 0;
559
560 mod c {
561 use super::super::<|>
562 }
563 }
564 }
565 ",
566 ),
567 @r###"
568 [
569 CompletionItem {
570 label: "A",
571 source_range: [217; 217),
572 delete: [217; 217),
573 insert: "A",
574 kind: Const,
575 },
576 CompletionItem {
577 label: "b",
578 source_range: [217; 217),
579 delete: [217; 217),
580 insert: "b",
581 kind: Module,
582 },
583 ]
584 "###
585 );
586 }
548} 587}
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index 6f517760f..f51263f22 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -184,6 +184,10 @@ pub fn handle_on_type_formatting(
184 // `text.char_at(position) == typed_char`. 184 // `text.char_at(position) == typed_char`.
185 position.offset -= TextUnit::of_char('.'); 185 position.offset -= TextUnit::of_char('.');
186 let char_typed = params.ch.chars().next().unwrap_or('\0'); 186 let char_typed = params.ch.chars().next().unwrap_or('\0');
187 assert!({
188 let text = world.analysis().file_text(position.file_id)?;
189 text[position.offset.to_usize()..].starts_with(char_typed)
190 });
187 191
188 // We have an assist that inserts ` ` after typing `->` in `fn foo() ->{`, 192 // We have an assist that inserts ` ` after typing `->` in `fn foo() ->{`,
189 // but it requires precise cursor positioning to work, and one can't 193 // but it requires precise cursor positioning to work, and one can't
diff --git a/xtask/src/install.rs b/xtask/src/install.rs
index 1d13b26da..f76467cac 100644
--- a/xtask/src/install.rs
+++ b/xtask/src/install.rs
@@ -122,7 +122,8 @@ fn install_client(ClientOpt::VsCode: ClientOpt) -> Result<()> {
122 if !installed_extensions.contains("rust-analyzer") { 122 if !installed_extensions.contains("rust-analyzer") {
123 bail!( 123 bail!(
124 "Could not install the Visual Studio Code extension. \ 124 "Could not install the Visual Studio Code extension. \
125 Please make sure you have at least NodeJS 12.x together with the latest version of VS Code installed and try again." 125 Please make sure you have at least NodeJS 12.x together with the latest version of VS Code installed and try again. \
126 Note that installing via xtask install does not work for VS Code Remote, instead you’ll need to install the .vsix manually."
126 ); 127 );
127 } 128 }
128 129