Repository: rust-analyzer/rust-analyzer
Pull request #3382 (2020-02-29 22:17:14)

ra_project_model: migrate to Sysroot::alloc()


Patch:
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index 377f44fa75..569d46cc38 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -28,7 +28,7 @@ use hir_def::{
     path::{path, Path},
     resolver::{HasResolver, Resolver, TypeNs},
     type_ref::{Mutability, TypeRef},
-    AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TraitId, TypeAliasId, VariantId,
+    AdtId, AssocItemId, DefWithBodyId, FunctionId, StructFieldId, TypeAliasId, VariantId,
 };
 use hir_expand::{diagnostics::DiagnosticSink, name::name};
 use ra_arena::map::ArenaMap;
@@ -540,12 +540,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
         Some(struct_.into())
     }
 
-    fn resolve_ops_index(&self) -> Option<TraitId> {
-        self.resolve_lang_item("index")?.as_trait()
-    }
-
     fn resolve_ops_index_output(&self) -> Option<TypeAliasId> {
-        let trait_ = self.resolve_ops_index()?;
+        let trait_ = self.resolve_lang_item("index")?.as_trait()?;
         self.db.trait_data(trait_).associated_type_by_name(&name![Output])
     }
 }
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index e89cc72987..3db5b2b515 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -429,27 +429,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
                 let base_ty = self.infer_expr_inner(*base, &Expectation::none());
                 let index_ty = self.infer_expr(*index, &Expectation::none());
 
-                if let (Some(index_trait), Some(krate)) =
-                    (self.resolve_ops_index(), self.resolver.krate())
-                {
-                    let canonicalized = self.canonicalizer().canonicalize_ty(base_ty);
-                    let self_ty = method_resolution::resolve_indexing_op(
-                        self.db,
-                        &canonicalized.value,
-                        self.trait_env.clone(),
-                        krate,
-                        index_trait,
-                    );
-                    let self_ty =
-                        self_ty.map_or(Ty::Unknown, |t| canonicalized.decanonicalize_ty(t.value));
-                    self.resolve_associated_type_with_params(
-                        self_ty,
-                        self.resolve_ops_index_output(),
-                        &[index_ty],
-                    )
-                } else {
-                    Ty::Unknown
-                }
+                self.resolve_associated_type_with_params(
+                    base_ty,
+                    self.resolve_ops_index_output(),
+                    &[index_ty],
+                )
             }
             Expr::Tuple { exprs } => {
                 let mut tys = match &expected.ty {
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 74b908c2e0..df5901835a 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -20,7 +20,7 @@ use crate::{
     db::HirDatabase,
     primitive::{FloatBitness, Uncertain},
     utils::all_super_traits,
-    ApplicationTy, Canonical, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk,
+    Canonical, InEnvironment, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk,
 };
 
 /// This is used as a key for indexing impls.
@@ -214,7 +214,7 @@ pub fn iterate_method_candidates<T>(
             // the methods by autoderef order of *receiver types*, not *self
             // types*.
 
-            let deref_chain = autoderef_method_receiver(db, krate, ty);
+            let deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
             for i in 0..deref_chain.len() {
                 if let Some(result) = iterate_method_candidates_with_autoref(
                     &deref_chain[i..],
@@ -447,25 +447,6 @@ fn iterate_inherent_methods<T>(
     None
 }
 
-/// Returns the self type for the index trait call.
-pub fn resolve_indexing_op(
-    db: &impl HirDatabase,
-    ty: &Canonical<Ty>,
-    env: Arc<TraitEnvironment>,
-    krate: CrateId,
-    index_trait: TraitId,
-) -> Option<Canonical<Ty>> {
-    let ty = InEnvironment { value: ty.clone(), environment: env.clone() };
-    let deref_chain = autoderef_method_receiver(db, krate, ty);
-    for ty in deref_chain {
-        let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone());
-        if db.trait_solve(krate, goal).is_some() {
-            return Some(ty);
-        }
-    }
-    None
-}
-
 fn is_valid_candidate(
     db: &impl HirDatabase,
     name: Option<&Name>,
@@ -567,20 +548,3 @@ fn generic_implements_goal(
     let obligation = super::Obligation::Trait(trait_ref);
     Canonical { num_vars, value: InEnvironment::new(env, obligation) }
 }
-
-fn autoderef_method_receiver(
-    db: &impl HirDatabase,
-    krate: CrateId,
-    ty: InEnvironment<Canonical<Ty>>,
-) -> Vec<Canonical<Ty>> {
-    let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
-    // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
-    if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) =
-        deref_chain.last().map(|ty| &ty.value)
-    {
-        let num_vars = deref_chain.last().unwrap().num_vars;
-        let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone());
-        deref_chain.push(Canonical { value: unsized_ty, num_vars })
-    }
-    deref_chain
-}
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs
index db779a2d26..c51957c1f1 100644
--- a/crates/ra_project_model/src/sysroot.rs
+++ b/crates/ra_project_model/src/sysroot.rs
@@ -66,7 +66,7 @@ impl Sysroot {
                 }
             }
         }
-        if let Some(alloc) = sysroot.by_name("alloc") {
+        if let Some(alloc) = sysroot.alloc() {
             if let Some(core) = sysroot.core() {
                 sysroot.crates[alloc].deps.push(core);
             }


Test patch:
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs
index f9b394f059..644d59e17c 100644
--- a/crates/ra_hir_ty/src/tests/method_resolution.rs
+++ b/crates/ra_hir_ty/src/tests/method_resolution.rs
@@ -838,24 +838,6 @@ fn test() { (&S).foo()<|>; }
     assert_eq!(t, "u128");
 }
 
-#[test]
-fn method_resolution_unsize_array() {
-    let t = type_at(
-        r#"
-//- /main.rs
-#[lang = "slice"]
-impl<T> [T] {
-    fn len(&self) -> usize { loop {} }
-}
-fn test() {
-    let a = [1, 2, 3];
-    a.len()<|>;
-}
-"#,
-    );
-    assert_eq!(t, "usize");
-}
-
 #[test]
 fn method_resolution_trait_from_prelude() {
     let (db, pos) = TestDB::with_position(
diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs
index 547010b351..7d796d0b94 100644
--- a/crates/ra_hir_ty/src/tests/traits.rs
+++ b/crates/ra_hir_ty/src/tests/traits.rs
@@ -567,34 +567,6 @@ mod ops {
     assert_eq!("Foo", type_at_pos(&db, pos));
 }
 
-#[test]
-fn infer_ops_index_autoderef() {
-    let (db, pos) = TestDB::with_position(
-        r#"
-//- /main.rs crate:main deps:std
-fn test() {
-    let a = &[1u32, 2, 3];
-    let b = a[1];
-    b<|>;
-}
-
-//- /std.rs crate:std
-impl<T> ops::Index<u32> for [T] {
-    type Output = T;
-}
-
-#[prelude_import] use ops::*;
-mod ops {
-    #[lang = "index"]
-    pub trait Index<Idx> {
-        type Output;
-    }
-}
-"#,
-    );
-    assert_eq!("u32", type_at_pos(&db, pos));
-}
-
 #[test]
 fn deref_trait() {
     let t = type_at(