Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 8afaaa5

Browse files
committed
Add TraitRef for HIR
1 parent ff4d55e commit 8afaaa5

File tree

1 file changed

+51
-4
lines changed

1 file changed

+51
-4
lines changed

crates/hir/src/lib.rs

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2791,14 +2791,19 @@ impl Impl {
27912791
all
27922792
}
27932793

2794-
// FIXME: the return type is wrong. This should be a hir version of
2795-
// `TraitRef` (to account for parameters and qualifiers)
27962794
pub fn trait_(self, db: &dyn HirDatabase) -> Option<Trait> {
2797-
let trait_ref = db.impl_trait(self.id)?.skip_binders().clone();
2798-
let id = hir_ty::from_chalk_trait_id(trait_ref.trait_id);
2795+
let trait_ref = db.impl_trait(self.id)?;
2796+
let id = trait_ref.skip_binders().hir_trait_id();
27992797
Some(Trait { id })
28002798
}
28012799

2800+
pub fn trait_ref(self, db: &dyn HirDatabase) -> Option<TraitRef> {
2801+
let substs = TyBuilder::placeholder_subst(db, self.id);
2802+
let trait_ref = db.impl_trait(self.id)?.substitute(Interner, &substs);
2803+
let resolver = self.id.resolver(db.upcast());
2804+
Some(TraitRef::new_with_resolver(db, &resolver, trait_ref))
2805+
}
2806+
28022807
pub fn self_ty(self, db: &dyn HirDatabase) -> Type {
28032808
let resolver = self.id.resolver(db.upcast());
28042809
let substs = TyBuilder::placeholder_subst(db, self.id);
@@ -2824,6 +2829,48 @@ impl Impl {
28242829
}
28252830
}
28262831

2832+
#[derive(Clone, PartialEq, Eq, Debug)]
2833+
pub struct TraitRef {
2834+
env: Arc<TraitEnvironment>,
2835+
trait_ref: hir_ty::TraitRef,
2836+
}
2837+
2838+
impl TraitRef {
2839+
pub(crate) fn new_with_resolver(
2840+
db: &dyn HirDatabase,
2841+
resolver: &Resolver,
2842+
trait_ref: hir_ty::TraitRef,
2843+
) -> TraitRef {
2844+
let env = resolver.generic_def().map_or_else(
2845+
|| Arc::new(TraitEnvironment::empty(resolver.krate())),
2846+
|d| db.trait_environment(d),
2847+
);
2848+
TraitRef { env, trait_ref }
2849+
}
2850+
2851+
pub fn trait_(&self) -> Trait {
2852+
let id = self.trait_ref.hir_trait_id();
2853+
Trait { id }
2854+
}
2855+
2856+
pub fn self_ty(&self) -> Type {
2857+
let ty = self.trait_ref.self_type_parameter(Interner);
2858+
Type { env: self.env.clone(), ty }
2859+
}
2860+
2861+
/// Returns `idx`-th argument of this trait reference if it is a type argument. Note that the
2862+
/// first argument is the `Self` type.
2863+
pub fn get_type_argument(&self, idx: usize) -> Option<Type> {
2864+
self.trait_ref
2865+
.substitution
2866+
.as_slice(Interner)
2867+
.get(idx)
2868+
.and_then(|arg| arg.ty(Interner))
2869+
.cloned()
2870+
.map(|ty| Type { env: self.env.clone(), ty })
2871+
}
2872+
}
2873+
28272874
#[derive(Clone, PartialEq, Eq, Debug)]
28282875
pub struct Type {
28292876
env: Arc<TraitEnvironment>,

0 commit comments

Comments
 (0)