diff options
-rw-r--r-- | Cargo.lock | 32 | ||||
-rw-r--r-- | crates/ra_hir_ty/Cargo.toml | 6 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/_match.rs | 42 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/autoderef.rs | 21 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/expr.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/unify.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/traits.rs | 118 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 13 | ||||
-rw-r--r-- | crates/ra_ide/src/display/navigation_target.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_db/src/symbol_index.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/algo.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/ptr.rs | 8 |
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]] |
115 | name = "chalk-derive" | 115 | name = "chalk-derive" |
116 | version = "0.1.0" | 116 | version = "0.1.0" |
117 | source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea" | 117 | source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" |
118 | dependencies = [ | 118 | dependencies = [ |
119 | "proc-macro2", | 119 | "proc-macro2", |
120 | "quote", | 120 | "quote", |
@@ -125,7 +125,7 @@ dependencies = [ | |||
125 | [[package]] | 125 | [[package]] |
126 | name = "chalk-engine" | 126 | name = "chalk-engine" |
127 | version = "0.9.0" | 127 | version = "0.9.0" |
128 | source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea" | 128 | source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" |
129 | dependencies = [ | 129 | dependencies = [ |
130 | "chalk-macros", | 130 | "chalk-macros", |
131 | "rustc-hash", | 131 | "rustc-hash", |
@@ -134,7 +134,7 @@ dependencies = [ | |||
134 | [[package]] | 134 | [[package]] |
135 | name = "chalk-ir" | 135 | name = "chalk-ir" |
136 | version = "0.1.0" | 136 | version = "0.1.0" |
137 | source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea" | 137 | source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" |
138 | dependencies = [ | 138 | dependencies = [ |
139 | "chalk-derive", | 139 | "chalk-derive", |
140 | "chalk-engine", | 140 | "chalk-engine", |
@@ -144,7 +144,7 @@ dependencies = [ | |||
144 | [[package]] | 144 | [[package]] |
145 | name = "chalk-macros" | 145 | name = "chalk-macros" |
146 | version = "0.1.1" | 146 | version = "0.1.1" |
147 | source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea" | 147 | source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" |
148 | dependencies = [ | 148 | dependencies = [ |
149 | "lazy_static", | 149 | "lazy_static", |
150 | ] | 150 | ] |
@@ -152,7 +152,7 @@ dependencies = [ | |||
152 | [[package]] | 152 | [[package]] |
153 | name = "chalk-rust-ir" | 153 | name = "chalk-rust-ir" |
154 | version = "0.1.0" | 154 | version = "0.1.0" |
155 | source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea" | 155 | source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" |
156 | dependencies = [ | 156 | dependencies = [ |
157 | "chalk-derive", | 157 | "chalk-derive", |
158 | "chalk-engine", | 158 | "chalk-engine", |
@@ -163,7 +163,7 @@ dependencies = [ | |||
163 | [[package]] | 163 | [[package]] |
164 | name = "chalk-solve" | 164 | name = "chalk-solve" |
165 | version = "0.1.0" | 165 | version = "0.1.0" |
166 | source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea" | 166 | source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" |
167 | dependencies = [ | 167 | dependencies = [ |
168 | "chalk-derive", | 168 | "chalk-derive", |
169 | "chalk-engine", | 169 | "chalk-engine", |
@@ -447,9 +447,9 @@ dependencies = [ | |||
447 | 447 | ||
448 | [[package]] | 448 | [[package]] |
449 | name = "hermit-abi" | 449 | name = "hermit-abi" |
450 | version = "0.1.10" | 450 | version = "0.1.11" |
451 | source = "registry+https://github.com/rust-lang/crates.io-index" | 451 | source = "registry+https://github.com/rust-lang/crates.io-index" |
452 | checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e" | 452 | checksum = "8a0d737e0f947a1864e93d33fdef4af8445a00d1ed8dc0c8ddb73139ea6abf15" |
453 | dependencies = [ | 453 | dependencies = [ |
454 | "libc", | 454 | "libc", |
455 | ] | 455 | ] |
@@ -594,15 +594,15 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" | |||
594 | 594 | ||
595 | [[package]] | 595 | [[package]] |
596 | name = "libc" | 596 | name = "libc" |
597 | version = "0.2.68" | 597 | version = "0.2.69" |
598 | source = "registry+https://github.com/rust-lang/crates.io-index" | 598 | source = "registry+https://github.com/rust-lang/crates.io-index" |
599 | checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0" | 599 | checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" |
600 | 600 | ||
601 | [[package]] | 601 | [[package]] |
602 | name = "libloading" | 602 | name = "libloading" |
603 | version = "0.6.0" | 603 | version = "0.6.1" |
604 | source = "registry+https://github.com/rust-lang/crates.io-index" | 604 | source = "registry+https://github.com/rust-lang/crates.io-index" |
605 | checksum = "2c979a19ffb457f0273965c333053f3d586bf759bf7b683fbebc37f9a9ebedc4" | 605 | checksum = "3c4f51b790f5bdb65acb4cc94bb81d7b2ee60348a5431ac1467d390b017600b0" |
606 | dependencies = [ | 606 | dependencies = [ |
607 | "winapi 0.3.8", | 607 | "winapi 0.3.8", |
608 | ] | 608 | ] |
@@ -758,9 +758,9 @@ dependencies = [ | |||
758 | 758 | ||
759 | [[package]] | 759 | [[package]] |
760 | name = "num_cpus" | 760 | name = "num_cpus" |
761 | version = "1.12.0" | 761 | version = "1.13.0" |
762 | source = "registry+https://github.com/rust-lang/crates.io-index" | 762 | source = "registry+https://github.com/rust-lang/crates.io-index" |
763 | checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6" | 763 | checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" |
764 | dependencies = [ | 764 | dependencies = [ |
765 | "hermit-abi", | 765 | "hermit-abi", |
766 | "libc", | 766 | "libc", |
@@ -780,9 +780,9 @@ checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" | |||
780 | 780 | ||
781 | [[package]] | 781 | [[package]] |
782 | name = "parking_lot" | 782 | name = "parking_lot" |
783 | version = "0.10.1" | 783 | version = "0.10.2" |
784 | source = "registry+https://github.com/rust-lang/crates.io-index" | 784 | source = "registry+https://github.com/rust-lang/crates.io-index" |
785 | checksum = "6fdfcb5f20930a79e326f7ec992a9fdb5b7bd809254b1e735bdd5a99f78bee0d" | 785 | checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" |
786 | dependencies = [ | 786 | dependencies = [ |
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 | ||
28 | scoped-tls = "1" | 28 | scoped-tls = "1" |
29 | 29 | ||
30 | chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "6222e416b96892b2a86bc08de7dbc9826ff1acea" } | 30 | chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" } |
31 | chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "6222e416b96892b2a86bc08de7dbc9826ff1acea" } | 31 | chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" } |
32 | chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "6222e416b96892b2a86bc08de7dbc9826ff1acea" } | 32 | chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" } |
33 | 33 | ||
34 | [dev-dependencies] | 34 | [dev-dependencies] |
35 | insta = "0.16.0" | 35 | insta = "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}; | |||
194 | use crate::{ | 194 | use 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 | }; |
199 | use hir_def::{adt::VariantData, EnumVariantId, VariantId}; | 199 | use hir_def::{adt::VariantData, AdtId, EnumVariantId, VariantId}; |
200 | use 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 | ||
514 | pub struct MatchCheckCtx<'a> { | 515 | pub 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 | ||
20 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 20 | const 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)] | ||
35 | pub(super) struct Canonicalized<T> { | 36 | pub(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] |
351 | fn infer_project_associated_type() { | 351 | fn 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#" |
355 | trait Iterable { | 354 | trait 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 | ||
550 | fn test() { | 549 | fn 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 |
575 | fn test() { | 574 | fn 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] |
1404 | fn projection_eq_within_chalk() { | 1399 | fn projection_eq_within_chalk() { |
1405 | // std::env::set_var("CHALK_DEBUG", "1"); | ||
1406 | assert_snapshot!( | 1400 | assert_snapshot!( |
1407 | infer(r#" | 1401 | infer(r#" |
1408 | trait Trait1 { | 1402 | trait 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] | ||
1990 | fn proc_macro_server_types() { | ||
1991 | assert_snapshot!( | ||
1992 | infer_with_mismatches(r#" | ||
1993 | macro_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 | } | ||
2004 | macro_rules! associated_item { | ||
2005 | (type TokenStream) => | ||
2006 | (type TokenStream: 'static + Clone;); | ||
2007 | (type Group) => | ||
2008 | (type Group: 'static + Clone;); | ||
2009 | ($($item:tt)*) => ($($item)*;) | ||
2010 | } | ||
2011 | macro_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 | } | ||
2027 | with_api!(Self, self_, declare_server_traits); | ||
2028 | struct Group {} | ||
2029 | struct TokenStream {} | ||
2030 | struct Rustc; | ||
2031 | impl Types for Rustc { | ||
2032 | type TokenStream = TokenStream; | ||
2033 | type Group = Group; | ||
2034 | } | ||
2035 | fn make<T>() -> T { loop {} } | ||
2036 | impl 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}; | |||
16 | pub(crate) mod chalk; | 16 | pub(crate) mod chalk; |
17 | mod builtin; | 17 | mod 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. |
22 | const 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. |
24 | const CHALK_SOLVER_FUEL: i32 = 100; | 26 | const CHALK_SOLVER_FUEL: i32 = 100; |
25 | 27 | ||
@@ -30,8 +32,7 @@ struct ChalkContext<'a> { | |||
30 | } | 32 | } |
31 | 33 | ||
32 | fn create_chalk_solver() -> chalk_solve::Solver<Interner> { | 34 | fn 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 | ||
513 | impl ToChalk for super::ProjectionPredicate { | 513 | impl 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 { | |||
312 | pub struct FileSymbol { | 312 | pub 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)> { | |||
377 | fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option<FileSymbol> { | 378 | fn 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 }) |