aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock71
-rw-r--r--crates/flycheck/src/lib.rs6
-rw-r--r--crates/ra_assists/src/handlers/raw_string.rs2
-rw-r--r--crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs2
-rw-r--r--crates/ra_hir_def/src/nameres.rs20
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs2
-rw-r--r--crates/ra_hir_ty/Cargo.toml6
-rw-r--r--crates/ra_hir_ty/src/display.rs22
-rw-r--r--crates/ra_hir_ty/src/lower.rs2
-rw-r--r--crates/ra_hir_ty/src/tests.rs13
-rw-r--r--crates/ra_hir_ty/src/tests/coercion.rs1417
-rw-r--r--crates/ra_hir_ty/src/tests/never_type.rs315
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs4
-rw-r--r--crates/ra_ide/src/diagnostics.rs2
-rw-r--r--crates/ra_ide/src/inlay_hints.rs4
-rw-r--r--crates/ra_project_model/src/project_json.rs60
-rw-r--r--crates/ra_syntax/Cargo.toml2
-rw-r--r--crates/rust-analyzer/src/config.rs12
-rw-r--r--crates/rust-analyzer/src/main_loop.rs2
-rw-r--r--crates/rust-analyzer/src/reload.rs2
-rw-r--r--crates/vfs/src/loader.rs14
-rw-r--r--xtask/src/release.rs2
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]]
28name = "ansi_term" 28name = "ansi_term"
29version = "0.11.0"
30source = "registry+https://github.com/rust-lang/crates.io-index"
31checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
32dependencies = [
33 "winapi 0.3.9",
34]
35
36[[package]]
37name = "ansi_term"
38version = "0.12.1" 29version = "0.12.1"
39source = "registry+https://github.com/rust-lang/crates.io-index" 30source = "registry+https://github.com/rust-lang/crates.io-index"
40checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 31checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
@@ -111,9 +102,9 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
111 102
112[[package]] 103[[package]]
113name = "cargo_metadata" 104name = "cargo_metadata"
114version = "0.10.0" 105version = "0.10.1"
115source = "registry+https://github.com/rust-lang/crates.io-index" 106source = "registry+https://github.com/rust-lang/crates.io-index"
116checksum = "b8de60b887edf6d74370fc8eb177040da4847d971d6234c7b13a6da324ef0caf" 107checksum = "052dbdd9db69a339d5fa9ac87bfe2e1319f709119f0345988a597af82bb1011c"
117dependencies = [ 108dependencies = [
118 "semver", 109 "semver",
119 "serde", 110 "serde",
@@ -135,9 +126,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
135 126
136[[package]] 127[[package]]
137name = "chalk-derive" 128name = "chalk-derive"
138version = "0.17.0" 129version = "0.18.0"
139source = "registry+https://github.com/rust-lang/crates.io-index" 130source = "registry+https://github.com/rust-lang/crates.io-index"
140checksum = "9396f12a23b1a40d5019aa81bc0cbd7ccd2c9736d6bc4afc95868533c2346dcb" 131checksum = "eea3a22f0c30b2504ac4ab58934dac0d00b92a4d7788df32795cabca24c3f929"
141dependencies = [ 132dependencies = [
142 "proc-macro2", 133 "proc-macro2",
143 "quote", 134 "quote",
@@ -147,9 +138,9 @@ dependencies = [
147 138
148[[package]] 139[[package]]
149name = "chalk-ir" 140name = "chalk-ir"
150version = "0.17.0" 141version = "0.18.0"
151source = "registry+https://github.com/rust-lang/crates.io-index" 142source = "registry+https://github.com/rust-lang/crates.io-index"
152checksum = "87e9c67d500717d65ede27affb7ae40efe240d86fbefff1006fe0ffb62d4caf9" 143checksum = "fb617b643e145e3b151502799e91a9625dd5daf1cf05dc2cb821bc75ae0c9cbd"
153dependencies = [ 144dependencies = [
154 "chalk-derive", 145 "chalk-derive",
155 "lazy_static", 146 "lazy_static",
@@ -157,9 +148,9 @@ dependencies = [
157 148
158[[package]] 149[[package]]
159name = "chalk-recursive" 150name = "chalk-recursive"
160version = "0.17.0" 151version = "0.18.0"
161source = "registry+https://github.com/rust-lang/crates.io-index" 152source = "registry+https://github.com/rust-lang/crates.io-index"
162checksum = "a8fd2ac0fc06c857b95614d229bbe8ea317d1d94a7e8b9442a3f05c9a2c2d5f4" 153checksum = "d280565c8eefbf9b2bc615df49c7dfd971faad37774bf65734e626fd23864bd6"
163dependencies = [ 154dependencies = [
164 "chalk-derive", 155 "chalk-derive",
165 "chalk-ir", 156 "chalk-ir",
@@ -170,9 +161,9 @@ dependencies = [
170 161
171[[package]] 162[[package]]
172name = "chalk-solve" 163name = "chalk-solve"
173version = "0.17.0" 164version = "0.18.0"
174source = "registry+https://github.com/rust-lang/crates.io-index" 165source = "registry+https://github.com/rust-lang/crates.io-index"
175checksum = "2a79166f2405c1e51eadcc1344f5ee833c7b391532dd78f64a0731a9a123cc58" 166checksum = "be906fbca3f3077dce0e76d9864771d0f450c946af0d86b569fb9504148a065a"
176dependencies = [ 167dependencies = [
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]]
464name = "hashbrown"
465version = "0.8.1"
466source = "registry+https://github.com/rust-lang/crates.io-index"
467checksum = "34f595585f103464d8d2f6e9864682d74c1601fed5e07d62b1c9058dba8246fb"
468dependencies = [
469 "autocfg",
470]
471
472[[package]]
473name = "heck" 473name = "heck"
474version = "0.3.1" 474version = "0.3.1"
475source = "registry+https://github.com/rust-lang/crates.io-index" 475source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -509,11 +509,12 @@ dependencies = [
509 509
510[[package]] 510[[package]]
511name = "indexmap" 511name = "indexmap"
512version = "1.4.0" 512version = "1.5.0"
513source = "registry+https://github.com/rust-lang/crates.io-index" 513source = "registry+https://github.com/rust-lang/crates.io-index"
514checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe" 514checksum = "5b88cd59ee5f71fea89a62248fc8f387d44400cefe05ef548466d61ced9029a7"
515dependencies = [ 515dependencies = [
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]]
644name = "libc" 645name = "libc"
645version = "0.2.72" 646version = "0.2.73"
646source = "registry+https://github.com/rust-lang/crates.io-index" 647source = "registry+https://github.com/rust-lang/crates.io-index"
647checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701" 648checksum = "bd7d4bd64732af4bf3a67f367c27df8520ad7e230c5817b8ff485864d80242b9"
648 649
649[[package]] 650[[package]]
650name = "libloading" 651name = "libloading"
@@ -984,9 +985,9 @@ checksum = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
984 985
985[[package]] 986[[package]]
986name = "proc-macro2" 987name = "proc-macro2"
987version = "1.0.18" 988version = "1.0.19"
988source = "registry+https://github.com/rust-lang/crates.io-index" 989source = "registry+https://github.com/rust-lang/crates.io-index"
989checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" 990checksum = "04f5f085b5d71e2188cb8271e5da0161ad52c3f227a661a3c135fdf28e258b12"
990dependencies = [ 991dependencies = [
991 "unicode-xid", 992 "unicode-xid",
992] 993]
@@ -1505,9 +1506,9 @@ dependencies = [
1505 1506
1506[[package]] 1507[[package]]
1507name = "rustc-ap-rustc_lexer" 1508name = "rustc-ap-rustc_lexer"
1508version = "666.0.0" 1509version = "669.0.0"
1509source = "registry+https://github.com/rust-lang/crates.io-index" 1510source = "registry+https://github.com/rust-lang/crates.io-index"
1510checksum = "4e00c526f9f8430ea4cd2178d25b02bfc7debe6677350c57292f92f50e65d2fe" 1511checksum = "456af5f09c006cf6c22c1a433ee0232c4bb74bdc6c647a010166a47c94ed2a63"
1511dependencies = [ 1512dependencies = [
1512 "unicode-xid", 1513 "unicode-xid",
1513] 1514]
@@ -1602,9 +1603,9 @@ dependencies = [
1602 1603
1603[[package]] 1604[[package]]
1604name = "semver" 1605name = "semver"
1605version = "0.9.0" 1606version = "0.10.0"
1606source = "registry+https://github.com/rust-lang/crates.io-index" 1607source = "registry+https://github.com/rust-lang/crates.io-index"
1607checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1608checksum = "394cec28fa623e00903caf7ba4fa6fb9a0e260280bb8cdbbba029611108a0190"
1608dependencies = [ 1609dependencies = [
1609 "semver-parser", 1610 "semver-parser",
1610 "serde", 1611 "serde",
@@ -1712,9 +1713,9 @@ checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
1712 1713
1713[[package]] 1714[[package]]
1714name = "syn" 1715name = "syn"
1715version = "1.0.34" 1716version = "1.0.35"
1716source = "registry+https://github.com/rust-lang/crates.io-index" 1717source = "registry+https://github.com/rust-lang/crates.io-index"
1717checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b" 1718checksum = "fb7f4c519df8c117855e19dd8cc851e89eb746fe7a73f0157e0d95fdec5369b0"
1718dependencies = [ 1719dependencies = [
1719 "proc-macro2", 1720 "proc-macro2",
1720 "quote", 1721 "quote",
@@ -1886,11 +1887,11 @@ dependencies = [
1886 1887
1887[[package]] 1888[[package]]
1888name = "tracing-subscriber" 1889name = "tracing-subscriber"
1889version = "0.2.7" 1890version = "0.2.8"
1890source = "registry+https://github.com/rust-lang/crates.io-index" 1891source = "registry+https://github.com/rust-lang/crates.io-index"
1891checksum = "c72c8cf3ec4ed69fef614d011a5ae4274537a8a8c59133558029bd731eb71659" 1892checksum = "cafe899b943f5433c6cab468d75a17ea92948fe9fe60b00f41e13d5e0d4fd054"
1892dependencies = [ 1893dependencies = [
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"
1910source = "registry+https://github.com/rust-lang/crates.io-index" 1911source = "registry+https://github.com/rust-lang/crates.io-index"
1911checksum = "37ee7f0f53ed2093971a698db799ef56a2dfd89b32e3aeb5165f0e637a02be04" 1912checksum = "37ee7f0f53ed2093971a698db799ef56a2dfd89b32e3aeb5165f0e637a02be04"
1912dependencies = [ 1913dependencies = [
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::{
22pub enum FlycheckConfig { 22pub 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> {
21fn check(ra_fixture: &str, expect: Expect) { 21fn 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
29scoped-tls = "1" 29scoped-tls = "1"
30 30
31chalk-solve = { version = "0.17.0" } 31chalk-solve = { version = "0.18.0" }
32chalk-ir = { version = "0.17.0" } 32chalk-ir = { version = "0.18.0" }
33chalk-recursive = { version = "0.17.0" } 33chalk-recursive = { version = "0.18.0" }
34 34
35[dev-dependencies] 35[dev-dependencies]
36insta = "0.16.0" 36insta = "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
11use std::sync::Arc; 11use std::sync::Arc;
12 12
13use expect::Expect;
13use hir_def::{ 14use 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
349fn 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
355fn 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 @@
1use insta::assert_snapshot; 1use expect::expect;
2use test_utils::mark; 2use test_utils::mark;
3 3
4use super::infer_with_mismatches; 4use super::{check_infer, check_infer_with_mismatches};
5
6// Infer with some common definitions and impls.
7fn 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]
25fn infer_block_expr_type_mismatch() { 7fn infer_block_expr_type_mismatch() {
26 assert_snapshot!( 8 check_infer(
27 infer(r#" 9 r"
28fn 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]
41fn coerce_places() { 24fn coerce_places() {
42 assert_snapshot!( 25 check_infer(
43 infer(r#" 26 r#"
44struct S<T> { a: T } 27 struct S<T> { a: T }
45 28
46fn f<T>(_: &[T]) -> T { loop {} } 29 fn f<T>(_: &[T]) -> T { loop {} }
47fn g<T>(_: S<&[T]>) -> T { loop {} } 30 fn g<T>(_: S<&[T]>) -> T { loop {} }
48 31
49fn gen<T>() -> *mut [T; 2] { loop {} } 32 fn gen<T>() -> *mut [T; 2] { loop {} }
50fn test1<U>() -> *mut [U] { 33 fn test1<U>() -> *mut [U] {
51 gen() 34 gen()
52} 35 }
53 36
54fn 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]
116fn infer_let_stmt_coerce() { 109fn infer_let_stmt_coerce() {
117 assert_snapshot!( 110 check_infer(
118 infer(r#" 111 r"
119fn 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]
138fn infer_custom_coerce_unsized() { 132fn infer_custom_coerce_unsized() {
139 assert_snapshot!( 133 check_infer(
140 infer(r#" 134 r#"
141struct A<T: ?Sized>(*const T); 135 struct A<T: ?Sized>(*const T);
142struct B<T: ?Sized>(*const T); 136 struct B<T: ?Sized>(*const T);
143struct C<T: ?Sized> { inner: *const T } 137 struct C<T: ?Sized> { inner: *const T }
144 138
145impl<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> {}
146impl<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
148fn foo1<T>(x: A<[T]>) -> A<[T]> { x } 142 fn foo1<T>(x: A<[T]>) -> A<[T]> { x }
149fn foo2<T>(x: B<[T]>) -> B<[T]> { x } 143 fn foo2<T>(x: B<[T]>) -> B<[T]> { x }
150fn foo3<T>(x: C<[T]>) -> C<[T]> { x } 144 fn foo3<T>(x: C<[T]>) -> C<[T]> { x }
151 145
152fn 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]
189fn infer_if_coerce() { 194fn infer_if_coerce() {
190 assert_snapshot!( 195 check_infer(
191 infer(r#" 196 r#"
192fn foo<T>(x: &[T]) -> &[T] { loop {} } 197 fn foo<T>(x: &[T]) -> &[T] { loop {} }
193fn 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]
225fn infer_if_else_coerce() { 236fn infer_if_else_coerce() {
226 assert_snapshot!( 237 check_infer(
227 infer(r#" 238 r#"
228fn foo<T>(x: &[T]) -> &[T] { loop {} } 239 fn foo<T>(x: &[T]) -> &[T] { loop {} }
229fn 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]
261fn infer_match_first_coerce() { 282fn infer_match_first_coerce() {
262 assert_snapshot!( 283 check_infer(
263 infer(r#" 284 r#"
264fn foo<T>(x: &[T]) -> &[T] { loop {} } 285 fn foo<T>(x: &[T]) -> &[T] { loop {} }
265fn 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]
304fn infer_match_second_coerce() { 330fn infer_match_second_coerce() {
305 assert_snapshot!( 331 check_infer(
306 infer(r#" 332 r#"
307fn foo<T>(x: &[T]) -> &[T] { loop {} } 333 fn foo<T>(x: &[T]) -> &[T] { loop {} }
308fn 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) {
347fn coerce_merge_one_by_one1() { 383fn 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"
352fn 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]
385fn return_coerce_unknown() { 421fn return_coerce_unknown() {
386 assert_snapshot!( 422 check_infer_with_mismatches(
387 infer_with_mismatches(r#" 423 r"
388fn 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]
401fn coerce_autoderef() { 437fn coerce_autoderef() {
402 assert_snapshot!( 438 check_infer_with_mismatches(
403 infer_with_mismatches(r#" 439 r"
404struct Foo; 440 struct Foo;
405fn takes_ref_foo(x: &Foo) {} 441 fn takes_ref_foo(x: &Foo) {}
406fn 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]
436fn coerce_autoderef_generic() { 472fn coerce_autoderef_generic() {
437 assert_snapshot!( 473 check_infer_with_mismatches(
438 infer_with_mismatches(r#" 474 r"
439struct Foo; 475 struct Foo;
440fn takes_ref<T>(x: &T) -> T { *x } 476 fn takes_ref<T>(x: &T) -> T { *x }
441fn 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]
473fn coerce_autoderef_block() { 509fn coerce_autoderef_block() {
474 assert_snapshot!( 510 check_infer_with_mismatches(
475 infer_with_mismatches(r#" 511 r#"
476struct String {} 512 struct String {}
477#[lang = "deref"] 513 #[lang = "deref"]
478trait Deref { type Target; } 514 trait Deref { type Target; }
479impl Deref for String { type Target = str; } 515 impl Deref for String { type Target = str; }
480fn takes_ref_str(x: &str) {} 516 fn takes_ref_str(x: &str) {}
481fn returns_string() -> String { loop {} } 517 fn returns_string() -> String { loop {} }
482fn 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]
504fn closure_return_coerce() { 540fn closure_return_coerce() {
505 assert_snapshot!( 541 check_infer_with_mismatches(
506 infer_with_mismatches(r#" 542 r"
507fn 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]
535fn coerce_fn_item_to_fn_ptr() { 571fn coerce_fn_item_to_fn_ptr() {
536 assert_snapshot!( 572 check_infer_with_mismatches(
537 infer_with_mismatches(r#" 573 r"
538fn foo(x: u32) -> isize { 1 } 574 fn foo(x: u32) -> isize { 1 }
539fn 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]
555fn coerce_fn_items_in_match_arms() { 591fn 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(
559fn foo1(x: u32) -> isize { 1 } 595 r"
560fn foo2(x: u32) -> isize { 2 } 596 fn foo1(x: u32) -> isize { 1 }
561fn foo3(x: u32) -> isize { 3 } 597 fn foo2(x: u32) -> isize { 2 }
562fn 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]
597fn coerce_closure_to_fn_ptr() { 634fn coerce_closure_to_fn_ptr() {
598 assert_snapshot!( 635 check_infer_with_mismatches(
599 infer_with_mismatches(r#" 636 r"
600fn 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]
616fn coerce_placeholder_ref() { 653fn 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"
620struct S<T> { t: T } 657 struct S<T> { t: T }
621impl<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]
638fn coerce_unsize_array() { 675fn coerce_unsize_array() {
639 assert_snapshot!( 676 check_infer_with_mismatches(
640 infer_with_mismatches(r#" 677 r#"
641#[lang = "unsize"] 678 #[lang = "unsize"]
642pub trait Unsize<T> {} 679 pub trait Unsize<T> {}
643#[lang = "coerce_unsized"] 680 #[lang = "coerce_unsized"]
644pub trait CoerceUnsized<T> {} 681 pub trait CoerceUnsized<T> {}
645 682
646impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 683 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
647 684
648fn 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]
665fn coerce_unsize_trait_object_simple() { 702fn 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"]
669pub trait Sized {} 706 pub trait Sized {}
670#[lang = "unsize"] 707 #[lang = "unsize"]
671pub trait Unsize<T> {} 708 pub trait Unsize<T> {}
672#[lang = "coerce_unsized"] 709 #[lang = "coerce_unsized"]
673pub trait CoerceUnsized<T> {} 710 pub trait CoerceUnsized<T> {}
674 711
675impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 712 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
676 713
677trait Foo<T, U> {} 714 trait Foo<T, U> {}
678trait Bar<U, T, X>: Foo<T, U> {} 715 trait Bar<U, T, X>: Foo<T, U> {}
679trait Baz<T, X>: Bar<usize, T, X> {} 716 trait Baz<T, X>: Bar<usize, T, X> {}
680 717
681struct S<T, X>; 718 struct S<T, X>;
682impl<T, X> Foo<T, usize> for S<T, X> {} 719 impl<T, X> Foo<T, usize> for S<T, X> {}
683impl<T, X> Bar<usize, T, X> for S<T, X> {} 720 impl<T, X> Bar<usize, T, X> for S<T, X> {}
684impl<T, X> Baz<T, X> for S<T, X> {} 721 impl<T, X> Baz<T, X> for S<T, X> {}
685 722
686fn 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]
711fn coerce_unsize_trait_object_to_trait_object() { 748fn 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"]
715pub trait Sized {} 752 pub trait Sized {}
716#[lang = "unsize"] 753 #[lang = "unsize"]
717pub trait Unsize<T> {} 754 pub trait Unsize<T> {}
718#[lang = "coerce_unsized"] 755 #[lang = "coerce_unsized"]
719pub trait CoerceUnsized<T> {} 756 pub trait CoerceUnsized<T> {}
720 757
721impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 758 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
722 759
723trait Foo<T, U> {} 760 trait Foo<T, U> {}
724trait Bar<U, T, X>: Foo<T, U> {} 761 trait Bar<U, T, X>: Foo<T, U> {}
725trait Baz<T, X>: Bar<usize, T, X> {} 762 trait Baz<T, X>: Bar<usize, T, X> {}
726 763
727struct S<T, X>; 764 struct S<T, X>;
728impl<T, X> Foo<T, usize> for S<T, X> {} 765 impl<T, X> Foo<T, usize> for S<T, X> {}
729impl<T, X> Bar<usize, T, X> for S<T, X> {} 766 impl<T, X> Bar<usize, T, X> for S<T, X> {}
730impl<T, X> Baz<T, X> for S<T, X> {} 767 impl<T, X> Baz<T, X> for S<T, X> {}
731 768
732fn 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]
759fn coerce_unsize_super_trait_cycle() { 796fn 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"]
763pub trait Sized {} 800 pub trait Sized {}
764#[lang = "unsize"] 801 #[lang = "unsize"]
765pub trait Unsize<T> {} 802 pub trait Unsize<T> {}
766#[lang = "coerce_unsized"] 803 #[lang = "coerce_unsized"]
767pub trait CoerceUnsized<T> {} 804 pub trait CoerceUnsized<T> {}
768 805
769impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 806 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
770 807
771trait A {} 808 trait A {}
772trait B: C + A {} 809 trait B: C + A {}
773trait C: B {} 810 trait C: B {}
774trait D: C 811 trait D: C
775 812
776struct S; 813 struct S;
777impl A for S {} 814 impl A for S {}
778impl B for S {} 815 impl B for S {}
779impl C for S {} 816 impl C for S {}
780impl D for S {} 817 impl D for S {}
781 818
782fn 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() {
801fn coerce_unsize_generic() { 838fn 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"]
807pub trait Unsize<T> {} 844 pub trait Unsize<T> {}
808#[lang = "coerce_unsized"] 845 #[lang = "coerce_unsized"]
809pub trait CoerceUnsized<T> {} 846 pub trait CoerceUnsized<T> {}
810 847
811impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {} 848 impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
812 849
813struct Foo<T> { t: T }; 850 struct Foo<T> { t: T };
814struct Bar<T>(Foo<T>); 851 struct Bar<T>(Foo<T>);
815 852
816fn 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 @@
1use insta::assert_snapshot; 1use expect::expect;
2 2
3use super::{check_types, infer_with_mismatches}; 3use super::{check_infer_with_mismatches, check_types};
4 4
5#[test] 5#[test]
6fn infer_never1() { 6fn infer_never1() {
@@ -240,173 +240,170 @@ fn test(a: i32) {
240 240
241#[test] 241#[test]
242fn diverging_expression_1() { 242fn diverging_expression_1() {
243 let t = infer_with_mismatches( 243 check_infer_with_mismatches(
244 r#" 244 r"
245//- /main.rs 245 //- /main.rs
246fn test1() { 246 fn test1() {
247 let x: u32 = return; 247 let x: u32 = return;
248} 248 }
249fn test2() { 249 fn test2() {
250 let x: u32 = { return; }; 250 let x: u32 = { return; };
251} 251 }
252fn test3() { 252 fn test3() {
253 let x: u32 = loop {}; 253 let x: u32 = loop {};
254} 254 }
255fn test4() { 255 fn test4() {
256 let x: u32 = { loop {} }; 256 let x: u32 = { loop {} };
257} 257 }
258fn test5() { 258 fn test5() {
259 let x: u32 = { if true { loop {}; } else { loop {}; } }; 259 let x: u32 = { if true { loop {}; } else { loop {}; } };
260} 260 }
261fn 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]
306fn diverging_expression_2() { 305fn diverging_expression_2() {
307 let t = infer_with_mismatches( 306 check_infer_with_mismatches(
308 r#" 307 r#"
309//- /main.rs 308 //- /main.rs
310fn 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]
330fn diverging_expression_3_break() { 328fn 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
334fn 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 }
338fn 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 }
346fn 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
39impl ProjectJson { 40impl 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]
14itertools = "0.9.0" 14itertools = "0.9.0"
15rowan = "0.10.0" 15rowan = "0.10.0"
16rustc_lexer = { version = "666.0.0", package = "rustc-ap-rustc_lexer" } 16rustc_lexer = { version = "669.0.0", package = "rustc-ap-rustc_lexer" }
17rustc-hash = "1.1.0" 17rustc-hash = "1.1.0"
18arrayvec = "0.5.1" 18arrayvec = "0.5.1"
19once_cell = "1.3.1" 19once_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