]> git.lizzy.rs Git - rust.git/commitdiff
Merge #5331
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>
Sun, 12 Jul 2020 20:31:51 +0000 (20:31 +0000)
committerGitHub <noreply@github.com>
Sun, 12 Jul 2020 20:31:51 +0000 (20:31 +0000)
5331: Fix #4966 r=flodiebold a=flodiebold

We add a level of binders when converting our function pointer to Chalk's; we need to remove it again on the way back.

Fixes #4966.

Co-authored-by: Florian Diebold <florian.diebold@freiheit.com>
15 files changed:
Cargo.lock
crates/ra_hir_ty/Cargo.toml
crates/ra_hir_ty/src/method_resolution.rs
crates/ra_hir_ty/src/tests.rs
crates/ra_hir_ty/src/tests/coercion.rs
crates/ra_hir_ty/src/tests/traits.rs
crates/ra_hir_ty/src/traits.rs
crates/ra_hir_ty/src/traits/builtin.rs
crates/ra_hir_ty/src/traits/chalk.rs
crates/ra_hir_ty/src/traits/chalk/interner.rs
crates/ra_hir_ty/src/traits/chalk/mapping.rs
crates/ra_hir_ty/src/traits/chalk/tls.rs
crates/ra_hir_ty/src/utils.rs
crates/rust-analyzer/Cargo.toml
crates/rust-analyzer/src/caps.rs

index 292ddb98261956f710dc567128272f7e5114c062..66ae19b1e4561507aca2630fad57cf0172c0d4a9 100644 (file)
@@ -33,6 +33,15 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "ansi_term"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
+dependencies = [
+ "winapi 0.3.9",
+]
+
 [[package]]
 name = "anyhow"
 version = "1.0.31"
@@ -51,6 +60,17 @@ version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
 
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi 0.3.9",
+]
+
 [[package]]
 name = "autocfg"
 version = "1.0.0"
@@ -124,9 +144,9 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
 
 [[package]]
 name = "chalk-derive"
-version = "0.15.0"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c7379caa72d04103fcfd9bde5642b816f58e3ffd6a0d39347e9e35a066648226"
+checksum = "9396f12a23b1a40d5019aa81bc0cbd7ccd2c9736d6bc4afc95868533c2346dcb"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -135,35 +155,35 @@ dependencies = [
 ]
 
 [[package]]
-name = "chalk-engine"
-version = "0.15.0"
+name = "chalk-ir"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e8afe48b5663504b485791ab4fae69cf4864869a71ceec9c758fd4d03423722"
+checksum = "87e9c67d500717d65ede27affb7ae40efe240d86fbefff1006fe0ffb62d4caf9"
 dependencies = [
  "chalk-derive",
- "chalk-ir",
- "rustc-hash",
- "tracing",
+ "lazy_static",
 ]
 
 [[package]]
-name = "chalk-ir"
-version = "0.15.0"
+name = "chalk-recursive"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "231e391a03c1fc45874171d92be9542efedc939bac59d9501ee28b9521feb406"
+checksum = "a8fd2ac0fc06c857b95614d229bbe8ea317d1d94a7e8b9442a3f05c9a2c2d5f4"
 dependencies = [
  "chalk-derive",
- "lazy_static",
+ "chalk-ir",
+ "chalk-solve",
+ "rustc-hash",
+ "tracing",
 ]
 
 [[package]]
 name = "chalk-solve"
-version = "0.15.0"
+version = "0.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72c969c0fd06ad50538253327ca3445ff02cc9d0209f94c3cbf198ad9d365b48"
+checksum = "2a79166f2405c1e51eadcc1344f5ee833c7b391532dd78f64a0731a9a123cc58"
 dependencies = [
  "chalk-derive",
- "chalk-engine",
  "chalk-ir",
  "ena",
  "itertools",
@@ -171,6 +191,7 @@ dependencies = [
  "rustc-hash",
  "tracing",
  "tracing-subscriber",
+ "tracing-tree",
 ]
 
 [[package]]
@@ -691,9 +712,9 @@ dependencies = [
 
 [[package]]
 name = "lsp-types"
-version = "0.75.0"
+version = "0.76.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1b4ab1df4a5538413c707860e13fff9e0c9bc2fa613efc15d78196bc06ae06d"
+checksum = "af5586f0631c7f7826c3ea39377c326d7b4623138be7ab1204dab22e47717449"
 dependencies = [
  "base64",
  "bitflags",
@@ -971,6 +992,16 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "quanta"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4f7a1905379198075914bc93d32a5465c40474f90a078bb13439cb00c547bcc"
+dependencies = [
+ "libc",
+ "winapi 0.3.9",
+]
+
 [[package]]
 name = "quote"
 version = "1.0.7"
@@ -1103,6 +1134,7 @@ version = "0.1.0"
 dependencies = [
  "arrayvec",
  "chalk-ir",
+ "chalk-recursive",
  "chalk-solve",
  "ena",
  "expect",
@@ -1120,6 +1152,9 @@ dependencies = [
  "smallvec",
  "stdx",
  "test_utils",
+ "tracing",
+ "tracing-subscriber",
+ "tracing-tree",
 ]
 
 [[package]]
@@ -1722,6 +1757,15 @@ dependencies = [
  "winapi 0.3.9",
 ]
 
+[[package]]
+name = "termcolor"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
+dependencies = [
+ "winapi-util",
+]
+
 [[package]]
 name = "terminal_size"
 version = "0.1.13"
@@ -1856,7 +1900,7 @@ version = "0.2.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c72c8cf3ec4ed69fef614d011a5ae4274537a8a8c59133558029bd731eb71659"
 dependencies = [
- "ansi_term",
+ "ansi_term 0.11.0",
  "chrono",
  "lazy_static",
  "matchers",
@@ -1870,6 +1914,21 @@ dependencies = [
  "tracing-serde",
 ]
 
+[[package]]
+name = "tracing-tree"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a389731c9e6c56fef11e438e5b6afae861d5bc301c8b4bdca8d19f0e830d82"
+dependencies = [
+ "ansi_term 0.12.1",
+ "atty",
+ "chrono",
+ "quanta",
+ "termcolor",
+ "tracing",
+ "tracing-subscriber",
+]
+
 [[package]]
 name = "unicode-bidi"
 version = "0.3.4"
index ce257dc0bb58d6d295261d6fda9c297139e06090..90368220b919d1b3d022cfcc8aa8d75935f9261a 100644 (file)
@@ -27,9 +27,14 @@ test_utils = { path = "../test_utils" }
 
 scoped-tls = "1"
 
-chalk-solve = { version = "0.15.0" }
-chalk-ir = { version = "0.15.0" }
+chalk-solve = { version = "0.17.0" }
+chalk-ir = { version = "0.17.0" }
+chalk-recursive = { version = "0.17.0" }
 
 [dev-dependencies]
 insta = "0.16.0"
 expect = { path = "../expect" }
+
+tracing = "0.1"
+tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] }
+tracing-tree = { version = "0.1.3" }
index a45febbf74ea978130eaf0828f07709bff4b0e70..fb4b30a131fc1ddf2ad599c4bbccff0376e4b7ad 100644 (file)
@@ -6,8 +6,10 @@
 
 use arrayvec::ArrayVec;
 use hir_def::{
-    lang_item::LangItemTarget, type_ref::Mutability, AssocContainerId, AssocItemId, FunctionId,
-    HasModule, ImplId, Lookup, TraitId,
+    builtin_type::{IntBitness, Signedness},
+    lang_item::LangItemTarget,
+    type_ref::Mutability,
+    AssocContainerId, AssocItemId, FunctionId, HasModule, ImplId, Lookup, TraitId,
 };
 use hir_expand::name::Name;
 use ra_db::CrateId;
 
 use super::Substs;
 use crate::{
-    autoderef, db::HirDatabase, primitive::FloatBitness, utils::all_super_traits, ApplicationTy,
-    Canonical, DebruijnIndex, InEnvironment, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor,
-    TypeWalk,
+    autoderef,
+    db::HirDatabase,
+    primitive::{FloatBitness, FloatTy, IntTy},
+    utils::all_super_traits,
+    ApplicationTy, Canonical, DebruijnIndex, InEnvironment, TraitEnvironment, TraitRef, Ty, TyKind,
+    TypeCtor, TypeWalk,
 };
 
 /// This is used as a key for indexing impls.
@@ -39,6 +44,62 @@ pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
     }
 }
 
+pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
+    TyFingerprint::Apply(TypeCtor::Int(IntTy {
+        signedness: Signedness::Unsigned,
+        bitness: IntBitness::X8,
+    })),
+    TyFingerprint::Apply(TypeCtor::Int(IntTy {
+        signedness: Signedness::Unsigned,
+        bitness: IntBitness::X16,
+    })),
+    TyFingerprint::Apply(TypeCtor::Int(IntTy {
+        signedness: Signedness::Unsigned,
+        bitness: IntBitness::X32,
+    })),
+    TyFingerprint::Apply(TypeCtor::Int(IntTy {
+        signedness: Signedness::Unsigned,
+        bitness: IntBitness::X64,
+    })),
+    TyFingerprint::Apply(TypeCtor::Int(IntTy {
+        signedness: Signedness::Unsigned,
+        bitness: IntBitness::X128,
+    })),
+    TyFingerprint::Apply(TypeCtor::Int(IntTy {
+        signedness: Signedness::Unsigned,
+        bitness: IntBitness::Xsize,
+    })),
+    TyFingerprint::Apply(TypeCtor::Int(IntTy {
+        signedness: Signedness::Signed,
+        bitness: IntBitness::X8,
+    })),
+    TyFingerprint::Apply(TypeCtor::Int(IntTy {
+        signedness: Signedness::Signed,
+        bitness: IntBitness::X16,
+    })),
+    TyFingerprint::Apply(TypeCtor::Int(IntTy {
+        signedness: Signedness::Signed,
+        bitness: IntBitness::X32,
+    })),
+    TyFingerprint::Apply(TypeCtor::Int(IntTy {
+        signedness: Signedness::Signed,
+        bitness: IntBitness::X64,
+    })),
+    TyFingerprint::Apply(TypeCtor::Int(IntTy {
+        signedness: Signedness::Signed,
+        bitness: IntBitness::X128,
+    })),
+    TyFingerprint::Apply(TypeCtor::Int(IntTy {
+        signedness: Signedness::Signed,
+        bitness: IntBitness::Xsize,
+    })),
+];
+
+pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
+    TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })),
+    TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })),
+];
+
 /// Trait impls defined or available in some crate.
 #[derive(Debug, Eq, PartialEq)]
 pub struct TraitImpls {
index 69f2d7667eec750bab4bcec3162e58e6da97b736..27f5a60bf6edbea68ffaed2db09cbbe9e7d7e91e 100644 (file)
 // against snapshots of the expected results using insta. Use cargo-insta to
 // update the snapshots.
 
+fn setup_tracing() -> tracing::subscriber::DefaultGuard {
+    use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry};
+    use tracing_tree::HierarchicalLayer;
+    let filter = EnvFilter::from_env("CHALK_DEBUG");
+    let layer = HierarchicalLayer::default().with_indent_amount(2).with_writer(std::io::stderr);
+    let subscriber = Registry::default().with(filter).with(layer);
+    tracing::subscriber::set_default(subscriber)
+}
+
 fn check_types(ra_fixture: &str) {
     check_types_impl(ra_fixture, false)
 }
@@ -46,6 +55,7 @@ fn check_types_source_code(ra_fixture: &str) {
 }
 
 fn check_types_impl(ra_fixture: &str, display_source: bool) {
+    let _tracing = setup_tracing();
     let db = TestDB::with_files(ra_fixture);
     let mut checked_one = false;
     for (file_id, annotations) in db.extract_annotations() {
@@ -86,6 +96,7 @@ fn infer(ra_fixture: &str) -> String {
 }
 
 fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
+    let _tracing = setup_tracing();
     let (db, file_id) = TestDB::with_single_file(content);
 
     let mut buf = String::new();
index 136d28a9160998b214b7e6dc223b12983ff07e18..d7fb6a962e8e9ed07a02b92eb577e6dce58e1d60 100644 (file)
@@ -662,7 +662,53 @@ fn test() {
 }
 
 #[test]
-fn coerce_unsize_trait_object() {
+fn coerce_unsize_trait_object_simple() {
+    assert_snapshot!(
+        infer_with_mismatches(r#"
+#[lang = "sized"]
+pub trait Sized {}
+#[lang = "unsize"]
+pub trait Unsize<T> {}
+#[lang = "coerce_unsized"]
+pub trait CoerceUnsized<T> {}
+
+impl<T: Unsize<U>, U> CoerceUnsized<&U> for &T {}
+
+trait Foo<T, U> {}
+trait Bar<U, T, X>: Foo<T, U> {}
+trait Baz<T, X>: Bar<usize, T, X> {}
+
+struct S<T, X>;
+impl<T, X> Foo<T, usize> for S<T, X> {}
+impl<T, X> Bar<usize, T, X> for S<T, X> {}
+impl<T, X> Baz<T, X> for S<T, X> {}
+
+fn test() {
+    let obj: &dyn Baz<i8, i16> = &S;
+    let obj: &dyn Bar<_, i8, i16> = &S;
+    let obj: &dyn Foo<i8, _> = &S;
+}
+"#, true),
+        @r###"
+    424..539 '{     ... &S; }': ()
+    434..437 'obj': &dyn Baz<i8, i16>
+    459..461 '&S': &S<i8, i16>
+    460..461 'S': S<i8, i16>
+    471..474 'obj': &dyn Bar<usize, i8, i16>
+    499..501 '&S': &S<i8, i16>
+    500..501 'S': S<i8, i16>
+    511..514 'obj': &dyn Foo<i8, usize>
+    534..536 '&S': &S<i8, {unknown}>
+    535..536 'S': S<i8, {unknown}>
+    "###
+    );
+}
+
+#[test]
+// The rust reference says this should be possible, but rustc doesn't implement
+// it. We used to support it, but Chalk doesn't.
+#[ignore]
+fn coerce_unsize_trait_object_to_trait_object() {
     assert_snapshot!(
         infer_with_mismatches(r#"
 #[lang = "sized"]
@@ -735,16 +781,17 @@ impl D for S {}
 
 fn test() {
     let obj: &dyn D = &S;
-    let obj: &dyn A = obj;
+    let obj: &dyn A = &S;
 }
 "#, true),
         @r###"
-    328..384 '{     ...obj; }': ()
+    328..383 '{     ... &S; }': ()
     338..341 'obj': &dyn D
     352..354 '&S': &S
     353..354 'S': S
     364..367 'obj': &dyn A
-    378..381 'obj': &dyn D
+    378..380 '&S': &S
+    379..380 'S': S
     "###
     );
 }
index 529d9e253e7a4aa23a8782a2e23a82560d54ef1c..27737fa941ed40a7ae2dfadadc45a2a8b4ff4825 100644 (file)
@@ -1991,6 +1991,28 @@ fn test() {
     );
 }
 
+#[test]
+fn fn_item_fn_trait() {
+    check_types(
+        r#"
+#[lang = "fn_once"]
+trait FnOnce<Args> {
+    type Output;
+}
+
+struct S;
+
+fn foo() -> S {}
+
+fn takes_closure<U, F: FnOnce() -> U>(f: F) -> U { f() }
+
+fn test() {
+    takes_closure(foo);
+} //^^^^^^^^^^^^^^^^^^ S
+"#,
+    );
+}
+
 #[test]
 fn unselected_projection_in_trait_env_1() {
     check_types(
@@ -3000,74 +3022,47 @@ fn foo() {
 
 #[test]
 fn infer_dyn_fn_output() {
-    assert_snapshot!(
-        infer(
-            r#"
-            //- /lib.rs deps:std
-
-            #[lang = "fn_once"]
-            pub trait FnOnce<Args> {
-                type Output;
-
-                extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
-            }
-
-            #[lang = "fn"]
-            pub trait Fn<Args>:FnOnce<Args> {
-                extern "rust-call" fn call(&self, args: Args) -> Self::Output;
-            }
-
-            #[lang = "deref"]
-            pub trait Deref {
-                type Target: ?Sized;
-
-                fn deref(&self) -> &Self::Target;
-            }
+    check_types(
+        r#"
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+    type Output;
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
 
-            #[lang = "owned_box"]
-            pub struct Box<T: ?Sized> {
-                inner: *mut T,
-            }
+#[lang = "fn"]
+pub trait Fn<Args>: FnOnce<Args> {
+    extern "rust-call" fn call(&self, args: Args) -> Self::Output;
+}
 
-            impl<T: ?Sized> Deref for Box<T> {
-                type Target = T;
+fn foo() {
+    let f: &dyn Fn() -> i32;
+    f();
+  //^^^ i32
+}"#,
+    );
+}
 
-                fn deref(&self) -> &T {
-                    &self.inner
-                }
-            }
+#[test]
+fn infer_dyn_fn_once_output() {
+    check_types(
+        r#"
+#[lang = "fn_once"]
+pub trait FnOnce<Args> {
+    type Output;
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
+}
 
-            fn foo() {
-                let f: Box<dyn Fn() -> i32> = box(|| 5);
-                let x = f();
-            }
-        "#
-        ),
-        @r###"
-    100..104 'self': Self
-    106..110 'args': Args
-    219..223 'self': &Self
-    225..229 'args': Args
-    333..337 'self': &Self
-    503..507 'self': &Box<T>
-    515..542 '{     ...     }': &T
-    525..536 '&self.inner': &*mut T
-    526..530 'self': &Box<T>
-    526..536 'self.inner': *mut T
-    555..620 '{     ...f(); }': ()
-    565..566 'f': Box<dyn Fn<(), Output = i32>>
-    591..600 'box(|| 5)': Box<|| -> i32>
-    595..599 '|| 5': || -> i32
-    598..599 '5': i32
-    610..611 'x': FnOnce::Output<dyn Fn<(), Output = i32>, ()>
-    614..615 'f': Box<dyn Fn<(), Output = i32>>
-    614..617 'f()': FnOnce::Output<dyn Fn<(), Output = i32>, ()>
-    "###
+fn foo() {
+    let f: dyn FnOnce() -> i32;
+    f();
+  //^^^ i32
+}"#,
     );
 }
 
 #[test]
-fn variable_kinds() {
+fn variable_kinds_1() {
     check_types(
         r#"
 trait Trait<T> { fn get(self, t: T) -> T; }
@@ -3083,3 +3078,20 @@ fn test() {
         "#,
     );
 }
+
+#[test]
+fn variable_kinds_2() {
+    check_types(
+        r#"
+trait Trait { fn get(self) -> Self; }
+impl Trait for u128 {}
+impl Trait for f32 {}
+fn test() {
+    1.get();
+  //^^^^^^^ u128
+    (1.).get();
+  //^^^^^^^^^^ f32
+}
+        "#,
+    );
+}
index 2a6d7faefe5637de3755f5c47ca74333fb88591e..f7edb4c8b6af740040c82fbaa3646fb7b593a658 100644 (file)
@@ -2,6 +2,7 @@
 use std::sync::Arc;
 
 use chalk_ir::cast::Cast;
+use chalk_solve::Solver;
 use hir_def::{
     expr::ExprId, lang_item::LangItemTarget, DefWithBodyId, ImplId, TraitId, TypeAliasId,
 };
@@ -32,9 +33,10 @@ struct ChalkContext<'a> {
     krate: CrateId,
 }
 
-fn create_chalk_solver() -> chalk_solve::Solver<Interner> {
-    let solver_choice = chalk_solve::SolverChoice::recursive();
-    solver_choice.into_solver()
+fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> {
+    let overflow_depth = 100;
+    let caching_enabled = true;
+    chalk_recursive::RecursiveSolver::new(overflow_depth, caching_enabled)
 }
 
 /// A set of clauses that we assume to be true. E.g. if we are inside this function:
@@ -293,13 +295,8 @@ pub enum Impl {
     /// A normal impl from an impl block.
     ImplDef(ImplId),
     /// Closure types implement the Fn traits synthetically.
+    // FIXME: implement closure support from Chalk, remove this
     ClosureFnTraitImpl(ClosureFnTraitImplData),
-    /// [T; n]: Unsize<[T]>
-    UnsizeArray,
-    /// T: Unsize<dyn Trait> where T: Trait
-    UnsizeToTraitObject(TraitId),
-    /// dyn Trait: Unsize<dyn SuperTrait> if Trait: SuperTrait
-    UnsizeToSuperTraitObject(UnsizeToSuperTraitObjectData),
 }
 /// This exists just for Chalk, because our ImplIds are only unique per module.
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
index 6d5f2d46a72cc56ba4382fe10b07c170586bd419..86e22e459542a669ac49a86b7fb333b749412917 100644 (file)
@@ -1,15 +1,12 @@
 //! This module provides the built-in trait implementations, e.g. to make
 //! closures implement `Fn`.
-use hir_def::{expr::Expr, lang_item::LangItemTarget, TraitId, TypeAliasId};
+use hir_def::{expr::Expr, TraitId, TypeAliasId};
 use hir_expand::name::name;
 use ra_db::CrateId;
 
-use super::{AssocTyValue, Impl, UnsizeToSuperTraitObjectData};
+use super::{AssocTyValue, Impl};
 use crate::{
-    db::HirDatabase,
-    utils::{all_super_traits, generics},
-    ApplicationTy, Binders, BoundVar, DebruijnIndex, GenericPredicate, Substs, TraitRef, Ty,
-    TypeCtor, TypeWalk,
+    db::HirDatabase, ApplicationTy, BoundVar, DebruijnIndex, Substs, TraitRef, Ty, TypeCtor,
 };
 
 pub(super) struct BuiltinImplData {
@@ -31,7 +28,7 @@ pub(super) fn get_builtin_impls(
     krate: CrateId,
     ty: &Ty,
     // The first argument for the trait, if present
-    arg: &Option<Ty>,
+    _arg: &Option<Ty>,
     trait_: TraitId,
     mut callback: impl FnMut(Impl),
 ) {
@@ -50,60 +47,12 @@ pub(super) fn get_builtin_impls(
             }
         }
     }
-
-    let unsize_trait = get_unsize_trait(db, krate);
-    if let Some(actual_trait) = unsize_trait {
-        if trait_ == actual_trait {
-            get_builtin_unsize_impls(db, krate, ty, arg, callback);
-        }
-    }
-}
-
-fn get_builtin_unsize_impls(
-    db: &dyn HirDatabase,
-    krate: CrateId,
-    ty: &Ty,
-    // The first argument for the trait, if present
-    arg: &Option<Ty>,
-    mut callback: impl FnMut(Impl),
-) {
-    if !check_unsize_impl_prerequisites(db, krate) {
-        return;
-    }
-
-    if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, .. }) = ty {
-        callback(Impl::UnsizeArray);
-        return; // array is unsized, the rest of the impls shouldn't apply
-    }
-
-    if let Some(target_trait) = arg.as_ref().and_then(|t| t.dyn_trait_ref()) {
-        // FIXME what about more complicated dyn tys with marker traits?
-        if let Some(trait_ref) = ty.dyn_trait_ref() {
-            if trait_ref.trait_ != target_trait.trait_ {
-                let super_traits = all_super_traits(db.upcast(), trait_ref.trait_);
-                if super_traits.contains(&target_trait.trait_) {
-                    callback(Impl::UnsizeToSuperTraitObject(UnsizeToSuperTraitObjectData {
-                        trait_: trait_ref.trait_,
-                        super_trait: target_trait.trait_,
-                    }));
-                }
-            }
-        } else {
-            // FIXME only for sized types
-            callback(Impl::UnsizeToTraitObject(target_trait.trait_));
-        }
-    }
 }
 
 pub(super) fn impl_datum(db: &dyn HirDatabase, krate: CrateId, impl_: Impl) -> BuiltinImplData {
     match impl_ {
         Impl::ImplDef(_) => unreachable!(),
         Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data),
-        Impl::UnsizeArray => array_unsize_impl_datum(db, krate),
-        Impl::UnsizeToTraitObject(trait_) => trait_object_unsize_impl_datum(db, krate, trait_),
-        Impl::UnsizeToSuperTraitObject(data) => {
-            super_trait_object_unsize_impl_datum(db, krate, data)
-        }
     }
 }
 
@@ -227,145 +176,3 @@ fn closure_fn_trait_output_assoc_ty_value(
         value: output_ty,
     }
 }
-
-// Array unsizing
-
-fn check_unsize_impl_prerequisites(db: &dyn HirDatabase, krate: CrateId) -> bool {
-    // the Unsize trait needs to exist and have two type parameters (Self and T)
-    let unsize_trait = match get_unsize_trait(db, krate) {
-        Some(t) => t,
-        None => return false,
-    };
-    let generic_params = generics(db.upcast(), unsize_trait.into());
-    generic_params.len() == 2
-}
-
-fn array_unsize_impl_datum(db: &dyn HirDatabase, krate: CrateId) -> BuiltinImplData {
-    // impl<T> Unsize<[T]> for [T; _]
-    // (this can be a single impl because we don't distinguish array sizes currently)
-
-    let trait_ = get_unsize_trait(db, krate) // get unsize trait
-        // the existence of the Unsize trait has been checked before
-        .expect("Unsize trait missing");
-
-    let var = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
-    let substs = Substs::builder(2)
-        .push(Ty::apply_one(TypeCtor::Array, var.clone()))
-        .push(Ty::apply_one(TypeCtor::Slice, var))
-        .build();
-
-    let trait_ref = TraitRef { trait_, substs };
-
-    BuiltinImplData {
-        num_vars: 1,
-        trait_ref,
-        where_clauses: Vec::new(),
-        assoc_ty_values: Vec::new(),
-    }
-}
-
-// Trait object unsizing
-
-fn trait_object_unsize_impl_datum(
-    db: &dyn HirDatabase,
-    krate: CrateId,
-    trait_: TraitId,
-) -> BuiltinImplData {
-    // impl<T, T1, ...> Unsize<dyn Trait<T1, ...>> for T where T: Trait<T1, ...>
-
-    let unsize_trait = get_unsize_trait(db, krate) // get unsize trait
-        // the existence of the Unsize trait has been checked before
-        .expect("Unsize trait missing");
-
-    let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
-
-    let target_substs = Substs::build_for_def(db, trait_)
-        .push(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)))
-        .fill_with_bound_vars(DebruijnIndex::ONE, 1)
-        .build();
-    let num_vars = target_substs.len();
-    let target_trait_ref = TraitRef { trait_, substs: target_substs };
-    let target_bounds = vec![GenericPredicate::Implemented(target_trait_ref)];
-
-    let self_substs =
-        Substs::build_for_def(db, trait_).fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build();
-    let self_trait_ref = TraitRef { trait_, substs: self_substs };
-    let where_clauses = vec![GenericPredicate::Implemented(self_trait_ref)];
-
-    let impl_substs = Substs::builder(2).push(self_ty).push(Ty::Dyn(target_bounds.into())).build();
-
-    let trait_ref = TraitRef { trait_: unsize_trait, substs: impl_substs };
-
-    BuiltinImplData { num_vars, trait_ref, where_clauses, assoc_ty_values: Vec::new() }
-}
-
-fn super_trait_object_unsize_impl_datum(
-    db: &dyn HirDatabase,
-    krate: CrateId,
-    data: UnsizeToSuperTraitObjectData,
-) -> BuiltinImplData {
-    // impl<T1, ...> Unsize<dyn SuperTrait> for dyn Trait<T1, ...>
-
-    let unsize_trait = get_unsize_trait(db, krate) // get unsize trait
-        // the existence of the Unsize trait has been checked before
-        .expect("Unsize trait missing");
-
-    let self_substs = Substs::build_for_def(db, data.trait_)
-        .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
-        .build();
-    let self_trait_ref = TraitRef { trait_: data.trait_, substs: self_substs.clone() };
-
-    let num_vars = self_substs.len() - 1;
-
-    // we need to go from our trait to the super trait, substituting type parameters
-    let path = crate::utils::find_super_trait_path(db.upcast(), data.trait_, data.super_trait);
-
-    let mut current_trait_ref = self_trait_ref.clone();
-    for t in path.into_iter().skip(1) {
-        let bounds = db.generic_predicates(current_trait_ref.trait_.into());
-        let super_trait_ref = bounds
-            .iter()
-            .find_map(|b| match &b.value {
-                GenericPredicate::Implemented(tr)
-                    if tr.trait_ == t
-                        && tr.substs[0]
-                            == Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)) =>
-                {
-                    Some(Binders { value: tr, num_binders: b.num_binders })
-                }
-                _ => None,
-            })
-            .expect("trait bound for known super trait not found");
-        current_trait_ref = super_trait_ref.cloned().subst(&current_trait_ref.substs);
-    }
-
-    // We need to renumber the variables a bit now: from ^0.0, ^0.1, ^0.2, ...
-    // to ^0.0, ^1.0, ^1.1. The reason for this is that the first variable comes
-    // from the dyn Trait binder, while the other variables come from the impl.
-    let new_substs = Substs::builder(num_vars + 1)
-        .push(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)))
-        .fill_with_bound_vars(DebruijnIndex::ONE, 0)
-        .build();
-
-    let self_bounds =
-        vec![GenericPredicate::Implemented(self_trait_ref.subst_bound_vars(&new_substs))];
-    let super_bounds =
-        vec![GenericPredicate::Implemented(current_trait_ref.subst_bound_vars(&new_substs))];
-
-    let substs = Substs::builder(2)
-        .push(Ty::Dyn(self_bounds.into()))
-        .push(Ty::Dyn(super_bounds.into()))
-        .build();
-
-    let trait_ref = TraitRef { trait_: unsize_trait, substs };
-
-    BuiltinImplData { num_vars, trait_ref, where_clauses: Vec::new(), assoc_ty_values: Vec::new() }
-}
-
-fn get_unsize_trait(db: &dyn HirDatabase, krate: CrateId) -> Option<TraitId> {
-    let target = db.lang_item(krate, "unsize".into())?;
-    match target {
-        LangItemTarget::TraitId(t) => Some(t),
-        _ => None,
-    }
-}
index c97b81d57923676f4f245b420babe82767552517..c448aea656645c563175aecd7fbec4ad969dcfed 100644 (file)
@@ -3,7 +3,7 @@
 
 use log::debug;
 
-use chalk_ir::{fold::shift::Shift, GenericArg, TypeName};
+use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg, TypeName};
 use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
 
 use hir_def::{
 
 use super::{builtin, AssocTyValue, ChalkContext, Impl};
 use crate::{
-    db::HirDatabase, display::HirDisplay, method_resolution::TyFingerprint, utils::generics,
+    db::HirDatabase,
+    display::HirDisplay,
+    method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
+    utils::generics,
     CallableDef, DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor,
 };
 use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders};
@@ -66,13 +69,31 @@ fn impls_for_trait(
         &self,
         trait_id: TraitId,
         parameters: &[GenericArg<Interner>],
+        binders: &CanonicalVarKinds<Interner>,
     ) -> Vec<ImplId> {
         debug!("impls_for_trait {:?}", trait_id);
         let trait_: hir_def::TraitId = from_chalk(self.db, trait_id);
 
         let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone());
 
+        fn binder_kind(ty: &Ty, binders: &CanonicalVarKinds<Interner>) -> Option<chalk_ir::TyKind> {
+            if let Ty::Bound(bv) = ty {
+                let binders = binders.as_slice(&Interner);
+                if bv.debruijn == DebruijnIndex::INNERMOST {
+                    if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind {
+                        return Some(tk);
+                    }
+                }
+            }
+            None
+        }
+
         let self_ty_fp = TyFingerprint::for_impl(&ty);
+        let fps: &[TyFingerprint] = match binder_kind(&ty, binders) {
+            Some(chalk_ir::TyKind::Integer) => &ALL_INT_FPS,
+            Some(chalk_ir::TyKind::Float) => &ALL_FLOAT_FPS,
+            _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]),
+        };
 
         // Note: Since we're using impls_for_trait, only impls where the trait
         // can be resolved should ever reach Chalk. `impl_datum` relies on that
@@ -83,17 +104,21 @@ fn impls_for_trait(
 
         let id_to_chalk = |id: hir_def::ImplId| Impl::ImplDef(id).to_chalk(self.db);
 
-        let mut result: Vec<_> = match self_ty_fp {
-            Some(fp) => impl_maps
+        let mut result: Vec<_> = if fps.is_empty() {
+            debug!("Unrestricted search for {:?} impls...", trait_);
+            impl_maps
+                .iter()
+                .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk))
+                .collect()
+        } else {
+            impl_maps
                 .iter()
                 .flat_map(|crate_impl_defs| {
-                    crate_impl_defs.for_trait_and_self_ty(trait_, fp).map(id_to_chalk)
+                    fps.iter().flat_map(move |fp| {
+                        crate_impl_defs.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk)
+                    })
                 })
-                .collect(),
-            None => impl_maps
-                .iter()
-                .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk))
-                .collect(),
+                .collect()
         };
 
         let arg: Option<Ty> =
@@ -219,6 +244,22 @@ fn closure_fn_substitution(
         // FIXME: implement closure support
         unimplemented!()
     }
+
+    fn trait_name(&self, _trait_id: chalk_ir::TraitId<Interner>) -> String {
+        unimplemented!()
+    }
+    fn adt_name(&self, _struct_id: chalk_ir::AdtId<Interner>) -> String {
+        unimplemented!()
+    }
+    fn assoc_type_name(&self, _assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> String {
+        unimplemented!()
+    }
+    fn opaque_type_name(&self, _opaque_ty_id: chalk_ir::OpaqueTyId<Interner>) -> String {
+        unimplemented!()
+    }
+    fn fn_def_name(&self, _fn_def_id: chalk_ir::FnDefId<Interner>) -> String {
+        unimplemented!()
+    }
 }
 
 pub(crate) fn program_clauses_for_chalk_env_query(
@@ -354,12 +395,18 @@ pub(crate) fn struct_datum_query(
         fundamental: false,
         phantom_data: false,
     };
-    let struct_datum_bound = rust_ir::AdtDatumBound {
-        fields: Vec::new(), // FIXME add fields (only relevant for auto traits)
-        where_clauses,
+    // FIXME provide enum variants properly (for auto traits)
+    let variant = rust_ir::AdtVariantDatum {
+        fields: Vec::new(), // FIXME add fields (only relevant for auto traits),
+    };
+    let struct_datum_bound = rust_ir::AdtDatumBound { variants: vec![variant], where_clauses };
+    let struct_datum = StructDatum {
+        // FIXME set ADT kind
+        kind: rust_ir::AdtKind::Struct,
+        id: struct_id,
+        binders: make_binders(struct_datum_bound, num_params),
+        flags,
     };
-    let struct_datum =
-        StructDatum { id: struct_id, binders: make_binders(struct_datum_bound, num_params), flags };
     Arc::new(struct_datum)
 }
 
index 15426b022487f0a0cae851215ca58ab011a05b54..156b691b45c3a3acbaa0681f553b3bdbdf779d43 100644 (file)
@@ -39,6 +39,7 @@ impl chalk_ir::interner::Interner for Interner {
     type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
     type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>;
     type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>;
+    type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>;
     type DefId = InternId;
     type InternedAdtId = crate::TypeCtorId;
     type Identifier = TypeAliasId;
@@ -349,6 +350,20 @@ fn canonical_var_kinds_data<'a>(
     ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
         &canonical_var_kinds
     }
+
+    fn intern_constraints<E>(
+        &self,
+        data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>,
+    ) -> Result<Self::InternedConstraints, E> {
+        data.into_iter().collect()
+    }
+
+    fn constraints_data<'a>(
+        &self,
+        constraints: &'a Self::InternedConstraints,
+    ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] {
+        constraints
+    }
 }
 
 impl chalk_ir::interner::HasInterner for Interner {
index cb354d586bb3838670277298cdc436d1c72005e9..06453ef820810eba1520232df03f10d6a8476c7a 100644 (file)
@@ -29,6 +29,7 @@ fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
         match self {
             Ty::Apply(apply_ty) => match apply_ty.ctor {
                 TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters),
+                TypeCtor::Array => array_to_chalk(db, apply_ty.parameters),
                 TypeCtor::FnPtr { num_args: _ } => {
                     let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner);
                     chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution })
@@ -61,13 +62,13 @@ fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
             Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner),
             Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
             Ty::Dyn(predicates) => {
-                let where_clauses = chalk_ir::QuantifiedWhereClauses::from(
+                let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
                     &Interner,
                     predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)),
                 );
                 let bounded_ty = chalk_ir::DynTy {
                     bounds: make_binders(where_clauses, 1),
-                    lifetime: LIFETIME_PLACEHOLDER.to_lifetime(&Interner),
+                    lifetime: FAKE_PLACEHOLDER.to_lifetime(&Interner),
                 };
                 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
             }
@@ -92,6 +93,7 @@ fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
             chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
                 TypeName::Error => Ty::Unknown,
                 TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution),
+                TypeName::Array => array_from_chalk(db, apply_ty.substitution),
                 _ => {
                     let ctor = from_chalk(db, apply_ty.name);
                     let parameters = from_chalk(db, apply_ty.substitution);
@@ -142,7 +144,7 @@ fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
     }
 }
 
-const LIFETIME_PLACEHOLDER: PlaceholderIndex =
+const FAKE_PLACEHOLDER: PlaceholderIndex =
     PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX };
 
 /// We currently don't model lifetimes, but Chalk does. So, we have to insert a
@@ -153,10 +155,10 @@ fn ref_to_chalk(
     subst: Substs,
 ) -> chalk_ir::Ty<Interner> {
     let arg = subst[0].clone().to_chalk(db);
-    let lifetime = LIFETIME_PLACEHOLDER.to_lifetime(&Interner);
+    let lifetime = FAKE_PLACEHOLDER.to_lifetime(&Interner);
     chalk_ir::ApplicationTy {
         name: TypeName::Ref(mutability.to_chalk(db)),
-        substitution: chalk_ir::Substitution::from(
+        substitution: chalk_ir::Substitution::from_iter(
             &Interner,
             vec![lifetime.cast(&Interner), arg.cast(&Interner)],
         ),
@@ -177,11 +179,40 @@ fn ref_from_chalk(
     Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
 }
 
+/// We currently don't model constants, but Chalk does. So, we have to insert a
+/// fake constant here, because Chalks built-in logic may expect it to be there.
+fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> {
+    let arg = subst[0].clone().to_chalk(db);
+    let usize_ty = chalk_ir::ApplicationTy {
+        name: TypeName::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)),
+        substitution: chalk_ir::Substitution::empty(&Interner),
+    }
+    .intern(&Interner);
+    let const_ = FAKE_PLACEHOLDER.to_const(&Interner, usize_ty);
+    chalk_ir::ApplicationTy {
+        name: TypeName::Array,
+        substitution: chalk_ir::Substitution::from_iter(
+            &Interner,
+            vec![arg.cast(&Interner), const_.cast(&Interner)],
+        ),
+    }
+    .intern(&Interner)
+}
+
+/// Here we remove the const from the type we got from Chalk.
+fn array_from_chalk(db: &dyn HirDatabase, subst: chalk_ir::Substitution<Interner>) -> Ty {
+    let tys = subst
+        .iter(&Interner)
+        .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
+        .collect();
+    Ty::apply(TypeCtor::Array, Substs(tys))
+}
+
 impl ToChalk for Substs {
     type Chalk = chalk_ir::Substitution<Interner>;
 
     fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
-        chalk_ir::Substitution::from(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
+        chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
     }
 
     fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs {
@@ -267,6 +298,7 @@ fn to_chalk(self, db: &dyn HirDatabase) -> TypeName<Interner> {
             TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
             TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
             TypeCtor::Slice => TypeName::Slice,
+            TypeCtor::Array => TypeName::Array,
             TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
             TypeCtor::Str => TypeName::Str,
             TypeCtor::FnDef(callable_def) => {
@@ -275,10 +307,8 @@ fn to_chalk(self, db: &dyn HirDatabase) -> TypeName<Interner> {
             }
             TypeCtor::Never => TypeName::Never,
 
-            TypeCtor::Adt(_)
-            | TypeCtor::Array
-            | TypeCtor::FnPtr { .. }
-            | TypeCtor::Closure { .. } => {
+            // FIXME convert these
+            TypeCtor::Adt(_) | TypeCtor::FnPtr { .. } | TypeCtor::Closure { .. } => {
                 // other TypeCtors get interned and turned into a chalk StructId
                 let struct_id = db.intern_type_ctor(self).into();
                 TypeName::Adt(struct_id)
@@ -496,6 +526,11 @@ fn from_chalk(
                 // we shouldn't get these from Chalk
                 panic!("encountered LifetimeOutlives from Chalk")
             }
+
+            chalk_ir::WhereClause::TypeOutlives(_) => {
+                // we shouldn't get these from Chalk
+                panic!("encountered TypeOutlives from Chalk")
+            }
         }
     }
 }
@@ -574,7 +609,10 @@ fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
                 )
             });
         let value = self.value.to_chalk(db);
-        chalk_ir::Canonical { value, binders: chalk_ir::CanonicalVarKinds::from(&Interner, kinds) }
+        chalk_ir::Canonical {
+            value,
+            binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds),
+        }
     }
 
     fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
@@ -695,7 +733,7 @@ pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
     T: HasInterner<Interner = Interner>,
 {
     chalk_ir::Binders::new(
-        chalk_ir::VariableKinds::from(
+        chalk_ir::VariableKinds::from_iter(
             &Interner,
             std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars),
         ),
index e6a9d32116a92b89fc0a7a704679af22039228c2..1e226baead897ff39152f9b38319f4f900bb1c18 100644 (file)
@@ -157,7 +157,7 @@ pub fn debug_projection_ty(
             _ => panic!("associated type not in trait"),
         };
         let trait_data = self.0.trait_data(trait_);
-        let params = projection_ty.substitution.parameters(&Interner);
+        let params = projection_ty.substitution.as_slice(&Interner);
         write!(fmt, "<{:?} as {}", &params[0], trait_data.name,)?;
         if params.len() > 1 {
             write!(
index c45820ff059bfd5ebfca3279b614321e3a59e271..e3e2442680e8ec7946c19501c70e480fe40c482b 100644 (file)
@@ -110,38 +110,6 @@ pub(super) fn all_super_trait_refs(db: &dyn HirDatabase, trait_ref: TraitRef) ->
     result
 }
 
-/// Finds a path from a trait to one of its super traits. Returns an empty
-/// vector if there is no path.
-pub(super) fn find_super_trait_path(
-    db: &dyn DefDatabase,
-    trait_: TraitId,
-    super_trait: TraitId,
-) -> Vec<TraitId> {
-    let mut result = Vec::with_capacity(2);
-    result.push(trait_);
-    return if go(db, super_trait, &mut result) { result } else { Vec::new() };
-
-    fn go(db: &dyn DefDatabase, super_trait: TraitId, path: &mut Vec<TraitId>) -> bool {
-        let trait_ = *path.last().unwrap();
-        if trait_ == super_trait {
-            return true;
-        }
-
-        for tt in direct_super_traits(db, trait_) {
-            if path.contains(&tt) {
-                continue;
-            }
-            path.push(tt);
-            if go(db, super_trait, path) {
-                return true;
-            } else {
-                path.pop();
-            }
-        }
-        false
-    }
-}
-
 pub(super) fn associated_type_by_name_including_super_traits(
     db: &dyn HirDatabase,
     trait_ref: TraitRef,
index 676a0426993636fe2c4a6240da56955f5885b471..c02f72517b556c8d24ff3e4b8adb15dd4c4fd5dd 100644 (file)
@@ -20,7 +20,7 @@ globset = "0.4.4"
 itertools = "0.9.0"
 jod-thread = "0.1.0"
 log = "0.4.8"
-lsp-types = { version = "0.75.0", features = ["proposed"] }
+lsp-types = { version = "0.76.0", features = ["proposed"] }
 parking_lot = "0.11.0"
 pico-args = "0.3.1"
 rand = { version = "0.7.3", features = ["small_rng"] }
index f999c730aed9671894bfec556bda07fcdf64b1a9..681b4e27992670ddb3779e343ed5eb008b5396f2 100644 (file)
@@ -28,7 +28,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
             }),
             will_save: None,
             will_save_wait_until: None,
-            save: Some(SaveOptions::default()),
+            save: Some(SaveOptions::default().into()),
         })),
         hover_provider: Some(true),
         completion_provider: Some(CompletionOptions {