Merge #8156
8156: Correctly lower TraitRefs with default params r=flodiebold a=Veykril Fixes #5685 Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
4b997b8663
@ -521,7 +521,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||
TyDefId::AdtId(it) => Some(it.into()),
|
||||
TyDefId::TypeAliasId(it) => Some(it.into()),
|
||||
};
|
||||
let substs = self.substs_from_path_segment(segment, generic_def, infer_args);
|
||||
let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None);
|
||||
self.db.ty(typeable).subst(&substs)
|
||||
}
|
||||
|
||||
@ -558,7 +558,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||
(segment, Some(var.parent.into()))
|
||||
}
|
||||
};
|
||||
self.substs_from_path_segment(segment, generic_def, infer_args)
|
||||
self.substs_from_path_segment(segment, generic_def, infer_args, None)
|
||||
}
|
||||
|
||||
fn substs_from_path_segment(
|
||||
@ -566,6 +566,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||
segment: PathSegment<'_>,
|
||||
def_generic: Option<GenericDefId>,
|
||||
infer_args: bool,
|
||||
explicit_self_ty: Option<Ty>,
|
||||
) -> Substitution {
|
||||
let mut substs = Vec::new();
|
||||
let def_generics = def_generic.map(|def| generics(self.db.upcast(), def));
|
||||
@ -576,11 +577,19 @@ impl<'a> TyLoweringContext<'a> {
|
||||
|
||||
substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(parent_params));
|
||||
|
||||
let fill_self_params = || {
|
||||
substs.extend(
|
||||
explicit_self_ty
|
||||
.into_iter()
|
||||
.chain(iter::repeat(TyKind::Unknown.intern(&Interner)))
|
||||
.take(self_params),
|
||||
)
|
||||
};
|
||||
let mut had_explicit_type_args = false;
|
||||
|
||||
if let Some(generic_args) = &segment.args_and_bindings {
|
||||
if !generic_args.has_self_type {
|
||||
substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(self_params));
|
||||
fill_self_params();
|
||||
}
|
||||
let expected_num =
|
||||
if generic_args.has_self_type { self_params + type_params } else { type_params };
|
||||
@ -602,6 +611,8 @@ impl<'a> TyLoweringContext<'a> {
|
||||
GenericArg::Lifetime(_) => {}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fill_self_params();
|
||||
}
|
||||
|
||||
// handle defaults. In expression or pattern path segments without
|
||||
@ -650,10 +661,7 @@ impl<'a> TyLoweringContext<'a> {
|
||||
segment: PathSegment<'_>,
|
||||
explicit_self_ty: Option<Ty>,
|
||||
) -> TraitRef {
|
||||
let mut substs = self.trait_ref_substs_from_path(segment, resolved);
|
||||
if let Some(self_ty) = explicit_self_ty {
|
||||
substs.0[0] = self_ty;
|
||||
}
|
||||
let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
|
||||
TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
|
||||
}
|
||||
|
||||
@ -673,8 +681,9 @@ impl<'a> TyLoweringContext<'a> {
|
||||
&self,
|
||||
segment: PathSegment<'_>,
|
||||
resolved: TraitId,
|
||||
explicit_self_ty: Option<Ty>,
|
||||
) -> Substitution {
|
||||
self.substs_from_path_segment(segment, Some(resolved.into()), false)
|
||||
self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
|
||||
}
|
||||
|
||||
pub(crate) fn lower_where_predicate(
|
||||
|
@ -3324,3 +3324,49 @@ fn f() {
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_default_trait_type_parameter() {
|
||||
check_infer(
|
||||
r#"
|
||||
struct A;
|
||||
|
||||
trait Op<RHS=Self> {
|
||||
type Output;
|
||||
|
||||
fn do_op(self, rhs: RHS) -> Self::Output;
|
||||
}
|
||||
|
||||
impl Op for A {
|
||||
type Output = bool;
|
||||
|
||||
fn do_op(self, rhs: Self) -> Self::Output {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn test() {
|
||||
let x = A;
|
||||
let y = A;
|
||||
let r = x.do_op(y);
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
63..67 'self': Self
|
||||
69..72 'rhs': RHS
|
||||
153..157 'self': A
|
||||
159..162 'rhs': A
|
||||
186..206 '{ ... }': bool
|
||||
196..200 'true': bool
|
||||
220..277 '{ ...(y); }': ()
|
||||
230..231 'x': A
|
||||
234..235 'A': A
|
||||
245..246 'y': A
|
||||
249..250 'A': A
|
||||
260..261 'r': bool
|
||||
264..265 'x': A
|
||||
264..274 'x.do_op(y)': bool
|
||||
272..273 'y': A
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user