From 0c01b4eb6aaf86dd6a67cae7bc810916bfc20aeb Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Thu, 23 Apr 2020 20:50:14 +0200 Subject: Fix wrong substitution code We need to shift in when we're substituting inside a binder. This should fix #4053 (it doesn't fix the occasional overflow that also occurs on the Diesel codebase though). --- crates/ra_hir_ty/src/lib.rs | 2 +- crates/ra_hir_ty/src/tests/regression.rs | 41 ++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_ty/src') diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index a4b8d6683..279c06d65 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -863,7 +863,7 @@ pub trait TypeWalk { &mut |ty, binders| { if let &mut Ty::Bound(bound) = ty { if bound.debruijn >= binders { - *ty = substs.0[bound.index].clone(); + *ty = substs.0[bound.index].clone().shift_bound_vars(binders); } } }, diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs index 61284d672..61a6801fc 100644 --- a/crates/ra_hir_ty/src/tests/regression.rs +++ b/crates/ra_hir_ty/src/tests/regression.rs @@ -533,3 +533,44 @@ fn foo(b: Bar) { "### ); } + +#[test] +fn issue_4053_diesel_where_clauses() { + assert_snapshot!( + infer(r#" +trait BoxedDsl { + type Output; + fn internal_into_boxed(self) -> Self::Output; +} + +struct SelectStatement { + order: Order, +} + +trait QueryFragment {} + +trait Into { fn into(self) -> T; } + +impl BoxedDsl + for SelectStatement +where + O: Into>, +{ + type Output = XXX; + + fn internal_into_boxed(self) -> Self::Output { + self.order.into(); + } +} +"#), + @r###" + [66; 70) 'self': Self + [268; 272) 'self': Self + [467; 471) 'self': SelectStatement + [489; 523) '{ ... }': () + [499; 503) 'self': SelectStatement + [499; 509) 'self.order': O + [499; 516) 'self.o...into()': dyn QueryFragment + "### + ); +} -- cgit v1.2.3