fix: resolve associated types of bare dyn types
This commit is contained in:
parent
d6412b5866
commit
12abaf8ddd
@ -238,18 +238,7 @@ pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
|
||||
})
|
||||
.intern(Interner)
|
||||
}
|
||||
TypeRef::DynTrait(bounds) => {
|
||||
let self_ty =
|
||||
TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
|
||||
let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
|
||||
QuantifiedWhereClauses::from_iter(
|
||||
Interner,
|
||||
bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
|
||||
)
|
||||
});
|
||||
let bounds = crate::make_single_type_binders(bounds);
|
||||
TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
|
||||
}
|
||||
TypeRef::DynTrait(bounds) => self.lower_dyn_trait(bounds),
|
||||
TypeRef::ImplTrait(bounds) => {
|
||||
match self.impl_trait_mode {
|
||||
ImplTraitLoweringMode::Opaque => {
|
||||
@ -468,29 +457,10 @@ pub(crate) fn lower_partly_resolved_path(
|
||||
}
|
||||
}
|
||||
0 => {
|
||||
let self_ty = Some(
|
||||
TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
|
||||
.intern(Interner),
|
||||
);
|
||||
let trait_ref = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
|
||||
ctx.lower_trait_ref_from_resolved_path(
|
||||
trait_,
|
||||
resolved_segment,
|
||||
self_ty,
|
||||
)
|
||||
});
|
||||
let dyn_ty = DynTy {
|
||||
bounds: crate::make_single_type_binders(
|
||||
QuantifiedWhereClauses::from_iter(
|
||||
Interner,
|
||||
Some(crate::wrap_empty_binders(WhereClause::Implemented(
|
||||
trait_ref,
|
||||
))),
|
||||
),
|
||||
),
|
||||
lifetime: static_lifetime(),
|
||||
};
|
||||
TyKind::Dyn(dyn_ty).intern(Interner)
|
||||
// Trait object type without dyn; this should be handled in upstream. See
|
||||
// `lower_path()`.
|
||||
stdx::never!("unexpected fully resolved trait path");
|
||||
TyKind::Error.intern(Interner)
|
||||
}
|
||||
_ => {
|
||||
// FIXME report error (ambiguous associated type)
|
||||
@ -555,11 +525,20 @@ pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
|
||||
let (ty, res) = self.lower_ty_ext(type_ref);
|
||||
return self.lower_ty_relative_path(ty, res, path.segments());
|
||||
}
|
||||
|
||||
let (resolution, remaining_index) =
|
||||
match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
|
||||
Some(it) => it,
|
||||
None => return (TyKind::Error.intern(Interner), None),
|
||||
};
|
||||
|
||||
if matches!(resolution, TypeNs::TraitId(_)) && remaining_index.is_none() {
|
||||
// trait object type without dyn
|
||||
let bound = TypeBound::Path(path.clone(), TraitBoundModifier::None);
|
||||
let ty = self.lower_dyn_trait(&[Interned::new(bound)]);
|
||||
return (ty, None);
|
||||
}
|
||||
|
||||
let (resolved_segment, remaining_segments) = match remaining_index {
|
||||
None => (
|
||||
path.segments().last().expect("resolved path has at least one element"),
|
||||
@ -987,6 +966,18 @@ fn assoc_type_bindings_from_type_bound(
|
||||
})
|
||||
}
|
||||
|
||||
fn lower_dyn_trait(&self, bounds: &[Interned<TypeBound>]) -> Ty {
|
||||
let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
|
||||
let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
|
||||
QuantifiedWhereClauses::from_iter(
|
||||
Interner,
|
||||
bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)),
|
||||
)
|
||||
});
|
||||
let bounds = crate::make_single_type_binders(bounds);
|
||||
TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
|
||||
}
|
||||
|
||||
fn lower_impl_trait(
|
||||
&self,
|
||||
bounds: &[Interned<TypeBound>],
|
||||
|
@ -1476,6 +1476,34 @@ fn test(x: Trait, y: &Trait) -> u64 {
|
||||
165..172 'z.foo()': u64
|
||||
"#]],
|
||||
);
|
||||
|
||||
check_infer_with_mismatches(
|
||||
r#"
|
||||
//- minicore: fn, coerce_unsized
|
||||
struct S;
|
||||
impl S {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
fn f(_: &Fn(S)) {}
|
||||
fn main() {
|
||||
f(&|number| number.foo());
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
31..35 'self': &S
|
||||
37..39 '{}': ()
|
||||
47..48 '_': &dyn Fn(S)
|
||||
58..60 '{}': ()
|
||||
71..105 '{ ...()); }': ()
|
||||
77..78 'f': fn f(&dyn Fn(S))
|
||||
77..102 'f(&|nu...foo())': ()
|
||||
79..101 '&|numb....foo()': &|S| -> ()
|
||||
80..101 '|numbe....foo()': |S| -> ()
|
||||
81..87 'number': S
|
||||
89..95 'number': S
|
||||
89..101 'number.foo()': ()
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
Reference in New Issue
Block a user