]> git.lizzy.rs Git - rust.git/commitdiff
Merge #3958
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>
Thu, 16 Apr 2020 20:21:59 +0000 (20:21 +0000)
committerGitHub <noreply@github.com>
Thu, 16 Apr 2020 20:21:59 +0000 (20:21 +0000)
3958: Add proc-macro related config and tests r=matklad a=edwin0cheng

This PR do the following things:

1. Add cli argument `proc-macro` for running proc-macro server.
2. Added support for proc-macro in bench and analysis-stats
3. Added typescript config for proc-macros
4. Added an heavy test for proc-macros.

To test it out:

1. run `cargo xtask install --proc-macro`
2. add `"rust-analyzer.cargo.loadOutDirsFromCheck": true"` and `"rust-analyzer.procMacro.enabled": true"` in vs code config.

[Edit] Change to use `rust-analyzer proc-macro` for running proc-macro standalone process.

Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
14 files changed:
Cargo.lock
crates/ra_hir_ty/Cargo.toml
crates/ra_hir_ty/src/_match.rs
crates/ra_hir_ty/src/autoderef.rs
crates/ra_hir_ty/src/expr.rs
crates/ra_hir_ty/src/infer/unify.rs
crates/ra_hir_ty/src/lib.rs
crates/ra_hir_ty/src/tests/traits.rs
crates/ra_hir_ty/src/traits.rs
crates/ra_hir_ty/src/traits/chalk.rs
crates/ra_ide/src/display/navigation_target.rs
crates/ra_ide_db/src/symbol_index.rs
crates/ra_syntax/src/algo.rs
crates/ra_syntax/src/ptr.rs

index 8e204d39ff28032b50bb6181ae24abb16c392728..89a734c9bb935cae217aa20213debe4aaff6fe9c 100644 (file)
@@ -114,7 +114,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
 [[package]]
 name = "chalk-derive"
 version = "0.1.0"
-source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea"
+source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -125,7 +125,7 @@ dependencies = [
 [[package]]
 name = "chalk-engine"
 version = "0.9.0"
-source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea"
+source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
 dependencies = [
  "chalk-macros",
  "rustc-hash",
@@ -134,7 +134,7 @@ dependencies = [
 [[package]]
 name = "chalk-ir"
 version = "0.1.0"
-source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea"
+source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
 dependencies = [
  "chalk-derive",
  "chalk-engine",
@@ -144,7 +144,7 @@ dependencies = [
 [[package]]
 name = "chalk-macros"
 version = "0.1.1"
-source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea"
+source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
 dependencies = [
  "lazy_static",
 ]
@@ -152,7 +152,7 @@ dependencies = [
 [[package]]
 name = "chalk-rust-ir"
 version = "0.1.0"
-source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea"
+source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
 dependencies = [
  "chalk-derive",
  "chalk-engine",
@@ -163,7 +163,7 @@ dependencies = [
 [[package]]
 name = "chalk-solve"
 version = "0.1.0"
-source = "git+https://github.com/rust-lang/chalk.git?rev=6222e416b96892b2a86bc08de7dbc9826ff1acea#6222e416b96892b2a86bc08de7dbc9826ff1acea"
+source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
 dependencies = [
  "chalk-derive",
  "chalk-engine",
@@ -447,9 +447,9 @@ dependencies = [
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.10"
+version = "0.1.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e"
+checksum = "8a0d737e0f947a1864e93d33fdef4af8445a00d1ed8dc0c8ddb73139ea6abf15"
 dependencies = [
  "libc",
 ]
@@ -594,15 +594,15 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
 
 [[package]]
 name = "libc"
-version = "0.2.68"
+version = "0.2.69"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
+checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
 
 [[package]]
 name = "libloading"
-version = "0.6.0"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c979a19ffb457f0273965c333053f3d586bf759bf7b683fbebc37f9a9ebedc4"
+checksum = "3c4f51b790f5bdb65acb4cc94bb81d7b2ee60348a5431ac1467d390b017600b0"
 dependencies = [
  "winapi 0.3.8",
 ]
@@ -758,9 +758,9 @@ dependencies = [
 
 [[package]]
 name = "num_cpus"
-version = "1.12.0"
+version = "1.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
+checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
 dependencies = [
  "hermit-abi",
  "libc",
@@ -780,9 +780,9 @@ checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063"
 
 [[package]]
 name = "parking_lot"
-version = "0.10.1"
+version = "0.10.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fdfcb5f20930a79e326f7ec992a9fdb5b7bd809254b1e735bdd5a99f78bee0d"
+checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
 dependencies = [
  "lock_api",
  "parking_lot_core",
index e891d733fc787c3453ddeb8af1892a53e3d54048..177bdbcb0eb6ace64e23bd016baa81480905efaa 100644 (file)
@@ -27,9 +27,9 @@ test_utils = { path = "../test_utils" }
 
 scoped-tls = "1"
 
-chalk-solve =   { git = "https://github.com/rust-lang/chalk.git", rev = "6222e416b96892b2a86bc08de7dbc9826ff1acea" }
-chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "6222e416b96892b2a86bc08de7dbc9826ff1acea" }
-chalk-ir =      { git = "https://github.com/rust-lang/chalk.git", rev = "6222e416b96892b2a86bc08de7dbc9826ff1acea" }
+chalk-solve =   { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" }
+chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" }
+chalk-ir =      { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" }
 
 [dev-dependencies]
 insta = "0.16.0"
index a64be9848ef1cebebdf1cd695e888812d4467f7d..688026a0408d2401fa2802172d02e3a84bcc4753 100644 (file)
 use crate::{
     db::HirDatabase,
     expr::{Body, Expr, Literal, Pat, PatId},
-    InferenceResult,
+    ApplicationTy, InferenceResult, Ty, TypeCtor,
 };
-use hir_def::{adt::VariantData, EnumVariantId, VariantId};
+use hir_def::{adt::VariantData, AdtId, EnumVariantId, VariantId};
+use ra_arena::Idx;
 
 #[derive(Debug, Clone, Copy)]
 /// Either a pattern from the source code being analyzed, represented as
@@ -512,6 +513,7 @@ pub enum Usefulness {
 }
 
 pub struct MatchCheckCtx<'a> {
+    pub match_expr: Idx<Expr>,
     pub body: Arc<Body>,
     pub infer: Arc<InferenceResult>,
     pub db: &'a dyn HirDatabase,
@@ -530,6 +532,16 @@ pub(crate) fn is_useful(
     matrix: &Matrix,
     v: &PatStack,
 ) -> MatchCheckResult<Usefulness> {
+    // Handle the special case of enums with no variants. In that case, no match
+    // arm is useful.
+    if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(AdtId::EnumId(enum_id)), .. }) =
+        cx.infer[cx.match_expr].strip_references()
+    {
+        if cx.db.enum_data(*enum_id).variants.is_empty() {
+            return Ok(Usefulness::NotUseful);
+        }
+    }
+
     if v.is_empty() {
         let result = if matrix.is_empty() { Usefulness::Useful } else { Usefulness::NotUseful };
 
@@ -1618,6 +1630,32 @@ fn test_fn() {
 
         check_no_diagnostic(content);
     }
+
+    #[test]
+    fn enum_never() {
+        let content = r"
+            enum Never {}
+
+            fn test_fn(never: Never) {
+                match never {}
+            }
+        ";
+
+        check_no_diagnostic(content);
+    }
+
+    #[test]
+    fn enum_never_ref() {
+        let content = r"
+            enum Never {}
+
+            fn test_fn(never: &Never) {
+                match never {}
+            }
+        ";
+
+        check_no_diagnostic(content);
+    }
 }
 
 #[cfg(test)]
index d91c21e24cce7a31e64a5000358d01535d4098d1..1b0f84c5c752eb3b890827dfdf4a3f5994e67090 100644 (file)
@@ -14,7 +14,7 @@
     db::HirDatabase,
     traits::{InEnvironment, Solution},
     utils::generics,
-    BoundVar, Canonical, DebruijnIndex, Substs, Ty,
+    BoundVar, Canonical, DebruijnIndex, Obligation, Substs, TraitRef, Ty,
 };
 
 const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -66,6 +66,20 @@ fn deref_by_trait(
     let parameters =
         Substs::build_for_generics(&generic_params).push(ty.value.value.clone()).build();
 
+    // Check that the type implements Deref at all
+    let trait_ref = TraitRef { trait_: deref_trait, substs: parameters.clone() };
+    let implements_goal = super::Canonical {
+        num_vars: ty.value.num_vars,
+        value: InEnvironment {
+            value: Obligation::Trait(trait_ref),
+            environment: ty.environment.clone(),
+        },
+    };
+    if db.trait_solve(krate, implements_goal).is_none() {
+        return None;
+    }
+
+    // Now do the assoc type projection
     let projection = super::traits::ProjectionPredicate {
         ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.num_vars)),
         projection_ty: super::ProjectionTy { associated_ty: target, parameters },
@@ -91,6 +105,11 @@ fn deref_by_trait(
             // they're just being 'passed through'. In the 'standard' case where
             // we have `impl<T> Deref for Foo<T> { Target = T }`, that should be
             // the case.
+
+            // FIXME: if the trait solver decides to truncate the type, these
+            // assumptions will be broken. We would need to properly introduce
+            // new variables in that case
+
             for i in 1..vars.0.num_vars {
                 if vars.0.value[i - 1] != Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
                 {
index 21abbcf1e2d157f7344219ae514e112d0d8284ab..fd59f43207e428fa448ecdbb10fb76061a2a9051 100644 (file)
@@ -156,7 +156,7 @@ fn validate_match(
             None => return,
         };
 
-        let cx = MatchCheckCtx { body, infer: infer.clone(), db };
+        let cx = MatchCheckCtx { match_expr, body, infer: infer.clone(), db };
         let pats = arms.iter().map(|arm| arm.pat);
 
         let mut seen = Matrix::empty();
index ac25f8a80577f5397531c99a20dc9782f098ec7a..5f6cea8d318e13863f8c33d4aff81128ed08783a 100644 (file)
@@ -32,6 +32,7 @@ pub(super) struct Canonicalizer<'a, 'b>
     var_stack: Vec<TypeVarId>,
 }
 
+#[derive(Debug)]
 pub(super) struct Canonicalized<T> {
     pub value: Canonical<T>,
     free_vars: Vec<InferTy>,
index 18f74d3b12bd47c2145ef72cfc12b47cbfb01927..2677f3af2d752e1e791513fb47ad1552e48beed7 100644 (file)
@@ -680,6 +680,16 @@ pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
         }
     }
 
+    pub fn strip_references(&self) -> &Ty {
+        let mut t: &Ty = self;
+
+        while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t {
+            t = parameters.as_single();
+        }
+
+        t
+    }
+
     pub fn as_adt(&self) -> Option<(AdtId, &Substs)> {
         match self {
             Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => {
index b3a2fc4395dfae992bd9819827b9f4ada3c35f9f..0a889f8057e60eeebed77041d6c89cef394f0109 100644 (file)
@@ -349,7 +349,6 @@ fn bar(&self) -> {
 
 #[test]
 fn infer_project_associated_type() {
-    // y, z, a don't yet work because of https://github.com/rust-lang/chalk/issues/234
     assert_snapshot!(
         infer(r#"
 trait Iterable {
@@ -368,12 +367,12 @@ fn test<T: Iterable>() {
     [108; 261) '{     ...ter; }': ()
     [118; 119) 'x': u32
     [145; 146) '1': u32
-    [156; 157) 'y': {unknown}
-    [183; 192) 'no_matter': {unknown}
-    [202; 203) 'z': {unknown}
-    [215; 224) 'no_matter': {unknown}
-    [234; 235) 'a': {unknown}
-    [249; 258) 'no_matter': {unknown}
+    [156; 157) 'y': Iterable::Item<T>
+    [183; 192) 'no_matter': Iterable::Item<T>
+    [202; 203) 'z': Iterable::Item<T>
+    [215; 224) 'no_matter': Iterable::Item<T>
+    [234; 235) 'a': Iterable::Item<T>
+    [249; 258) 'no_matter': Iterable::Item<T>
     "###
     );
 }
@@ -433,8 +432,8 @@ fn test<T: Iterable<Item=u32>>() {
 "#),
         @r###"
     [67; 100) '{     ...own; }': ()
-    [77; 78) 'y': {unknown}
-    [90; 97) 'unknown': {unknown}
+    [77; 78) 'y': u32
+    [90; 97) 'unknown': u32
     "###
     );
 }
@@ -549,7 +548,7 @@ impl std::ops::Index<u32> for Bar {
 
 fn test() {
     let a = Bar;
-    let b = a[1];
+    let b = a[1u32];
     b<|>;
 }
 
@@ -574,7 +573,7 @@ fn infer_ops_index_autoderef() {
 //- /main.rs crate:main deps:std
 fn test() {
     let a = &[1u32, 2, 3];
-    let b = a[1];
+    let b = a[1u32];
     b<|>;
 }
 
@@ -916,11 +915,7 @@ fn test<T: ApplyL>(t: T) {
 }
 "#,
     );
-    // FIXME here Chalk doesn't normalize the type to a placeholder. I think we
-    // need to add a rule like Normalize(<T as ApplyL>::Out -> ApplyL::Out<T>)
-    // to the trait env ourselves here; probably Chalk can't do this by itself.
-    // assert_eq!(t, "ApplyL::Out<[missing name]>");
-    assert_eq!(t, "{unknown}");
+    assert_eq!(t, "ApplyL::Out<T>");
 }
 
 #[test]
@@ -1329,16 +1324,16 @@ fn test<T: Trait<Type = u32>>(x: T, y: impl Trait<Type = i64>) {
     [263; 264) 'y': impl Trait<Type = i64>
     [290; 398) '{     ...r>); }': ()
     [296; 299) 'get': fn get<T>(T) -> <T as Trait>::Type
-    [296; 302) 'get(x)': {unknown}
+    [296; 302) 'get(x)': u32
     [300; 301) 'x': T
-    [308; 312) 'get2': fn get2<{unknown}, T>(T) -> {unknown}
-    [308; 315) 'get2(x)': {unknown}
+    [308; 312) 'get2': fn get2<u32, T>(T) -> u32
+    [308; 315) 'get2(x)': u32
     [313; 314) 'x': T
     [321; 324) 'get': fn get<impl Trait<Type = i64>>(impl Trait<Type = i64>) -> <impl Trait<Type = i64> as Trait>::Type
-    [321; 327) 'get(y)': {unknown}
+    [321; 327) 'get(y)': i64
     [325; 326) 'y': impl Trait<Type = i64>
-    [333; 337) 'get2': fn get2<{unknown}, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> {unknown}
-    [333; 340) 'get2(y)': {unknown}
+    [333; 337) 'get2': fn get2<i64, impl Trait<Type = i64>>(impl Trait<Type = i64>) -> i64
+    [333; 340) 'get2(y)': i64
     [338; 339) 'y': impl Trait<Type = i64>
     [346; 349) 'get': fn get<S<u64>>(S<u64>) -> <S<u64> as Trait>::Type
     [346; 357) 'get(set(S))': u64
@@ -1402,7 +1397,6 @@ impl<T: Iterator> IntoIterator for T {
 
 #[test]
 fn projection_eq_within_chalk() {
-    // std::env::set_var("CHALK_DEBUG", "1");
     assert_snapshot!(
         infer(r#"
 trait Trait1 {
@@ -1422,7 +1416,7 @@ fn test<T: Trait1<Type = u32>>(x: T) {
     [164; 165) 'x': T
     [170; 186) '{     ...o(); }': ()
     [176; 177) 'x': T
-    [176; 183) 'x.foo()': {unknown}
+    [176; 183) 'x.foo()': u32
     "###
     );
 }
@@ -1578,7 +1572,7 @@ fn test<F: FnOnce(u32, u64) -> u128>(f: F) {
     [150; 151) 'f': F
     [156; 184) '{     ...2)); }': ()
     [162; 163) 'f': F
-    [162; 181) 'f.call...1, 2))': {unknown}
+    [162; 181) 'f.call...1, 2))': u128
     [174; 180) '(1, 2)': (u32, u64)
     [175; 176) '1': u32
     [178; 179) '2': u64
@@ -1829,7 +1823,7 @@ impl Trait for S2 {
 "#,
     ), @r###"
     [54; 58) 'self': &Self
-    [60; 61) 'x': {unknown}
+    [60; 61) 'x': Trait::Item<Self>
     [140; 144) 'self': &S
     [146; 147) 'x': u32
     [161; 175) '{ let y = x; }': ()
@@ -1989,9 +1983,75 @@ fn test<I: Iterator<Item: Iterator<Item = u32>>>() {
 }
 "#,
     );
-    // assert_eq!(t, "u32");
-    // doesn't currently work, Chalk #234
-    assert_eq!(t, "{unknown}");
+    assert_eq!(t, "u32");
+}
+
+#[test]
+fn proc_macro_server_types() {
+    assert_snapshot!(
+        infer_with_mismatches(r#"
+macro_rules! with_api {
+    ($S:ident, $self:ident, $m:ident) => {
+        $m! {
+            TokenStream {
+                fn new() -> $S::TokenStream;
+            },
+            Group {
+            },
+        }
+    };
+}
+macro_rules! associated_item {
+    (type TokenStream) =>
+        (type TokenStream: 'static + Clone;);
+    (type Group) =>
+        (type Group: 'static + Clone;);
+    ($($item:tt)*) => ($($item)*;)
+}
+macro_rules! declare_server_traits {
+    ($($name:ident {
+        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
+    }),* $(,)?) => {
+        pub trait Types {
+            $(associated_item!(type $name);)*
+        }
+
+        $(pub trait $name: Types {
+            $(associated_item!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?);)*
+        })*
+
+        pub trait Server: Types $(+ $name)* {}
+        impl<S: Types $(+ $name)*> Server for S {}
+    }
+}
+with_api!(Self, self_, declare_server_traits);
+struct Group {}
+struct TokenStream {}
+struct Rustc;
+impl Types for Rustc {
+    type TokenStream = TokenStream;
+    type Group = Group;
+}
+fn make<T>() -> T { loop {} }
+impl TokenStream for Rustc {
+    fn new() -> Self::TokenStream {
+        let group: Self::Group = make();
+        make()
+    }
+}
+"#, true),
+        @r###"
+    [1115; 1126) '{ loop {} }': T
+    [1117; 1124) 'loop {}': !
+    [1122; 1124) '{}': ()
+    [1190; 1253) '{     ...     }': {unknown}
+    [1204; 1209) 'group': {unknown}
+    [1225; 1229) 'make': fn make<{unknown}>() -> {unknown}
+    [1225; 1231) 'make()': {unknown}
+    [1241; 1245) 'make': fn make<{unknown}>() -> {unknown}
+    [1241; 1247) 'make()': {unknown}
+    "###
+    );
 }
 
 #[test]
index 44fbdb19701594c3eefd87876d44338b42a559f5..05791a84868fdef628434a2e11d17e772191a6bc 100644 (file)
 pub(crate) mod chalk;
 mod builtin;
 
-/// This controls the maximum size of types Chalk considers. If we set this too
-/// high, we can run into slow edge cases; if we set it too low, Chalk won't
-/// find some solutions.
-const CHALK_SOLVER_MAX_SIZE: usize = 10;
+// This controls the maximum size of types Chalk considers. If we set this too
+// high, we can run into slow edge cases; if we set it too low, Chalk won't
+// find some solutions.
+// FIXME this is currently hardcoded in the recursive solver
+// const CHALK_SOLVER_MAX_SIZE: usize = 10;
+
 /// This controls how much 'time' we give the Chalk solver before giving up.
 const CHALK_SOLVER_FUEL: i32 = 100;
 
@@ -30,8 +32,7 @@ struct ChalkContext<'a> {
 }
 
 fn create_chalk_solver() -> chalk_solve::Solver<Interner> {
-    let solver_choice =
-        chalk_solve::SolverChoice::SLG { max_size: CHALK_SOLVER_MAX_SIZE, expected_answers: None };
+    let solver_choice = chalk_solve::SolverChoice::recursive();
     solver_choice.into_solver()
 }
 
index 55eb0ffcb0bf999714ebb3af90b4879fc92d759f..60d70d18e89d031612e196e4fc177ef66587daa8 100644 (file)
@@ -511,13 +511,13 @@ fn from_chalk(
 }
 
 impl ToChalk for super::ProjectionPredicate {
-    type Chalk = chalk_ir::Normalize<Interner>;
+    type Chalk = chalk_ir::AliasEq<Interner>;
 
-    fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Normalize<Interner> {
-        chalk_ir::Normalize { alias: self.projection_ty.to_chalk(db), ty: self.ty.to_chalk(db) }
+    fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> {
+        chalk_ir::AliasEq { alias: self.projection_ty.to_chalk(db), ty: self.ty.to_chalk(db) }
     }
 
-    fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::Normalize<Interner>) -> Self {
+    fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::AliasEq<Interner>) -> Self {
         unimplemented!()
     }
 }
@@ -795,8 +795,9 @@ fn interner(&self) -> &Interner {
     fn well_known_trait_id(
         &self,
         _well_known_trait: chalk_rust_ir::WellKnownTrait,
-    ) -> chalk_ir::TraitId<Interner> {
-        unimplemented!()
+    ) -> Option<chalk_ir::TraitId<Interner>> {
+        // FIXME tell Chalk about well-known traits (here and in trait_datum)
+        None
     }
 }
 
index e61846995a76961068c090247e57a0d22b6c15bb..6289f53f3f0ffe7ade71b38bdf99a0673e0095a6 100644 (file)
@@ -175,7 +175,7 @@ fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
         NavigationTarget {
             file_id: self.file_id,
             name: self.name.clone(),
-            kind: self.ptr.kind(),
+            kind: self.kind,
             full_range: self.ptr.range(),
             focus_range: self.name_range,
             container_name: self.container_name.clone(),
index d30458d8651ae1bb028cb1bba8d5625ff56cd61f..937abb4330e0c2378242005cc605851e85c9561e 100644 (file)
@@ -285,7 +285,7 @@ pub(crate) fn search(self, indices: &[Arc<SymbolIndex>]) -> Vec<FileSymbol> {
                 let (start, end) = SymbolIndex::map_value_to_range(indexed_value.value);
 
                 for symbol in &symbol_index.symbols[start..end] {
-                    if self.only_types && !is_type(symbol.ptr.kind()) {
+                    if self.only_types && !is_type(symbol.kind) {
                         continue;
                     }
                     if self.exact && symbol.name != self.query {
@@ -312,6 +312,7 @@ fn is_type(kind: SyntaxKind) -> bool {
 pub struct FileSymbol {
     pub file_id: FileId,
     pub name: SmolStr,
+    pub kind: SyntaxKind,
     pub ptr: SyntaxNodePtr,
     pub name_range: Option<TextRange>,
     pub container_name: Option<SmolStr>,
@@ -377,6 +378,7 @@ fn decl<N: NameOwner>(node: N) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> {
 fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option<FileSymbol> {
     to_symbol(node).map(move |(name, ptr, name_range)| FileSymbol {
         name,
+        kind: node.kind(),
         ptr,
         file_id,
         name_range: Some(name_range),
index 7f87f421262e067485412ea91f831e76e991ada6..ea41bf85d16684086e45ced8ecea0b555a3bf533 100644 (file)
@@ -351,7 +351,7 @@ fn with_children(
     // FIXME: use a more elegant way to re-fetch the node (#1185), make
     // `range` private afterwards
     let mut ptr = SyntaxNodePtr::new(parent);
-    ptr.range = TextRange::offset_len(ptr.range().start(), len);
+    ptr.range = TextRange::offset_len(ptr.range.start(), len);
     ptr.to_node(&new_root_node)
 }
 
index bc48a2e71434b220c96417b58d12d306b0e6ac12..3be648c2ae5c12397fb5df34e8e225450697c80c 100644 (file)
@@ -34,12 +34,8 @@ pub fn range(&self) -> TextRange {
         self.range
     }
 
-    pub fn kind(&self) -> SyntaxKind {
-        self.kind
-    }
-
     pub fn cast<N: AstNode>(self) -> Option<AstPtr<N>> {
-        if !N::can_cast(self.kind()) {
+        if !N::can_cast(self.kind) {
             return None;
         }
         Some(AstPtr { raw: self, _ty: PhantomData })
@@ -88,7 +84,7 @@ pub fn syntax_node_ptr(&self) -> SyntaxNodePtr {
     }
 
     pub fn cast<U: AstNode>(self) -> Option<AstPtr<U>> {
-        if !U::can_cast(self.raw.kind()) {
+        if !U::can_cast(self.raw.kind) {
             return None;
         }
         Some(AstPtr { raw: self.raw, _ty: PhantomData })