diff options
22 files changed, 1036 insertions, 946 deletions
diff --git a/Cargo.lock b/Cargo.lock index c58c3035c..90a9f3822 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -26,15 +26,6 @@ dependencies = [ | |||
26 | 26 | ||
27 | [[package]] | 27 | [[package]] |
28 | name = "ansi_term" | 28 | name = "ansi_term" |
29 | version = "0.11.0" | ||
30 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
31 | checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" | ||
32 | dependencies = [ | ||
33 | "winapi 0.3.9", | ||
34 | ] | ||
35 | |||
36 | [[package]] | ||
37 | name = "ansi_term" | ||
38 | version = "0.12.1" | 29 | version = "0.12.1" |
39 | source = "registry+https://github.com/rust-lang/crates.io-index" | 30 | source = "registry+https://github.com/rust-lang/crates.io-index" |
40 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" | 31 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" |
@@ -111,9 +102,9 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" | |||
111 | 102 | ||
112 | [[package]] | 103 | [[package]] |
113 | name = "cargo_metadata" | 104 | name = "cargo_metadata" |
114 | version = "0.10.0" | 105 | version = "0.10.1" |
115 | source = "registry+https://github.com/rust-lang/crates.io-index" | 106 | source = "registry+https://github.com/rust-lang/crates.io-index" |
116 | checksum = "b8de60b887edf6d74370fc8eb177040da4847d971d6234c7b13a6da324ef0caf" | 107 | checksum = "052dbdd9db69a339d5fa9ac87bfe2e1319f709119f0345988a597af82bb1011c" |
117 | dependencies = [ | 108 | dependencies = [ |
118 | "semver", | 109 | "semver", |
119 | "serde", | 110 | "serde", |
@@ -135,9 +126,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" | |||
135 | 126 | ||
136 | [[package]] | 127 | [[package]] |
137 | name = "chalk-derive" | 128 | name = "chalk-derive" |
138 | version = "0.17.0" | 129 | version = "0.18.0" |
139 | source = "registry+https://github.com/rust-lang/crates.io-index" | 130 | source = "registry+https://github.com/rust-lang/crates.io-index" |
140 | checksum = "9396f12a23b1a40d5019aa81bc0cbd7ccd2c9736d6bc4afc95868533c2346dcb" | 131 | checksum = "eea3a22f0c30b2504ac4ab58934dac0d00b92a4d7788df32795cabca24c3f929" |
141 | dependencies = [ | 132 | dependencies = [ |
142 | "proc-macro2", | 133 | "proc-macro2", |
143 | "quote", | 134 | "quote", |
@@ -147,9 +138,9 @@ dependencies = [ | |||
147 | 138 | ||
148 | [[package]] | 139 | [[package]] |
149 | name = "chalk-ir" | 140 | name = "chalk-ir" |
150 | version = "0.17.0" | 141 | version = "0.18.0" |
151 | source = "registry+https://github.com/rust-lang/crates.io-index" | 142 | source = "registry+https://github.com/rust-lang/crates.io-index" |
152 | checksum = "87e9c67d500717d65ede27affb7ae40efe240d86fbefff1006fe0ffb62d4caf9" | 143 | checksum = "fb617b643e145e3b151502799e91a9625dd5daf1cf05dc2cb821bc75ae0c9cbd" |
153 | dependencies = [ | 144 | dependencies = [ |
154 | "chalk-derive", | 145 | "chalk-derive", |
155 | "lazy_static", | 146 | "lazy_static", |
@@ -157,9 +148,9 @@ dependencies = [ | |||
157 | 148 | ||
158 | [[package]] | 149 | [[package]] |
159 | name = "chalk-recursive" | 150 | name = "chalk-recursive" |
160 | version = "0.17.0" | 151 | version = "0.18.0" |
161 | source = "registry+https://github.com/rust-lang/crates.io-index" | 152 | source = "registry+https://github.com/rust-lang/crates.io-index" |
162 | checksum = "a8fd2ac0fc06c857b95614d229bbe8ea317d1d94a7e8b9442a3f05c9a2c2d5f4" | 153 | checksum = "d280565c8eefbf9b2bc615df49c7dfd971faad37774bf65734e626fd23864bd6" |
163 | dependencies = [ | 154 | dependencies = [ |
164 | "chalk-derive", | 155 | "chalk-derive", |
165 | "chalk-ir", | 156 | "chalk-ir", |
@@ -170,9 +161,9 @@ dependencies = [ | |||
170 | 161 | ||
171 | [[package]] | 162 | [[package]] |
172 | name = "chalk-solve" | 163 | name = "chalk-solve" |
173 | version = "0.17.0" | 164 | version = "0.18.0" |
174 | source = "registry+https://github.com/rust-lang/crates.io-index" | 165 | source = "registry+https://github.com/rust-lang/crates.io-index" |
175 | checksum = "2a79166f2405c1e51eadcc1344f5ee833c7b391532dd78f64a0731a9a123cc58" | 166 | checksum = "be906fbca3f3077dce0e76d9864771d0f450c946af0d86b569fb9504148a065a" |
176 | dependencies = [ | 167 | dependencies = [ |
177 | "chalk-derive", | 168 | "chalk-derive", |
178 | "chalk-ir", | 169 | "chalk-ir", |
@@ -470,6 +461,15 @@ dependencies = [ | |||
470 | ] | 461 | ] |
471 | 462 | ||
472 | [[package]] | 463 | [[package]] |
464 | name = "hashbrown" | ||
465 | version = "0.8.1" | ||
466 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
467 | checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb" | ||
468 | dependencies = [ | ||
469 | "autocfg", | ||
470 | ] | ||
471 | |||
472 | [[package]] | ||
473 | name = "heck" | 473 | name = "heck" |
474 | version = "0.3.1" | 474 | version = "0.3.1" |
475 | source = "registry+https://github.com/rust-lang/crates.io-index" | 475 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -509,11 +509,12 @@ dependencies = [ | |||
509 | 509 | ||
510 | [[package]] | 510 | [[package]] |
511 | name = "indexmap" | 511 | name = "indexmap" |
512 | version = "1.4.0" | 512 | version = "1.5.0" |
513 | source = "registry+https://github.com/rust-lang/crates.io-index" | 513 | source = "registry+https://github.com/rust-lang/crates.io-index" |
514 | checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe" | 514 | checksum = "5b88cd59ee5f71fea89a62248fc8f387d44400cefe05ef548466d61ced9029a7" |
515 | dependencies = [ | 515 | dependencies = [ |
516 | "autocfg", | 516 | "autocfg", |
517 | "hashbrown", | ||
517 | ] | 518 | ] |
518 | 519 | ||
519 | [[package]] | 520 | [[package]] |
@@ -642,9 +643,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" | |||
642 | 643 | ||
643 | [[package]] | 644 | [[package]] |
644 | name = "libc" | 645 | name = "libc" |
645 | version = "0.2.72" | 646 | version = "0.2.73" |
646 | source = "registry+https://github.com/rust-lang/crates.io-index" | 647 | source = "registry+https://github.com/rust-lang/crates.io-index" |
647 | checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701" | 648 | checksum = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9" |
648 | 649 | ||
649 | [[package]] | 650 | [[package]] |
650 | name = "libloading" | 651 | name = "libloading" |
@@ -984,9 +985,9 @@ checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4" | |||
984 | 985 | ||
985 | [[package]] | 986 | [[package]] |
986 | name = "proc-macro2" | 987 | name = "proc-macro2" |
987 | version = "1.0.18" | 988 | version = "1.0.19" |
988 | source = "registry+https://github.com/rust-lang/crates.io-index" | 989 | source = "registry+https://github.com/rust-lang/crates.io-index" |
989 | checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" | 990 | checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12" |
990 | dependencies = [ | 991 | dependencies = [ |
991 | "unicode-xid", | 992 | "unicode-xid", |
992 | ] | 993 | ] |
@@ -1505,9 +1506,9 @@ dependencies = [ | |||
1505 | 1506 | ||
1506 | [[package]] | 1507 | [[package]] |
1507 | name = "rustc-ap-rustc_lexer" | 1508 | name = "rustc-ap-rustc_lexer" |
1508 | version = "666.0.0" | 1509 | version = "669.0.0" |
1509 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1510 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1510 | checksum = "4e00c526f9f8430ea4cd2178d25b02bfc7debe6677350c57292f92f50e65d2fe" | 1511 | checksum = "456af5f09c006cf6c22c1a433ee0232c4bb74bdc6c647a010166a47c94ed2a63" |
1511 | dependencies = [ | 1512 | dependencies = [ |
1512 | "unicode-xid", | 1513 | "unicode-xid", |
1513 | ] | 1514 | ] |
@@ -1602,9 +1603,9 @@ dependencies = [ | |||
1602 | 1603 | ||
1603 | [[package]] | 1604 | [[package]] |
1604 | name = "semver" | 1605 | name = "semver" |
1605 | version = "0.9.0" | 1606 | version = "0.10.0" |
1606 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1607 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1607 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" | 1608 | checksum = "394cec28fa623e00903caf7ba4fa6fb9a0e260280bb8cdbbba029611108a0190" |
1608 | dependencies = [ | 1609 | dependencies = [ |
1609 | "semver-parser", | 1610 | "semver-parser", |
1610 | "serde", | 1611 | "serde", |
@@ -1712,9 +1713,9 @@ checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" | |||
1712 | 1713 | ||
1713 | [[package]] | 1714 | [[package]] |
1714 | name = "syn" | 1715 | name = "syn" |
1715 | version = "1.0.34" | 1716 | version = "1.0.35" |
1716 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1717 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1717 | checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b" | 1718 | checksum = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0" |
1718 | dependencies = [ | 1719 | dependencies = [ |
1719 | "proc-macro2", | 1720 | "proc-macro2", |
1720 | "quote", | 1721 | "quote", |
@@ -1886,11 +1887,11 @@ dependencies = [ | |||
1886 | 1887 | ||
1887 | [[package]] | 1888 | [[package]] |
1888 | name = "tracing-subscriber" | 1889 | name = "tracing-subscriber" |
1889 | version = "0.2.7" | 1890 | version = "0.2.8" |
1890 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1891 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1891 | checksum = "c72c8cf3ec4ed69fef614d011a5ae4274537a8a8c59133558029bd731eb71659" | 1892 | checksum = "cafe899b943f5433c6cab468d75a17ea92948fe9fe60b00f41e13d5e0d4fd054" |
1892 | dependencies = [ | 1893 | dependencies = [ |
1893 | "ansi_term 0.11.0", | 1894 | "ansi_term", |
1894 | "chrono", | 1895 | "chrono", |
1895 | "lazy_static", | 1896 | "lazy_static", |
1896 | "matchers", | 1897 | "matchers", |
@@ -1910,7 +1911,7 @@ version = "0.1.4" | |||
1910 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1911 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1911 | checksum = "37ee7f0f53ed2093971a698db799ef56a2dfd89b32e3aeb5165f0e637a02be04" | 1912 | checksum = "37ee7f0f53ed2093971a698db799ef56a2dfd89b32e3aeb5165f0e637a02be04" |
1912 | dependencies = [ | 1913 | dependencies = [ |
1913 | "ansi_term 0.12.1", | 1914 | "ansi_term", |
1914 | "atty", | 1915 | "atty", |
1915 | "chrono", | 1916 | "chrono", |
1916 | "termcolor", | 1917 | "termcolor", |
diff --git a/crates/flycheck/src/lib.rs b/crates/flycheck/src/lib.rs index 6804d9bda..ad376ad18 100644 --- a/crates/flycheck/src/lib.rs +++ b/crates/flycheck/src/lib.rs | |||
@@ -22,6 +22,7 @@ pub use cargo_metadata::diagnostic::{ | |||
22 | pub enum FlycheckConfig { | 22 | pub enum FlycheckConfig { |
23 | CargoCommand { | 23 | CargoCommand { |
24 | command: String, | 24 | command: String, |
25 | target_triple: Option<String>, | ||
25 | all_targets: bool, | 26 | all_targets: bool, |
26 | all_features: bool, | 27 | all_features: bool, |
27 | features: Vec<String>, | 28 | features: Vec<String>, |
@@ -178,6 +179,7 @@ impl FlycheckActor { | |||
178 | let mut cmd = match &self.config { | 179 | let mut cmd = match &self.config { |
179 | FlycheckConfig::CargoCommand { | 180 | FlycheckConfig::CargoCommand { |
180 | command, | 181 | command, |
182 | target_triple, | ||
181 | all_targets, | 183 | all_targets, |
182 | all_features, | 184 | all_features, |
183 | extra_args, | 185 | extra_args, |
@@ -187,6 +189,10 @@ impl FlycheckActor { | |||
187 | cmd.arg(command); | 189 | cmd.arg(command); |
188 | cmd.args(&["--workspace", "--message-format=json", "--manifest-path"]) | 190 | cmd.args(&["--workspace", "--message-format=json", "--manifest-path"]) |
189 | .arg(self.workspace_root.join("Cargo.toml")); | 191 | .arg(self.workspace_root.join("Cargo.toml")); |
192 | |||
193 | if let Some(target) = target_triple { | ||
194 | cmd.args(&["--target", target.as_str()]); | ||
195 | } | ||
190 | if *all_targets { | 196 | if *all_targets { |
191 | cmd.arg("--all-targets"); | 197 | cmd.arg("--all-targets"); |
192 | } | 198 | } |
diff --git a/crates/ra_assists/src/handlers/raw_string.rs b/crates/ra_assists/src/handlers/raw_string.rs index ba1dcb610..4e8a0c2db 100644 --- a/crates/ra_assists/src/handlers/raw_string.rs +++ b/crates/ra_assists/src/handlers/raw_string.rs | |||
@@ -131,7 +131,7 @@ pub(crate) fn remove_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> | |||
131 | let token = ctx.find_token_at_offset(RAW_STRING).and_then(ast::RawString::cast)?; | 131 | let token = ctx.find_token_at_offset(RAW_STRING).and_then(ast::RawString::cast)?; |
132 | 132 | ||
133 | let text = token.text().as_str(); | 133 | let text = token.text().as_str(); |
134 | if !text.starts_with("r#") && text.ends_with("#") { | 134 | if !text.starts_with("r#") && text.ends_with('#') { |
135 | return None; | 135 | return None; |
136 | } | 136 | } |
137 | 137 | ||
diff --git a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs index dfd314abf..3d51faa54 100644 --- a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs +++ b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs | |||
@@ -106,7 +106,7 @@ fn maybe_replace_path( | |||
106 | path: ast::Path, | 106 | path: ast::Path, |
107 | target: ast::Path, | 107 | target: ast::Path, |
108 | ) -> Option<()> { | 108 | ) -> Option<()> { |
109 | if !path_eq(path.clone(), target.clone()) { | 109 | if !path_eq(path.clone(), target) { |
110 | return None; | 110 | return None; |
111 | } | 111 | } |
112 | 112 | ||
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index b279bdeef..5a9de3d3e 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs | |||
@@ -229,12 +229,11 @@ impl CrateDefMap { | |||
229 | // even), as this should be a great debugging aid. | 229 | // even), as this should be a great debugging aid. |
230 | pub fn dump(&self) -> String { | 230 | pub fn dump(&self) -> String { |
231 | let mut buf = String::new(); | 231 | let mut buf = String::new(); |
232 | go(&mut buf, self, "\ncrate", self.root); | 232 | go(&mut buf, self, "crate", self.root); |
233 | return buf.trim().to_string(); | 233 | return buf; |
234 | 234 | ||
235 | fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: LocalModuleId) { | 235 | fn go(buf: &mut String, map: &CrateDefMap, path: &str, module: LocalModuleId) { |
236 | *buf += path; | 236 | format_to!(buf, "{}\n", path); |
237 | *buf += "\n"; | ||
238 | 237 | ||
239 | let mut entries: Vec<_> = map.modules[module].scope.resolutions().collect(); | 238 | let mut entries: Vec<_> = map.modules[module].scope.resolutions().collect(); |
240 | entries.sort_by_key(|(name, _)| name.clone()); | 239 | entries.sort_by_key(|(name, _)| name.clone()); |
@@ -243,23 +242,24 @@ impl CrateDefMap { | |||
243 | format_to!(buf, "{}:", name); | 242 | format_to!(buf, "{}:", name); |
244 | 243 | ||
245 | if def.types.is_some() { | 244 | if def.types.is_some() { |
246 | *buf += " t"; | 245 | buf.push_str(" t"); |
247 | } | 246 | } |
248 | if def.values.is_some() { | 247 | if def.values.is_some() { |
249 | *buf += " v"; | 248 | buf.push_str(" v"); |
250 | } | 249 | } |
251 | if def.macros.is_some() { | 250 | if def.macros.is_some() { |
252 | *buf += " m"; | 251 | buf.push_str(" m"); |
253 | } | 252 | } |
254 | if def.is_none() { | 253 | if def.is_none() { |
255 | *buf += " _"; | 254 | buf.push_str(" _"); |
256 | } | 255 | } |
257 | 256 | ||
258 | *buf += "\n"; | 257 | buf.push_str("\n"); |
259 | } | 258 | } |
260 | 259 | ||
261 | for (name, child) in map.modules[module].children.iter() { | 260 | for (name, child) in map.modules[module].children.iter() { |
262 | let path = &format!("{}::{}", path, name); | 261 | let path = format!("{}::{}", path, name); |
262 | buf.push('\n'); | ||
263 | go(buf, map, &path, *child); | 263 | go(buf, map, &path, *child); |
264 | } | 264 | } |
265 | } | 265 | } |
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index 02dca80c2..205d3528b 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs | |||
@@ -21,7 +21,7 @@ fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> { | |||
21 | fn check(ra_fixture: &str, expect: Expect) { | 21 | fn check(ra_fixture: &str, expect: Expect) { |
22 | let db = TestDB::with_files(ra_fixture); | 22 | let db = TestDB::with_files(ra_fixture); |
23 | let krate = db.crate_graph().iter().next().unwrap(); | 23 | let krate = db.crate_graph().iter().next().unwrap(); |
24 | let actual = db.crate_def_map(krate).dump() + "\n"; | 24 | let actual = db.crate_def_map(krate).dump(); |
25 | expect.assert_eq(&actual); | 25 | expect.assert_eq(&actual); |
26 | } | 26 | } |
27 | 27 | ||
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml index 78f5e55bb..548a3fc1f 100644 --- a/crates/ra_hir_ty/Cargo.toml +++ b/crates/ra_hir_ty/Cargo.toml | |||
@@ -28,9 +28,9 @@ test_utils = { path = "../test_utils" } | |||
28 | 28 | ||
29 | scoped-tls = "1" | 29 | scoped-tls = "1" |
30 | 30 | ||
31 | chalk-solve = { version = "0.17.0" } | 31 | chalk-solve = { version = "0.18.0" } |
32 | chalk-ir = { version = "0.17.0" } | 32 | chalk-ir = { version = "0.18.0" } |
33 | chalk-recursive = { version = "0.17.0" } | 33 | chalk-recursive = { version = "0.18.0" } |
34 | 34 | ||
35 | [dev-dependencies] | 35 | [dev-dependencies] |
36 | insta = "0.16.0" | 36 | insta = "0.16.0" |
diff --git a/crates/ra_hir_ty/src/display.rs b/crates/ra_hir_ty/src/display.rs index 758d5f5ac..19770e609 100644 --- a/crates/ra_hir_ty/src/display.rs +++ b/crates/ra_hir_ty/src/display.rs | |||
@@ -257,7 +257,12 @@ impl HirDisplay for ApplicationTy { | |||
257 | write!(f, ")")?; | 257 | write!(f, ")")?; |
258 | let ret = sig.ret(); | 258 | let ret = sig.ret(); |
259 | if *ret != Ty::unit() { | 259 | if *ret != Ty::unit() { |
260 | write!(f, " -> {}", ret.display(f.db))?; | 260 | let ret_display = if f.omit_verbose_types() { |
261 | ret.display_truncated(f.db, f.max_size) | ||
262 | } else { | ||
263 | ret.display(f.db) | ||
264 | }; | ||
265 | write!(f, " -> {}", ret_display)?; | ||
261 | } | 266 | } |
262 | } | 267 | } |
263 | TypeCtor::FnDef(def) => { | 268 | TypeCtor::FnDef(def) => { |
@@ -288,7 +293,12 @@ impl HirDisplay for ApplicationTy { | |||
288 | write!(f, ")")?; | 293 | write!(f, ")")?; |
289 | let ret = sig.ret(); | 294 | let ret = sig.ret(); |
290 | if *ret != Ty::unit() { | 295 | if *ret != Ty::unit() { |
291 | write!(f, " -> {}", ret.display(f.db))?; | 296 | let ret_display = if f.omit_verbose_types() { |
297 | ret.display_truncated(f.db, f.max_size) | ||
298 | } else { | ||
299 | ret.display(f.db) | ||
300 | }; | ||
301 | write!(f, " -> {}", ret_display)?; | ||
292 | } | 302 | } |
293 | } | 303 | } |
294 | TypeCtor::Adt(def_id) => { | 304 | TypeCtor::Adt(def_id) => { |
@@ -397,7 +407,13 @@ impl HirDisplay for ApplicationTy { | |||
397 | f.write_joined(sig.params(), ", ")?; | 407 | f.write_joined(sig.params(), ", ")?; |
398 | write!(f, "|")?; | 408 | write!(f, "|")?; |
399 | }; | 409 | }; |
400 | write!(f, " -> {}", sig.ret().display(f.db))?; | 410 | |
411 | let ret_display = if f.omit_verbose_types() { | ||
412 | sig.ret().display_truncated(f.db, f.max_size) | ||
413 | } else { | ||
414 | sig.ret().display(f.db) | ||
415 | }; | ||
416 | write!(f, " -> {}", ret_display)?; | ||
401 | } else { | 417 | } else { |
402 | write!(f, "{{closure}}")?; | 418 | write!(f, "{{closure}}")?; |
403 | } | 419 | } |
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index f274579ea..1eacc6f95 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -341,7 +341,7 @@ impl Ty { | |||
341 | let segment = remaining_segments.first().unwrap(); | 341 | let segment = remaining_segments.first().unwrap(); |
342 | let found = associated_type_by_name_including_super_traits( | 342 | let found = associated_type_by_name_including_super_traits( |
343 | ctx.db, | 343 | ctx.db, |
344 | trait_ref.clone(), | 344 | trait_ref, |
345 | &segment.name, | 345 | &segment.name, |
346 | ); | 346 | ); |
347 | match found { | 347 | match found { |
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs index c972bf845..59a21092e 100644 --- a/crates/ra_hir_ty/src/tests.rs +++ b/crates/ra_hir_ty/src/tests.rs | |||
@@ -10,6 +10,7 @@ mod display_source_code; | |||
10 | 10 | ||
11 | use std::sync::Arc; | 11 | use std::sync::Arc; |
12 | 12 | ||
13 | use expect::Expect; | ||
13 | use hir_def::{ | 14 | use hir_def::{ |
14 | body::{BodySourceMap, SyntheticSyntax}, | 15 | body::{BodySourceMap, SyntheticSyntax}, |
15 | child_by_source::ChildBySource, | 16 | child_by_source::ChildBySource, |
@@ -344,3 +345,15 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
344 | assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) | 345 | assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) |
345 | } | 346 | } |
346 | } | 347 | } |
348 | |||
349 | fn check_infer(ra_fixture: &str, expect: Expect) { | ||
350 | let mut actual = infer(ra_fixture); | ||
351 | actual.push('\n'); | ||
352 | expect.assert_eq(&actual); | ||
353 | } | ||
354 | |||
355 | fn check_infer_with_mismatches(ra_fixture: &str, expect: Expect) { | ||
356 | let mut actual = infer_with_mismatches(ra_fixture, true); | ||
357 | actual.push('\n'); | ||
358 | expect.assert_eq(&actual); | ||
359 | } | ||
diff --git a/crates/ra_hir_ty/src/tests/coercion.rs b/crates/ra_hir_ty/src/tests/coercion.rs index d7fb6a962..17efd75cb 100644 --- a/crates/ra_hir_ty/src/tests/coercion.rs +++ b/crates/ra_hir_ty/src/tests/coercion.rs | |||
@@ -1,345 +1,381 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | use test_utils::mark; | 2 | use test_utils::mark; |
3 | 3 | ||
4 | use super::infer_with_mismatches; | 4 | use super::{check_infer, check_infer_with_mismatches}; |
5 | |||
6 | // Infer with some common definitions and impls. | ||
7 | fn infer(source: &str) -> String { | ||
8 | let defs = r#" | ||
9 | #[lang = "sized"] | ||
10 | pub trait Sized {} | ||
11 | #[lang = "unsize"] | ||
12 | pub trait Unsize<T: ?Sized> {} | ||
13 | #[lang = "coerce_unsized"] | ||
14 | pub trait CoerceUnsized<T> {} | ||
15 | |||
16 | impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} | ||
17 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} | ||
18 | "#; | ||
19 | |||
20 | // Append to the end to keep positions unchanged. | ||
21 | super::infer(&format!("{}{}", source, defs)) | ||
22 | } | ||
23 | 5 | ||
24 | #[test] | 6 | #[test] |
25 | fn infer_block_expr_type_mismatch() { | 7 | fn infer_block_expr_type_mismatch() { |
26 | assert_snapshot!( | 8 | check_infer( |
27 | infer(r#" | 9 | r" |
28 | fn test() { | 10 | fn test() { |
29 | let a: i32 = { 1i64 }; | 11 | let a: i32 = { 1i64 }; |
30 | } | 12 | } |
31 | "#), | 13 | ", |
32 | @r###" | 14 | expect![[r" |
33 | 10..40 '{ ...4 }; }': () | 15 | 10..40 '{ ...4 }; }': () |
34 | 20..21 'a': i32 | 16 | 20..21 'a': i32 |
35 | 29..37 '{ 1i64 }': i64 | 17 | 29..37 '{ 1i64 }': i64 |
36 | 31..35 '1i64': i64 | 18 | 31..35 '1i64': i64 |
37 | "###); | 19 | "]], |
20 | ); | ||
38 | } | 21 | } |
39 | 22 | ||
40 | #[test] | 23 | #[test] |
41 | fn coerce_places() { | 24 | fn coerce_places() { |
42 | assert_snapshot!( | 25 | check_infer( |
43 | infer(r#" | 26 | r#" |
44 | struct S<T> { a: T } | 27 | struct S<T> { a: T } |
45 | 28 | ||
46 | fn f<T>(_: &[T]) -> T { loop {} } | 29 | fn f<T>(_: &[T]) -> T { loop {} } |
47 | fn g<T>(_: S<&[T]>) -> T { loop {} } | 30 | fn g<T>(_: S<&[T]>) -> T { loop {} } |
48 | 31 | ||
49 | fn gen<T>() -> *mut [T; 2] { loop {} } | 32 | fn gen<T>() -> *mut [T; 2] { loop {} } |
50 | fn test1<U>() -> *mut [U] { | 33 | fn test1<U>() -> *mut [U] { |
51 | gen() | 34 | gen() |
52 | } | 35 | } |
53 | 36 | ||
54 | fn test2() { | 37 | fn test2() { |
55 | let arr: &[u8; 1] = &[1]; | 38 | let arr: &[u8; 1] = &[1]; |
56 | 39 | ||
57 | let a: &[_] = arr; | 40 | let a: &[_] = arr; |
58 | let b = f(arr); | 41 | let b = f(arr); |
59 | let c: &[_] = { arr }; | 42 | let c: &[_] = { arr }; |
60 | let d = g(S { a: arr }); | 43 | let d = g(S { a: arr }); |
61 | let e: [&[_]; 1] = [arr]; | 44 | let e: [&[_]; 1] = [arr]; |
62 | let f: [&[_]; 2] = [arr; 2]; | 45 | let f: [&[_]; 2] = [arr; 2]; |
63 | let g: (&[_], &[_]) = (arr, arr); | 46 | let g: (&[_], &[_]) = (arr, arr); |
64 | } | 47 | } |
65 | "#), | 48 | |
66 | @r###" | 49 | #[lang = "sized"] |
67 | 30..31 '_': &[T] | 50 | pub trait Sized {} |
68 | 44..55 '{ loop {} }': T | 51 | #[lang = "unsize"] |
69 | 46..53 'loop {}': ! | 52 | pub trait Unsize<T: ?Sized> {} |
70 | 51..53 '{}': () | 53 | #[lang = "coerce_unsized"] |
71 | 64..65 '_': S<&[T]> | 54 | pub trait CoerceUnsized<T> {} |
72 | 81..92 '{ loop {} }': T | 55 | |
73 | 83..90 'loop {}': ! | 56 | impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} |
74 | 88..90 '{}': () | 57 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} |
75 | 121..132 '{ loop {} }': *mut [T; _] | 58 | "#, |
76 | 123..130 'loop {}': ! | 59 | expect![[r" |
77 | 128..130 '{}': () | 60 | 30..31 '_': &[T] |
78 | 159..172 '{ gen() }': *mut [U] | 61 | 44..55 '{ loop {} }': T |
79 | 165..168 'gen': fn gen<U>() -> *mut [U; _] | 62 | 46..53 'loop {}': ! |
80 | 165..170 'gen()': *mut [U; _] | 63 | 51..53 '{}': () |
81 | 185..419 '{ ...rr); }': () | 64 | 64..65 '_': S<&[T]> |
82 | 195..198 'arr': &[u8; _] | 65 | 81..92 '{ loop {} }': T |
83 | 211..215 '&[1]': &[u8; _] | 66 | 83..90 'loop {}': ! |
84 | 212..215 '[1]': [u8; _] | 67 | 88..90 '{}': () |
85 | 213..214 '1': u8 | 68 | 121..132 '{ loop {} }': *mut [T; _] |
86 | 226..227 'a': &[u8] | 69 | 123..130 'loop {}': ! |
87 | 236..239 'arr': &[u8; _] | 70 | 128..130 '{}': () |
88 | 249..250 'b': u8 | 71 | 159..172 '{ gen() }': *mut [U] |
89 | 253..254 'f': fn f<u8>(&[u8]) -> u8 | 72 | 165..168 'gen': fn gen<U>() -> *mut [U; _] |
90 | 253..259 'f(arr)': u8 | 73 | 165..170 'gen()': *mut [U; _] |
91 | 255..258 'arr': &[u8; _] | 74 | 185..419 '{ ...rr); }': () |
92 | 269..270 'c': &[u8] | 75 | 195..198 'arr': &[u8; _] |
93 | 279..286 '{ arr }': &[u8] | 76 | 211..215 '&[1]': &[u8; _] |
94 | 281..284 'arr': &[u8; _] | 77 | 212..215 '[1]': [u8; _] |
95 | 296..297 'd': u8 | 78 | 213..214 '1': u8 |
96 | 300..301 'g': fn g<u8>(S<&[u8]>) -> u8 | 79 | 226..227 'a': &[u8] |
97 | 300..315 'g(S { a: arr })': u8 | 80 | 236..239 'arr': &[u8; _] |
98 | 302..314 'S { a: arr }': S<&[u8]> | 81 | 249..250 'b': u8 |
99 | 309..312 'arr': &[u8; _] | 82 | 253..254 'f': fn f<u8>(&[u8]) -> u8 |
100 | 325..326 'e': [&[u8]; _] | 83 | 253..259 'f(arr)': u8 |
101 | 340..345 '[arr]': [&[u8]; _] | 84 | 255..258 'arr': &[u8; _] |
102 | 341..344 'arr': &[u8; _] | 85 | 269..270 'c': &[u8] |
103 | 355..356 'f': [&[u8]; _] | 86 | 279..286 '{ arr }': &[u8] |
104 | 370..378 '[arr; 2]': [&[u8]; _] | 87 | 281..284 'arr': &[u8; _] |
105 | 371..374 'arr': &[u8; _] | 88 | 296..297 'd': u8 |
106 | 376..377 '2': usize | 89 | 300..301 'g': fn g<u8>(S<&[u8]>) -> u8 |
107 | 388..389 'g': (&[u8], &[u8]) | 90 | 300..315 'g(S { a: arr })': u8 |
108 | 406..416 '(arr, arr)': (&[u8], &[u8]) | 91 | 302..314 'S { a: arr }': S<&[u8]> |
109 | 407..410 'arr': &[u8; _] | 92 | 309..312 'arr': &[u8; _] |
110 | 412..415 'arr': &[u8; _] | 93 | 325..326 'e': [&[u8]; _] |
111 | "### | 94 | 340..345 '[arr]': [&[u8]; _] |
95 | 341..344 'arr': &[u8; _] | ||
96 | 355..356 'f': [&[u8]; _] | ||
97 | 370..378 '[arr; 2]': [&[u8]; _] | ||
98 | 371..374 'arr': &[u8; _] | ||
99 | 376..377 '2': usize | ||
100 | 388..389 'g': (&[u8], &[u8]) | ||
101 | 406..416 '(arr, arr)': (&[u8], &[u8]) | ||
102 | 407..410 'arr': &[u8; _] | ||
103 | 412..415 'arr': &[u8; _] | ||
104 | "]], | ||
112 | ); | 105 | ); |
113 | } | 106 | } |
114 | 107 | ||
115 | #[test] | 108 | #[test] |
116 | fn infer_let_stmt_coerce() { | 109 | fn infer_let_stmt_coerce() { |
117 | assert_snapshot!( | 110 | check_infer( |
118 | infer(r#" | 111 | r" |
119 | fn test() { | 112 | fn test() { |
120 | let x: &[isize] = &[1]; | 113 | let x: &[isize] = &[1]; |
121 | let x: *const [isize] = &[1]; | 114 | let x: *const [isize] = &[1]; |
122 | } | 115 | } |
123 | "#), | 116 | ", |
124 | @r###" | 117 | expect![[r" |
125 | 10..75 '{ ...[1]; }': () | 118 | 10..75 '{ ...[1]; }': () |
126 | 20..21 'x': &[isize] | 119 | 20..21 'x': &[isize] |
127 | 34..38 '&[1]': &[isize; _] | 120 | 34..38 '&[1]': &[isize; _] |
128 | 35..38 '[1]': [isize; _] | 121 | 35..38 '[1]': [isize; _] |
129 | 36..37 '1': isize | 122 | 36..37 '1': isize |
130 | 48..49 'x': *const [isize] | 123 | 48..49 'x': *const [isize] |
131 | 68..72 '&[1]': &[isize; _] | 124 | 68..72 '&[1]': &[isize; _] |
132 | 69..72 '[1]': [isize; _] | 125 | 69..72 '[1]': [isize; _] |
133 | 70..71 '1': isize | 126 | 70..71 '1': isize |
134 | "###); | 127 | "]], |
128 | ); | ||
135 | } | 129 | } |
136 | 130 | ||
137 | #[test] | 131 | #[test] |
138 | fn infer_custom_coerce_unsized() { | 132 | fn infer_custom_coerce_unsized() { |
139 | assert_snapshot!( | 133 | check_infer( |
140 | infer(r#" | 134 | r#" |
141 | struct A<T: ?Sized>(*const T); | 135 | struct A<T: ?Sized>(*const T); |
142 | struct B<T: ?Sized>(*const T); | 136 | struct B<T: ?Sized>(*const T); |
143 | struct C<T: ?Sized> { inner: *const T } | 137 | struct C<T: ?Sized> { inner: *const T } |
144 | 138 | ||
145 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {} | 139 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<B<U>> for B<T> {} |
146 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {} | 140 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<C<U>> for C<T> {} |
147 | 141 | ||
148 | fn foo1<T>(x: A<[T]>) -> A<[T]> { x } | 142 | fn foo1<T>(x: A<[T]>) -> A<[T]> { x } |
149 | fn foo2<T>(x: B<[T]>) -> B<[T]> { x } | 143 | fn foo2<T>(x: B<[T]>) -> B<[T]> { x } |
150 | fn foo3<T>(x: C<[T]>) -> C<[T]> { x } | 144 | fn foo3<T>(x: C<[T]>) -> C<[T]> { x } |
151 | 145 | ||
152 | fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { | 146 | fn test(a: A<[u8; 2]>, b: B<[u8; 2]>, c: C<[u8; 2]>) { |
153 | let d = foo1(a); | 147 | let d = foo1(a); |
154 | let e = foo2(b); | 148 | let e = foo2(b); |
155 | let f = foo3(c); | 149 | let f = foo3(c); |
156 | } | 150 | } |
157 | "#), | 151 | |
158 | @r###" | 152 | |
159 | 257..258 'x': A<[T]> | 153 | #[lang = "sized"] |
160 | 278..283 '{ x }': A<[T]> | 154 | pub trait Sized {} |
161 | 280..281 'x': A<[T]> | 155 | #[lang = "unsize"] |
162 | 295..296 'x': B<[T]> | 156 | pub trait Unsize<T: ?Sized> {} |
163 | 316..321 '{ x }': B<[T]> | 157 | #[lang = "coerce_unsized"] |
164 | 318..319 'x': B<[T]> | 158 | pub trait CoerceUnsized<T> {} |
165 | 333..334 'x': C<[T]> | 159 | |
166 | 354..359 '{ x }': C<[T]> | 160 | impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} |
167 | 356..357 'x': C<[T]> | 161 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} |
168 | 369..370 'a': A<[u8; _]> | 162 | "#, |
169 | 384..385 'b': B<[u8; _]> | 163 | expect![[r" |
170 | 399..400 'c': C<[u8; _]> | 164 | 257..258 'x': A<[T]> |
171 | 414..480 '{ ...(c); }': () | 165 | 278..283 '{ x }': A<[T]> |
172 | 424..425 'd': A<[{unknown}]> | 166 | 280..281 'x': A<[T]> |
173 | 428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]> | 167 | 295..296 'x': B<[T]> |
174 | 428..435 'foo1(a)': A<[{unknown}]> | 168 | 316..321 '{ x }': B<[T]> |
175 | 433..434 'a': A<[u8; _]> | 169 | 318..319 'x': B<[T]> |
176 | 445..446 'e': B<[u8]> | 170 | 333..334 'x': C<[T]> |
177 | 449..453 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]> | 171 | 354..359 '{ x }': C<[T]> |
178 | 449..456 'foo2(b)': B<[u8]> | 172 | 356..357 'x': C<[T]> |
179 | 454..455 'b': B<[u8; _]> | 173 | 369..370 'a': A<[u8; _]> |
180 | 466..467 'f': C<[u8]> | 174 | 384..385 'b': B<[u8; _]> |
181 | 470..474 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]> | 175 | 399..400 'c': C<[u8; _]> |
182 | 470..477 'foo3(c)': C<[u8]> | 176 | 414..480 '{ ...(c); }': () |
183 | 475..476 'c': C<[u8; _]> | 177 | 424..425 'd': A<[{unknown}]> |
184 | "### | 178 | 428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]> |
179 | 428..435 'foo1(a)': A<[{unknown}]> | ||
180 | 433..434 'a': A<[u8; _]> | ||
181 | 445..446 'e': B<[u8]> | ||
182 | 449..453 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]> | ||
183 | 449..456 'foo2(b)': B<[u8]> | ||
184 | 454..455 'b': B<[u8; _]> | ||
185 | 466..467 'f': C<[u8]> | ||
186 | 470..474 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]> | ||
187 | 470..477 'foo3(c)': C<[u8]> | ||
188 | 475..476 'c': C<[u8; _]> | ||
189 | "]], | ||
185 | ); | 190 | ); |
186 | } | 191 | } |
187 | 192 | ||
188 | #[test] | 193 | #[test] |
189 | fn infer_if_coerce() { | 194 | fn infer_if_coerce() { |
190 | assert_snapshot!( | 195 | check_infer( |
191 | infer(r#" | 196 | r#" |
192 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | 197 | fn foo<T>(x: &[T]) -> &[T] { loop {} } |
193 | fn test() { | 198 | fn test() { |
194 | let x = if true { | 199 | let x = if true { |
195 | foo(&[1]) | 200 | foo(&[1]) |
196 | } else { | 201 | } else { |
197 | &[1] | 202 | &[1] |
198 | }; | 203 | }; |
199 | } | 204 | } |
200 | "#), | 205 | |
201 | @r###" | 206 | |
202 | 10..11 'x': &[T] | 207 | #[lang = "sized"] |
203 | 27..38 '{ loop {} }': &[T] | 208 | pub trait Sized {} |
204 | 29..36 'loop {}': ! | 209 | #[lang = "unsize"] |
205 | 34..36 '{}': () | 210 | pub trait Unsize<T: ?Sized> {} |
206 | 49..125 '{ ... }; }': () | 211 | "#, |
207 | 59..60 'x': &[i32] | 212 | expect![[r" |
208 | 63..122 'if tru... }': &[i32] | 213 | 10..11 'x': &[T] |
209 | 66..70 'true': bool | 214 | 27..38 '{ loop {} }': &[T] |
210 | 71..96 '{ ... }': &[i32] | 215 | 29..36 'loop {}': ! |
211 | 81..84 'foo': fn foo<i32>(&[i32]) -> &[i32] | 216 | 34..36 '{}': () |
212 | 81..90 'foo(&[1])': &[i32] | 217 | 49..125 '{ ... }; }': () |
213 | 85..89 '&[1]': &[i32; _] | 218 | 59..60 'x': &[i32] |
214 | 86..89 '[1]': [i32; _] | 219 | 63..122 'if tru... }': &[i32] |
215 | 87..88 '1': i32 | 220 | 66..70 'true': bool |
216 | 102..122 '{ ... }': &[i32; _] | 221 | 71..96 '{ ... }': &[i32] |
217 | 112..116 '&[1]': &[i32; _] | 222 | 81..84 'foo': fn foo<i32>(&[i32]) -> &[i32] |
218 | 113..116 '[1]': [i32; _] | 223 | 81..90 'foo(&[1])': &[i32] |
219 | 114..115 '1': i32 | 224 | 85..89 '&[1]': &[i32; _] |
220 | "### | 225 | 86..89 '[1]': [i32; _] |
226 | 87..88 '1': i32 | ||
227 | 102..122 '{ ... }': &[i32; _] | ||
228 | 112..116 '&[1]': &[i32; _] | ||
229 | 113..116 '[1]': [i32; _] | ||
230 | 114..115 '1': i32 | ||
231 | "]], | ||
221 | ); | 232 | ); |
222 | } | 233 | } |
223 | 234 | ||
224 | #[test] | 235 | #[test] |
225 | fn infer_if_else_coerce() { | 236 | fn infer_if_else_coerce() { |
226 | assert_snapshot!( | 237 | check_infer( |
227 | infer(r#" | 238 | r#" |
228 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | 239 | fn foo<T>(x: &[T]) -> &[T] { loop {} } |
229 | fn test() { | 240 | fn test() { |
230 | let x = if true { | 241 | let x = if true { |
231 | &[1] | 242 | &[1] |
232 | } else { | 243 | } else { |
233 | foo(&[1]) | 244 | foo(&[1]) |
234 | }; | 245 | }; |
235 | } | 246 | } |
236 | "#), | 247 | |
237 | @r###" | 248 | #[lang = "sized"] |
238 | 10..11 'x': &[T] | 249 | pub trait Sized {} |
239 | 27..38 '{ loop {} }': &[T] | 250 | #[lang = "unsize"] |
240 | 29..36 'loop {}': ! | 251 | pub trait Unsize<T: ?Sized> {} |
241 | 34..36 '{}': () | 252 | #[lang = "coerce_unsized"] |
242 | 49..125 '{ ... }; }': () | 253 | pub trait CoerceUnsized<T> {} |
243 | 59..60 'x': &[i32] | 254 | |
244 | 63..122 'if tru... }': &[i32] | 255 | impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} |
245 | 66..70 'true': bool | 256 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} |
246 | 71..91 '{ ... }': &[i32; _] | 257 | "#, |
247 | 81..85 '&[1]': &[i32; _] | 258 | expect![[r" |
248 | 82..85 '[1]': [i32; _] | 259 | 10..11 'x': &[T] |
249 | 83..84 '1': i32 | 260 | 27..38 '{ loop {} }': &[T] |
250 | 97..122 '{ ... }': &[i32] | 261 | 29..36 'loop {}': ! |
251 | 107..110 'foo': fn foo<i32>(&[i32]) -> &[i32] | 262 | 34..36 '{}': () |
252 | 107..116 'foo(&[1])': &[i32] | 263 | 49..125 '{ ... }; }': () |
253 | 111..115 '&[1]': &[i32; _] | 264 | 59..60 'x': &[i32] |
254 | 112..115 '[1]': [i32; _] | 265 | 63..122 'if tru... }': &[i32] |
255 | 113..114 '1': i32 | 266 | 66..70 'true': bool |
256 | "### | 267 | 71..91 '{ ... }': &[i32; _] |
257 | ); | 268 | 81..85 '&[1]': &[i32; _] |
269 | 82..85 '[1]': [i32; _] | ||
270 | 83..84 '1': i32 | ||
271 | 97..122 '{ ... }': &[i32] | ||
272 | 107..110 'foo': fn foo<i32>(&[i32]) -> &[i32] | ||
273 | 107..116 'foo(&[1])': &[i32] | ||
274 | 111..115 '&[1]': &[i32; _] | ||
275 | 112..115 '[1]': [i32; _] | ||
276 | 113..114 '1': i32 | ||
277 | "]], | ||
278 | ) | ||
258 | } | 279 | } |
259 | 280 | ||
260 | #[test] | 281 | #[test] |
261 | fn infer_match_first_coerce() { | 282 | fn infer_match_first_coerce() { |
262 | assert_snapshot!( | 283 | check_infer( |
263 | infer(r#" | 284 | r#" |
264 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | 285 | fn foo<T>(x: &[T]) -> &[T] { loop {} } |
265 | fn test(i: i32) { | 286 | fn test(i: i32) { |
266 | let x = match i { | 287 | let x = match i { |
267 | 2 => foo(&[2]), | 288 | 2 => foo(&[2]), |
268 | 1 => &[1], | 289 | 1 => &[1], |
269 | _ => &[3], | 290 | _ => &[3], |
270 | }; | 291 | }; |
271 | } | 292 | } |
272 | "#), | 293 | |
273 | @r###" | 294 | #[lang = "sized"] |
274 | 10..11 'x': &[T] | 295 | pub trait Sized {} |
275 | 27..38 '{ loop {} }': &[T] | 296 | #[lang = "unsize"] |
276 | 29..36 'loop {}': ! | 297 | pub trait Unsize<T: ?Sized> {} |
277 | 34..36 '{}': () | 298 | "#, |
278 | 47..48 'i': i32 | 299 | expect![[r" |
279 | 55..149 '{ ... }; }': () | 300 | 10..11 'x': &[T] |
280 | 65..66 'x': &[i32] | 301 | 27..38 '{ loop {} }': &[T] |
281 | 69..146 'match ... }': &[i32] | 302 | 29..36 'loop {}': ! |
282 | 75..76 'i': i32 | 303 | 34..36 '{}': () |
283 | 87..88 '2': i32 | 304 | 47..48 'i': i32 |
284 | 87..88 '2': i32 | 305 | 55..149 '{ ... }; }': () |
285 | 92..95 'foo': fn foo<i32>(&[i32]) -> &[i32] | 306 | 65..66 'x': &[i32] |
286 | 92..101 'foo(&[2])': &[i32] | 307 | 69..146 'match ... }': &[i32] |
287 | 96..100 '&[2]': &[i32; _] | 308 | 75..76 'i': i32 |
288 | 97..100 '[2]': [i32; _] | 309 | 87..88 '2': i32 |
289 | 98..99 '2': i32 | 310 | 87..88 '2': i32 |
290 | 111..112 '1': i32 | 311 | 92..95 'foo': fn foo<i32>(&[i32]) -> &[i32] |
291 | 111..112 '1': i32 | 312 | 92..101 'foo(&[2])': &[i32] |
292 | 116..120 '&[1]': &[i32; _] | 313 | 96..100 '&[2]': &[i32; _] |
293 | 117..120 '[1]': [i32; _] | 314 | 97..100 '[2]': [i32; _] |
294 | 118..119 '1': i32 | 315 | 98..99 '2': i32 |
295 | 130..131 '_': i32 | 316 | 111..112 '1': i32 |
296 | 135..139 '&[3]': &[i32; _] | 317 | 111..112 '1': i32 |
297 | 136..139 '[3]': [i32; _] | 318 | 116..120 '&[1]': &[i32; _] |
298 | 137..138 '3': i32 | 319 | 117..120 '[1]': [i32; _] |
299 | "### | 320 | 118..119 '1': i32 |
321 | 130..131 '_': i32 | ||
322 | 135..139 '&[3]': &[i32; _] | ||
323 | 136..139 '[3]': [i32; _] | ||
324 | 137..138 '3': i32 | ||
325 | "]], | ||
300 | ); | 326 | ); |
301 | } | 327 | } |
302 | 328 | ||
303 | #[test] | 329 | #[test] |
304 | fn infer_match_second_coerce() { | 330 | fn infer_match_second_coerce() { |
305 | assert_snapshot!( | 331 | check_infer( |
306 | infer(r#" | 332 | r#" |
307 | fn foo<T>(x: &[T]) -> &[T] { loop {} } | 333 | fn foo<T>(x: &[T]) -> &[T] { loop {} } |
308 | fn test(i: i32) { | 334 | fn test(i: i32) { |
309 | let x = match i { | 335 | let x = match i { |
310 | 1 => &[1], | 336 | 1 => &[1], |
311 | 2 => foo(&[2]), | 337 | 2 => foo(&[2]), |
312 | _ => &[3], | 338 | _ => &[3], |
313 | }; | 339 | }; |
314 | } | 340 | } |
315 | "#), | 341 | |
316 | @r###" | 342 | #[lang = "sized"] |
317 | 10..11 'x': &[T] | 343 | pub trait Sized {} |
318 | 27..38 '{ loop {} }': &[T] | 344 | #[lang = "unsize"] |
319 | 29..36 'loop {}': ! | 345 | pub trait Unsize<T: ?Sized> {} |
320 | 34..36 '{}': () | 346 | #[lang = "coerce_unsized"] |
321 | 47..48 'i': i32 | 347 | pub trait CoerceUnsized<T> {} |
322 | 55..149 '{ ... }; }': () | 348 | |
323 | 65..66 'x': &[i32] | 349 | impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} |
324 | 69..146 'match ... }': &[i32] | 350 | impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} |
325 | 75..76 'i': i32 | 351 | "#, |
326 | 87..88 '1': i32 | 352 | expect![[r" |
327 | 87..88 '1': i32 | 353 | 10..11 'x': &[T] |
328 | 92..96 '&[1]': &[i32; _] | 354 | 27..38 '{ loop {} }': &[T] |
329 | 93..96 '[1]': [i32; _] | 355 | 29..36 'loop {}': ! |
330 | 94..95 '1': i32 | 356 | 34..36 '{}': () |
331 | 106..107 '2': i32 | 357 | 47..48 'i': i32 |
332 | 106..107 '2': i32 | 358 | 55..149 '{ ... }; }': () |
333 | 111..114 'foo': fn foo<i32>(&[i32]) -> &[i32] | 359 | 65..66 'x': &[i32] |
334 | 111..120 'foo(&[2])': &[i32] | 360 | 69..146 'match ... }': &[i32] |
335 | 115..119 '&[2]': &[i32; _] | 361 | 75..76 'i': i32 |
336 | 116..119 '[2]': [i32; _] | 362 | 87..88 '1': i32 |
337 | 117..118 '2': i32 | 363 | 87..88 '1': i32 |
338 | 130..131 '_': i32 | 364 | 92..96 '&[1]': &[i32; _] |
339 | 135..139 '&[3]': &[i32; _] | 365 | 93..96 '[1]': [i32; _] |
340 | 136..139 '[3]': [i32; _] | 366 | 94..95 '1': i32 |
341 | 137..138 '3': i32 | 367 | 106..107 '2': i32 |
342 | "### | 368 | 106..107 '2': i32 |
369 | 111..114 'foo': fn foo<i32>(&[i32]) -> &[i32] | ||
370 | 111..120 'foo(&[2])': &[i32] | ||
371 | 115..119 '&[2]': &[i32; _] | ||
372 | 116..119 '[2]': [i32; _] | ||
373 | 117..118 '2': i32 | ||
374 | 130..131 '_': i32 | ||
375 | 135..139 '&[3]': &[i32; _] | ||
376 | 136..139 '[3]': [i32; _] | ||
377 | 137..138 '3': i32 | ||
378 | "]], | ||
343 | ); | 379 | ); |
344 | } | 380 | } |
345 | 381 | ||
@@ -347,360 +383,361 @@ fn test(i: i32) { | |||
347 | fn coerce_merge_one_by_one1() { | 383 | fn coerce_merge_one_by_one1() { |
348 | mark::check!(coerce_merge_fail_fallback); | 384 | mark::check!(coerce_merge_fail_fallback); |
349 | 385 | ||
350 | assert_snapshot!( | 386 | check_infer( |
351 | infer(r#" | 387 | r" |
352 | fn test() { | 388 | fn test() { |
353 | let t = &mut 1; | 389 | let t = &mut 1; |
354 | let x = match 1 { | 390 | let x = match 1 { |
355 | 1 => t as *mut i32, | 391 | 1 => t as *mut i32, |
356 | 2 => t as &i32, | 392 | 2 => t as &i32, |
357 | _ => t as *const i32, | 393 | _ => t as *const i32, |
358 | }; | 394 | }; |
359 | } | 395 | } |
360 | "#), | 396 | ", |
361 | @r###" | 397 | expect![[r" |
362 | 10..144 '{ ... }; }': () | 398 | 10..144 '{ ... }; }': () |
363 | 20..21 't': &mut i32 | 399 | 20..21 't': &mut i32 |
364 | 24..30 '&mut 1': &mut i32 | 400 | 24..30 '&mut 1': &mut i32 |
365 | 29..30 '1': i32 | 401 | 29..30 '1': i32 |
366 | 40..41 'x': *const i32 | 402 | 40..41 'x': *const i32 |
367 | 44..141 'match ... }': *const i32 | 403 | 44..141 'match ... }': *const i32 |
368 | 50..51 '1': i32 | 404 | 50..51 '1': i32 |
369 | 62..63 '1': i32 | 405 | 62..63 '1': i32 |
370 | 62..63 '1': i32 | 406 | 62..63 '1': i32 |
371 | 67..68 't': &mut i32 | 407 | 67..68 't': &mut i32 |
372 | 67..80 't as *mut i32': *mut i32 | 408 | 67..80 't as *mut i32': *mut i32 |
373 | 90..91 '2': i32 | 409 | 90..91 '2': i32 |
374 | 90..91 '2': i32 | 410 | 90..91 '2': i32 |
375 | 95..96 't': &mut i32 | 411 | 95..96 't': &mut i32 |
376 | 95..104 't as &i32': &i32 | 412 | 95..104 't as &i32': &i32 |
377 | 114..115 '_': i32 | 413 | 114..115 '_': i32 |
378 | 119..120 't': &mut i32 | 414 | 119..120 't': &mut i32 |
379 | 119..134 't as *const i32': *const i32 | 415 | 119..134 't as *const i32': *const i32 |
380 | "### | 416 | "]], |
381 | ); | 417 | ); |
382 | } | 418 | } |
383 | 419 | ||
384 | #[test] | 420 | #[test] |
385 | fn return_coerce_unknown() { | 421 | fn return_coerce_unknown() { |
386 | assert_snapshot!( | 422 | check_infer_with_mismatches( |
387 | infer_with_mismatches(r#" | 423 | r" |
388 | fn foo() -> u32 { | 424 | fn foo() -> u32 { |
389 | return unknown; | 425 | return unknown; |
390 | } | 426 | } |
391 | "#, true), | 427 | ", |
392 | @r###" | 428 | expect![[r" |
393 | 16..39 '{ ...own; }': u32 | 429 | 16..39 '{ ...own; }': u32 |
394 | 22..36 'return unknown': ! | 430 | 22..36 'return unknown': ! |
395 | 29..36 'unknown': u32 | 431 | 29..36 'unknown': u32 |
396 | "### | 432 | "]], |
397 | ); | 433 | ); |
398 | } | 434 | } |
399 | 435 | ||
400 | #[test] | 436 | #[test] |
401 | fn coerce_autoderef() { | 437 | fn coerce_autoderef() { |
402 | assert_snapshot!( | 438 | check_infer_with_mismatches( |
403 | infer_with_mismatches(r#" | 439 | r" |
404 | struct Foo; | 440 | struct Foo; |
405 | fn takes_ref_foo(x: &Foo) {} | 441 | fn takes_ref_foo(x: &Foo) {} |
406 | fn test() { | 442 | fn test() { |
407 | takes_ref_foo(&Foo); | 443 | takes_ref_foo(&Foo); |
408 | takes_ref_foo(&&Foo); | 444 | takes_ref_foo(&&Foo); |
409 | takes_ref_foo(&&&Foo); | 445 | takes_ref_foo(&&&Foo); |
410 | } | 446 | } |
411 | "#, true), | 447 | ", |
412 | @r###" | 448 | expect![[r" |
413 | 29..30 'x': &Foo | 449 | 29..30 'x': &Foo |
414 | 38..40 '{}': () | 450 | 38..40 '{}': () |
415 | 51..132 '{ ...oo); }': () | 451 | 51..132 '{ ...oo); }': () |
416 | 57..70 'takes_ref_foo': fn takes_ref_foo(&Foo) | 452 | 57..70 'takes_ref_foo': fn takes_ref_foo(&Foo) |
417 | 57..76 'takes_...(&Foo)': () | 453 | 57..76 'takes_...(&Foo)': () |
418 | 71..75 '&Foo': &Foo | 454 | 71..75 '&Foo': &Foo |
419 | 72..75 'Foo': Foo | 455 | 72..75 'Foo': Foo |
420 | 82..95 'takes_ref_foo': fn takes_ref_foo(&Foo) | 456 | 82..95 'takes_ref_foo': fn takes_ref_foo(&Foo) |
421 | 82..102 'takes_...&&Foo)': () | 457 | 82..102 'takes_...&&Foo)': () |
422 | 96..101 '&&Foo': &&Foo | 458 | 96..101 '&&Foo': &&Foo |
423 | 97..101 '&Foo': &Foo | 459 | 97..101 '&Foo': &Foo |
424 | 98..101 'Foo': Foo | 460 | 98..101 'Foo': Foo |
425 | 108..121 'takes_ref_foo': fn takes_ref_foo(&Foo) | 461 | 108..121 'takes_ref_foo': fn takes_ref_foo(&Foo) |
426 | 108..129 'takes_...&&Foo)': () | 462 | 108..129 'takes_...&&Foo)': () |
427 | 122..128 '&&&Foo': &&&Foo | 463 | 122..128 '&&&Foo': &&&Foo |
428 | 123..128 '&&Foo': &&Foo | 464 | 123..128 '&&Foo': &&Foo |
429 | 124..128 '&Foo': &Foo | 465 | 124..128 '&Foo': &Foo |
430 | 125..128 'Foo': Foo | 466 | 125..128 'Foo': Foo |
431 | "### | 467 | "]], |
432 | ); | 468 | ); |
433 | } | 469 | } |
434 | 470 | ||
435 | #[test] | 471 | #[test] |
436 | fn coerce_autoderef_generic() { | 472 | fn coerce_autoderef_generic() { |
437 | assert_snapshot!( | 473 | check_infer_with_mismatches( |
438 | infer_with_mismatches(r#" | 474 | r" |
439 | struct Foo; | 475 | struct Foo; |
440 | fn takes_ref<T>(x: &T) -> T { *x } | 476 | fn takes_ref<T>(x: &T) -> T { *x } |
441 | fn test() { | 477 | fn test() { |
442 | takes_ref(&Foo); | 478 | takes_ref(&Foo); |
443 | takes_ref(&&Foo); | 479 | takes_ref(&&Foo); |
444 | takes_ref(&&&Foo); | 480 | takes_ref(&&&Foo); |
445 | } | 481 | } |
446 | "#, true), | 482 | ", |
447 | @r###" | 483 | expect![[r" |
448 | 28..29 'x': &T | 484 | 28..29 'x': &T |
449 | 40..46 '{ *x }': T | 485 | 40..46 '{ *x }': T |
450 | 42..44 '*x': T | 486 | 42..44 '*x': T |
451 | 43..44 'x': &T | 487 | 43..44 'x': &T |
452 | 57..126 '{ ...oo); }': () | 488 | 57..126 '{ ...oo); }': () |
453 | 63..72 'takes_ref': fn takes_ref<Foo>(&Foo) -> Foo | 489 | 63..72 'takes_ref': fn takes_ref<Foo>(&Foo) -> Foo |
454 | 63..78 'takes_ref(&Foo)': Foo | 490 | 63..78 'takes_ref(&Foo)': Foo |
455 | 73..77 '&Foo': &Foo | 491 | 73..77 '&Foo': &Foo |
456 | 74..77 'Foo': Foo | 492 | 74..77 'Foo': Foo |
457 | 84..93 'takes_ref': fn takes_ref<&Foo>(&&Foo) -> &Foo | 493 | 84..93 'takes_ref': fn takes_ref<&Foo>(&&Foo) -> &Foo |
458 | 84..100 'takes_...&&Foo)': &Foo | 494 | 84..100 'takes_...&&Foo)': &Foo |
459 | 94..99 '&&Foo': &&Foo | 495 | 94..99 '&&Foo': &&Foo |
460 | 95..99 '&Foo': &Foo | 496 | 95..99 '&Foo': &Foo |
461 | 96..99 'Foo': Foo | 497 | 96..99 'Foo': Foo |
462 | 106..115 'takes_ref': fn takes_ref<&&Foo>(&&&Foo) -> &&Foo | 498 | 106..115 'takes_ref': fn takes_ref<&&Foo>(&&&Foo) -> &&Foo |
463 | 106..123 'takes_...&&Foo)': &&Foo | 499 | 106..123 'takes_...&&Foo)': &&Foo |
464 | 116..122 '&&&Foo': &&&Foo | 500 | 116..122 '&&&Foo': &&&Foo |
465 | 117..122 '&&Foo': &&Foo | 501 | 117..122 '&&Foo': &&Foo |
466 | 118..122 '&Foo': &Foo | 502 | 118..122 '&Foo': &Foo |
467 | 119..122 'Foo': Foo | 503 | 119..122 'Foo': Foo |
468 | "### | 504 | "]], |
469 | ); | 505 | ); |
470 | } | 506 | } |
471 | 507 | ||
472 | #[test] | 508 | #[test] |
473 | fn coerce_autoderef_block() { | 509 | fn coerce_autoderef_block() { |
474 | assert_snapshot!( | 510 | check_infer_with_mismatches( |
475 | infer_with_mismatches(r#" | 511 | r#" |
476 | struct String {} | 512 | struct String {} |
477 | #[lang = "deref"] | 513 | #[lang = "deref"] |
478 | trait Deref { type Target; } | 514 | trait Deref { type Target; } |
479 | impl Deref for String { type Target = str; } | 515 | impl Deref for String { type Target = str; } |
480 | fn takes_ref_str(x: &str) {} | 516 | fn takes_ref_str(x: &str) {} |
481 | fn returns_string() -> String { loop {} } | 517 | fn returns_string() -> String { loop {} } |
482 | fn test() { | 518 | fn test() { |
483 | takes_ref_str(&{ returns_string() }); | 519 | takes_ref_str(&{ returns_string() }); |
484 | } | 520 | } |
485 | "#, true), | 521 | "#, |
486 | @r###" | 522 | expect![[r" |
487 | 126..127 'x': &str | 523 | 126..127 'x': &str |
488 | 135..137 '{}': () | 524 | 135..137 '{}': () |
489 | 168..179 '{ loop {} }': String | 525 | 168..179 '{ loop {} }': String |
490 | 170..177 'loop {}': ! | 526 | 170..177 'loop {}': ! |
491 | 175..177 '{}': () | 527 | 175..177 '{}': () |
492 | 190..235 '{ ... }); }': () | 528 | 190..235 '{ ... }); }': () |
493 | 196..209 'takes_ref_str': fn takes_ref_str(&str) | 529 | 196..209 'takes_ref_str': fn takes_ref_str(&str) |
494 | 196..232 'takes_...g() })': () | 530 | 196..232 'takes_...g() })': () |
495 | 210..231 '&{ ret...ng() }': &String | 531 | 210..231 '&{ ret...ng() }': &String |
496 | 211..231 '{ retu...ng() }': String | 532 | 211..231 '{ retu...ng() }': String |
497 | 213..227 'returns_string': fn returns_string() -> String | 533 | 213..227 'returns_string': fn returns_string() -> String |
498 | 213..229 'return...ring()': String | 534 | 213..229 'return...ring()': String |
499 | "### | 535 | "]], |
500 | ); | 536 | ); |
501 | } | 537 | } |
502 | 538 | ||
503 | #[test] | 539 | #[test] |
504 | fn closure_return_coerce() { | 540 | fn closure_return_coerce() { |
505 | assert_snapshot!( | 541 | check_infer_with_mismatches( |
506 | infer_with_mismatches(r#" | 542 | r" |
507 | fn foo() { | 543 | fn foo() { |
508 | let x = || { | 544 | let x = || { |
509 | if true { | 545 | if true { |
510 | return &1u32; | 546 | return &1u32; |
547 | } | ||
548 | &&1u32 | ||
549 | }; | ||
511 | } | 550 | } |
512 | &&1u32 | 551 | ", |
513 | }; | 552 | expect![[r" |
514 | } | 553 | 9..105 '{ ... }; }': () |
515 | "#, true), | 554 | 19..20 'x': || -> &u32 |
516 | @r###" | 555 | 23..102 '|| { ... }': || -> &u32 |
517 | 9..105 '{ ... }; }': () | 556 | 26..102 '{ ... }': &u32 |
518 | 19..20 'x': || -> &u32 | 557 | 36..81 'if tru... }': () |
519 | 23..102 '|| { ... }': || -> &u32 | 558 | 39..43 'true': bool |
520 | 26..102 '{ ... }': &u32 | 559 | 44..81 '{ ... }': () |
521 | 36..81 'if tru... }': () | 560 | 58..70 'return &1u32': ! |
522 | 39..43 'true': bool | 561 | 65..70 '&1u32': &u32 |
523 | 44..81 '{ ... }': () | 562 | 66..70 '1u32': u32 |
524 | 58..70 'return &1u32': ! | 563 | 90..96 '&&1u32': &&u32 |
525 | 65..70 '&1u32': &u32 | 564 | 91..96 '&1u32': &u32 |
526 | 66..70 '1u32': u32 | 565 | 92..96 '1u32': u32 |
527 | 90..96 '&&1u32': &&u32 | 566 | "]], |
528 | 91..96 '&1u32': &u32 | ||
529 | 92..96 '1u32': u32 | ||
530 | "### | ||
531 | ); | 567 | ); |
532 | } | 568 | } |
533 | 569 | ||
534 | #[test] | 570 | #[test] |
535 | fn coerce_fn_item_to_fn_ptr() { | 571 | fn coerce_fn_item_to_fn_ptr() { |
536 | assert_snapshot!( | 572 | check_infer_with_mismatches( |
537 | infer_with_mismatches(r#" | 573 | r" |
538 | fn foo(x: u32) -> isize { 1 } | 574 | fn foo(x: u32) -> isize { 1 } |
539 | fn test() { | 575 | fn test() { |
540 | let f: fn(u32) -> isize = foo; | 576 | let f: fn(u32) -> isize = foo; |
541 | } | 577 | } |
542 | "#, true), | 578 | ", |
543 | @r###" | 579 | expect![[r" |
544 | 7..8 'x': u32 | 580 | 7..8 'x': u32 |
545 | 24..29 '{ 1 }': isize | 581 | 24..29 '{ 1 }': isize |
546 | 26..27 '1': isize | 582 | 26..27 '1': isize |
547 | 40..78 '{ ...foo; }': () | 583 | 40..78 '{ ...foo; }': () |
548 | 50..51 'f': fn(u32) -> isize | 584 | 50..51 'f': fn(u32) -> isize |
549 | 72..75 'foo': fn foo(u32) -> isize | 585 | 72..75 'foo': fn foo(u32) -> isize |
550 | "### | 586 | "]], |
551 | ); | 587 | ); |
552 | } | 588 | } |
553 | 589 | ||
554 | #[test] | 590 | #[test] |
555 | fn coerce_fn_items_in_match_arms() { | 591 | fn coerce_fn_items_in_match_arms() { |
556 | mark::check!(coerce_fn_reification); | 592 | mark::check!(coerce_fn_reification); |
557 | assert_snapshot!( | 593 | |
558 | infer_with_mismatches(r#" | 594 | check_infer_with_mismatches( |
559 | fn foo1(x: u32) -> isize { 1 } | 595 | r" |
560 | fn foo2(x: u32) -> isize { 2 } | 596 | fn foo1(x: u32) -> isize { 1 } |
561 | fn foo3(x: u32) -> isize { 3 } | 597 | fn foo2(x: u32) -> isize { 2 } |
562 | fn test() { | 598 | fn foo3(x: u32) -> isize { 3 } |
563 | let x = match 1 { | 599 | fn test() { |
564 | 1 => foo1, | 600 | let x = match 1 { |
565 | 2 => foo2, | 601 | 1 => foo1, |
566 | _ => foo3, | 602 | 2 => foo2, |
567 | }; | 603 | _ => foo3, |
568 | } | 604 | }; |
569 | "#, true), | 605 | } |
570 | @r###" | 606 | ", |
571 | 8..9 'x': u32 | 607 | expect![[r" |
572 | 25..30 '{ 1 }': isize | 608 | 8..9 'x': u32 |
573 | 27..28 '1': isize | 609 | 25..30 '{ 1 }': isize |
574 | 39..40 'x': u32 | 610 | 27..28 '1': isize |
575 | 56..61 '{ 2 }': isize | 611 | 39..40 'x': u32 |
576 | 58..59 '2': isize | 612 | 56..61 '{ 2 }': isize |
577 | 70..71 'x': u32 | 613 | 58..59 '2': isize |
578 | 87..92 '{ 3 }': isize | 614 | 70..71 'x': u32 |
579 | 89..90 '3': isize | 615 | 87..92 '{ 3 }': isize |
580 | 103..192 '{ ... }; }': () | 616 | 89..90 '3': isize |
581 | 113..114 'x': fn(u32) -> isize | 617 | 103..192 '{ ... }; }': () |
582 | 117..189 'match ... }': fn(u32) -> isize | 618 | 113..114 'x': fn(u32) -> isize |
583 | 123..124 '1': i32 | 619 | 117..189 'match ... }': fn(u32) -> isize |
584 | 135..136 '1': i32 | 620 | 123..124 '1': i32 |
585 | 135..136 '1': i32 | 621 | 135..136 '1': i32 |
586 | 140..144 'foo1': fn foo1(u32) -> isize | 622 | 135..136 '1': i32 |
587 | 154..155 '2': i32 | 623 | 140..144 'foo1': fn foo1(u32) -> isize |
588 | 154..155 '2': i32 | 624 | 154..155 '2': i32 |
589 | 159..163 'foo2': fn foo2(u32) -> isize | 625 | 154..155 '2': i32 |
590 | 173..174 '_': i32 | 626 | 159..163 'foo2': fn foo2(u32) -> isize |
591 | 178..182 'foo3': fn foo3(u32) -> isize | 627 | 173..174 '_': i32 |
592 | "### | 628 | 178..182 'foo3': fn foo3(u32) -> isize |
629 | "]], | ||
593 | ); | 630 | ); |
594 | } | 631 | } |
595 | 632 | ||
596 | #[test] | 633 | #[test] |
597 | fn coerce_closure_to_fn_ptr() { | 634 | fn coerce_closure_to_fn_ptr() { |
598 | assert_snapshot!( | 635 | check_infer_with_mismatches( |
599 | infer_with_mismatches(r#" | 636 | r" |
600 | fn test() { | 637 | fn test() { |
601 | let f: fn(u32) -> isize = |x| { 1 }; | 638 | let f: fn(u32) -> isize = |x| { 1 }; |
602 | } | 639 | } |
603 | "#, true), | 640 | ", |
604 | @r###" | 641 | expect![[r" |
605 | 10..54 '{ ...1 }; }': () | 642 | 10..54 '{ ...1 }; }': () |
606 | 20..21 'f': fn(u32) -> isize | 643 | 20..21 'f': fn(u32) -> isize |
607 | 42..51 '|x| { 1 }': |u32| -> isize | 644 | 42..51 '|x| { 1 }': |u32| -> isize |
608 | 43..44 'x': u32 | 645 | 43..44 'x': u32 |
609 | 46..51 '{ 1 }': isize | 646 | 46..51 '{ 1 }': isize |
610 | 48..49 '1': isize | 647 | 48..49 '1': isize |
611 | "### | 648 | "]], |
612 | ); | 649 | ); |
613 | } | 650 | } |
614 | 651 | ||
615 | #[test] | 652 | #[test] |
616 | fn coerce_placeholder_ref() { | 653 | fn coerce_placeholder_ref() { |
617 | // placeholders should unify, even behind references | 654 | // placeholders should unify, even behind references |
618 | assert_snapshot!( | 655 | check_infer_with_mismatches( |
619 | infer_with_mismatches(r#" | 656 | r" |
620 | struct S<T> { t: T } | 657 | struct S<T> { t: T } |
621 | impl<TT> S<TT> { | 658 | impl<TT> S<TT> { |
622 | fn get(&self) -> &TT { | 659 | fn get(&self) -> &TT { |
623 | &self.t | 660 | &self.t |
624 | } | 661 | } |
625 | } | 662 | } |
626 | "#, true), | 663 | ", |
627 | @r###" | 664 | expect![[r" |
628 | 50..54 'self': &S<TT> | 665 | 50..54 'self': &S<TT> |
629 | 63..86 '{ ... }': &TT | 666 | 63..86 '{ ... }': &TT |
630 | 73..80 '&self.t': &TT | 667 | 73..80 '&self.t': &TT |
631 | 74..78 'self': &S<TT> | 668 | 74..78 'self': &S<TT> |
632 | 74..80 'self.t': TT | 669 | 74..80 'self.t': TT |
633 | "### | 670 | "]], |
634 | ); | 671 | ); |
635 | } | 672 | } |
636 | 673 | ||
637 | #[test] | 674 | #[test] |
638 | fn coerce_unsize_array() { | 675 | fn coerce_unsize_array() { |
639 | assert_snapshot!( | 676 | check_infer_with_mismatches( |
640 | infer_with_mismatches(r#" | 677 | r#" |
641 | #[lang = "unsize"] | 678 | #[lang = "unsize"] |
642 | pub trait Unsize<T> {} | 679 | pub trait Unsize<T> {} |
643 | #[lang = "coerce_unsized"] | 680 | #[lang = "coerce_unsized"] |
644 | pub trait CoerceUnsized<T> {} | 681 | pub trait CoerceUnsized<T> {} |
645 | 682 | ||
646 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 683 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
647 | 684 | ||
648 | fn test() { | 685 | fn test() { |
649 | let f: &[usize] = &[1, 2, 3]; | 686 | let f: &[usize] = &[1, 2, 3]; |
650 | } | 687 | } |
651 | "#, true), | 688 | "#, |
652 | @r###" | 689 | expect![[r" |
653 | 161..198 '{ ... 3]; }': () | 690 | 161..198 '{ ... 3]; }': () |
654 | 171..172 'f': &[usize] | 691 | 171..172 'f': &[usize] |
655 | 185..195 '&[1, 2, 3]': &[usize; _] | 692 | 185..195 '&[1, 2, 3]': &[usize; _] |
656 | 186..195 '[1, 2, 3]': [usize; _] | 693 | 186..195 '[1, 2, 3]': [usize; _] |
657 | 187..188 '1': usize | 694 | 187..188 '1': usize |
658 | 190..191 '2': usize | 695 | 190..191 '2': usize |
659 | 193..194 '3': usize | 696 | 193..194 '3': usize |
660 | "### | 697 | "]], |
661 | ); | 698 | ); |
662 | } | 699 | } |
663 | 700 | ||
664 | #[test] | 701 | #[test] |
665 | fn coerce_unsize_trait_object_simple() { | 702 | fn coerce_unsize_trait_object_simple() { |
666 | assert_snapshot!( | 703 | check_infer_with_mismatches( |
667 | infer_with_mismatches(r#" | 704 | r#" |
668 | #[lang = "sized"] | 705 | #[lang = "sized"] |
669 | pub trait Sized {} | 706 | pub trait Sized {} |
670 | #[lang = "unsize"] | 707 | #[lang = "unsize"] |
671 | pub trait Unsize<T> {} | 708 | pub trait Unsize<T> {} |
672 | #[lang = "coerce_unsized"] | 709 | #[lang = "coerce_unsized"] |
673 | pub trait CoerceUnsized<T> {} | 710 | pub trait CoerceUnsized<T> {} |
674 | 711 | ||
675 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 712 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
676 | 713 | ||
677 | trait Foo<T, U> {} | 714 | trait Foo<T, U> {} |
678 | trait Bar<U, T, X>: Foo<T, U> {} | 715 | trait Bar<U, T, X>: Foo<T, U> {} |
679 | trait Baz<T, X>: Bar<usize, T, X> {} | 716 | trait Baz<T, X>: Bar<usize, T, X> {} |
680 | 717 | ||
681 | struct S<T, X>; | 718 | struct S<T, X>; |
682 | impl<T, X> Foo<T, usize> for S<T, X> {} | 719 | impl<T, X> Foo<T, usize> for S<T, X> {} |
683 | impl<T, X> Bar<usize, T, X> for S<T, X> {} | 720 | impl<T, X> Bar<usize, T, X> for S<T, X> {} |
684 | impl<T, X> Baz<T, X> for S<T, X> {} | 721 | impl<T, X> Baz<T, X> for S<T, X> {} |
685 | 722 | ||
686 | fn test() { | 723 | fn test() { |
687 | let obj: &dyn Baz<i8, i16> = &S; | 724 | let obj: &dyn Baz<i8, i16> = &S; |
688 | let obj: &dyn Bar<_, i8, i16> = &S; | 725 | let obj: &dyn Bar<_, i8, i16> = &S; |
689 | let obj: &dyn Foo<i8, _> = &S; | 726 | let obj: &dyn Foo<i8, _> = &S; |
690 | } | 727 | } |
691 | "#, true), | 728 | "#, |
692 | @r###" | 729 | expect![[r" |
693 | 424..539 '{ ... &S; }': () | 730 | 424..539 '{ ... &S; }': () |
694 | 434..437 'obj': &dyn Baz<i8, i16> | 731 | 434..437 'obj': &dyn Baz<i8, i16> |
695 | 459..461 '&S': &S<i8, i16> | 732 | 459..461 '&S': &S<i8, i16> |
696 | 460..461 'S': S<i8, i16> | 733 | 460..461 'S': S<i8, i16> |
697 | 471..474 'obj': &dyn Bar<usize, i8, i16> | 734 | 471..474 'obj': &dyn Bar<usize, i8, i16> |
698 | 499..501 '&S': &S<i8, i16> | 735 | 499..501 '&S': &S<i8, i16> |
699 | 500..501 'S': S<i8, i16> | 736 | 500..501 'S': S<i8, i16> |
700 | 511..514 'obj': &dyn Foo<i8, usize> | 737 | 511..514 'obj': &dyn Foo<i8, usize> |
701 | 534..536 '&S': &S<i8, {unknown}> | 738 | 534..536 '&S': &S<i8, {unknown}> |
702 | 535..536 'S': S<i8, {unknown}> | 739 | 535..536 'S': S<i8, {unknown}> |
703 | "### | 740 | "]], |
704 | ); | 741 | ); |
705 | } | 742 | } |
706 | 743 | ||
@@ -709,90 +746,90 @@ fn test() { | |||
709 | // it. We used to support it, but Chalk doesn't. | 746 | // it. We used to support it, but Chalk doesn't. |
710 | #[ignore] | 747 | #[ignore] |
711 | fn coerce_unsize_trait_object_to_trait_object() { | 748 | fn coerce_unsize_trait_object_to_trait_object() { |
712 | assert_snapshot!( | 749 | check_infer_with_mismatches( |
713 | infer_with_mismatches(r#" | 750 | r#" |
714 | #[lang = "sized"] | 751 | #[lang = "sized"] |
715 | pub trait Sized {} | 752 | pub trait Sized {} |
716 | #[lang = "unsize"] | 753 | #[lang = "unsize"] |
717 | pub trait Unsize<T> {} | 754 | pub trait Unsize<T> {} |
718 | #[lang = "coerce_unsized"] | 755 | #[lang = "coerce_unsized"] |
719 | pub trait CoerceUnsized<T> {} | 756 | pub trait CoerceUnsized<T> {} |
720 | 757 | ||
721 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 758 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
722 | 759 | ||
723 | trait Foo<T, U> {} | 760 | trait Foo<T, U> {} |
724 | trait Bar<U, T, X>: Foo<T, U> {} | 761 | trait Bar<U, T, X>: Foo<T, U> {} |
725 | trait Baz<T, X>: Bar<usize, T, X> {} | 762 | trait Baz<T, X>: Bar<usize, T, X> {} |
726 | 763 | ||
727 | struct S<T, X>; | 764 | struct S<T, X>; |
728 | impl<T, X> Foo<T, usize> for S<T, X> {} | 765 | impl<T, X> Foo<T, usize> for S<T, X> {} |
729 | impl<T, X> Bar<usize, T, X> for S<T, X> {} | 766 | impl<T, X> Bar<usize, T, X> for S<T, X> {} |
730 | impl<T, X> Baz<T, X> for S<T, X> {} | 767 | impl<T, X> Baz<T, X> for S<T, X> {} |
731 | 768 | ||
732 | fn test() { | 769 | fn test() { |
733 | let obj: &dyn Baz<i8, i16> = &S; | 770 | let obj: &dyn Baz<i8, i16> = &S; |
734 | let obj: &dyn Bar<_, _, _> = obj; | 771 | let obj: &dyn Bar<_, _, _> = obj; |
735 | let obj: &dyn Foo<_, _> = obj; | 772 | let obj: &dyn Foo<_, _> = obj; |
736 | let obj2: &dyn Baz<i8, i16> = &S; | 773 | let obj2: &dyn Baz<i8, i16> = &S; |
737 | let _: &dyn Foo<_, _> = obj2; | 774 | let _: &dyn Foo<_, _> = obj2; |
738 | } | 775 | } |
739 | "#, true), | 776 | "#, |
740 | @r###" | 777 | expect![[r" |
741 | 424..609 '{ ...bj2; }': () | 778 | 424..609 '{ ...bj2; }': () |
742 | 434..437 'obj': &dyn Baz<i8, i16> | 779 | 434..437 'obj': &dyn Baz<i8, i16> |
743 | 459..461 '&S': &S<i8, i16> | 780 | 459..461 '&S': &S<i8, i16> |
744 | 460..461 'S': S<i8, i16> | 781 | 460..461 'S': S<i8, i16> |
745 | 471..474 'obj': &dyn Bar<usize, i8, i16> | 782 | 471..474 'obj': &dyn Bar<usize, i8, i16> |
746 | 496..499 'obj': &dyn Baz<i8, i16> | 783 | 496..499 'obj': &dyn Baz<i8, i16> |
747 | 509..512 'obj': &dyn Foo<i8, usize> | 784 | 509..512 'obj': &dyn Foo<i8, usize> |
748 | 531..534 'obj': &dyn Bar<usize, i8, i16> | 785 | 531..534 'obj': &dyn Bar<usize, i8, i16> |
749 | 544..548 'obj2': &dyn Baz<i8, i16> | 786 | 544..548 'obj2': &dyn Baz<i8, i16> |
750 | 570..572 '&S': &S<i8, i16> | 787 | 570..572 '&S': &S<i8, i16> |
751 | 571..572 'S': S<i8, i16> | 788 | 571..572 'S': S<i8, i16> |
752 | 582..583 '_': &dyn Foo<i8, usize> | 789 | 582..583 '_': &dyn Foo<i8, usize> |
753 | 602..606 'obj2': &dyn Baz<i8, i16> | 790 | 602..606 'obj2': &dyn Baz<i8, i16> |
754 | "### | 791 | "]], |
755 | ); | 792 | ); |
756 | } | 793 | } |
757 | 794 | ||
758 | #[test] | 795 | #[test] |
759 | fn coerce_unsize_super_trait_cycle() { | 796 | fn coerce_unsize_super_trait_cycle() { |
760 | assert_snapshot!( | 797 | check_infer_with_mismatches( |
761 | infer_with_mismatches(r#" | 798 | r#" |
762 | #[lang = "sized"] | 799 | #[lang = "sized"] |
763 | pub trait Sized {} | 800 | pub trait Sized {} |
764 | #[lang = "unsize"] | 801 | #[lang = "unsize"] |
765 | pub trait Unsize<T> {} | 802 | pub trait Unsize<T> {} |
766 | #[lang = "coerce_unsized"] | 803 | #[lang = "coerce_unsized"] |
767 | pub trait CoerceUnsized<T> {} | 804 | pub trait CoerceUnsized<T> {} |
768 | 805 | ||
769 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 806 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
770 | 807 | ||
771 | trait A {} | 808 | trait A {} |
772 | trait B: C + A {} | 809 | trait B: C + A {} |
773 | trait C: B {} | 810 | trait C: B {} |
774 | trait D: C | 811 | trait D: C |
775 | 812 | ||
776 | struct S; | 813 | struct S; |
777 | impl A for S {} | 814 | impl A for S {} |
778 | impl B for S {} | 815 | impl B for S {} |
779 | impl C for S {} | 816 | impl C for S {} |
780 | impl D for S {} | 817 | impl D for S {} |
781 | 818 | ||
782 | fn test() { | 819 | fn test() { |
783 | let obj: &dyn D = &S; | 820 | let obj: &dyn D = &S; |
784 | let obj: &dyn A = &S; | 821 | let obj: &dyn A = &S; |
785 | } | 822 | } |
786 | "#, true), | 823 | "#, |
787 | @r###" | 824 | expect![[r" |
788 | 328..383 '{ ... &S; }': () | 825 | 328..383 '{ ... &S; }': () |
789 | 338..341 'obj': &dyn D | 826 | 338..341 'obj': &dyn D |
790 | 352..354 '&S': &S | 827 | 352..354 '&S': &S |
791 | 353..354 'S': S | 828 | 353..354 'S': S |
792 | 364..367 'obj': &dyn A | 829 | 364..367 'obj': &dyn A |
793 | 378..380 '&S': &S | 830 | 378..380 '&S': &S |
794 | 379..380 'S': S | 831 | 379..380 'S': S |
795 | "### | 832 | "]], |
796 | ); | 833 | ); |
797 | } | 834 | } |
798 | 835 | ||
@@ -801,24 +838,24 @@ fn test() { | |||
801 | fn coerce_unsize_generic() { | 838 | fn coerce_unsize_generic() { |
802 | // FIXME: Implement this | 839 | // FIXME: Implement this |
803 | // https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions | 840 | // https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions |
804 | assert_snapshot!( | 841 | check_infer_with_mismatches( |
805 | infer_with_mismatches(r#" | 842 | r#" |
806 | #[lang = "unsize"] | 843 | #[lang = "unsize"] |
807 | pub trait Unsize<T> {} | 844 | pub trait Unsize<T> {} |
808 | #[lang = "coerce_unsized"] | 845 | #[lang = "coerce_unsized"] |
809 | pub trait CoerceUnsized<T> {} | 846 | pub trait CoerceUnsized<T> {} |
810 | 847 | ||
811 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} | 848 | impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} |
812 | 849 | ||
813 | struct Foo<T> { t: T }; | 850 | struct Foo<T> { t: T }; |
814 | struct Bar<T>(Foo<T>); | 851 | struct Bar<T>(Foo<T>); |
815 | 852 | ||
816 | fn test() { | 853 | fn test() { |
817 | let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; | 854 | let _: &Foo<[usize]> = &Foo { t: [1, 2, 3] }; |
818 | let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); | 855 | let _: &Bar<[usize]> = &Bar(Foo { t: [1, 2, 3] }); |
819 | } | 856 | } |
820 | "#, true), | 857 | "#, |
821 | @r###" | 858 | expect![[r" |
822 | "### | 859 | "]], |
823 | ); | 860 | ); |
824 | } | 861 | } |
diff --git a/crates/ra_hir_ty/src/tests/never_type.rs b/crates/ra_hir_ty/src/tests/never_type.rs index 64d421d40..49538b572 100644 --- a/crates/ra_hir_ty/src/tests/never_type.rs +++ b/crates/ra_hir_ty/src/tests/never_type.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use insta::assert_snapshot; | 1 | use expect::expect; |
2 | 2 | ||
3 | use super::{check_types, infer_with_mismatches}; | 3 | use super::{check_infer_with_mismatches, check_types}; |
4 | 4 | ||
5 | #[test] | 5 | #[test] |
6 | fn infer_never1() { | 6 | fn infer_never1() { |
@@ -240,173 +240,170 @@ fn test(a: i32) { | |||
240 | 240 | ||
241 | #[test] | 241 | #[test] |
242 | fn diverging_expression_1() { | 242 | fn diverging_expression_1() { |
243 | let t = infer_with_mismatches( | 243 | check_infer_with_mismatches( |
244 | r#" | 244 | r" |
245 | //- /main.rs | 245 | //- /main.rs |
246 | fn test1() { | 246 | fn test1() { |
247 | let x: u32 = return; | 247 | let x: u32 = return; |
248 | } | 248 | } |
249 | fn test2() { | 249 | fn test2() { |
250 | let x: u32 = { return; }; | 250 | let x: u32 = { return; }; |
251 | } | 251 | } |
252 | fn test3() { | 252 | fn test3() { |
253 | let x: u32 = loop {}; | 253 | let x: u32 = loop {}; |
254 | } | 254 | } |
255 | fn test4() { | 255 | fn test4() { |
256 | let x: u32 = { loop {} }; | 256 | let x: u32 = { loop {} }; |
257 | } | 257 | } |
258 | fn test5() { | 258 | fn test5() { |
259 | let x: u32 = { if true { loop {}; } else { loop {}; } }; | 259 | let x: u32 = { if true { loop {}; } else { loop {}; } }; |
260 | } | 260 | } |
261 | fn test6() { | 261 | fn test6() { |
262 | let x: u32 = { let y: u32 = { loop {}; }; }; | 262 | let x: u32 = { let y: u32 = { loop {}; }; }; |
263 | } | 263 | } |
264 | "#, | 264 | ", |
265 | true, | 265 | expect![[r" |
266 | 11..39 '{ ...urn; }': () | ||
267 | 21..22 'x': u32 | ||
268 | 30..36 'return': ! | ||
269 | 51..84 '{ ...; }; }': () | ||
270 | 61..62 'x': u32 | ||
271 | 70..81 '{ return; }': u32 | ||
272 | 72..78 'return': ! | ||
273 | 96..125 '{ ... {}; }': () | ||
274 | 106..107 'x': u32 | ||
275 | 115..122 'loop {}': ! | ||
276 | 120..122 '{}': () | ||
277 | 137..170 '{ ...} }; }': () | ||
278 | 147..148 'x': u32 | ||
279 | 156..167 '{ loop {} }': u32 | ||
280 | 158..165 'loop {}': ! | ||
281 | 163..165 '{}': () | ||
282 | 182..246 '{ ...} }; }': () | ||
283 | 192..193 'x': u32 | ||
284 | 201..243 '{ if t...}; } }': u32 | ||
285 | 203..241 'if tru... {}; }': u32 | ||
286 | 206..210 'true': bool | ||
287 | 211..223 '{ loop {}; }': u32 | ||
288 | 213..220 'loop {}': ! | ||
289 | 218..220 '{}': () | ||
290 | 229..241 '{ loop {}; }': u32 | ||
291 | 231..238 'loop {}': ! | ||
292 | 236..238 '{}': () | ||
293 | 258..310 '{ ...; }; }': () | ||
294 | 268..269 'x': u32 | ||
295 | 277..307 '{ let ...; }; }': u32 | ||
296 | 283..284 'y': u32 | ||
297 | 292..304 '{ loop {}; }': u32 | ||
298 | 294..301 'loop {}': ! | ||
299 | 299..301 '{}': () | ||
300 | "]], | ||
266 | ); | 301 | ); |
267 | assert_snapshot!(t, @r###" | ||
268 | 11..39 '{ ...urn; }': () | ||
269 | 21..22 'x': u32 | ||
270 | 30..36 'return': ! | ||
271 | 51..84 '{ ...; }; }': () | ||
272 | 61..62 'x': u32 | ||
273 | 70..81 '{ return; }': u32 | ||
274 | 72..78 'return': ! | ||
275 | 96..125 '{ ... {}; }': () | ||
276 | 106..107 'x': u32 | ||
277 | 115..122 'loop {}': ! | ||
278 | 120..122 '{}': () | ||
279 | 137..170 '{ ...} }; }': () | ||
280 | 147..148 'x': u32 | ||
281 | 156..167 '{ loop {} }': u32 | ||
282 | 158..165 'loop {}': ! | ||
283 | 163..165 '{}': () | ||
284 | 182..246 '{ ...} }; }': () | ||
285 | 192..193 'x': u32 | ||
286 | 201..243 '{ if t...}; } }': u32 | ||
287 | 203..241 'if tru... {}; }': u32 | ||
288 | 206..210 'true': bool | ||
289 | 211..223 '{ loop {}; }': u32 | ||
290 | 213..220 'loop {}': ! | ||
291 | 218..220 '{}': () | ||
292 | 229..241 '{ loop {}; }': u32 | ||
293 | 231..238 'loop {}': ! | ||
294 | 236..238 '{}': () | ||
295 | 258..310 '{ ...; }; }': () | ||
296 | 268..269 'x': u32 | ||
297 | 277..307 '{ let ...; }; }': u32 | ||
298 | 283..284 'y': u32 | ||
299 | 292..304 '{ loop {}; }': u32 | ||
300 | 294..301 'loop {}': ! | ||
301 | 299..301 '{}': () | ||
302 | "###); | ||
303 | } | 302 | } |
304 | 303 | ||
305 | #[test] | 304 | #[test] |
306 | fn diverging_expression_2() { | 305 | fn diverging_expression_2() { |
307 | let t = infer_with_mismatches( | 306 | check_infer_with_mismatches( |
308 | r#" | 307 | r#" |
309 | //- /main.rs | 308 | //- /main.rs |
310 | fn test1() { | 309 | fn test1() { |
311 | // should give type mismatch | 310 | // should give type mismatch |
312 | let x: u32 = { loop {}; "foo" }; | 311 | let x: u32 = { loop {}; "foo" }; |
313 | } | 312 | } |
314 | "#, | 313 | "#, |
315 | true, | 314 | expect![[r#" |
315 | 11..84 '{ ..." }; }': () | ||
316 | 54..55 'x': u32 | ||
317 | 63..81 '{ loop...foo" }': &str | ||
318 | 65..72 'loop {}': ! | ||
319 | 70..72 '{}': () | ||
320 | 74..79 '"foo"': &str | ||
321 | 63..81: expected u32, got &str | ||
322 | 74..79: expected u32, got &str | ||
323 | "#]], | ||
316 | ); | 324 | ); |
317 | assert_snapshot!(t, @r###" | ||
318 | 11..84 '{ ..." }; }': () | ||
319 | 54..55 'x': u32 | ||
320 | 63..81 '{ loop...foo" }': &str | ||
321 | 65..72 'loop {}': ! | ||
322 | 70..72 '{}': () | ||
323 | 74..79 '"foo"': &str | ||
324 | 63..81: expected u32, got &str | ||
325 | 74..79: expected u32, got &str | ||
326 | "###); | ||
327 | } | 325 | } |
328 | 326 | ||
329 | #[test] | 327 | #[test] |
330 | fn diverging_expression_3_break() { | 328 | fn diverging_expression_3_break() { |
331 | let t = infer_with_mismatches( | 329 | check_infer_with_mismatches( |
332 | r#" | 330 | r" |
333 | //- /main.rs | 331 | //- /main.rs |
334 | fn test1() { | 332 | fn test1() { |
335 | // should give type mismatch | 333 | // should give type mismatch |
336 | let x: u32 = { loop { break; } }; | 334 | let x: u32 = { loop { break; } }; |
337 | } | 335 | } |
338 | fn test2() { | 336 | fn test2() { |
339 | // should give type mismatch | 337 | // should give type mismatch |
340 | let x: u32 = { for a in b { break; }; }; | 338 | let x: u32 = { for a in b { break; }; }; |
341 | // should give type mismatch as well | 339 | // should give type mismatch as well |
342 | let x: u32 = { for a in b {}; }; | 340 | let x: u32 = { for a in b {}; }; |
343 | // should give type mismatch as well | 341 | // should give type mismatch as well |
344 | let x: u32 = { for a in b { return; }; }; | 342 | let x: u32 = { for a in b { return; }; }; |
345 | } | 343 | } |
346 | fn test3() { | 344 | fn test3() { |
347 | // should give type mismatch | 345 | // should give type mismatch |
348 | let x: u32 = { while true { break; }; }; | 346 | let x: u32 = { while true { break; }; }; |
349 | // should give type mismatch as well -- there's an implicit break, even if it's never hit | 347 | // should give type mismatch as well -- there's an implicit break, even if it's never hit |
350 | let x: u32 = { while true {}; }; | 348 | let x: u32 = { while true {}; }; |
351 | // should give type mismatch as well | 349 | // should give type mismatch as well |
352 | let x: u32 = { while true { return; }; }; | 350 | let x: u32 = { while true { return; }; }; |
353 | } | 351 | } |
354 | "#, | 352 | ", |
355 | true, | 353 | expect![[r" |
354 | 11..85 '{ ...} }; }': () | ||
355 | 54..55 'x': u32 | ||
356 | 63..82 '{ loop...k; } }': () | ||
357 | 65..80 'loop { break; }': () | ||
358 | 70..80 '{ break; }': () | ||
359 | 72..77 'break': ! | ||
360 | 63..82: expected u32, got () | ||
361 | 65..80: expected u32, got () | ||
362 | 97..343 '{ ...; }; }': () | ||
363 | 140..141 'x': u32 | ||
364 | 149..175 '{ for ...; }; }': () | ||
365 | 151..172 'for a ...eak; }': () | ||
366 | 155..156 'a': {unknown} | ||
367 | 160..161 'b': {unknown} | ||
368 | 162..172 '{ break; }': () | ||
369 | 164..169 'break': ! | ||
370 | 226..227 'x': u32 | ||
371 | 235..253 '{ for ... {}; }': () | ||
372 | 237..250 'for a in b {}': () | ||
373 | 241..242 'a': {unknown} | ||
374 | 246..247 'b': {unknown} | ||
375 | 248..250 '{}': () | ||
376 | 304..305 'x': u32 | ||
377 | 313..340 '{ for ...; }; }': () | ||
378 | 315..337 'for a ...urn; }': () | ||
379 | 319..320 'a': {unknown} | ||
380 | 324..325 'b': {unknown} | ||
381 | 326..337 '{ return; }': () | ||
382 | 328..334 'return': ! | ||
383 | 149..175: expected u32, got () | ||
384 | 235..253: expected u32, got () | ||
385 | 313..340: expected u32, got () | ||
386 | 355..654 '{ ...; }; }': () | ||
387 | 398..399 'x': u32 | ||
388 | 407..433 '{ whil...; }; }': () | ||
389 | 409..430 'while ...eak; }': () | ||
390 | 415..419 'true': bool | ||
391 | 420..430 '{ break; }': () | ||
392 | 422..427 'break': ! | ||
393 | 537..538 'x': u32 | ||
394 | 546..564 '{ whil... {}; }': () | ||
395 | 548..561 'while true {}': () | ||
396 | 554..558 'true': bool | ||
397 | 559..561 '{}': () | ||
398 | 615..616 'x': u32 | ||
399 | 624..651 '{ whil...; }; }': () | ||
400 | 626..648 'while ...urn; }': () | ||
401 | 632..636 'true': bool | ||
402 | 637..648 '{ return; }': () | ||
403 | 639..645 'return': ! | ||
404 | 407..433: expected u32, got () | ||
405 | 546..564: expected u32, got () | ||
406 | 624..651: expected u32, got () | ||
407 | "]], | ||
356 | ); | 408 | ); |
357 | assert_snapshot!(t, @r###" | ||
358 | 11..85 '{ ...} }; }': () | ||
359 | 54..55 'x': u32 | ||
360 | 63..82 '{ loop...k; } }': () | ||
361 | 65..80 'loop { break; }': () | ||
362 | 70..80 '{ break; }': () | ||
363 | 72..77 'break': ! | ||
364 | 63..82: expected u32, got () | ||
365 | 65..80: expected u32, got () | ||
366 | 97..343 '{ ...; }; }': () | ||
367 | 140..141 'x': u32 | ||
368 | 149..175 '{ for ...; }; }': () | ||
369 | 151..172 'for a ...eak; }': () | ||
370 | 155..156 'a': {unknown} | ||
371 | 160..161 'b': {unknown} | ||
372 | 162..172 '{ break; }': () | ||
373 | 164..169 'break': ! | ||
374 | 226..227 'x': u32 | ||
375 | 235..253 '{ for ... {}; }': () | ||
376 | 237..250 'for a in b {}': () | ||
377 | 241..242 'a': {unknown} | ||
378 | 246..247 'b': {unknown} | ||
379 | 248..250 '{}': () | ||
380 | 304..305 'x': u32 | ||
381 | 313..340 '{ for ...; }; }': () | ||
382 | 315..337 'for a ...urn; }': () | ||
383 | 319..320 'a': {unknown} | ||
384 | 324..325 'b': {unknown} | ||
385 | 326..337 '{ return; }': () | ||
386 | 328..334 'return': ! | ||
387 | 149..175: expected u32, got () | ||
388 | 235..253: expected u32, got () | ||
389 | 313..340: expected u32, got () | ||
390 | 355..654 '{ ...; }; }': () | ||
391 | 398..399 'x': u32 | ||
392 | 407..433 '{ whil...; }; }': () | ||
393 | 409..430 'while ...eak; }': () | ||
394 | 415..419 'true': bool | ||
395 | 420..430 '{ break; }': () | ||
396 | 422..427 'break': ! | ||
397 | 537..538 'x': u32 | ||
398 | 546..564 '{ whil... {}; }': () | ||
399 | 548..561 'while true {}': () | ||
400 | 554..558 'true': bool | ||
401 | 559..561 '{}': () | ||
402 | 615..616 'x': u32 | ||
403 | 624..651 '{ whil...; }; }': () | ||
404 | 626..648 'while ...urn; }': () | ||
405 | 632..636 'true': bool | ||
406 | 637..648 '{ return; }': () | ||
407 | 639..645 'return': ! | ||
408 | 407..433: expected u32, got () | ||
409 | 546..564: expected u32, got () | ||
410 | 624..651: expected u32, got () | ||
411 | "###); | ||
412 | } | 409 | } |
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index 9e82d6854..c84d43d77 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs | |||
@@ -215,7 +215,7 @@ impl<'a> CompletionContext<'a> { | |||
215 | 215 | ||
216 | fn fill_keyword_patterns(&mut self, file_with_fake_ident: &SyntaxNode, offset: TextSize) { | 216 | fn fill_keyword_patterns(&mut self, file_with_fake_ident: &SyntaxNode, offset: TextSize) { |
217 | let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap(); | 217 | let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap(); |
218 | let syntax_element = NodeOrToken::Token(fake_ident_token.clone()); | 218 | let syntax_element = NodeOrToken::Token(fake_ident_token); |
219 | self.block_expr_parent = has_block_expr_parent(syntax_element.clone()); | 219 | self.block_expr_parent = has_block_expr_parent(syntax_element.clone()); |
220 | self.unsafe_is_prev = unsafe_is_prev(syntax_element.clone()); | 220 | self.unsafe_is_prev = unsafe_is_prev(syntax_element.clone()); |
221 | self.if_is_prev = if_is_prev(syntax_element.clone()); | 221 | self.if_is_prev = if_is_prev(syntax_element.clone()); |
@@ -228,7 +228,7 @@ impl<'a> CompletionContext<'a> { | |||
228 | self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone()); | 228 | self.trait_as_prev_sibling = has_trait_as_prev_sibling(syntax_element.clone()); |
229 | self.is_match_arm = is_match_arm(syntax_element.clone()); | 229 | self.is_match_arm = is_match_arm(syntax_element.clone()); |
230 | self.has_item_list_or_source_file_parent = | 230 | self.has_item_list_or_source_file_parent = |
231 | has_item_list_or_source_file_parent(syntax_element.clone()); | 231 | has_item_list_or_source_file_parent(syntax_element); |
232 | } | 232 | } |
233 | 233 | ||
234 | fn fill( | 234 | fn fill( |
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs index fe75f4b2c..e029af0dc 100644 --- a/crates/ra_ide/src/diagnostics.rs +++ b/crates/ra_ide/src/diagnostics.rs | |||
@@ -183,7 +183,7 @@ fn missing_struct_field_fix( | |||
183 | } | 183 | } |
184 | new_field = format!("\n{}{}", indent, new_field); | 184 | new_field = format!("\n{}{}", indent, new_field); |
185 | 185 | ||
186 | let needs_comma = !last_field_syntax.to_string().ends_with(","); | 186 | let needs_comma = !last_field_syntax.to_string().ends_with(','); |
187 | if needs_comma { | 187 | if needs_comma { |
188 | new_field = format!(",{}", new_field); | 188 | new_field = format!(",{}", new_field); |
189 | } | 189 | } |
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index 43a5e29b5..f2e4f7ee5 100644 --- a/crates/ra_ide/src/inlay_hints.rs +++ b/crates/ra_ide/src/inlay_hints.rs | |||
@@ -171,7 +171,7 @@ fn get_param_name_hints( | |||
171 | .map(|(param_name, arg)| InlayHint { | 171 | .map(|(param_name, arg)| InlayHint { |
172 | range: arg.syntax().text_range(), | 172 | range: arg.syntax().text_range(), |
173 | kind: InlayKind::ParameterHint, | 173 | kind: InlayKind::ParameterHint, |
174 | label: param_name.to_string().into(), | 174 | label: param_name.into(), |
175 | }); | 175 | }); |
176 | 176 | ||
177 | acc.extend(hints); | 177 | acc.extend(hints); |
@@ -425,6 +425,8 @@ fn main() { | |||
425 | //^^ Test<i32> | 425 | //^^ Test<i32> |
426 | let zz_ref = &zz; | 426 | let zz_ref = &zz; |
427 | //^^^^^^ &Test<i32> | 427 | //^^^^^^ &Test<i32> |
428 | let test = || zz; | ||
429 | //^^^^ || -> Test<i32> | ||
428 | }"#, | 430 | }"#, |
429 | ); | 431 | ); |
430 | } | 432 | } |
diff --git a/crates/ra_project_model/src/project_json.rs b/crates/ra_project_model/src/project_json.rs index b96227949..778cc84ef 100644 --- a/crates/ra_project_model/src/project_json.rs +++ b/crates/ra_project_model/src/project_json.rs | |||
@@ -34,6 +34,7 @@ pub struct Crate { | |||
34 | pub(crate) target: Option<String>, | 34 | pub(crate) target: Option<String>, |
35 | pub(crate) out_dir: Option<AbsPathBuf>, | 35 | pub(crate) out_dir: Option<AbsPathBuf>, |
36 | pub(crate) proc_macro_dylib_path: Option<AbsPathBuf>, | 36 | pub(crate) proc_macro_dylib_path: Option<AbsPathBuf>, |
37 | pub(crate) is_workspace_member: bool, | ||
37 | } | 38 | } |
38 | 39 | ||
39 | impl ProjectJson { | 40 | impl ProjectJson { |
@@ -43,32 +44,42 @@ impl ProjectJson { | |||
43 | crates: data | 44 | crates: data |
44 | .crates | 45 | .crates |
45 | .into_iter() | 46 | .into_iter() |
46 | .map(|crate_data| Crate { | 47 | .map(|crate_data| { |
47 | root_module: base.join(crate_data.root_module), | 48 | let is_workspace_member = crate_data.is_workspace_member.unwrap_or_else(|| { |
48 | edition: crate_data.edition.into(), | 49 | crate_data.root_module.is_relative() |
49 | deps: crate_data | 50 | && !crate_data.root_module.starts_with("..") |
50 | .deps | 51 | || crate_data.root_module.starts_with(base) |
51 | .into_iter() | 52 | }); |
52 | .map(|dep_data| Dependency { | 53 | Crate { |
53 | crate_id: CrateId(dep_data.krate as u32), | 54 | root_module: base.join(crate_data.root_module), |
54 | name: dep_data.name, | 55 | edition: crate_data.edition.into(), |
55 | }) | 56 | deps: crate_data |
56 | .collect::<Vec<_>>(), | 57 | .deps |
57 | cfg: { | 58 | .into_iter() |
58 | let mut cfg = CfgOptions::default(); | 59 | .map(|dep_data| Dependency { |
59 | for entry in &crate_data.cfg { | 60 | crate_id: CrateId(dep_data.krate as u32), |
60 | match split_delim(entry, '=') { | 61 | name: dep_data.name, |
61 | Some((key, value)) => { | 62 | }) |
62 | cfg.insert_key_value(key.into(), value.into()); | 63 | .collect::<Vec<_>>(), |
64 | cfg: { | ||
65 | let mut cfg = CfgOptions::default(); | ||
66 | for entry in &crate_data.cfg { | ||
67 | match split_delim(entry, '=') { | ||
68 | Some((key, value)) => { | ||
69 | cfg.insert_key_value(key.into(), value.into()); | ||
70 | } | ||
71 | None => cfg.insert_atom(entry.into()), | ||
63 | } | 72 | } |
64 | None => cfg.insert_atom(entry.into()), | ||
65 | } | 73 | } |
66 | } | 74 | cfg |
67 | cfg | 75 | }, |
68 | }, | 76 | target: crate_data.target, |
69 | target: crate_data.target, | 77 | out_dir: crate_data.out_dir.map(|it| base.join(it)), |
70 | out_dir: crate_data.out_dir.map(|it| base.join(it)), | 78 | proc_macro_dylib_path: crate_data |
71 | proc_macro_dylib_path: crate_data.proc_macro_dylib_path.map(|it| base.join(it)), | 79 | .proc_macro_dylib_path |
80 | .map(|it| base.join(it)), | ||
81 | is_workspace_member, | ||
82 | } | ||
72 | }) | 83 | }) |
73 | .collect::<Vec<_>>(), | 84 | .collect::<Vec<_>>(), |
74 | } | 85 | } |
@@ -91,6 +102,7 @@ struct CrateData { | |||
91 | target: Option<String>, | 102 | target: Option<String>, |
92 | out_dir: Option<PathBuf>, | 103 | out_dir: Option<PathBuf>, |
93 | proc_macro_dylib_path: Option<PathBuf>, | 104 | proc_macro_dylib_path: Option<PathBuf>, |
105 | is_workspace_member: Option<bool>, | ||
94 | } | 106 | } |
95 | 107 | ||
96 | #[derive(Deserialize)] | 108 | #[derive(Deserialize)] |
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml index 57cc09854..670f04578 100644 --- a/crates/ra_syntax/Cargo.toml +++ b/crates/ra_syntax/Cargo.toml | |||
@@ -13,7 +13,7 @@ doctest = false | |||
13 | [dependencies] | 13 | [dependencies] |
14 | itertools = "0.9.0" | 14 | itertools = "0.9.0" |
15 | rowan = "0.10.0" | 15 | rowan = "0.10.0" |
16 | rustc_lexer = { version = "666.0.0", package = "rustc-ap-rustc_lexer" } | 16 | rustc_lexer = { version = "669.0.0", package = "rustc-ap-rustc_lexer" } |
17 | rustc-hash = "1.1.0" | 17 | rustc-hash = "1.1.0" |
18 | arrayvec = "0.5.1" | 18 | arrayvec = "0.5.1" |
19 | once_cell = "1.3.1" | 19 | once_cell = "1.3.1" |
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 68b2a2abd..8947ccf07 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -148,6 +148,7 @@ impl Config { | |||
148 | rustfmt: RustfmtConfig::Rustfmt { extra_args: Vec::new() }, | 148 | rustfmt: RustfmtConfig::Rustfmt { extra_args: Vec::new() }, |
149 | flycheck: Some(FlycheckConfig::CargoCommand { | 149 | flycheck: Some(FlycheckConfig::CargoCommand { |
150 | command: "check".to_string(), | 150 | command: "check".to_string(), |
151 | target_triple: None, | ||
151 | all_targets: true, | 152 | all_targets: true, |
152 | all_features: false, | 153 | all_features: false, |
153 | extra_args: Vec::new(), | 154 | extra_args: Vec::new(), |
@@ -177,6 +178,11 @@ impl Config { | |||
177 | 178 | ||
178 | pub fn update(&mut self, json: serde_json::Value) { | 179 | pub fn update(&mut self, json: serde_json::Value) { |
179 | log::info!("Config::update({:#})", json); | 180 | log::info!("Config::update({:#})", json); |
181 | |||
182 | if json.is_null() || json.as_object().map_or(false, |it| it.is_empty()) { | ||
183 | return; | ||
184 | } | ||
185 | |||
180 | let data = ConfigData::from_json(json); | 186 | let data = ConfigData::from_json(json); |
181 | 187 | ||
182 | self.with_sysroot = data.withSysroot; | 188 | self.with_sysroot = data.withSysroot; |
@@ -198,7 +204,7 @@ impl Config { | |||
198 | all_features: data.cargo_allFeatures, | 204 | all_features: data.cargo_allFeatures, |
199 | features: data.cargo_features.clone(), | 205 | features: data.cargo_features.clone(), |
200 | load_out_dirs_from_check: data.cargo_loadOutDirsFromCheck, | 206 | load_out_dirs_from_check: data.cargo_loadOutDirsFromCheck, |
201 | target: data.cargo_target, | 207 | target: data.cargo_target.clone(), |
202 | }; | 208 | }; |
203 | 209 | ||
204 | self.proc_macro_srv = if data.procMacro_enable { | 210 | self.proc_macro_srv = if data.procMacro_enable { |
@@ -223,6 +229,7 @@ impl Config { | |||
223 | } | 229 | } |
224 | Some(_) | None => FlycheckConfig::CargoCommand { | 230 | Some(_) | None => FlycheckConfig::CargoCommand { |
225 | command: data.checkOnSave_command, | 231 | command: data.checkOnSave_command, |
232 | target_triple: data.checkOnSave_target.or(data.cargo_target), | ||
226 | all_targets: data.checkOnSave_allTargets, | 233 | all_targets: data.checkOnSave_allTargets, |
227 | all_features: data.checkOnSave_allFeatures.unwrap_or(data.cargo_allFeatures), | 234 | all_features: data.checkOnSave_allFeatures.unwrap_or(data.cargo_allFeatures), |
228 | features: data.checkOnSave_features.unwrap_or(data.cargo_features), | 235 | features: data.checkOnSave_features.unwrap_or(data.cargo_features), |
@@ -384,10 +391,11 @@ config_data! { | |||
384 | cargo_noDefaultFeatures: bool = false, | 391 | cargo_noDefaultFeatures: bool = false, |
385 | cargo_target: Option<String> = None, | 392 | cargo_target: Option<String> = None, |
386 | 393 | ||
394 | checkOnSave_enable: bool = false, | ||
387 | checkOnSave_allFeatures: Option<bool> = None, | 395 | checkOnSave_allFeatures: Option<bool> = None, |
388 | checkOnSave_allTargets: bool = true, | 396 | checkOnSave_allTargets: bool = true, |
389 | checkOnSave_command: String = "check".into(), | 397 | checkOnSave_command: String = "check".into(), |
390 | checkOnSave_enable: bool = false, | 398 | checkOnSave_target: Option<String> = None, |
391 | checkOnSave_extraArgs: Vec<String> = Vec::new(), | 399 | checkOnSave_extraArgs: Vec<String> = Vec::new(), |
392 | checkOnSave_features: Option<Vec<String>> = None, | 400 | checkOnSave_features: Option<Vec<String>> = None, |
393 | checkOnSave_overrideCommand: Option<Vec<String>> = None, | 401 | checkOnSave_overrideCommand: Option<Vec<String>> = None, |
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index a41f7f564..bb7c4c0c6 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -468,6 +468,8 @@ impl GlobalState { | |||
468 | } | 468 | } |
469 | (None, Some(mut configs)) => { | 469 | (None, Some(mut configs)) => { |
470 | if let Some(json) = configs.get_mut(0) { | 470 | if let Some(json) = configs.get_mut(0) { |
471 | // Note that json can be null according to the spec if the client can't | ||
472 | // provide a configuration. This is handled in Config::update below. | ||
471 | let mut config = this.config.clone(); | 473 | let mut config = this.config.clone(); |
472 | config.update(json.take()); | 474 | config.update(json.take()); |
473 | this.update_configuration(config); | 475 | this.update_configuration(config); |
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 3f4dbdd8c..d7ae00b07 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs | |||
@@ -242,7 +242,7 @@ impl GlobalState { | |||
242 | }) | 242 | }) |
243 | .map(move |cargo| { | 243 | .map(move |cargo| { |
244 | let cargo_project_root = cargo.workspace_root().to_path_buf(); | 244 | let cargo_project_root = cargo.workspace_root().to_path_buf(); |
245 | FlycheckHandle::spawn(sender, config.clone(), cargo_project_root.into()) | 245 | FlycheckHandle::spawn(sender, config, cargo_project_root.into()) |
246 | }) | 246 | }) |
247 | } | 247 | } |
248 | } | 248 | } |
diff --git a/crates/vfs/src/loader.rs b/crates/vfs/src/loader.rs index 9c6e4b6a7..04e257f53 100644 --- a/crates/vfs/src/loader.rs +++ b/crates/vfs/src/loader.rs | |||
@@ -83,11 +83,11 @@ impl Directories { | |||
83 | self.includes_path(path) | 83 | self.includes_path(path) |
84 | } | 84 | } |
85 | fn includes_path(&self, path: &AbsPath) -> bool { | 85 | fn includes_path(&self, path: &AbsPath) -> bool { |
86 | let mut include = None; | 86 | let mut include: Option<&AbsPathBuf> = None; |
87 | for incl in &self.include { | 87 | for incl in &self.include { |
88 | if is_prefix(incl, path) { | 88 | if path.starts_with(incl) { |
89 | include = Some(match include { | 89 | include = Some(match include { |
90 | Some(prev) if is_prefix(incl, prev) => prev, | 90 | Some(prev) if prev.starts_with(incl) => prev, |
91 | _ => incl, | 91 | _ => incl, |
92 | }) | 92 | }) |
93 | } | 93 | } |
@@ -97,15 +97,11 @@ impl Directories { | |||
97 | None => return false, | 97 | None => return false, |
98 | }; | 98 | }; |
99 | for excl in &self.exclude { | 99 | for excl in &self.exclude { |
100 | if is_prefix(excl, path) && is_prefix(include, excl) { | 100 | if path.starts_with(excl) && excl.starts_with(include) { |
101 | return false; | 101 | return false; |
102 | } | 102 | } |
103 | } | 103 | } |
104 | return true; | 104 | true |
105 | |||
106 | fn is_prefix(short: &AbsPath, long: &AbsPath) -> bool { | ||
107 | long.strip_prefix(short).is_some() | ||
108 | } | ||
109 | } | 105 | } |
110 | } | 106 | } |
111 | 107 | ||
diff --git a/xtask/src/release.rs b/xtask/src/release.rs index 530bd8205..7fa0966aa 100644 --- a/xtask/src/release.rs +++ b/xtask/src/release.rs | |||
@@ -37,7 +37,7 @@ Release: release:{}[] | |||
37 | 37 | ||
38 | == Sponsors | 38 | == Sponsors |
39 | 39 | ||
40 | **Become a sponsor:** https://opencollective.com/rust-analyzer/[opecollective.com/rust-analyzer] | 40 | **Become a sponsor:** https://opencollective.com/rust-analyzer/[opencollective.com/rust-analyzer] |
41 | 41 | ||
42 | == New Features | 42 | == New Features |
43 | 43 | ||