aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r--crates/ra_hir_ty/src/lib.rs2
-rw-r--r--crates/ra_hir_ty/src/tests.rs52
-rw-r--r--crates/ra_hir_ty/src/tests/regression.rs41
3 files changed, 74 insertions, 21 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.rs b/crates/ra_hir_ty/src/tests.rs
index 81fc0f63a..846005baa 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -18,16 +18,19 @@ use hir_def::{
18 nameres::CrateDefMap, 18 nameres::CrateDefMap,
19 AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId, 19 AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId,
20}; 20};
21use hir_expand::InFile; 21use hir_expand::{db::AstDatabase, InFile};
22use insta::assert_snapshot; 22use insta::assert_snapshot;
23use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase}; 23use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase};
24use ra_syntax::{ 24use ra_syntax::{
25 algo, 25 algo,
26 ast::{self, AstNode}, 26 ast::{self, AstNode},
27 SyntaxNode,
27}; 28};
28use stdx::format_to; 29use stdx::format_to;
29 30
30use crate::{db::HirDatabase, display::HirDisplay, test_db::TestDB, InferenceResult}; 31use crate::{
32 db::HirDatabase, display::HirDisplay, infer::TypeMismatch, test_db::TestDB, InferenceResult, Ty,
33};
31 34
32// These tests compare the inference results for all expressions in a file 35// These tests compare the inference results for all expressions in a file
33// against snapshots of the expected results using insta. Use cargo-insta to 36// against snapshots of the expected results using insta. Use cargo-insta to
@@ -67,13 +70,19 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
67 70
68 let mut infer_def = |inference_result: Arc<InferenceResult>, 71 let mut infer_def = |inference_result: Arc<InferenceResult>,
69 body_source_map: Arc<BodySourceMap>| { 72 body_source_map: Arc<BodySourceMap>| {
70 let mut types = Vec::new(); 73 let mut types: Vec<(InFile<SyntaxNode>, &Ty)> = Vec::new();
71 let mut mismatches = Vec::new(); 74 let mut mismatches: Vec<(InFile<SyntaxNode>, &TypeMismatch)> = Vec::new();
72 75
73 for (pat, ty) in inference_result.type_of_pat.iter() { 76 for (pat, ty) in inference_result.type_of_pat.iter() {
74 let syntax_ptr = match body_source_map.pat_syntax(pat) { 77 let syntax_ptr = match body_source_map.pat_syntax(pat) {
75 Ok(sp) => { 78 Ok(sp) => {
76 sp.map(|ast| ast.either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr())) 79 let root = db.parse_or_expand(sp.file_id).unwrap();
80 sp.map(|ptr| {
81 ptr.either(
82 |it| it.to_node(&root).syntax().clone(),
83 |it| it.to_node(&root).syntax().clone(),
84 )
85 })
77 } 86 }
78 Err(SyntheticSyntax) => continue, 87 Err(SyntheticSyntax) => continue,
79 }; 88 };
@@ -81,29 +90,31 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
81 } 90 }
82 91
83 for (expr, ty) in inference_result.type_of_expr.iter() { 92 for (expr, ty) in inference_result.type_of_expr.iter() {
84 let syntax_ptr = match body_source_map.expr_syntax(expr) { 93 let node = match body_source_map.expr_syntax(expr) {
85 Ok(sp) => sp.map(|ast| ast.syntax_node_ptr()), 94 Ok(sp) => {
95 let root = db.parse_or_expand(sp.file_id).unwrap();
96 sp.map(|ptr| ptr.to_node(&root).syntax().clone())
97 }
86 Err(SyntheticSyntax) => continue, 98 Err(SyntheticSyntax) => continue,
87 }; 99 };
88 types.push((syntax_ptr.clone(), ty)); 100 types.push((node.clone(), ty));
89 if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr) { 101 if let Some(mismatch) = inference_result.type_mismatch_for_expr(expr) {
90 mismatches.push((syntax_ptr, mismatch)); 102 mismatches.push((node, mismatch));
91 } 103 }
92 } 104 }
93 105
94 // sort ranges for consistency 106 // sort ranges for consistency
95 types.sort_by_key(|(src_ptr, _)| { 107 types.sort_by_key(|(node, _)| {
96 (src_ptr.value.range().start(), src_ptr.value.range().end()) 108 let range = node.value.text_range();
109 (range.start(), range.end())
97 }); 110 });
98 for (src_ptr, ty) in &types { 111 for (node, ty) in &types {
99 let node = src_ptr.value.to_node(&src_ptr.file_syntax(&db)); 112 let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.value.clone()) {
100
101 let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.clone()) {
102 (self_param.self_token().unwrap().text_range(), "self".to_string()) 113 (self_param.self_token().unwrap().text_range(), "self".to_string())
103 } else { 114 } else {
104 (src_ptr.value.range(), node.text().to_string().replace("\n", " ")) 115 (node.value.text_range(), node.value.text().to_string().replace("\n", " "))
105 }; 116 };
106 let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" }; 117 let macro_prefix = if node.file_id != file_id.into() { "!" } else { "" };
107 format_to!( 118 format_to!(
108 buf, 119 buf,
109 "{}{} '{}': {}\n", 120 "{}{} '{}': {}\n",
@@ -114,11 +125,12 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
114 ); 125 );
115 } 126 }
116 if include_mismatches { 127 if include_mismatches {
117 mismatches.sort_by_key(|(src_ptr, _)| { 128 mismatches.sort_by_key(|(node, _)| {
118 (src_ptr.value.range().start(), src_ptr.value.range().end()) 129 let range = node.value.text_range();
130 (range.start(), range.end())
119 }); 131 });
120 for (src_ptr, mismatch) in &mismatches { 132 for (src_ptr, mismatch) in &mismatches {
121 let range = src_ptr.value.range(); 133 let range = src_ptr.value.text_range();
122 let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" }; 134 let macro_prefix = if src_ptr.file_id != file_id.into() { "!" } else { "" };
123 format_to!( 135 format_to!(
124 buf, 136 buf,
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]
538fn issue_4053_diesel_where_clauses() {
539 assert_snapshot!(
540 infer(r#"
541trait BoxedDsl<DB> {
542 type Output;
543 fn internal_into_boxed(self) -> Self::Output;
544}
545
546struct SelectStatement<From, Select, Distinct, Where, Order, LimitOffset, GroupBy, Locking> {
547 order: Order,
548}
549
550trait QueryFragment<DB: Backend> {}
551
552trait Into<T> { fn into(self) -> T; }
553
554impl<F, S, D, W, O, LOf, DB> BoxedDsl<DB>
555 for SelectStatement<F, S, D, W, O, LOf, G>
556where
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}