Skip to content

Commit 4b997b8

Browse files
bors[bot]Veykril
andauthored
Merge #8156
8156: Correctly lower TraitRefs with default params r=flodiebold a=Veykril Fixes #5685 Co-authored-by: Lukas Wirth <[email protected]>
2 parents 97fe64a + 0aa4ac3 commit 4b997b8

File tree

2 files changed

+63
-8
lines changed

2 files changed

+63
-8
lines changed

crates/hir_ty/src/lower.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ impl<'a> TyLoweringContext<'a> {
521521
TyDefId::AdtId(it) => Some(it.into()),
522522
TyDefId::TypeAliasId(it) => Some(it.into()),
523523
};
524-
let substs = self.substs_from_path_segment(segment, generic_def, infer_args);
524+
let substs = self.substs_from_path_segment(segment, generic_def, infer_args, None);
525525
self.db.ty(typeable).subst(&substs)
526526
}
527527

@@ -558,14 +558,15 @@ impl<'a> TyLoweringContext<'a> {
558558
(segment, Some(var.parent.into()))
559559
}
560560
};
561-
self.substs_from_path_segment(segment, generic_def, infer_args)
561+
self.substs_from_path_segment(segment, generic_def, infer_args, None)
562562
}
563563

564564
fn substs_from_path_segment(
565565
&self,
566566
segment: PathSegment<'_>,
567567
def_generic: Option<GenericDefId>,
568568
infer_args: bool,
569+
explicit_self_ty: Option<Ty>,
569570
) -> Substitution {
570571
let mut substs = Vec::new();
571572
let def_generics = def_generic.map(|def| generics(self.db.upcast(), def));
@@ -576,11 +577,19 @@ impl<'a> TyLoweringContext<'a> {
576577

577578
substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(parent_params));
578579

580+
let fill_self_params = || {
581+
substs.extend(
582+
explicit_self_ty
583+
.into_iter()
584+
.chain(iter::repeat(TyKind::Unknown.intern(&Interner)))
585+
.take(self_params),
586+
)
587+
};
579588
let mut had_explicit_type_args = false;
580589

581590
if let Some(generic_args) = &segment.args_and_bindings {
582591
if !generic_args.has_self_type {
583-
substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(self_params));
592+
fill_self_params();
584593
}
585594
let expected_num =
586595
if generic_args.has_self_type { self_params + type_params } else { type_params };
@@ -602,6 +611,8 @@ impl<'a> TyLoweringContext<'a> {
602611
GenericArg::Lifetime(_) => {}
603612
}
604613
}
614+
} else {
615+
fill_self_params();
605616
}
606617

607618
// handle defaults. In expression or pattern path segments without
@@ -650,10 +661,7 @@ impl<'a> TyLoweringContext<'a> {
650661
segment: PathSegment<'_>,
651662
explicit_self_ty: Option<Ty>,
652663
) -> TraitRef {
653-
let mut substs = self.trait_ref_substs_from_path(segment, resolved);
654-
if let Some(self_ty) = explicit_self_ty {
655-
substs.0[0] = self_ty;
656-
}
664+
let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
657665
TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
658666
}
659667

@@ -673,8 +681,9 @@ impl<'a> TyLoweringContext<'a> {
673681
&self,
674682
segment: PathSegment<'_>,
675683
resolved: TraitId,
684+
explicit_self_ty: Option<Ty>,
676685
) -> Substitution {
677-
self.substs_from_path_segment(segment, Some(resolved.into()), false)
686+
self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
678687
}
679688

680689
pub(crate) fn lower_where_predicate(

crates/hir_ty/src/tests/traits.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3324,3 +3324,49 @@ fn f() {
33243324
"#]],
33253325
)
33263326
}
3327+
3328+
#[test]
3329+
fn infer_default_trait_type_parameter() {
3330+
check_infer(
3331+
r#"
3332+
struct A;
3333+
3334+
trait Op<RHS=Self> {
3335+
type Output;
3336+
3337+
fn do_op(self, rhs: RHS) -> Self::Output;
3338+
}
3339+
3340+
impl Op for A {
3341+
type Output = bool;
3342+
3343+
fn do_op(self, rhs: Self) -> Self::Output {
3344+
true
3345+
}
3346+
}
3347+
3348+
fn test() {
3349+
let x = A;
3350+
let y = A;
3351+
let r = x.do_op(y);
3352+
}
3353+
"#,
3354+
expect![[r#"
3355+
63..67 'self': Self
3356+
69..72 'rhs': RHS
3357+
153..157 'self': A
3358+
159..162 'rhs': A
3359+
186..206 '{ ... }': bool
3360+
196..200 'true': bool
3361+
220..277 '{ ...(y); }': ()
3362+
230..231 'x': A
3363+
234..235 'A': A
3364+
245..246 'y': A
3365+
249..250 'A': A
3366+
260..261 'r': bool
3367+
264..265 'x': A
3368+
264..274 'x.do_op(y)': bool
3369+
272..273 'y': A
3370+
"#]],
3371+
)
3372+
}

0 commit comments

Comments
 (0)