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`
3de0106789/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.
This commit is contained in:
commit
7a8329f5da
2 changed files with 5 additions and 21 deletions
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue