about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-04-12 12:18:11 +0200
committerGitHub <noreply@github.com>2019-04-12 12:18:11 +0200
commit7a8329f5dacae9352a0ea72f9ab136c38403d20a (patch)
tree6fc44d52d9a8943b358cebb476639118444126da
parentdddcd928dd0e6d9a88f7e59a79b5b1027aebf92f (diff)
parentbcd263e1f13494197503ec2f3eba554fe6055595 (diff)
downloadrust-7a8329f5dacae9352a0ea72f9ab136c38403d20a.tar.gz
rust-7a8329f5dacae9352a0ea72f9ab136c38403d20a.zip
Rollup merge of #59894 - Xanewok:save-assoc-ty-qpath, r=eddyb
save-analysis: Pull associated type definition using `qpath_def`

Closes https://github.com/rust-lang/rls/issues/1390

This (probably?) fixes the case where we run the save-analysis code on the following snippet:
```rust
trait Test<'a> {
    type Thing: Test2;
}

trait Test2 {
    fn print();
}

#[allow(unused)]
fn example<T>(t: T)
    where T: for<'a> Test<'a>
{
    T::Thing::print(); //~ ERROR cannot extract an associated type from a higher-ranked trait bound in this context
    // ^ only errors in save-analysis mode
}
```

The chain is as follows:
- culprit is `hir_ty_to_ty`
- which calls `ast_ty_to_ty` in the `ItemCtxt`
- which calls `associated_path_to_ty`
- which finally fails on `projected_ty_from_poly_trait_ref`
https://github.com/rust-lang/rust/blob/3de0106789468b211bcc3a25c09c0cf07119186d/src/librustc_typeck/collect.rs#L212-L224

I'm not exactly sure why `hir_ty_to_ty` fails - is it because it needs more setup from typeck to work correctly? I'm guessing the fix is okay since we just pull the already typeck'd data (we run save-analysis after all the analysis passes are complete) from the tables.

With this change we can 'go to def' on all segments in the `T::Thing::print()` path.
-rw-r--r--src/librustc_save_analysis/lib.rs24
-rw-r--r--src/librustc_typeck/lib.rs2
2 files changed, 5 insertions, 21 deletions
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index a363fe11418..d6923b4490d 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -23,7 +23,6 @@ use rustc::middle::cstore::ExternCrate;
 use rustc::session::config::{CrateType, Input, OutputType};
 use rustc::ty::{self, DefIdTree, TyCtxt};
 use rustc::{bug, span_bug};
-use rustc_typeck::hir_ty_to_ty;
 use rustc_codegen_utils::link::{filename_for_metadata, out_filename};
 use rustc_data_structures::sync::Lrc;
 
@@ -648,6 +647,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
             Node::Pat(&hir::Pat {
                 node: hir::PatKind::TupleStruct(ref qpath, ..),
                 ..
+            }) |
+            Node::Ty(&hir::Ty {
+                node: hir::TyKind::Path(ref qpath),
+                ..
             }) => {
                 let hir_id = self.tcx.hir().node_to_hir_id(id);
                 self.tables.qpath_def(qpath, hir_id)
@@ -658,25 +661,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                 ..
             }) => HirDef::Local(self.tcx.hir().hir_to_node_id(canonical_id)),
 
-            Node::Ty(ty) => if let hir::Ty {
-                node: hir::TyKind::Path(ref qpath),
-                ..
-            } = *ty
-            {
-                match *qpath {
-                    hir::QPath::Resolved(_, ref path) => path.def,
-                    hir::QPath::TypeRelative(..) => {
-                        let ty = hir_ty_to_ty(self.tcx, ty);
-                        if let ty::Projection(proj) = ty.sty {
-                            return HirDef::AssociatedTy(proj.item_def_id);
-                        }
-                        HirDef::Err
-                    }
-                }
-            } else {
-                HirDef::Err
-            },
-
             _ => HirDef::Err,
         }
     }
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 4a7b1e67366..710c84a6bc9 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -379,7 +379,7 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
     }
 }
 
-/// A quasi-deprecated helper used in rustdoc and save-analysis to get
+/// A quasi-deprecated helper used in rustdoc and clippy to get
 /// the type from a HIR node.
 pub fn hir_ty_to_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_ty: &hir::Ty) -> Ty<'tcx> {
     // In case there are any projections etc, find the "environment"