aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock32
-rw-r--r--crates/ra_hir_ty/Cargo.toml6
-rw-r--r--crates/ra_hir_ty/src/_match.rs42
-rw-r--r--crates/ra_hir_ty/src/autoderef.rs21
-rw-r--r--crates/ra_hir_ty/src/expr.rs2
-rw-r--r--crates/ra_hir_ty/src/infer/unify.rs1
-rw-r--r--crates/ra_hir_ty/src/lib.rs10
-rw-r--r--crates/ra_hir_ty/src/tests/traits.rs118
-rw-r--r--crates/ra_hir_ty/src/traits.rs13
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs13
-rw-r--r--crates/ra_ide/src/display/navigation_target.rs2
-rw-r--r--crates/ra_ide_db/src/symbol_index.rs4
-rw-r--r--crates/ra_syntax/src/algo.rs2
-rw-r--r--crates/ra_syntax/src/ptr.rs8
14 files changed, 201 insertions, 73 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8e204d39f..89a734c9b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -114,7 +114,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
114[[package]] 114[[package]]
115name = "chalk-derive" 115name = "chalk-derive"
116version = "0.1.0" 116version = "0.1.0"
117source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea" 117source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
118dependencies = [ 118dependencies = [
119 "proc-macro2", 119 "proc-macro2",
120 "quote", 120 "quote",
@@ -125,7 +125,7 @@ dependencies = [
125[[package]] 125[[package]]
126name = "chalk-engine" 126name = "chalk-engine"
127version = "0.9.0" 127version = "0.9.0"
128source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea" 128source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
129dependencies = [ 129dependencies = [
130 "chalk-macros", 130 "chalk-macros",
131 "rustc-hash", 131 "rustc-hash",
@@ -134,7 +134,7 @@ dependencies = [
134[[package]] 134[[package]]
135name = "chalk-ir" 135name = "chalk-ir"
136version = "0.1.0" 136version = "0.1.0"
137source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea" 137source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
138dependencies = [ 138dependencies = [
139 "chalk-derive", 139 "chalk-derive",
140 "chalk-engine", 140 "chalk-engine",
@@ -144,7 +144,7 @@ dependencies = [
144[[package]] 144[[package]]
145name = "chalk-macros" 145name = "chalk-macros"
146version = "0.1.1" 146version = "0.1.1"
147source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea" 147source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
148dependencies = [ 148dependencies = [
149 "lazy_static", 149 "lazy_static",
150] 150]
@@ -152,7 +152,7 @@ dependencies = [
152[[package]] 152[[package]]
153name = "chalk-rust-ir" 153name = "chalk-rust-ir"
154version = "0.1.0" 154version = "0.1.0"
155source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea" 155source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
156dependencies = [ 156dependencies = [
157 "chalk-derive", 157 "chalk-derive",
158 "chalk-engine", 158 "chalk-engine",
@@ -163,7 +163,7 @@ dependencies = [
163[[package]] 163[[package]]
164name = "chalk-solve" 164name = "chalk-solve"
165version = "0.1.0" 165version = "0.1.0"
166source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea" 166source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
167dependencies = [ 167dependencies = [
168 "chalk-derive", 168 "chalk-derive",
169 "chalk-engine", 169 "chalk-engine",
@@ -447,9 +447,9 @@ dependencies = [
447 447
448[[package]] 448[[package]]
449name = "hermit-abi" 449name = "hermit-abi"
450version = "0.1.10" 450version = "0.1.11"
451source = "registry+https://github.com/rust-lang/crates.io-index" 451source = "registry+https://github.com/rust-lang/crates.io-index"
452checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e" 452checksum = "8a0d737e0f947a1864e93d33fdef4af8445a00d1ed8dc0c8ddb73139ea6abf15"
453dependencies = [ 453dependencies = [
454 "libc", 454 "libc",
455] 455]
@@ -594,15 +594,15 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
594 594
595[[package]] 595[[package]]
596name = "libc" 596name = "libc"
597version = "0.2.68" 597version = "0.2.69"
598source = "registry+https://github.com/rust-lang/crates.io-index" 598source = "registry+https://github.com/rust-lang/crates.io-index"
599checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" 599checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
600 600
601[[package]] 601[[package]]
602name = "libloading" 602name = "libloading"
603version = "0.6.0" 603version = "0.6.1"
604source = "registry+https://github.com/rust-lang/crates.io-index" 604source = "registry+https://github.com/rust-lang/crates.io-index"
605checksum = "2c979a19ffb457f0273965c333053f3d586bf759bf7b683fbebc37f9a9ebedc4" 605checksum = "3c4f51b790f5bdb65acb4cc94bb81d7b2ee60348a5431ac1467d390b017600b0"
606dependencies = [ 606dependencies = [
607 "winapi 0.3.8", 607 "winapi 0.3.8",
608] 608]
@@ -758,9 +758,9 @@ dependencies = [
758 758
759[[package]] 759[[package]]
760name = "num_cpus" 760name = "num_cpus"
761version = "1.12.0" 761version = "1.13.0"
762source = "registry+https://github.com/rust-lang/crates.io-index" 762source = "registry+https://github.com/rust-lang/crates.io-index"
763checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" 763checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
764dependencies = [ 764dependencies = [
765 "hermit-abi", 765 "hermit-abi",
766 "libc", 766 "libc",
@@ -780,9 +780,9 @@ checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
780 780
781[[package]] 781[[package]]
782name = "parking_lot" 782name = "parking_lot"
783version = "0.10.1" 783version = "0.10.2"
784source = "registry+https://github.com/rust-lang/crates.io-index" 784source = "registry+https://github.com/rust-lang/crates.io-index"
785checksum = "6fdfcb5f20930a79e326f7ec992a9fdb5b7bd809254b1e735bdd5a99f78bee0d" 785checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
786dependencies = [ 786dependencies = [
787 "lock_api", 787 "lock_api",
788 "parking_lot_core", 788 "parking_lot_core",
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index e891d733f..177bdbcb0 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -27,9 +27,9 @@ test_utils = { path = "../test_utils" }
27 27
28scoped-tls = "1" 28scoped-tls = "1"
29 29
30chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "6222e416b96892b2a86bc08de7dbc9826ff1acea" } 30chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" }
31chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "6222e416b96892b2a86bc08de7dbc9826ff1acea" } 31chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" }
32chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "6222e416b96892b2a86bc08de7dbc9826ff1acea" } 32chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" }
33 33
34[dev-dependencies] 34[dev-dependencies]
35insta = "0.16.0" 35insta = "0.16.0"
diff --git a/crates/ra_hir_ty/src/_match.rs b/crates/ra_hir_ty/src/_match.rs
index a64be9848..688026a04 100644
--- a/crates/ra_hir_ty/src/_match.rs
+++ b/crates/ra_hir_ty/src/_match.rs
@@ -194,9 +194,10 @@ use smallvec::{smallvec, SmallVec};
194use crate::{ 194use crate::{
195 db::HirDatabase, 195 db::HirDatabase,
196 expr::{Body, Expr, Literal, Pat, PatId}, 196 expr::{Body, Expr, Literal, Pat, PatId},
197 InferenceResult, 197 ApplicationTy, InferenceResult, Ty, TypeCtor,
198}; 198};
199use hir_def::{adt::VariantData, EnumVariantId, VariantId}; 199use hir_def::{adt::VariantData, AdtId, EnumVariantId, VariantId};
200use ra_arena::Idx;
200 201
201#[derive(Debug, Clone, Copy)] 202#[derive(Debug, Clone, Copy)]
202/// Either a pattern from the source code being analyzed, represented as 203/// Either a pattern from the source code being analyzed, represented as
@@ -512,6 +513,7 @@ pub enum Usefulness {
512} 513}
513 514
514pub struct MatchCheckCtx<'a> { 515pub struct MatchCheckCtx<'a> {
516 pub match_expr: Idx<Expr>,
515 pub body: Arc<Body>, 517 pub body: Arc<Body>,
516 pub infer: Arc<InferenceResult>, 518 pub infer: Arc<InferenceResult>,
517 pub db: &'a dyn HirDatabase, 519 pub db: &'a dyn HirDatabase,
@@ -530,6 +532,16 @@ pub(crate) fn is_useful(
530 matrix: &Matrix, 532 matrix: &Matrix,
531 v: &PatStack, 533 v: &PatStack,
532) -> MatchCheckResult<Usefulness> { 534) -> MatchCheckResult<Usefulness> {
535 // Handle the special case of enums with no variants. In that case, no match
536 // arm is useful.
537 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(AdtId::EnumId(enum_id)), .. }) =
538 cx.infer[cx.match_expr].strip_references()
539 {
540 if cx.db.enum_data(*enum_id).variants.is_empty() {
541 return Ok(Usefulness::NotUseful);
542 }
543 }
544
533 if v.is_empty() { 545 if v.is_empty() {
534 let result = if matrix.is_empty() { Usefulness::Useful } else { Usefulness::NotUseful }; 546 let result = if matrix.is_empty() { Usefulness::Useful } else { Usefulness::NotUseful };
535 547
@@ -1618,6 +1630,32 @@ mod tests {
1618 1630
1619 check_no_diagnostic(content); 1631 check_no_diagnostic(content);
1620 } 1632 }
1633
1634 #[test]
1635 fn enum_never() {
1636 let content = r"
1637 enum Never {}
1638
1639 fn test_fn(never: Never) {
1640 match never {}
1641 }
1642 ";
1643
1644 check_no_diagnostic(content);
1645 }
1646
1647 #[test]
1648 fn enum_never_ref() {
1649 let content = r"
1650 enum Never {}
1651
1652 fn test_fn(never: &Never) {
1653 match never {}
1654 }
1655 ";
1656
1657 check_no_diagnostic(content);
1658 }
1621} 1659}
1622 1660
1623#[cfg(test)] 1661#[cfg(test)]
diff --git a/crates/ra_hir_ty/src/autoderef.rs b/crates/ra_hir_ty/src/autoderef.rs
index d91c21e24..1b0f84c5c 100644
--- a/crates/ra_hir_ty/src/autoderef.rs
+++ b/crates/ra_hir_ty/src/autoderef.rs
@@ -14,7 +14,7 @@ use crate::{
14 db::HirDatabase, 14 db::HirDatabase,
15 traits::{InEnvironment, Solution}, 15 traits::{InEnvironment, Solution},
16 utils::generics, 16 utils::generics,
17 BoundVar, Canonical, DebruijnIndex, Substs, Ty, 17 BoundVar, Canonical, DebruijnIndex, Obligation, Substs, TraitRef, Ty,
18}; 18};
19 19
20const AUTODEREF_RECURSION_LIMIT: usize = 10; 20const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -66,6 +66,20 @@ fn deref_by_trait(
66 let parameters = 66 let parameters =
67 Substs::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); 67 Substs::build_for_generics(&generic_params).push(ty.value.value.clone()).build();
68 68
69 // Check that the type implements Deref at all
70 let trait_ref = TraitRef { trait_: deref_trait, substs: parameters.clone() };
71 let implements_goal = super::Canonical {
72 num_vars: ty.value.num_vars,
73 value: InEnvironment {
74 value: Obligation::Trait(trait_ref),
75 environment: ty.environment.clone(),
76 },
77 };
78 if db.trait_solve(krate, implements_goal).is_none() {
79 return None;
80 }
81
82 // Now do the assoc type projection
69 let projection = super::traits::ProjectionPredicate { 83 let projection = super::traits::ProjectionPredicate {
70 ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.num_vars)), 84 ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.num_vars)),
71 projection_ty: super::ProjectionTy { associated_ty: target, parameters }, 85 projection_ty: super::ProjectionTy { associated_ty: target, parameters },
@@ -91,6 +105,11 @@ fn deref_by_trait(
91 // they're just being 'passed through'. In the 'standard' case where 105 // they're just being 'passed through'. In the 'standard' case where
92 // we have `impl<T> Deref for Foo<T> { Target = T }`, that should be 106 // we have `impl<T> Deref for Foo<T> { Target = T }`, that should be
93 // the case. 107 // the case.
108
109 // FIXME: if the trait solver decides to truncate the type, these
110 // assumptions will be broken. We would need to properly introduce
111 // new variables in that case
112
94 for i in 1..vars.0.num_vars { 113 for i in 1..vars.0.num_vars {
95 if vars.0.value[i - 1] != Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 114 if vars.0.value[i - 1] != Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
96 { 115 {
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs
index 21abbcf1e..fd59f4320 100644
--- a/crates/ra_hir_ty/src/expr.rs
+++ b/crates/ra_hir_ty/src/expr.rs
@@ -156,7 +156,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
156 None => return, 156 None => return,
157 }; 157 };
158 158
159 let cx = MatchCheckCtx { body, infer: infer.clone(), db }; 159 let cx = MatchCheckCtx { match_expr, body, infer: infer.clone(), db };
160 let pats = arms.iter().map(|arm| arm.pat); 160 let pats = arms.iter().map(|arm| arm.pat);
161 161
162 let mut seen = Matrix::empty(); 162 let mut seen = Matrix::empty();
diff --git a/crates/ra_hir_ty/src/infer/unify.rs b/crates/ra_hir_ty/src/infer/unify.rs
index ac25f8a80..5f6cea8d3 100644
--- a/crates/ra_hir_ty/src/infer/unify.rs
+++ b/crates/ra_hir_ty/src/infer/unify.rs
@@ -32,6 +32,7 @@ where
32 var_stack: Vec<TypeVarId>, 32 var_stack: Vec<TypeVarId>,
33} 33}
34 34
35#[derive(Debug)]
35pub(super) struct Canonicalized<T> { 36pub(super) struct Canonicalized<T> {
36 pub value: Canonical<T>, 37 pub value: Canonical<T>,
37 free_vars: Vec<InferTy>, 38 free_vars: Vec<InferTy>,
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 18f74d3b1..2677f3af2 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -680,6 +680,16 @@ impl Ty {
680 } 680 }
681 } 681 }
682 682
683 pub fn strip_references(&self) -> &Ty {
684 let mut t: &Ty = self;
685
686 while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t {
687 t = parameters.as_single();
688 }
689
690 t
691 }
692
683 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { 693 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> {
684 match self { 694 match self {
685 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { 695 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => {
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index b3a2fc439..0a889f805 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -349,7 +349,6 @@ trait Trait: SuperTrait {
349 349
350#[test] 350#[test]
351fn infer_project_associated_type() { 351fn infer_project_associated_type() {
352 // y, z, a don't yet work because of https://github.com/rust-lang/chalk/issues/234
353 assert_snapshot!( 352 assert_snapshot!(
354 infer(r#" 353 infer(r#"
355trait Iterable { 354trait Iterable {
@@ -368,12 +367,12 @@ fn test<T: Iterable>() {
368 [108; 261) '{ ...ter; }': () 367 [108; 261) '{ ...ter; }': ()
369 [118; 119) 'x': u32 368 [118; 119) 'x': u32
370 [145; 146) '1': u32 369 [145; 146) '1': u32
371 [156; 157) 'y': {unknown} 370 [156; 157) 'y': Iterable::Item<T>
372 [183; 192) 'no_matter': {unknown} 371 [183; 192) 'no_matter': Iterable::Item<T>
373 [202; 203) 'z': {unknown} 372 [202; 203) 'z': Iterable::Item<T>
374 [215; 224) 'no_matter': {unknown} 373 [215; 224) 'no_matter': Iterable::Item<T>
375 [234; 235) 'a': {unknown} 374 [234; 235) 'a': Iterable::Item<T>
376 [249; 258) 'no_matter': {unknown} 375 [249; 258) 'no_matter': Iterable::Item<T>
377 "### 376 "###
378 ); 377 );
379} 378}
@@ -433,8 +432,8 @@ fn test<T: Iterable<Item=u32>>() {
433"#), 432"#),
434 @r###" 433 @r###"
435 [67; 100) '{ ...own; }': () 434 [67; 100) '{ ...own; }': ()
436 [77; 78) 'y': {unknown} 435 [77; 78) 'y': u32
437 [90; 97) 'unknown': {unknown} 436 [90; 97) 'unknown': u32
438 "### 437 "###
439 ); 438 );
440} 439}
@@ -549,7 +548,7 @@ impl std::ops::Index<u32> for Bar {
549 548
550fn test() { 549fn test() {
551 let a = Bar; 550 let a = Bar;
552 let b = a[1]; 551 let b = a[1u32];
553 b<|>; 552 b<|>;
554} 553}
555 554
@@ -574,7 +573,7 @@ fn infer_ops_index_autoderef() {
574//- /main.rs crate:main deps:std 573//- /main.rs crate:main deps:std
575fn test() { 574fn test() {
576 let a = &[1u32, 2, 3]; 575 let a = &[1u32, 2, 3];
577 let b = a[1]; 576 let b = a[1u32];
578 b<|>; 577 b<|>;
579} 578}
580 579
@@ -916,11 +915,7 @@ fn test<T: ApplyL>(t: T) {
916} 915}
917"#, 916"#,
918 ); 917 );
919 // FIXME here Chalk doesn't normalize the type to a placeholder. I think we 918 assert_eq!(t, "ApplyL::Out<T>");
920 // need to add a rule like Normalize(<T as ApplyL>::Out -> ApplyL::Out<T>)
921 // to the trait env ourselves here; probably Chalk can't do this by itself.
922 // assert_eq!(t, "ApplyL::Out<[missing name]>");
923 assert_eq!(t, "{unknown}");
924} 919}
925 920
926#[test] 921#[test]
@@ -1329,16 +1324,16 @@ fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
1329 [263; 264) 'y': impl Trait<Type = i64> 1324 [263; 264) 'y': impl Trait<Type = i64>
1330 [290; 398) '{ ...r>); }': () 1325 [290; 398) '{ ...r>); }': ()
1331 [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type 1326 [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type
1332 [296; 302) 'get(x)': {unknown} 1327 [296; 302) 'get(x)': u32
1333 [300; 301) 'x': T 1328 [300; 301) 'x': T
1334 [308; 312) 'get2': fn get2<{unknown}, T>(T) -> {unknown} 1329 [308; 312) 'get2': fn get2<u32, T>(T) -> u32
1335 [308; 315) 'get2(x)': {unknown} 1330 [308; 315) 'get2(x)': u32
1336 [313; 314) 'x': T 1331 [313; 314) 'x': T
1337 [321; 324) 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type 1332 [321; 324) 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type
1338 [321; 327) 'get(y)': {unknown} 1333 [321; 327) 'get(y)': i64
1339 [325; 326) 'y': impl Trait<Type = i64> 1334 [325; 326) 'y': impl Trait<Type = i64>
1340 [333; 337) 'get2': fn get2<{unknown}, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> {unknown} 1335 [333; 337) 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64
1341 [333; 340) 'get2(y)': {unknown} 1336 [333; 340) 'get2(y)': i64
1342 [338; 339) 'y': impl Trait<Type = i64> 1337 [338; 339) 'y': impl Trait<Type = i64>
1343 [346; 349) 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type 1338 [346; 349) 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type
1344 [346; 357) 'get(set(S))': u64 1339 [346; 357) 'get(set(S))': u64
@@ -1402,7 +1397,6 @@ mod iter {
1402 1397
1403#[test] 1398#[test]
1404fn projection_eq_within_chalk() { 1399fn projection_eq_within_chalk() {
1405 // std::env::set_var("CHALK_DEBUG", "1");
1406 assert_snapshot!( 1400 assert_snapshot!(
1407 infer(r#" 1401 infer(r#"
1408trait Trait1 { 1402trait Trait1 {
@@ -1422,7 +1416,7 @@ fn test<T: Trait1<Type = u32>>(x: T) {
1422 [164; 165) 'x': T 1416 [164; 165) 'x': T
1423 [170; 186) '{ ...o(); }': () 1417 [170; 186) '{ ...o(); }': ()
1424 [176; 177) 'x': T 1418 [176; 177) 'x': T
1425 [176; 183) 'x.foo()': {unknown} 1419 [176; 183) 'x.foo()': u32
1426 "### 1420 "###
1427 ); 1421 );
1428} 1422}
@@ -1578,7 +1572,7 @@ fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
1578 [150; 151) 'f': F 1572 [150; 151) 'f': F
1579 [156; 184) '{ ...2)); }': () 1573 [156; 184) '{ ...2)); }': ()
1580 [162; 163) 'f': F 1574 [162; 163) 'f': F
1581 [162; 181) 'f.call...1, 2))': {unknown} 1575 [162; 181) 'f.call...1, 2))': u128
1582 [174; 180) '(1, 2)': (u32, u64) 1576 [174; 180) '(1, 2)': (u32, u64)
1583 [175; 176) '1': u32 1577 [175; 176) '1': u32
1584 [178; 179) '2': u64 1578 [178; 179) '2': u64
@@ -1829,7 +1823,7 @@ impl Trait for S2 {
1829"#, 1823"#,
1830 ), @r###" 1824 ), @r###"
1831 [54; 58) 'self': &Self 1825 [54; 58) 'self': &Self
1832 [60; 61) 'x': {unknown} 1826 [60; 61) 'x': Trait::Item<Self>
1833 [140; 144) 'self': &S 1827 [140; 144) 'self': &S
1834 [146; 147) 'x': u32 1828 [146; 147) 'x': u32
1835 [161; 175) '{ let y = x; }': () 1829 [161; 175) '{ let y = x; }': ()
@@ -1989,9 +1983,75 @@ fn test<I: Iterator<Item: Iterator<Item = u32>>>() {
1989} 1983}
1990"#, 1984"#,
1991 ); 1985 );
1992 // assert_eq!(t, "u32"); 1986 assert_eq!(t, "u32");
1993 // doesn't currently work, Chalk #234 1987}
1994 assert_eq!(t, "{unknown}"); 1988
1989#[test]
1990fn proc_macro_server_types() {
1991 assert_snapshot!(
1992 infer_with_mismatches(r#"
1993macro_rules! with_api {
1994 ($S:ident, $self:ident, $m:ident) => {
1995 $m! {
1996 TokenStream {
1997 fn new() -> $S::TokenStream;
1998 },
1999 Group {
2000 },
2001 }
2002 };
2003}
2004macro_rules! associated_item {
2005 (type TokenStream) =>
2006 (type TokenStream: 'static + Clone;);
2007 (type Group) =>
2008 (type Group: 'static + Clone;);
2009 ($($item:tt)*) => ($($item)*;)
2010}
2011macro_rules! declare_server_traits {
2012 ($($name:ident {
2013 $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
2014 }),* $(,)?) => {
2015 pub trait Types {
2016 $(associated_item!(type $name);)*
2017 }
2018
2019 $(pub trait $name: Types {
2020 $(associated_item!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?);)*
2021 })*
2022
2023 pub trait Server: Types $(+ $name)* {}
2024 impl<S: Types $(+ $name)*> Server for S {}
2025 }
2026}
2027with_api!(Self, self_, declare_server_traits);
2028struct Group {}
2029struct TokenStream {}
2030struct Rustc;
2031impl Types for Rustc {
2032 type TokenStream = TokenStream;
2033 type Group = Group;
2034}
2035fn make<T>() -> T { loop {} }
2036impl TokenStream for Rustc {
2037 fn new() -> Self::TokenStream {
2038 let group: Self::Group = make();
2039 make()
2040 }
2041}
2042"#, true),
2043 @r###"
2044 [1115; 1126) '{ loop {} }': T
2045 [1117; 1124) 'loop {}': !
2046 [1122; 1124) '{}': ()
2047 [1190; 1253) '{ ... }': {unknown}
2048 [1204; 1209) 'group': {unknown}
2049 [1225; 1229) 'make': fn make<{unknown}>() -> {unknown}
2050 [1225; 1231) 'make()': {unknown}
2051 [1241; 1245) 'make': fn make<{unknown}>() -> {unknown}
2052 [1241; 1247) 'make()': {unknown}
2053 "###
2054 );
1995} 2055}
1996 2056
1997#[test] 2057#[test]
diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs
index 44fbdb197..05791a848 100644
--- a/crates/ra_hir_ty/src/traits.rs
+++ b/crates/ra_hir_ty/src/traits.rs
@@ -16,10 +16,12 @@ use self::chalk::{from_chalk, Interner, ToChalk};
16pub(crate) mod chalk; 16pub(crate) mod chalk;
17mod builtin; 17mod builtin;
18 18
19/// This controls the maximum size of types Chalk considers. If we set this too 19// This controls the maximum size of types Chalk considers. If we set this too
20/// high, we can run into slow edge cases; if we set it too low, Chalk won't 20// high, we can run into slow edge cases; if we set it too low, Chalk won't
21/// find some solutions. 21// find some solutions.
22const CHALK_SOLVER_MAX_SIZE: usize = 10; 22// FIXME this is currently hardcoded in the recursive solver
23// const CHALK_SOLVER_MAX_SIZE: usize = 10;
24
23/// This controls how much 'time' we give the Chalk solver before giving up. 25/// This controls how much 'time' we give the Chalk solver before giving up.
24const CHALK_SOLVER_FUEL: i32 = 100; 26const CHALK_SOLVER_FUEL: i32 = 100;
25 27
@@ -30,8 +32,7 @@ struct ChalkContext<'a> {
30} 32}
31 33
32fn create_chalk_solver() -> chalk_solve::Solver<Interner> { 34fn create_chalk_solver() -> chalk_solve::Solver<Interner> {
33 let solver_choice = 35 let solver_choice = chalk_solve::SolverChoice::recursive();
34 chalk_solve::SolverChoice::SLG { max_size: CHALK_SOLVER_MAX_SIZE, expected_answers: None };
35 solver_choice.into_solver() 36 solver_choice.into_solver()
36} 37}
37 38
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 55eb0ffcb..60d70d18e 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -511,13 +511,13 @@ impl ToChalk for ProjectionTy {
511} 511}
512 512
513impl ToChalk for super::ProjectionPredicate { 513impl ToChalk for super::ProjectionPredicate {
514 type Chalk = chalk_ir::Normalize<Interner>; 514 type Chalk = chalk_ir::AliasEq<Interner>;
515 515
516 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Normalize<Interner> { 516 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> {
517 chalk_ir::Normalize { alias: self.projection_ty.to_chalk(db), ty: self.ty.to_chalk(db) } 517 chalk_ir::AliasEq { alias: self.projection_ty.to_chalk(db), ty: self.ty.to_chalk(db) }
518 } 518 }
519 519
520 fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::Normalize<Interner>) -> Self { 520 fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::AliasEq<Interner>) -> Self {
521 unimplemented!() 521 unimplemented!()
522 } 522 }
523} 523}
@@ -795,8 +795,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
795 fn well_known_trait_id( 795 fn well_known_trait_id(
796 &self, 796 &self,
797 _well_known_trait: chalk_rust_ir::WellKnownTrait, 797 _well_known_trait: chalk_rust_ir::WellKnownTrait,
798 ) -> chalk_ir::TraitId<Interner> { 798 ) -> Option<chalk_ir::TraitId<Interner>> {
799 unimplemented!() 799 // FIXME tell Chalk about well-known traits (here and in trait_datum)
800 None
800 } 801 }
801} 802}
802 803
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs
index e61846995..6289f53f3 100644
--- a/crates/ra_ide/src/display/navigation_target.rs
+++ b/crates/ra_ide/src/display/navigation_target.rs
@@ -175,7 +175,7 @@ impl ToNav for FileSymbol {
175 NavigationTarget { 175 NavigationTarget {
176 file_id: self.file_id, 176 file_id: self.file_id,
177 name: self.name.clone(), 177 name: self.name.clone(),
178 kind: self.ptr.kind(), 178 kind: self.kind,
179 full_range: self.ptr.range(), 179 full_range: self.ptr.range(),
180 focus_range: self.name_range, 180 focus_range: self.name_range,
181 container_name: self.container_name.clone(), 181 container_name: self.container_name.clone(),
diff --git a/crates/ra_ide_db/src/symbol_index.rs b/crates/ra_ide_db/src/symbol_index.rs
index d30458d86..937abb433 100644
--- a/crates/ra_ide_db/src/symbol_index.rs
+++ b/crates/ra_ide_db/src/symbol_index.rs
@@ -285,7 +285,7 @@ impl Query {
285 let (start, end) = SymbolIndex::map_value_to_range(indexed_value.value); 285 let (start, end) = SymbolIndex::map_value_to_range(indexed_value.value);
286 286
287 for symbol in &symbol_index.symbols[start..end] { 287 for symbol in &symbol_index.symbols[start..end] {
288 if self.only_types && !is_type(symbol.ptr.kind()) { 288 if self.only_types && !is_type(symbol.kind) {
289 continue; 289 continue;
290 } 290 }
291 if self.exact && symbol.name != self.query { 291 if self.exact && symbol.name != self.query {
@@ -312,6 +312,7 @@ fn is_type(kind: SyntaxKind) -> bool {
312pub struct FileSymbol { 312pub struct FileSymbol {
313 pub file_id: FileId, 313 pub file_id: FileId,
314 pub name: SmolStr, 314 pub name: SmolStr,
315 pub kind: SyntaxKind,
315 pub ptr: SyntaxNodePtr, 316 pub ptr: SyntaxNodePtr,
316 pub name_range: Option<TextRange>, 317 pub name_range: Option<TextRange>,
317 pub container_name: Option<SmolStr>, 318 pub container_name: Option<SmolStr>,
@@ -377,6 +378,7 @@ fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> {
377fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option<FileSymbol> { 378fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option<FileSymbol> {
378 to_symbol(node).map(move |(name, ptr, name_range)| FileSymbol { 379 to_symbol(node).map(move |(name, ptr, name_range)| FileSymbol {
379 name, 380 name,
381 kind: node.kind(),
380 ptr, 382 ptr,
381 file_id, 383 file_id,
382 name_range: Some(name_range), 384 name_range: Some(name_range),
diff --git a/crates/ra_syntax/src/algo.rs b/crates/ra_syntax/src/algo.rs
index 7f87f4212..ea41bf85d 100644
--- a/crates/ra_syntax/src/algo.rs
+++ b/crates/ra_syntax/src/algo.rs
@@ -351,7 +351,7 @@ fn with_children(
351 // FIXME: use a more elegant way to re-fetch the node (#1185), make 351 // FIXME: use a more elegant way to re-fetch the node (#1185), make
352 // `range` private afterwards 352 // `range` private afterwards
353 let mut ptr = SyntaxNodePtr::new(parent); 353 let mut ptr = SyntaxNodePtr::new(parent);
354 ptr.range = TextRange::offset_len(ptr.range().start(), len); 354 ptr.range = TextRange::offset_len(ptr.range.start(), len);
355 ptr.to_node(&new_root_node) 355 ptr.to_node(&new_root_node)
356} 356}
357 357
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs
index bc48a2e71..3be648c2a 100644
--- a/crates/ra_syntax/src/ptr.rs
+++ b/crates/ra_syntax/src/ptr.rs
@@ -34,12 +34,8 @@ impl SyntaxNodePtr {
34 self.range 34 self.range
35 } 35 }
36 36
37 pub fn kind(&self) -> SyntaxKind {
38 self.kind
39 }
40
41 pub fn cast<N: AstNode>(self) -> Option<AstPtr<N>> { 37 pub fn cast<N: AstNode>(self) -> Option<AstPtr<N>> {
42 if !N::can_cast(self.kind()) { 38 if !N::can_cast(self.kind) {
43 return None; 39 return None;
44 } 40 }
45 Some(AstPtr { raw: self, _ty: PhantomData }) 41 Some(AstPtr { raw: self, _ty: PhantomData })
@@ -88,7 +84,7 @@ impl<N: AstNode> AstPtr<N> {
88 } 84 }
89 85
90 pub fn cast<U: AstNode>(self) -> Option<AstPtr<U>> { 86 pub fn cast<U: AstNode>(self) -> Option<AstPtr<U>> {
91 if !U::can_cast(self.raw.kind()) { 87 if !U::can_cast(self.raw.kind) {
92 return None; 88 return None;
93 } 89 }
94 Some(AstPtr { raw: self.raw, _ty: PhantomData }) 90 Some(AstPtr { raw: self.raw, _ty: PhantomData })