mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-15 10:12:21 +00:00
fix: Always explicitly set trait ref self types when lowering
This commit is contained in:
parent
70ee4e5545
commit
20f7ab5ab4
9 changed files with 80 additions and 64 deletions
|
|
@ -516,8 +516,11 @@ impl<'a> TyLoweringContext<'a> {
|
|||
TypeNs::TraitId(trait_) => {
|
||||
let ty = match remaining_segments.len() {
|
||||
1 => {
|
||||
let trait_ref =
|
||||
self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
|
||||
let trait_ref = self.lower_trait_ref_from_resolved_path(
|
||||
trait_,
|
||||
resolved_segment,
|
||||
TyKind::Error.intern(Interner),
|
||||
);
|
||||
let segment = remaining_segments.first().unwrap();
|
||||
let found = self
|
||||
.db
|
||||
|
|
@ -952,11 +955,17 @@ impl<'a> TyLoweringContext<'a> {
|
|||
Substitution::from_iter(Interner, substs)
|
||||
}
|
||||
|
||||
fn lower_trait_ref_from_path(
|
||||
pub(crate) fn lower_trait_ref_from_resolved_path(
|
||||
&self,
|
||||
path: &Path,
|
||||
explicit_self_ty: Option<Ty>,
|
||||
) -> Option<TraitRef> {
|
||||
resolved: TraitId,
|
||||
segment: PathSegment<'_>,
|
||||
explicit_self_ty: Ty,
|
||||
) -> TraitRef {
|
||||
let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
|
||||
TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
|
||||
}
|
||||
|
||||
fn lower_trait_ref_from_path(&self, path: &Path, explicit_self_ty: Ty) -> Option<TraitRef> {
|
||||
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,
|
||||
|
|
@ -966,21 +975,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty))
|
||||
}
|
||||
|
||||
pub(crate) fn lower_trait_ref_from_resolved_path(
|
||||
&self,
|
||||
resolved: TraitId,
|
||||
segment: PathSegment<'_>,
|
||||
explicit_self_ty: Option<Ty>,
|
||||
) -> TraitRef {
|
||||
let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
|
||||
TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
|
||||
}
|
||||
|
||||
fn lower_trait_ref(
|
||||
&self,
|
||||
trait_ref: &HirTraitRef,
|
||||
explicit_self_ty: Option<Ty>,
|
||||
) -> Option<TraitRef> {
|
||||
fn lower_trait_ref(&self, trait_ref: &HirTraitRef, explicit_self_ty: Ty) -> Option<TraitRef> {
|
||||
self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
|
||||
}
|
||||
|
||||
|
|
@ -988,9 +983,9 @@ impl<'a> TyLoweringContext<'a> {
|
|||
&self,
|
||||
segment: PathSegment<'_>,
|
||||
resolved: TraitId,
|
||||
explicit_self_ty: Option<Ty>,
|
||||
explicit_self_ty: Ty,
|
||||
) -> Substitution {
|
||||
self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
|
||||
self.substs_from_path_segment(segment, Some(resolved.into()), false, Some(explicit_self_ty))
|
||||
}
|
||||
|
||||
pub(crate) fn lower_where_predicate<'b>(
|
||||
|
|
@ -1041,7 +1036,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
let mut trait_ref = None;
|
||||
let clause = match bound.as_ref() {
|
||||
TypeBound::Path(path, TraitBoundModifier::None) => {
|
||||
trait_ref = self.lower_trait_ref_from_path(path, Some(self_ty));
|
||||
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) => {
|
||||
|
|
@ -1053,7 +1048,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
// `?Sized` has no of them.
|
||||
// If we got another trait here ignore the bound completely.
|
||||
let trait_id = self
|
||||
.lower_trait_ref_from_path(path, Some(self_ty.clone()))
|
||||
.lower_trait_ref_from_path(path, self_ty.clone())
|
||||
.map(|trait_ref| trait_ref.hir_trait_id());
|
||||
if trait_id == sized_trait {
|
||||
self.unsized_types.borrow_mut().insert(self_ty);
|
||||
|
|
@ -1062,7 +1057,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||
}
|
||||
TypeBound::ForLifetime(_, path) => {
|
||||
// FIXME Don't silently drop the hrtb lifetimes here
|
||||
trait_ref = self.lower_trait_ref_from_path(path, Some(self_ty));
|
||||
trait_ref = self.lower_trait_ref_from_path(path, self_ty);
|
||||
trait_ref.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
|
||||
}
|
||||
TypeBound::Lifetime(l) => {
|
||||
|
|
@ -2126,7 +2121,7 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<
|
|||
.with_type_param_mode(ParamLoweringMode::Variable);
|
||||
let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
|
||||
let target_trait = impl_data.target_trait.as_ref()?;
|
||||
Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
|
||||
Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, self_ty)?))
|
||||
}
|
||||
|
||||
pub(crate) fn return_type_impl_traits(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue