mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 05:38:46 +00:00
Store some hir_def Paths in the type ref source maps
Most paths are types and therefore already are in the source map, but the trait in impl trait and in bounds are not. We do this by storing them basically as `TypeRef`s. For convenience, I created a wrapper around `TypeRefId` called `PathId` that always stores a path, and implemented indexing from the types map to it. Fortunately, this change impacts memory usage negligibly (adds 2mb to `analysis-stats .`, but that could be just fluff). Probably because there aren't that many trait bounds and impl traits, and this also shrinks `TypeBound` by 8 bytes. I also added an accessor to `TypesSourceMap` to get the source code, which will be needed for diagnostics.
This commit is contained in:
parent
26bc01dae3
commit
4e475a3245
18 changed files with 145 additions and 78 deletions
|
@ -31,7 +31,7 @@ use crate::{
|
|||
path::{ModPath, Path},
|
||||
src::HasSource,
|
||||
type_ref::{TypeRef, TypeRefId, TypesMap, TypesSourceMap},
|
||||
BlockId, DefWithBodyId, HasModule, Lookup,
|
||||
BlockId, DefWithBodyId, HasModule, Lookup, SyntheticSyntax,
|
||||
};
|
||||
|
||||
/// A wrapper around [`span::SyntaxContextId`] that is intended only for comparisons.
|
||||
|
@ -160,9 +160,6 @@ pub struct BodySourceMap {
|
|||
diagnostics: Vec<BodyDiagnostic>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
|
||||
pub struct SyntheticSyntax;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
pub enum BodyDiagnostic {
|
||||
InactiveCode { node: InFile<SyntaxNodePtr>, cfg: CfgExpr, opts: CfgOptions },
|
||||
|
|
|
@ -369,7 +369,7 @@ impl ImplData {
|
|||
|
||||
let item_tree = tree_id.item_tree(db);
|
||||
let impl_def = &item_tree[tree_id.value];
|
||||
let target_trait = impl_def.target_trait.clone();
|
||||
let target_trait = impl_def.target_trait;
|
||||
let self_ty = impl_def.self_ty;
|
||||
let is_negative = impl_def.is_negative;
|
||||
let is_unsafe = impl_def.is_unsafe;
|
||||
|
|
|
@ -26,8 +26,8 @@ use crate::{
|
|||
nameres::{DefMap, MacroSubNs},
|
||||
path::{AssociatedTypeBinding, GenericArg, GenericArgs, NormalPath, Path},
|
||||
type_ref::{
|
||||
ArrayType, ConstRef, FnType, LifetimeRef, RefType, TypeBound, TypeRef, TypeRefId, TypesMap,
|
||||
TypesSourceMap,
|
||||
ArrayType, ConstRef, FnType, LifetimeRef, PathId, RefType, TypeBound, TypeRef, TypeRefId,
|
||||
TypesMap, TypesSourceMap,
|
||||
},
|
||||
AdtId, ConstParamId, GenericDefId, HasModule, ItemTreeLoc, LifetimeParamId,
|
||||
LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
|
||||
|
@ -874,14 +874,20 @@ fn copy_type_bound(
|
|||
to: &mut TypesMap,
|
||||
to_source_map: &mut TypesSourceMap,
|
||||
) -> TypeBound {
|
||||
match bound {
|
||||
TypeBound::Path(path, modifier) => {
|
||||
TypeBound::Path(copy_path(path, from, from_source_map, to, to_source_map), *modifier)
|
||||
let mut copy_path_id = |path: PathId| {
|
||||
let new_path = copy_path(&from[path], from, from_source_map, to, to_source_map);
|
||||
let new_path_id = to.types.alloc(TypeRef::Path(new_path));
|
||||
if let Some(&ptr) = from_source_map.types_map_back.get(path.type_ref()) {
|
||||
to_source_map.types_map_back.insert(new_path_id, ptr);
|
||||
}
|
||||
PathId::from_type_ref_unchecked(new_path_id)
|
||||
};
|
||||
|
||||
match bound {
|
||||
&TypeBound::Path(path, modifier) => TypeBound::Path(copy_path_id(path), modifier),
|
||||
TypeBound::ForLifetime(lifetimes, path) => {
|
||||
TypeBound::ForLifetime(lifetimes.clone(), copy_path_id(*path))
|
||||
}
|
||||
TypeBound::ForLifetime(lifetimes, path) => TypeBound::ForLifetime(
|
||||
lifetimes.clone(),
|
||||
copy_path(path, from, from_source_map, to, to_source_map),
|
||||
),
|
||||
TypeBound::Lifetime(lifetime) => TypeBound::Lifetime(lifetime.clone()),
|
||||
TypeBound::Use(use_args) => TypeBound::Use(use_args.clone()),
|
||||
TypeBound::Error => TypeBound::Error,
|
||||
|
|
|
@ -23,6 +23,7 @@ use crate::{
|
|||
hir::Literal,
|
||||
lower::LowerCtx,
|
||||
path::{GenericArg, Path},
|
||||
SyntheticSyntax,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
|
@ -91,19 +92,37 @@ impl Rawness {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
/// A `TypeRefId` that is guaranteed to always be `TypeRef::Path`. We use this for things like
|
||||
/// impl's trait, that are always paths but need to be traced back to source code.
|
||||
pub struct PathId(TypeRefId);
|
||||
|
||||
impl PathId {
|
||||
#[inline]
|
||||
pub fn from_type_ref_unchecked(type_ref: TypeRefId) -> Self {
|
||||
Self(type_ref)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn type_ref(self) -> TypeRefId {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct TraitRef {
|
||||
pub path: Path,
|
||||
pub path: PathId,
|
||||
}
|
||||
|
||||
impl TraitRef {
|
||||
/// Converts an `ast::PathType` to a `hir::TraitRef`.
|
||||
pub(crate) fn from_ast(ctx: &mut LowerCtx<'_>, node: ast::Type) -> Option<Self> {
|
||||
// FIXME: Use `Path::from_src`
|
||||
match node {
|
||||
ast::Type::PathType(path) => {
|
||||
path.path().and_then(|it| ctx.lower_path(it)).map(|path| TraitRef { path })
|
||||
}
|
||||
match &node {
|
||||
ast::Type::PathType(path) => path
|
||||
.path()
|
||||
.and_then(|it| ctx.lower_path(it))
|
||||
.map(|path| TraitRef { path: ctx.alloc_path(path, AstPtr::new(&node)) }),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -173,11 +192,24 @@ impl TypesMap {
|
|||
impl Index<TypeRefId> for TypesMap {
|
||||
type Output = TypeRef;
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: TypeRefId) -> &Self::Output {
|
||||
&self.types[index]
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<PathId> for TypesMap {
|
||||
type Output = Path;
|
||||
|
||||
#[inline]
|
||||
fn index(&self, index: PathId) -> &Self::Output {
|
||||
let TypeRef::Path(path) = &self[index.type_ref()] else {
|
||||
unreachable!("`PathId` always points to `TypeRef::Path`");
|
||||
};
|
||||
path
|
||||
}
|
||||
}
|
||||
|
||||
pub type TypePtr = AstPtr<ast::Type>;
|
||||
pub type TypeSource = InFile<TypePtr>;
|
||||
|
||||
|
@ -187,6 +219,10 @@ pub struct TypesSourceMap {
|
|||
}
|
||||
|
||||
impl TypesSourceMap {
|
||||
pub fn type_syntax(&self, id: TypeRefId) -> Result<TypeSource, SyntheticSyntax> {
|
||||
self.types_map_back.get(id).cloned().ok_or(SyntheticSyntax)
|
||||
}
|
||||
|
||||
pub(crate) fn shrink_to_fit(&mut self) {
|
||||
let TypesSourceMap { types_map_back } = self;
|
||||
types_map_back.shrink_to_fit();
|
||||
|
@ -214,15 +250,15 @@ impl LifetimeRef {
|
|||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum TypeBound {
|
||||
Path(Path, TraitBoundModifier),
|
||||
ForLifetime(Box<[Name]>, Path),
|
||||
Path(PathId, TraitBoundModifier),
|
||||
ForLifetime(Box<[Name]>, PathId),
|
||||
Lifetime(LifetimeRef),
|
||||
Use(Box<[UseArgRef]>),
|
||||
Error,
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
const _: [(); 32] = [(); ::std::mem::size_of::<TypeBound>()];
|
||||
const _: [(); 24] = [(); ::std::mem::size_of::<TypeBound>()];
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub enum UseArgRef {
|
||||
|
@ -365,8 +401,8 @@ impl TypeRef {
|
|||
TypeRef::ImplTrait(bounds) | TypeRef::DynTrait(bounds) => {
|
||||
for bound in bounds {
|
||||
match bound {
|
||||
TypeBound::Path(path, _) | TypeBound::ForLifetime(_, path) => {
|
||||
go_path(path, f, map)
|
||||
&TypeBound::Path(path, _) | &TypeBound::ForLifetime(_, path) => {
|
||||
go_path(&map[path], f, map)
|
||||
}
|
||||
TypeBound::Lifetime(_) | TypeBound::Error | TypeBound::Use(_) => (),
|
||||
}
|
||||
|
@ -397,8 +433,8 @@ impl TypeRef {
|
|||
}
|
||||
for bound in binding.bounds.iter() {
|
||||
match bound {
|
||||
TypeBound::Path(path, _) | TypeBound::ForLifetime(_, path) => {
|
||||
go_path(path, f, map)
|
||||
&TypeBound::Path(path, _) | &TypeBound::ForLifetime(_, path) => {
|
||||
go_path(&map[path], f, map)
|
||||
}
|
||||
TypeBound::Lifetime(_) | TypeBound::Error | TypeBound::Use(_) => (),
|
||||
}
|
||||
|
@ -425,7 +461,7 @@ pub(crate) fn type_bounds_from_ast(
|
|||
|
||||
impl TypeBound {
|
||||
pub(crate) fn from_ast(ctx: &mut LowerCtx<'_>, node: ast::TypeBound) -> Self {
|
||||
let mut lower_path_type = |path_type: ast::PathType| ctx.lower_path(path_type.path()?);
|
||||
let mut lower_path_type = |path_type: &ast::PathType| ctx.lower_path(path_type.path()?);
|
||||
|
||||
match node.kind() {
|
||||
ast::TypeBoundKind::PathType(path_type) => {
|
||||
|
@ -433,8 +469,10 @@ impl TypeBound {
|
|||
Some(_) => TraitBoundModifier::Maybe,
|
||||
None => TraitBoundModifier::None,
|
||||
};
|
||||
lower_path_type(path_type)
|
||||
.map(|p| TypeBound::Path(p, m))
|
||||
lower_path_type(&path_type)
|
||||
.map(|p| {
|
||||
TypeBound::Path(ctx.alloc_path(p, AstPtr::new(&path_type).upcast()), m)
|
||||
})
|
||||
.unwrap_or(TypeBound::Error)
|
||||
}
|
||||
ast::TypeBoundKind::ForType(for_type) => {
|
||||
|
@ -445,12 +483,14 @@ impl TypeBound {
|
|||
.collect(),
|
||||
None => Box::default(),
|
||||
};
|
||||
let path = for_type.ty().and_then(|ty| match ty {
|
||||
ast::Type::PathType(path_type) => lower_path_type(path_type),
|
||||
let path = for_type.ty().and_then(|ty| match &ty {
|
||||
ast::Type::PathType(path_type) => lower_path_type(path_type).map(|p| (p, ty)),
|
||||
_ => None,
|
||||
});
|
||||
match path {
|
||||
Some(p) => TypeBound::ForLifetime(lt_refs, p),
|
||||
Some((p, ty)) => {
|
||||
TypeBound::ForLifetime(lt_refs, ctx.alloc_path(p, AstPtr::new(&ty)))
|
||||
}
|
||||
None => TypeBound::Error,
|
||||
}
|
||||
}
|
||||
|
@ -470,10 +510,10 @@ impl TypeBound {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn as_path(&self) -> Option<(&Path, &TraitBoundModifier)> {
|
||||
pub fn as_path<'a>(&self, map: &'a TypesMap) -> Option<(&'a Path, TraitBoundModifier)> {
|
||||
match self {
|
||||
TypeBound::Path(p, m) => Some((p, m)),
|
||||
TypeBound::ForLifetime(_, p) => Some((p, &TraitBoundModifier::None)),
|
||||
&TypeBound::Path(p, m) => Some((&map[p], m)),
|
||||
&TypeBound::ForLifetime(_, p) => Some((&map[p], TraitBoundModifier::None)),
|
||||
TypeBound::Lifetime(_) | TypeBound::Error | TypeBound::Use(_) => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ use crate::{
|
|||
lower::LowerCtx,
|
||||
path::AssociatedTypeBinding,
|
||||
type_ref::{
|
||||
LifetimeRef, RefType, TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId,
|
||||
LifetimeRef, PathId, RefType, TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId,
|
||||
TypesMap, TypesSourceMap,
|
||||
},
|
||||
visibility::RawVisibility,
|
||||
|
@ -514,7 +514,7 @@ impl<'a> Ctx<'a> {
|
|||
};
|
||||
|
||||
let ret_type = if func.async_token().is_some() {
|
||||
let future_impl = desugar_future_path(ret_type);
|
||||
let future_impl = desugar_future_path(&mut body_ctx, ret_type);
|
||||
let ty_bound = TypeBound::Path(future_impl, TraitBoundModifier::None);
|
||||
body_ctx.alloc_type_ref_desugared(TypeRef::ImplTrait(ThinVec::from_iter([ty_bound])))
|
||||
} else {
|
||||
|
@ -936,7 +936,7 @@ impl<'a> Ctx<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn desugar_future_path(orig: TypeRefId) -> Path {
|
||||
fn desugar_future_path(ctx: &mut LowerCtx<'_>, orig: TypeRefId) -> PathId {
|
||||
let path = path![core::future::Future];
|
||||
let mut generic_args: Vec<_> =
|
||||
std::iter::repeat(None).take(path.segments().len() - 1).collect();
|
||||
|
@ -948,7 +948,8 @@ fn desugar_future_path(orig: TypeRefId) -> Path {
|
|||
};
|
||||
generic_args.push(Some(GenericArgs { bindings: Box::new([binding]), ..GenericArgs::empty() }));
|
||||
|
||||
Path::from_known_path(path, generic_args)
|
||||
let path = Path::from_known_path(path, generic_args);
|
||||
PathId::from_type_ref_unchecked(ctx.alloc_type_ref_desugared(TypeRef::Path(path)))
|
||||
}
|
||||
|
||||
enum HasImplicitSelf {
|
||||
|
|
|
@ -484,7 +484,7 @@ impl Printer<'_> {
|
|||
w!(self, "!");
|
||||
}
|
||||
if let Some(tr) = target_trait {
|
||||
self.print_path(&tr.path, types_map);
|
||||
self.print_path(&types_map[tr.path], types_map);
|
||||
w!(self, " for ");
|
||||
}
|
||||
self.print_type_ref(*self_ty, types_map);
|
||||
|
|
|
@ -1535,3 +1535,6 @@ fn macro_call_as_call_id_with_eager(
|
|||
pub struct UnresolvedMacro {
|
||||
pub path: hir_expand::mod_path::ModPath,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Eq, PartialEq, Clone, Copy)]
|
||||
pub struct SyntheticSyntax;
|
||||
|
|
|
@ -10,7 +10,7 @@ use triomphe::Arc;
|
|||
use crate::{
|
||||
db::DefDatabase,
|
||||
path::Path,
|
||||
type_ref::{TypeBound, TypePtr, TypeRef, TypeRefId, TypesMap, TypesSourceMap},
|
||||
type_ref::{PathId, TypeBound, TypePtr, TypeRef, TypeRefId, TypesMap, TypesSourceMap},
|
||||
};
|
||||
|
||||
pub struct LowerCtx<'a> {
|
||||
|
@ -142,4 +142,8 @@ impl<'a> LowerCtx<'a> {
|
|||
pub(crate) fn alloc_error_type(&mut self) -> TypeRefId {
|
||||
self.types_map.types.alloc(TypeRef::Error)
|
||||
}
|
||||
|
||||
pub(crate) fn alloc_path(&mut self, path: Path, node: TypePtr) -> PathId {
|
||||
PathId::from_type_ref_unchecked(self.alloc_type_ref(TypeRef::Path(path), node))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ pub(crate) fn print_type_bounds(
|
|||
TraitBoundModifier::None => (),
|
||||
TraitBoundModifier::Maybe => write!(buf, "?")?,
|
||||
}
|
||||
print_path(db, path, map, buf, edition)?;
|
||||
print_path(db, &map[*path], map, buf, edition)?;
|
||||
}
|
||||
TypeBound::ForLifetime(lifetimes, path) => {
|
||||
write!(
|
||||
|
@ -279,7 +279,7 @@ pub(crate) fn print_type_bounds(
|
|||
"for<{}> ",
|
||||
lifetimes.iter().map(|it| it.display(db.upcast(), edition)).format(", ")
|
||||
)?;
|
||||
print_path(db, path, map, buf, edition)?;
|
||||
print_path(db, &map[*path], map, buf, edition)?;
|
||||
}
|
||||
TypeBound::Lifetime(lt) => write!(buf, "{}", lt.name.display(db.upcast(), edition))?,
|
||||
TypeBound::Use(args) => {
|
||||
|
|
|
@ -576,10 +576,12 @@ impl Resolver {
|
|||
match scope {
|
||||
Scope::BlockScope(m) => traits.extend(m.def_map[m.module_id].scope.traits()),
|
||||
&Scope::ImplDefScope(impl_) => {
|
||||
if let Some(target_trait) = &db.impl_data(impl_).target_trait {
|
||||
if let Some(TypeNs::TraitId(trait_)) =
|
||||
self.resolve_path_in_type_ns_fully(db, &target_trait.path)
|
||||
{
|
||||
let impl_data = db.impl_data(impl_);
|
||||
if let Some(target_trait) = impl_data.target_trait {
|
||||
if let Some(TypeNs::TraitId(trait_)) = self.resolve_path_in_type_ns_fully(
|
||||
db,
|
||||
&impl_data.types_map[target_trait.path],
|
||||
) {
|
||||
traits.insert(trait_);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2062,12 +2062,12 @@ impl HirDisplayWithTypesMap for TypeBound {
|
|||
types_map: &TypesMap,
|
||||
) -> Result<(), HirDisplayError> {
|
||||
match self {
|
||||
TypeBound::Path(path, modifier) => {
|
||||
&TypeBound::Path(path, modifier) => {
|
||||
match modifier {
|
||||
TraitBoundModifier::None => (),
|
||||
TraitBoundModifier::Maybe => write!(f, "?")?,
|
||||
}
|
||||
path.hir_fmt(f, types_map)
|
||||
types_map[path].hir_fmt(f, types_map)
|
||||
}
|
||||
TypeBound::Lifetime(lifetime) => {
|
||||
write!(f, "{}", lifetime.name.display(f.db.upcast(), f.edition()))
|
||||
|
@ -2079,7 +2079,7 @@ impl HirDisplayWithTypesMap for TypeBound {
|
|||
"for<{}> ",
|
||||
lifetimes.iter().map(|it| it.display(f.db.upcast(), edition)).format(", ")
|
||||
)?;
|
||||
path.hir_fmt(f, types_map)
|
||||
types_map[*path].hir_fmt(f, types_map)
|
||||
}
|
||||
TypeBound::Use(args) => {
|
||||
let edition = f.edition();
|
||||
|
|
|
@ -33,8 +33,8 @@ use hir_def::{
|
|||
path::{GenericArg, GenericArgs, ModPath, Path, PathKind, PathSegment, PathSegments},
|
||||
resolver::{HasResolver, LifetimeNs, Resolver, TypeNs},
|
||||
type_ref::{
|
||||
ConstRef, LifetimeRef, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound, TypeRef,
|
||||
TypeRefId, TypesMap, TypesSourceMap,
|
||||
ConstRef, LifetimeRef, PathId, TraitBoundModifier, TraitRef as HirTraitRef, TypeBound,
|
||||
TypeRef, TypeRefId, TypesMap, TypesSourceMap,
|
||||
},
|
||||
AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
|
||||
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, InTypeConstLoc, ItemContainerId,
|
||||
|
@ -264,7 +264,8 @@ impl<'a> TyLoweringContext<'a> {
|
|||
.intern(Interner)
|
||||
}
|
||||
TypeRef::Path(path) => {
|
||||
let (ty, res_) = self.lower_path(path);
|
||||
let (ty, res_) =
|
||||
self.lower_path(path, PathId::from_type_ref_unchecked(type_ref_id));
|
||||
res = res_;
|
||||
ty
|
||||
}
|
||||
|
@ -677,7 +678,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
|
||||
}
|
||||
|
||||
pub(crate) fn lower_path(&mut self, path: &Path) -> (Ty, Option<TypeNs>) {
|
||||
pub(crate) fn lower_path(&mut self, path: &Path, path_id: PathId) -> (Ty, Option<TypeNs>) {
|
||||
// Resolve the path (in type namespace)
|
||||
if let Some(type_ref) = path.type_anchor() {
|
||||
let (ty, res) = self.lower_ty_ext(type_ref);
|
||||
|
@ -692,7 +693,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
|
||||
if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
|
||||
// trait object type without dyn
|
||||
let bound = TypeBound::Path(path.clone(), TraitBoundModifier::None);
|
||||
let bound = TypeBound::Path(path_id, TraitBoundModifier::None);
|
||||
let ty = self.lower_dyn_trait(&[bound]);
|
||||
return (ty, None);
|
||||
}
|
||||
|
@ -998,7 +999,12 @@ impl<'a> TyLoweringContext<'a> {
|
|||
TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
|
||||
}
|
||||
|
||||
fn lower_trait_ref_from_path(&mut self, path: &Path, explicit_self_ty: Ty) -> Option<TraitRef> {
|
||||
fn lower_trait_ref_from_path(
|
||||
&mut self,
|
||||
path_id: PathId,
|
||||
explicit_self_ty: Ty,
|
||||
) -> Option<TraitRef> {
|
||||
let path = &self.types_map[path_id];
|
||||
let resolved = match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path)? {
|
||||
// FIXME(trait_alias): We need to handle trait alias here.
|
||||
TypeNs::TraitId(tr) => tr,
|
||||
|
@ -1013,7 +1019,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
trait_ref: &HirTraitRef,
|
||||
explicit_self_ty: Ty,
|
||||
) -> Option<TraitRef> {
|
||||
self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
|
||||
self.lower_trait_ref_from_path(trait_ref.path, explicit_self_ty)
|
||||
}
|
||||
|
||||
fn trait_ref_substs_from_path(
|
||||
|
@ -1072,11 +1078,11 @@ impl<'a> TyLoweringContext<'a> {
|
|||
) -> impl Iterator<Item = QuantifiedWhereClause> + use<'b, 'a> {
|
||||
let mut trait_ref = None;
|
||||
let clause = match bound {
|
||||
TypeBound::Path(path, TraitBoundModifier::None) => {
|
||||
&TypeBound::Path(path, TraitBoundModifier::None) => {
|
||||
trait_ref = self.lower_trait_ref_from_path(path, self_ty);
|
||||
trait_ref.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
|
||||
}
|
||||
TypeBound::Path(path, TraitBoundModifier::Maybe) => {
|
||||
&TypeBound::Path(path, TraitBoundModifier::Maybe) => {
|
||||
let sized_trait = self
|
||||
.db
|
||||
.lang_item(self.resolver.krate(), LangItem::Sized)
|
||||
|
@ -1092,7 +1098,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
None
|
||||
}
|
||||
TypeBound::ForLifetime(_, path) => {
|
||||
&TypeBound::ForLifetime(_, path) => {
|
||||
// FIXME Don't silently drop the hrtb lifetimes here
|
||||
trait_ref = self.lower_trait_ref_from_path(path, self_ty);
|
||||
trait_ref.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
|
||||
|
@ -1121,8 +1127,8 @@ impl<'a> TyLoweringContext<'a> {
|
|||
trait_ref: TraitRef,
|
||||
) -> impl Iterator<Item = QuantifiedWhereClause> + use<'b, 'a> {
|
||||
let last_segment = match bound {
|
||||
TypeBound::Path(path, TraitBoundModifier::None) | TypeBound::ForLifetime(_, path) => {
|
||||
path.segments().last()
|
||||
&TypeBound::Path(path, TraitBoundModifier::None) | &TypeBound::ForLifetime(_, path) => {
|
||||
self.types_map[path].segments().last()
|
||||
}
|
||||
TypeBound::Path(_, TraitBoundModifier::Maybe)
|
||||
| TypeBound::Use(_)
|
||||
|
@ -1593,9 +1599,10 @@ pub(crate) fn generic_predicates_for_param_query(
|
|||
}
|
||||
|
||||
match bound {
|
||||
TypeBound::ForLifetime(_, path) | TypeBound::Path(path, _) => {
|
||||
&TypeBound::ForLifetime(_, path) | &TypeBound::Path(path, _) => {
|
||||
// Only lower the bound if the trait could possibly define the associated
|
||||
// type we're looking for.
|
||||
let path = &ctx.types_map[path];
|
||||
|
||||
let Some(assoc_name) = &assoc_name else { return true };
|
||||
let Some(TypeNs::TraitId(tr)) =
|
||||
|
|
|
@ -18,13 +18,13 @@ use std::sync::LazyLock;
|
|||
use base_db::SourceDatabaseFileInputExt as _;
|
||||
use expect_test::Expect;
|
||||
use hir_def::{
|
||||
body::{Body, BodySourceMap, SyntheticSyntax},
|
||||
body::{Body, BodySourceMap},
|
||||
db::DefDatabase,
|
||||
hir::{ExprId, Pat, PatId},
|
||||
item_scope::ItemScope,
|
||||
nameres::DefMap,
|
||||
src::HasSource,
|
||||
AssocItemId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleDefId,
|
||||
AssocItemId, DefWithBodyId, HasModule, LocalModuleId, Lookup, ModuleDefId, SyntheticSyntax,
|
||||
};
|
||||
use hir_expand::{db::ExpandDatabase, FileRange, InFile};
|
||||
use itertools::Itertools;
|
||||
|
|
|
@ -185,7 +185,7 @@ fn direct_super_traits_cb(db: &dyn DefDatabase, trait_: TraitId, cb: impl FnMut(
|
|||
}
|
||||
};
|
||||
match is_trait {
|
||||
true => bound.as_path(),
|
||||
true => bound.as_path(&generic_params.types_map),
|
||||
false => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ use hir_ty::{
|
|||
use cfg::{CfgExpr, CfgOptions};
|
||||
use either::Either;
|
||||
pub use hir_def::VariantId;
|
||||
use hir_def::{body::SyntheticSyntax, hir::ExprOrPatId, path::ModPath, AssocItemId, DefWithBodyId};
|
||||
use hir_def::{hir::ExprOrPatId, path::ModPath, AssocItemId, DefWithBodyId, SyntheticSyntax};
|
||||
use hir_expand::{name::Name, HirFileId, InFile};
|
||||
use syntax::{ast, AstPtr, SyntaxError, SyntaxNodePtr, TextRange};
|
||||
use triomphe::Arc;
|
||||
|
|
|
@ -132,12 +132,18 @@ impl HirDisplay for Function {
|
|||
} else {
|
||||
match &data.types_map[data.ret_type] {
|
||||
TypeRef::ImplTrait(bounds) => match &bounds[0] {
|
||||
TypeBound::Path(path, _) => Some(
|
||||
*path.segments().iter().last().unwrap().args_and_bindings.unwrap().bindings
|
||||
[0]
|
||||
.type_ref
|
||||
.as_ref()
|
||||
.unwrap(),
|
||||
&TypeBound::Path(path, _) => Some(
|
||||
*data.types_map[path]
|
||||
.segments()
|
||||
.iter()
|
||||
.last()
|
||||
.unwrap()
|
||||
.args_and_bindings
|
||||
.unwrap()
|
||||
.bindings[0]
|
||||
.type_ref
|
||||
.as_ref()
|
||||
.unwrap(),
|
||||
),
|
||||
_ => None,
|
||||
},
|
||||
|
|
|
@ -43,7 +43,7 @@ use arrayvec::ArrayVec;
|
|||
use base_db::{CrateDisplayName, CrateId, CrateOrigin};
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
body::{BodyDiagnostic, SyntheticSyntax},
|
||||
body::BodyDiagnostic,
|
||||
data::adt::VariantData,
|
||||
generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
|
||||
hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, Pat},
|
||||
|
@ -57,8 +57,8 @@ use hir_def::{
|
|||
AssocItemId, AssocItemLoc, AttrDefId, CallableDefId, ConstId, ConstParamId, CrateRootModuleId,
|
||||
DefWithBodyId, EnumId, EnumVariantId, ExternCrateId, FunctionId, GenericDefId, GenericParamId,
|
||||
HasModule, ImplId, InTypeConstId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup,
|
||||
MacroExpander, ModuleId, StaticId, StructId, TraitAliasId, TraitId, TupleId, TypeAliasId,
|
||||
TypeOrConstParamId, TypeParamId, UnionId,
|
||||
MacroExpander, ModuleId, StaticId, StructId, SyntheticSyntax, TraitAliasId, TraitId, TupleId,
|
||||
TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
|
||||
};
|
||||
use hir_expand::{
|
||||
attrs::collect_attrs, proc_macro::ProcMacroKind, AstId, MacroCallKind, RenderedExpandError,
|
||||
|
|
|
@ -13,8 +13,9 @@ use hir::{
|
|||
ModuleDef, Name,
|
||||
};
|
||||
use hir_def::{
|
||||
body::{BodySourceMap, SyntheticSyntax},
|
||||
body::BodySourceMap,
|
||||
hir::{ExprId, PatId},
|
||||
SyntheticSyntax,
|
||||
};
|
||||
use hir_ty::{Interner, Substitution, TyExt, TypeFlags};
|
||||
use ide::{
|
||||
|
|
Loading…
Reference in a new issue