diff options
author | Florian Diebold <[email protected]> | 2020-04-23 19:50:14 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-04-23 22:53:08 +0100 |
commit | 0c01b4eb6aaf86dd6a67cae7bc810916bfc20aeb (patch) | |
tree | 8981f17bcd77c0b151437aa4c39d54a9dc1d13be /crates/ra_hir_ty/src | |
parent | 29bc218fba2e52711b038562ff23bbb76a002380 (diff) |
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).
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/regression.rs | 41 |
2 files changed, 42 insertions, 1 deletions
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 { | |||
863 | &mut |ty, binders| { | 863 | &mut |ty, binders| { |
864 | if let &mut Ty::Bound(bound) = ty { | 864 | if let &mut Ty::Bound(bound) = ty { |
865 | if bound.debruijn >= binders { | 865 | if bound.debruijn >= binders { |
866 | *ty = substs.0[bound.index].clone(); | 866 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); |
867 | } | 867 | } |
868 | } | 868 | } |
869 | }, | 869 | }, |
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) { | |||
533 | "### | 533 | "### |
534 | ); | 534 | ); |
535 | } | 535 | } |
536 | |||
537 | #[test] | ||
538 | fn issue_4053_diesel_where_clauses() { | ||
539 | assert_snapshot!( | ||
540 | infer(r#" | ||
541 | trait BoxedDsl<DB> { | ||
542 | type Output; | ||
543 | fn internal_into_boxed(self) -> Self::Output; | ||
544 | } | ||
545 | |||
546 | struct SelectStatement<From, Select, Distinct, Where, Order, LimitOffset, GroupBy, Locking> { | ||
547 | order: Order, | ||
548 | } | ||
549 | |||
550 | trait QueryFragment<DB: Backend> {} | ||
551 | |||
552 | trait Into<T> { fn into(self) -> T; } | ||
553 | |||
554 | impl<F, S, D, W, O, LOf, DB> BoxedDsl<DB> | ||
555 | for SelectStatement<F, S, D, W, O, LOf, G> | ||
556 | where | ||
557 | O: Into<dyn QueryFragment<DB>>, | ||
558 | { | ||
559 | type Output = XXX; | ||
560 | |||
561 | fn internal_into_boxed(self) -> Self::Output { | ||
562 | self.order.into(); | ||
563 | } | ||
564 | } | ||
565 | "#), | ||
566 | @r###" | ||
567 | [66; 70) 'self': Self | ||
568 | [268; 272) 'self': Self | ||
569 | [467; 471) 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}> | ||
570 | [489; 523) '{ ... }': () | ||
571 | [499; 503) 'self': SelectStatement<F, S, D, W, O, LOf, {unknown}, {unknown}> | ||
572 | [499; 509) 'self.order': O | ||
573 | [499; 516) 'self.o...into()': dyn QueryFragment<DB> | ||
574 | "### | ||
575 | ); | ||
576 | } | ||