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::AdtId(it) => Some(it.into()),
|
||||||
TyDefId::TypeAliasId(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)
|
self.db.ty(typeable).subst(&substs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,7 +558,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||||||
(segment, Some(var.parent.into()))
|
(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(
|
fn substs_from_path_segment(
|
||||||
@ -566,6 +566,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||||||
segment: PathSegment<'_>,
|
segment: PathSegment<'_>,
|
||||||
def_generic: Option<GenericDefId>,
|
def_generic: Option<GenericDefId>,
|
||||||
infer_args: bool,
|
infer_args: bool,
|
||||||
|
explicit_self_ty: Option<Ty>,
|
||||||
) -> Substitution {
|
) -> Substitution {
|
||||||
let mut substs = Vec::new();
|
let mut substs = Vec::new();
|
||||||
let def_generics = def_generic.map(|def| generics(self.db.upcast(), def));
|
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));
|
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;
|
let mut had_explicit_type_args = false;
|
||||||
|
|
||||||
if let Some(generic_args) = &segment.args_and_bindings {
|
if let Some(generic_args) = &segment.args_and_bindings {
|
||||||
if !generic_args.has_self_type {
|
if !generic_args.has_self_type {
|
||||||
substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(self_params));
|
fill_self_params();
|
||||||
}
|
}
|
||||||
let expected_num =
|
let expected_num =
|
||||||
if generic_args.has_self_type { self_params + type_params } else { type_params };
|
if generic_args.has_self_type { self_params + type_params } else { type_params };
|
||||||
@ -602,6 +611,8 @@ impl<'a> TyLoweringContext<'a> {
|
|||||||
GenericArg::Lifetime(_) => {}
|
GenericArg::Lifetime(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fill_self_params();
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle defaults. In expression or pattern path segments without
|
// handle defaults. In expression or pattern path segments without
|
||||||
@ -650,10 +661,7 @@ impl<'a> TyLoweringContext<'a> {
|
|||||||
segment: PathSegment<'_>,
|
segment: PathSegment<'_>,
|
||||||
explicit_self_ty: Option<Ty>,
|
explicit_self_ty: Option<Ty>,
|
||||||
) -> TraitRef {
|
) -> TraitRef {
|
||||||
let mut substs = self.trait_ref_substs_from_path(segment, resolved);
|
let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
|
||||||
if let Some(self_ty) = explicit_self_ty {
|
|
||||||
substs.0[0] = self_ty;
|
|
||||||
}
|
|
||||||
TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
|
TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,8 +681,9 @@ impl<'a> TyLoweringContext<'a> {
|
|||||||
&self,
|
&self,
|
||||||
segment: PathSegment<'_>,
|
segment: PathSegment<'_>,
|
||||||
resolved: TraitId,
|
resolved: TraitId,
|
||||||
|
explicit_self_ty: Option<Ty>,
|
||||||
) -> Substitution {
|
) -> 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(
|
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