aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
authorSeivan Heidari <[email protected]>2019-11-15 15:30:21 +0000
committerSeivan Heidari <[email protected]>2019-11-15 15:30:21 +0000
commitcb26df950699586b314731fb70786e0db8eaa049 (patch)
tree29a1fd853757824572bfebc956d20458d827926f /crates/ra_hir
parentc622413bc72ea56d5f62a16788d897cb61eca948 (diff)
parentc6f05abfbbfa2fd1ff06e1adeea7885151aaa768 (diff)
Merge branch 'master' of https://github.com/rust-analyzer/rust-analyzer into feature/themes
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/code_model.rs4
-rw-r--r--crates/ra_hir/src/expr.rs281
-rw-r--r--crates/ra_hir/src/expr/validation.rs137
-rw-r--r--crates/ra_hir/src/from_source.rs68
-rw-r--r--crates/ra_hir/src/resolve.rs23
-rw-r--r--crates/ra_hir/src/source_binder.rs38
-rw-r--r--crates/ra_hir/src/test_db.rs2
-rw-r--r--crates/ra_hir/src/ty/tests.rs54
8 files changed, 174 insertions, 433 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 962d5a8c1..078bd8609 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -23,7 +23,7 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
23use crate::{ 23use crate::{
24 adt::VariantDef, 24 adt::VariantDef,
25 db::{AstDatabase, DefDatabase, HirDatabase}, 25 db::{AstDatabase, DefDatabase, HirDatabase},
26 expr::{validation::ExprValidator, BindingAnnotation, Body, BodySourceMap, Pat, PatId}, 26 expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId},
27 generics::{GenericDef, HasGenericParams}, 27 generics::{GenericDef, HasGenericParams},
28 ids::{ 28 ids::{
29 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, 29 AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId,
@@ -157,7 +157,7 @@ impl Module {
157 } 157 }
158 158
159 /// Finds a child module with the specified name. 159 /// Finds a child module with the specified name.
160 pub fn child(self, db: &impl HirDatabase, name: &Name) -> Option<Module> { 160 pub fn child(self, db: &impl DefDatabase, name: &Name) -> Option<Module> {
161 let def_map = db.crate_def_map(self.id.krate); 161 let def_map = db.crate_def_map(self.id.krate);
162 let child_id = def_map[self.id.module_id].children.get(name)?; 162 let child_id = def_map[self.id.module_id].children.get(name)?;
163 Some(self.with_module_id(*child_id)) 163 Some(self.with_module_id(*child_id))
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 9262325f2..e3733779e 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -1,12 +1,19 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3pub(crate) mod validation;
4
5use std::sync::Arc; 3use std::sync::Arc;
6 4
5use hir_def::path::known;
6use hir_expand::diagnostics::DiagnosticSink;
7use ra_syntax::ast;
7use ra_syntax::AstPtr; 8use ra_syntax::AstPtr;
9use rustc_hash::FxHashSet;
8 10
9use crate::{db::HirDatabase, DefWithBody, HasBody, Resolver}; 11use crate::{
12 db::HirDatabase,
13 diagnostics::{MissingFields, MissingOkInTailExpr},
14 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor},
15 Adt, DefWithBody, Function, HasBody, Name, Path, Resolver,
16};
10 17
11pub use hir_def::{ 18pub use hir_def::{
12 body::{ 19 body::{
@@ -38,196 +45,126 @@ pub(crate) fn resolver_for_scope(
38 let scopes = owner.expr_scopes(db); 45 let scopes = owner.expr_scopes(db);
39 let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); 46 let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
40 for scope in scope_chain.into_iter().rev() { 47 for scope in scope_chain.into_iter().rev() {
41 r = r.push_expr_scope(Arc::clone(&scopes), scope); 48 r = r.push_expr_scope(owner, Arc::clone(&scopes), scope);
42 } 49 }
43 r 50 r
44} 51}
45 52
46#[cfg(test)] 53pub(crate) struct ExprValidator<'a, 'b: 'a> {
47mod tests { 54 func: Function,
48 use hir_expand::Source; 55 infer: Arc<InferenceResult>,
49 use ra_db::{fixture::WithFixture, SourceDatabase}; 56 sink: &'a mut DiagnosticSink<'b>,
50 use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; 57}
51 use test_utils::{assert_eq_text, extract_offset};
52
53 use crate::{source_binder::SourceAnalyzer, test_db::TestDB};
54
55 fn do_check(code: &str, expected: &[&str]) {
56 let (off, code) = extract_offset(code);
57 let code = {
58 let mut buf = String::new();
59 let off = u32::from(off) as usize;
60 buf.push_str(&code[..off]);
61 buf.push_str("marker");
62 buf.push_str(&code[off..]);
63 buf
64 };
65 58
66 let (db, file_id) = TestDB::with_single_file(&code); 59impl<'a, 'b> ExprValidator<'a, 'b> {
67 60 pub(crate) fn new(
68 let file = db.parse(file_id).ok().unwrap(); 61 func: Function,
69 let marker: ast::PathExpr = find_node_at_offset(file.syntax(), off).unwrap(); 62 infer: Arc<InferenceResult>,
70 let analyzer = SourceAnalyzer::new(&db, file_id, marker.syntax(), None); 63 sink: &'a mut DiagnosticSink<'b>,
71 64 ) -> ExprValidator<'a, 'b> {
72 let scopes = analyzer.scopes(); 65 ExprValidator { func, infer, sink }
73 let expr_id = analyzer
74 .body_source_map()
75 .node_expr(Source { file_id: file_id.into(), ast: &marker.into() })
76 .unwrap();
77 let scope = scopes.scope_for(expr_id);
78
79 let actual = scopes
80 .scope_chain(scope)
81 .flat_map(|scope| scopes.entries(scope))
82 .map(|it| it.name().to_string())
83 .collect::<Vec<_>>()
84 .join("\n");
85 let expected = expected.join("\n");
86 assert_eq_text!(&expected, &actual);
87 } 66 }
88 67
89 #[test] 68 pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) {
90 fn test_lambda_scope() { 69 let body = self.func.body(db);
91 do_check(
92 r"
93 fn quux(foo: i32) {
94 let f = |bar, baz: i32| {
95 <|>
96 };
97 }",
98 &["bar", "baz", "foo"],
99 );
100 }
101 70
102 #[test] 71 for e in body.exprs() {
103 fn test_call_scope() { 72 if let (id, Expr::RecordLit { path, fields, spread }) = e {
104 do_check( 73 self.validate_record_literal(id, path, fields, *spread, db);
105 r" 74 }
106 fn quux() { 75 }
107 f(|x| <|> );
108 }",
109 &["x"],
110 );
111 }
112 76
113 #[test] 77 let body_expr = &body[body.body_expr()];
114 fn test_method_call_scope() { 78 if let Expr::Block { statements: _, tail: Some(t) } = body_expr {
115 do_check( 79 self.validate_results_in_tail_expr(body.body_expr(), *t, db);
116 r" 80 }
117 fn quux() {
118 z.f(|x| <|> );
119 }",
120 &["x"],
121 );
122 } 81 }
123 82
124 #[test] 83 fn validate_record_literal(
125 fn test_loop_scope() { 84 &mut self,
126 do_check( 85 id: ExprId,
127 r" 86 _path: &Option<Path>,
128 fn quux() { 87 fields: &[RecordLitField],
129 loop { 88 spread: Option<ExprId>,
130 let x = (); 89 db: &impl HirDatabase,
131 <|> 90 ) {
132 }; 91 if spread.is_some() {
133 }", 92 return;
134 &["x"], 93 }
135 ); 94
136 } 95 let struct_def = match self.infer[id].as_adt() {
96 Some((Adt::Struct(s), _)) => s,
97 _ => return,
98 };
137 99
138 #[test] 100 let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
139 fn test_match() { 101 let missed_fields: Vec<Name> = struct_def
140 do_check( 102 .fields(db)
141 r" 103 .iter()
142 fn quux() { 104 .filter_map(|f| {
143 match () { 105 let name = f.name(db);
144 Some(x) => { 106 if lit_fields.contains(&name) {
145 <|> 107 None
108 } else {
109 Some(name)
110 }
111 })
112 .collect();
113 if missed_fields.is_empty() {
114 return;
115 }
116 let source_map = self.func.body_source_map(db);
117
118 if let Some(source_ptr) = source_map.expr_syntax(id) {
119 if let Some(expr) = source_ptr.ast.a() {
120 let root = source_ptr.file_syntax(db);
121 if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) {
122 if let Some(field_list) = record_lit.record_field_list() {
123 self.sink.push(MissingFields {
124 file: source_ptr.file_id,
125 field_list: AstPtr::new(&field_list),
126 missed_fields,
127 })
146 } 128 }
147 }; 129 }
148 }", 130 }
149 &["x"], 131 }
150 );
151 }
152
153 #[test]
154 fn test_shadow_variable() {
155 do_check(
156 r"
157 fn foo(x: String) {
158 let x : &str = &x<|>;
159 }",
160 &["x"],
161 );
162 } 132 }
163 133
164 fn do_check_local_name(code: &str, expected_offset: u32) { 134 fn validate_results_in_tail_expr(
165 let (off, code) = extract_offset(code); 135 &mut self,
166 136 body_id: ExprId,
167 let (db, file_id) = TestDB::with_single_file(&code); 137 id: ExprId,
168 let file = db.parse(file_id).ok().unwrap(); 138 db: &impl HirDatabase,
169 let expected_name = find_node_at_offset::<ast::Name>(file.syntax(), expected_offset.into()) 139 ) {
170 .expect("failed to find a name at the target offset"); 140 // the mismatch will be on the whole block currently
171 let name_ref: ast::NameRef = find_node_at_offset(file.syntax(), off).unwrap(); 141 let mismatch = match self.infer.type_mismatch_for_expr(body_id) {
172 let analyzer = SourceAnalyzer::new(&db, file_id, name_ref.syntax(), None); 142 Some(m) => m,
143 None => return,
144 };
173 145
174 let local_name_entry = analyzer.resolve_local_name(&name_ref).unwrap(); 146 let std_result_path = known::std_result_result();
175 let local_name =
176 local_name_entry.ptr().either(|it| it.syntax_node_ptr(), |it| it.syntax_node_ptr());
177 assert_eq!(local_name.range(), expected_name.syntax().text_range());
178 }
179 147
180 #[test] 148 let resolver = self.func.resolver(db);
181 fn test_resolve_local_name() { 149 let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) {
182 do_check_local_name( 150 Some(it) => it,
183 r#" 151 _ => return,
184 fn foo(x: i32, y: u32) { 152 };
185 {
186 let z = x * 2;
187 }
188 {
189 let t = x<|> * 3;
190 }
191 }"#,
192 21,
193 );
194 }
195 153
196 #[test] 154 let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum));
197 fn test_resolve_local_name_declaration() { 155 let params = match &mismatch.expected {
198 do_check_local_name( 156 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters,
199 r#" 157 _ => return,
200 fn foo(x: String) { 158 };
201 let x : &str = &x<|>;
202 }"#,
203 21,
204 );
205 }
206 159
207 #[test] 160 if params.len() == 2 && &params[0] == &mismatch.actual {
208 fn test_resolve_local_name_shadow() { 161 let source_map = self.func.body_source_map(db);
209 do_check_local_name(
210 r"
211 fn foo(x: String) {
212 let x : &str = &x;
213 x<|>
214 }
215 ",
216 53,
217 );
218 }
219 162
220 #[test] 163 if let Some(source_ptr) = source_map.expr_syntax(id) {
221 fn ref_patterns_contribute_bindings() { 164 if let Some(expr) = source_ptr.ast.a() {
222 do_check_local_name( 165 self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr });
223 r"
224 fn foo() {
225 if let Some(&from) = bar() {
226 from<|>;
227 } 166 }
228 } 167 }
229 ", 168 }
230 53,
231 );
232 } 169 }
233} 170}
diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs
deleted file mode 100644
index 3054f1dce..000000000
--- a/crates/ra_hir/src/expr/validation.rs
+++ /dev/null
@@ -1,137 +0,0 @@
1//! FIXME: write short doc here
2
3use std::sync::Arc;
4
5use hir_def::path::known;
6use hir_expand::diagnostics::DiagnosticSink;
7use ra_syntax::ast;
8use rustc_hash::FxHashSet;
9
10use crate::{
11 db::HirDatabase,
12 diagnostics::{MissingFields, MissingOkInTailExpr},
13 expr::AstPtr,
14 ty::{ApplicationTy, InferenceResult, Ty, TypeCtor},
15 Adt, Function, Name, Path,
16};
17
18use super::{Expr, ExprId, RecordLitField};
19
20pub(crate) struct ExprValidator<'a, 'b: 'a> {
21 func: Function,
22 infer: Arc<InferenceResult>,
23 sink: &'a mut DiagnosticSink<'b>,
24}
25
26impl<'a, 'b> ExprValidator<'a, 'b> {
27 pub(crate) fn new(
28 func: Function,
29 infer: Arc<InferenceResult>,
30 sink: &'a mut DiagnosticSink<'b>,
31 ) -> ExprValidator<'a, 'b> {
32 ExprValidator { func, infer, sink }
33 }
34
35 pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) {
36 let body = self.func.body(db);
37
38 for e in body.exprs() {
39 if let (id, Expr::RecordLit { path, fields, spread }) = e {
40 self.validate_record_literal(id, path, fields, *spread, db);
41 }
42 }
43
44 let body_expr = &body[body.body_expr()];
45 if let Expr::Block { statements: _, tail: Some(t) } = body_expr {
46 self.validate_results_in_tail_expr(body.body_expr(), *t, db);
47 }
48 }
49
50 fn validate_record_literal(
51 &mut self,
52 id: ExprId,
53 _path: &Option<Path>,
54 fields: &[RecordLitField],
55 spread: Option<ExprId>,
56 db: &impl HirDatabase,
57 ) {
58 if spread.is_some() {
59 return;
60 }
61
62 let struct_def = match self.infer[id].as_adt() {
63 Some((Adt::Struct(s), _)) => s,
64 _ => return,
65 };
66
67 let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
68 let missed_fields: Vec<Name> = struct_def
69 .fields(db)
70 .iter()
71 .filter_map(|f| {
72 let name = f.name(db);
73 if lit_fields.contains(&name) {
74 None
75 } else {
76 Some(name)
77 }
78 })
79 .collect();
80 if missed_fields.is_empty() {
81 return;
82 }
83 let source_map = self.func.body_source_map(db);
84
85 if let Some(source_ptr) = source_map.expr_syntax(id) {
86 if let Some(expr) = source_ptr.ast.a() {
87 let root = source_ptr.file_syntax(db);
88 if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) {
89 if let Some(field_list) = record_lit.record_field_list() {
90 self.sink.push(MissingFields {
91 file: source_ptr.file_id,
92 field_list: AstPtr::new(&field_list),
93 missed_fields,
94 })
95 }
96 }
97 }
98 }
99 }
100
101 fn validate_results_in_tail_expr(
102 &mut self,
103 body_id: ExprId,
104 id: ExprId,
105 db: &impl HirDatabase,
106 ) {
107 // the mismatch will be on the whole block currently
108 let mismatch = match self.infer.type_mismatch_for_expr(body_id) {
109 Some(m) => m,
110 None => return,
111 };
112
113 let std_result_path = known::std_result_result();
114
115 let resolver = self.func.resolver(db);
116 let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) {
117 Some(it) => it,
118 _ => return,
119 };
120
121 let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum));
122 let params = match &mismatch.expected {
123 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters,
124 _ => return,
125 };
126
127 if params.len() == 2 && &params[0] == &mismatch.actual {
128 let source_map = self.func.body_source_map(db);
129
130 if let Some(source_ptr) = source_map.expr_syntax(id) {
131 if let Some(expr) = source_ptr.ast.a() {
132 self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr });
133 }
134 }
135 }
136 }
137}
diff --git a/crates/ra_hir/src/from_source.rs b/crates/ra_hir/src/from_source.rs
index 9793af858..7e5523c54 100644
--- a/crates/ra_hir/src/from_source.rs
+++ b/crates/ra_hir/src/from_source.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir_def::{StructId, StructOrUnionId, UnionId}; 3use hir_def::{ModuleId, StructId, StructOrUnionId, UnionId};
4use hir_expand::name::AsName; 4use hir_expand::name::AsName;
5use ra_syntax::{ 5use ra_syntax::{
6 ast::{self, AstNode, NameOwner}, 6 ast::{self, AstNode, NameOwner},
@@ -10,9 +10,9 @@ use ra_syntax::{
10use crate::{ 10use crate::{
11 db::{AstDatabase, DefDatabase, HirDatabase}, 11 db::{AstDatabase, DefDatabase, HirDatabase},
12 ids::{AstItemDef, LocationCtx}, 12 ids::{AstItemDef, LocationCtx},
13 AstId, Const, Crate, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, 13 Const, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource, ImplBlock,
14 ImplBlock, Local, Module, ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, 14 Local, Module, ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, Union,
15 Union, VariantDef, 15 VariantDef,
16}; 16};
17 17
18pub trait FromSource: Sized { 18pub trait FromSource: Sized {
@@ -152,44 +152,48 @@ impl Local {
152} 152}
153 153
154impl Module { 154impl Module {
155 pub fn from_declaration(db: &impl HirDatabase, src: Source<ast::Module>) -> Option<Self> { 155 pub fn from_declaration(db: &impl DefDatabase, src: Source<ast::Module>) -> Option<Self> {
156 let src_parent = Source { 156 let parent_declaration = src.ast.syntax().ancestors().skip(1).find_map(ast::Module::cast);
157 file_id: src.file_id, 157
158 ast: ModuleSource::new(db, Some(src.file_id.original_file(db)), None), 158 let parent_module = match parent_declaration {
159 }; 159 Some(parent_declaration) => {
160 let parent_module = Module::from_definition(db, src_parent)?; 160 let src_parent = Source { file_id: src.file_id, ast: parent_declaration };
161 Module::from_declaration(db, src_parent)
162 }
163 _ => {
164 let src_parent = Source {
165 file_id: src.file_id,
166 ast: ModuleSource::new(db, Some(src.file_id.original_file(db)), None),
167 };
168 Module::from_definition(db, src_parent)
169 }
170 }?;
171
161 let child_name = src.ast.name()?; 172 let child_name = src.ast.name()?;
162 parent_module.child(db, &child_name.as_name()) 173 parent_module.child(db, &child_name.as_name())
163 } 174 }
164 175
165 pub fn from_definition( 176 pub fn from_definition(db: &impl DefDatabase, src: Source<ModuleSource>) -> Option<Self> {
166 db: &(impl DefDatabase + AstDatabase), 177 match src.ast {
167 src: Source<ModuleSource>,
168 ) -> Option<Self> {
169 let decl_id = match src.ast {
170 ModuleSource::Module(ref module) => { 178 ModuleSource::Module(ref module) => {
171 assert!(!module.has_semi()); 179 assert!(!module.has_semi());
172 let ast_id_map = db.ast_id_map(src.file_id); 180 return Module::from_declaration(
173 let item_id = AstId::new(src.file_id, ast_id_map.ast_id(module)); 181 db,
174 Some(item_id) 182 Source { file_id: src.file_id, ast: module.clone() },
183 );
175 } 184 }
176 ModuleSource::SourceFile(_) => None, 185 ModuleSource::SourceFile(_) => (),
177 }; 186 };
178 187
179 db.relevant_crates(src.file_id.original_file(db)).iter().find_map(|&crate_id| { 188 let original_file = src.file_id.original_file(db);
180 let def_map = db.crate_def_map(crate_id);
181
182 let (module_id, _module_data) =
183 def_map.modules.iter().find(|(_module_id, module_data)| {
184 if decl_id.is_some() {
185 module_data.declaration == decl_id
186 } else {
187 module_data.definition.map(|it| it.into()) == Some(src.file_id)
188 }
189 })?;
190 189
191 Some(Module::new(Crate { crate_id }, module_id)) 190 let (krate, module_id) =
192 }) 191 db.relevant_crates(original_file).iter().find_map(|&crate_id| {
192 let crate_def_map = db.crate_def_map(crate_id);
193 let local_module_id = crate_def_map.modules_for_file(original_file).next()?;
194 Some((crate_id, local_module_id))
195 })?;
196 Some(Module { id: ModuleId { krate, module_id } })
193 } 197 }
194} 198}
195 199
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 2f3e12eb8..2fb913108 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -16,8 +16,8 @@ use crate::{
16 expr::{ExprScopes, PatId, ScopeId}, 16 expr::{ExprScopes, PatId, ScopeId},
17 generics::GenericParams, 17 generics::GenericParams,
18 impl_block::ImplBlock, 18 impl_block::ImplBlock,
19 Adt, Const, Enum, EnumVariant, Function, MacroDef, ModuleDef, PerNs, Static, Struct, Trait, 19 Adt, Const, DefWithBody, Enum, EnumVariant, Function, Local, MacroDef, ModuleDef, PerNs,
20 TypeAlias, 20 Static, Struct, Trait, TypeAlias,
21}; 21};
22 22
23#[derive(Debug, Clone, Default)] 23#[derive(Debug, Clone, Default)]
@@ -34,6 +34,7 @@ pub(crate) struct ModuleItemMap {
34 34
35#[derive(Debug, Clone)] 35#[derive(Debug, Clone)]
36pub(crate) struct ExprScope { 36pub(crate) struct ExprScope {
37 owner: DefWithBody,
37 expr_scopes: Arc<ExprScopes>, 38 expr_scopes: Arc<ExprScopes>,
38 scope_id: ScopeId, 39 scope_id: ScopeId,
39} 40}
@@ -53,7 +54,7 @@ pub(crate) enum Scope {
53} 54}
54 55
55#[derive(Debug, Clone, PartialEq, Eq, Hash)] 56#[derive(Debug, Clone, PartialEq, Eq, Hash)]
56pub enum TypeNs { 57pub(crate) enum TypeNs {
57 SelfType(ImplBlock), 58 SelfType(ImplBlock),
58 GenericParam(u32), 59 GenericParam(u32),
59 Adt(Adt), 60 Adt(Adt),
@@ -68,13 +69,13 @@ pub enum TypeNs {
68} 69}
69 70
70#[derive(Debug, Clone, PartialEq, Eq, Hash)] 71#[derive(Debug, Clone, PartialEq, Eq, Hash)]
71pub enum ResolveValueResult { 72pub(crate) enum ResolveValueResult {
72 ValueNs(ValueNs), 73 ValueNs(ValueNs),
73 Partial(TypeNs, usize), 74 Partial(TypeNs, usize),
74} 75}
75 76
76#[derive(Debug, Clone, PartialEq, Eq, Hash)] 77#[derive(Debug, Clone, PartialEq, Eq, Hash)]
77pub enum ValueNs { 78pub(crate) enum ValueNs {
78 LocalBinding(PatId), 79 LocalBinding(PatId),
79 Function(Function), 80 Function(Function),
80 Const(Const), 81 Const(Const),
@@ -399,10 +400,11 @@ impl Resolver {
399 400
400 pub(crate) fn push_expr_scope( 401 pub(crate) fn push_expr_scope(
401 self, 402 self,
403 owner: DefWithBody,
402 expr_scopes: Arc<ExprScopes>, 404 expr_scopes: Arc<ExprScopes>,
403 scope_id: ScopeId, 405 scope_id: ScopeId,
404 ) -> Resolver { 406 ) -> Resolver {
405 self.push_scope(Scope::ExprScope(ExprScope { expr_scopes, scope_id })) 407 self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id }))
406 } 408 }
407} 409}
408 410
@@ -413,7 +415,7 @@ pub enum ScopeDef {
413 GenericParam(u32), 415 GenericParam(u32),
414 ImplSelfType(ImplBlock), 416 ImplSelfType(ImplBlock),
415 AdtSelfType(Adt), 417 AdtSelfType(Adt),
416 LocalBinding(PatId), 418 Local(Local),
417 Unknown, 419 Unknown,
418} 420}
419 421
@@ -467,9 +469,10 @@ impl Scope {
467 Scope::AdtScope(i) => { 469 Scope::AdtScope(i) => {
468 f(name::SELF_TYPE, ScopeDef::AdtSelfType(*i)); 470 f(name::SELF_TYPE, ScopeDef::AdtSelfType(*i));
469 } 471 }
470 Scope::ExprScope(e) => { 472 Scope::ExprScope(scope) => {
471 e.expr_scopes.entries(e.scope_id).iter().for_each(|e| { 473 scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| {
472 f(e.name().clone(), ScopeDef::LocalBinding(e.pat())); 474 let local = Local { parent: scope.owner, pat_id: e.pat() };
475 f(e.name().clone(), ScopeDef::Local(local));
473 }); 476 });
474 } 477 }
475 } 478 }
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs
index ca40e3b54..662d3f880 100644
--- a/crates/ra_hir/src/source_binder.rs
+++ b/crates/ra_hir/src/source_binder.rs
@@ -19,7 +19,6 @@ use ra_syntax::{
19 SyntaxKind::*, 19 SyntaxKind::*,
20 SyntaxNode, SyntaxNodePtr, TextRange, TextUnit, 20 SyntaxNode, SyntaxNodePtr, TextRange, TextUnit,
21}; 21};
22use rustc_hash::FxHashSet;
23 22
24use crate::{ 23use crate::{
25 db::HirDatabase, 24 db::HirDatabase,
@@ -195,14 +194,6 @@ impl SourceAnalyzer {
195 Some(self.infer.as_ref()?[pat_id].clone()) 194 Some(self.infer.as_ref()?[pat_id].clone())
196 } 195 }
197 196
198 pub fn type_of_pat_by_id(
199 &self,
200 _db: &impl HirDatabase,
201 pat_id: expr::PatId,
202 ) -> Option<crate::Ty> {
203 Some(self.infer.as_ref()?[pat_id].clone())
204 }
205
206 pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { 197 pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> {
207 let expr_id = self.expr_id(&call.clone().into())?; 198 let expr_id = self.expr_id(&call.clone().into())?;
208 self.infer.as_ref()?.method_resolution(expr_id) 199 self.infer.as_ref()?.method_resolution(expr_id)
@@ -293,23 +284,15 @@ impl SourceAnalyzer {
293 self.resolve_hir_path(db, &hir_path) 284 self.resolve_hir_path(db, &hir_path)
294 } 285 }
295 286
296 pub fn resolve_local_name(&self, name_ref: &ast::NameRef) -> Option<ScopeEntryWithSyntax> { 287 fn resolve_local_name(&self, name_ref: &ast::NameRef) -> Option<ScopeEntryWithSyntax> {
297 let mut shadowed = FxHashSet::default();
298 let name = name_ref.as_name(); 288 let name = name_ref.as_name();
299 let source_map = self.body_source_map.as_ref()?; 289 let source_map = self.body_source_map.as_ref()?;
300 let scopes = self.scopes.as_ref()?; 290 let scopes = self.scopes.as_ref()?;
301 let scope = scope_for(scopes, source_map, self.file_id.into(), name_ref.syntax()); 291 let scope = scope_for(scopes, source_map, self.file_id.into(), name_ref.syntax())?;
302 let ret = scopes 292 let entry = scopes.resolve_name_in_scope(scope, &name)?;
303 .scope_chain(scope) 293 Some(ScopeEntryWithSyntax {
304 .flat_map(|scope| scopes.entries(scope).iter()) 294 name: entry.name().clone(),
305 .filter(|entry| shadowed.insert(entry.name())) 295 ptr: source_map.pat_syntax(entry.pat())?.ast,
306 .filter(|entry| entry.name() == &name)
307 .nth(0);
308 ret.and_then(|entry| {
309 Some(ScopeEntryWithSyntax {
310 name: entry.name().clone(),
311 ptr: source_map.pat_syntax(entry.pat())?.ast,
312 })
313 }) 296 })
314 } 297 }
315 298
@@ -317,9 +300,9 @@ impl SourceAnalyzer {
317 self.resolver.process_all_names(db, f) 300 self.resolver.process_all_names(db, f)
318 } 301 }
319 302
303 // FIXME: we only use this in `inline_local_variable` assist, ideally, we
304 // should switch to general reference search infra there.
320 pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> { 305 pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec<ReferenceDescriptor> {
321 // FIXME: at least, this should work with any DefWithBody, but ideally
322 // this should be hir-based altogether
323 let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); 306 let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap();
324 let ptr = Either::A(AstPtr::new(&ast::Pat::from(pat.clone()))); 307 let ptr = Either::A(AstPtr::new(&ast::Pat::from(pat.clone())));
325 fn_def 308 fn_def
@@ -421,11 +404,6 @@ impl SourceAnalyzer {
421 pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> { 404 pub(crate) fn inference_result(&self) -> Arc<crate::ty::InferenceResult> {
422 self.infer.clone().unwrap() 405 self.infer.clone().unwrap()
423 } 406 }
424
425 #[cfg(test)]
426 pub(crate) fn scopes(&self) -> Arc<ExprScopes> {
427 self.scopes.clone().unwrap()
428 }
429} 407}
430 408
431fn scope_for( 409fn scope_for(
diff --git a/crates/ra_hir/src/test_db.rs b/crates/ra_hir/src/test_db.rs
index 5237b303a..1caa2e875 100644
--- a/crates/ra_hir/src/test_db.rs
+++ b/crates/ra_hir/src/test_db.rs
@@ -81,7 +81,7 @@ impl TestDB {
81 let crate_graph = self.crate_graph(); 81 let crate_graph = self.crate_graph();
82 for krate in crate_graph.iter().next() { 82 for krate in crate_graph.iter().next() {
83 let crate_def_map = self.crate_def_map(krate); 83 let crate_def_map = self.crate_def_map(krate);
84 for (module_id, _) in crate_def_map.modules.iter() { 84 for module_id in crate_def_map.modules() {
85 let module_id = ModuleId { krate, module_id }; 85 let module_id = ModuleId { krate, module_id };
86 let module = crate::Module::from(module_id); 86 let module = crate::Module::from(module_id);
87 module.diagnostics( 87 module.diagnostics(
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 8863c3608..fe9346c78 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -254,7 +254,6 @@ fn test(a: u32, b: isize, c: !, d: &str) {
254 1.0f32; 254 1.0f32;
255}"#), 255}"#),
256 @r###" 256 @r###"
257
258 [9; 10) 'a': u32 257 [9; 10) 'a': u32
259 [17; 18) 'b': isize 258 [17; 18) 'b': isize
260 [27; 28) 'c': ! 259 [27; 28) 'c': !
@@ -317,7 +316,6 @@ fn test() {
317} 316}
318"#), 317"#),
319 @r###" 318 @r###"
320
321 [15; 20) '{ 1 }': u32 319 [15; 20) '{ 1 }': u32
322 [17; 18) '1': u32 320 [17; 18) '1': u32
323 [48; 53) '{ 1 }': u32 321 [48; 53) '{ 1 }': u32
@@ -354,7 +352,7 @@ fn test() {
354 [66; 74) 'S::foo()': i32 352 [66; 74) 'S::foo()': i32
355 [80; 88) '<S>::foo': fn foo() -> i32 353 [80; 88) '<S>::foo': fn foo() -> i32
356 [80; 90) '<S>::foo()': i32 354 [80; 90) '<S>::foo()': i32
357"### 355 "###
358 ); 356 );
359} 357}
360 358
@@ -409,7 +407,6 @@ fn test() {
409} 407}
410"#), 408"#),
411 @r###" 409 @r###"
412
413 [72; 154) '{ ...a.c; }': () 410 [72; 154) '{ ...a.c; }': ()
414 [82; 83) 'c': C 411 [82; 83) 'c': C
415 [86; 87) 'C': C(usize) -> C 412 [86; 87) 'C': C(usize) -> C
@@ -443,7 +440,6 @@ fn test() {
443 E::V2; 440 E::V2;
444}"#), 441}"#),
445 @r###" 442 @r###"
446
447 [48; 82) '{ E:...:V2; }': () 443 [48; 82) '{ E:...:V2; }': ()
448 [52; 70) 'E::V1 ...d: 1 }': E 444 [52; 70) 'E::V1 ...d: 1 }': E
449 [67; 68) '1': u32 445 [67; 68) '1': u32
@@ -471,7 +467,6 @@ fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) {
471} 467}
472"#), 468"#),
473 @r###" 469 @r###"
474
475 [9; 10) 'a': &u32 470 [9; 10) 'a': &u32
476 [18; 19) 'b': &mut u32 471 [18; 19) 'b': &mut u32
477 [31; 32) 'c': *const u32 472 [31; 32) 'c': *const u32
@@ -524,7 +519,6 @@ fn test() {
524} 519}
525"##), 520"##),
526 @r###" 521 @r###"
527
528 [11; 221) '{ ...o"#; }': () 522 [11; 221) '{ ...o"#; }': ()
529 [17; 21) '5i32': i32 523 [17; 21) '5i32': i32
530 [27; 31) '5f32': f32 524 [27; 31) '5f32': f32
@@ -568,7 +562,6 @@ fn test(x: SomeType) {
568} 562}
569"#), 563"#),
570 @r###" 564 @r###"
571
572 [27; 28) 'x': SomeType 565 [27; 28) 'x': SomeType
573 [40; 272) '{ ...lo"; }': () 566 [40; 272) '{ ...lo"; }': ()
574 [50; 51) 'b': bool 567 [50; 51) 'b': bool
@@ -632,7 +625,6 @@ fn test() -> &mut &f64 {
632} 625}
633"#), 626"#),
634 @r###" 627 @r###"
635
636 [14; 15) 'x': u32 628 [14; 15) 'x': u32
637 [22; 24) '{}': () 629 [22; 24) '{}': ()
638 [78; 231) '{ ...t &c }': &mut &f64 630 [78; 231) '{ ...t &c }': &mut &f64
@@ -679,7 +671,6 @@ impl S {
679} 671}
680"#), 672"#),
681 @r###" 673 @r###"
682
683 [34; 38) 'self': &S 674 [34; 38) 'self': &S
684 [40; 61) '{ ... }': () 675 [40; 61) '{ ... }': ()
685 [50; 54) 'self': &S 676 [50; 54) 'self': &S
@@ -719,7 +710,6 @@ fn test() -> bool {
719} 710}
720"#), 711"#),
721 @r###" 712 @r###"
722
723 [6; 7) 'x': bool 713 [6; 7) 'x': bool
724 [22; 34) '{ 0i32 }': i32 714 [22; 34) '{ 0i32 }': i32
725 [28; 32) '0i32': i32 715 [28; 32) '0i32': i32
@@ -802,7 +792,6 @@ fn test2(a1: *const A, a2: *mut A) {
802} 792}
803"#), 793"#),
804 @r###" 794 @r###"
805
806 [44; 45) 'a': A 795 [44; 45) 'a': A
807 [50; 213) '{ ...5.b; }': () 796 [50; 213) '{ ...5.b; }': ()
808 [60; 62) 'a1': A 797 [60; 62) 'a1': A
@@ -970,7 +959,7 @@ fn test(a: A<i32>) {
970 [374; 375) 'B': B<A<i32>>(T) -> B<T> 959 [374; 375) 'B': B<A<i32>>(T) -> B<T>
971 [374; 378) 'B(a)': B<A<i32>> 960 [374; 378) 'B(a)': B<A<i32>>
972 [376; 377) 'a': A<i32> 961 [376; 377) 'a': A<i32>
973"### 962 "###
974 ); 963 );
975} 964}
976 965
@@ -983,7 +972,6 @@ fn test() {
983} 972}
984"#), 973"#),
985 @r###" 974 @r###"
986
987 [11; 37) '{ l... {}; }': () 975 [11; 37) '{ l... {}; }': ()
988 [20; 21) 'x': () 976 [20; 21) 'x': ()
989 [24; 34) 'if true {}': () 977 [24; 34) 'if true {}': ()
@@ -1105,7 +1093,6 @@ fn test(a: A) {
1105} 1093}
1106"#), 1094"#),
1107 @r###" 1095 @r###"
1108
1109 [32; 36) 'self': A 1096 [32; 36) 'self': A
1110 [38; 39) 'x': u32 1097 [38; 39) 'x': u32
1111 [53; 55) '{}': () 1098 [53; 55) '{}': ()
@@ -1142,7 +1129,6 @@ fn test() {
1142} 1129}
1143"#), 1130"#),
1144 @r###" 1131 @r###"
1145
1146 [40; 44) 'self': &str 1132 [40; 44) 'self': &str
1147 [53; 55) '{}': () 1133 [53; 55) '{}': ()
1148 [69; 89) '{ ...o(); }': () 1134 [69; 89) '{ ...o(); }': ()
@@ -1166,7 +1152,6 @@ fn test(x: &str, y: isize) {
1166} 1152}
1167"#), 1153"#),
1168 @r###" 1154 @r###"
1169
1170 [9; 10) 'x': &str 1155 [9; 10) 'x': &str
1171 [18; 19) 'y': isize 1156 [18; 19) 'y': isize
1172 [28; 170) '{ ...d"); }': () 1157 [28; 170) '{ ...d"); }': ()
@@ -1367,7 +1352,6 @@ fn test() {
1367} 1352}
1368"#), 1353"#),
1369 @r###" 1354 @r###"
1370
1371 [28; 79) '{ ...(1); }': () 1355 [28; 79) '{ ...(1); }': ()
1372 [38; 42) 'A(n)': A<i32> 1356 [38; 42) 'A(n)': A<i32>
1373 [40; 41) 'n': &i32 1357 [40; 41) 'n': &i32
@@ -1396,7 +1380,6 @@ fn test() {
1396} 1380}
1397"#), 1381"#),
1398 @r###" 1382 @r###"
1399
1400 [11; 57) '{ ...= v; }': () 1383 [11; 57) '{ ...= v; }': ()
1401 [21; 22) 'v': &(i32, &i32) 1384 [21; 22) 'v': &(i32, &i32)
1402 [25; 33) '&(1, &2)': &(i32, &i32) 1385 [25; 33) '&(1, &2)': &(i32, &i32)
@@ -1441,7 +1424,6 @@ fn test() {
1441} 1424}
1442"#), 1425"#),
1443 @r###" 1426 @r###"
1444
1445 [68; 289) '{ ... d; }': () 1427 [68; 289) '{ ... d; }': ()
1446 [78; 79) 'e': E 1428 [78; 79) 'e': E
1447 [82; 95) 'E::A { x: 3 }': E 1429 [82; 95) 'E::A { x: 3 }': E
@@ -1488,7 +1470,6 @@ fn test(a1: A<u32>, i: i32) {
1488} 1470}
1489"#), 1471"#),
1490 @r###" 1472 @r###"
1491
1492 [36; 38) 'a1': A<u32> 1473 [36; 38) 'a1': A<u32>
1493 [48; 49) 'i': i32 1474 [48; 49) 'i': i32
1494 [56; 147) '{ ...3.x; }': () 1475 [56; 147) '{ ...3.x; }': ()
@@ -1569,7 +1550,6 @@ fn test(a1: A<u32>, o: Option<u64>) {
1569} 1550}
1570"#), 1551"#),
1571 @r###" 1552 @r###"
1572
1573 [79; 81) 'a1': A<u32> 1553 [79; 81) 'a1': A<u32>
1574 [91; 92) 'o': Option<u64> 1554 [91; 92) 'o': Option<u64>
1575 [107; 244) '{ ... }; }': () 1555 [107; 244) '{ ... }; }': ()
@@ -1604,7 +1584,6 @@ fn test() {
1604} 1584}
1605"#), 1585"#),
1606 @r###" 1586 @r###"
1607
1608 [10; 11) 't': T 1587 [10; 11) 't': T
1609 [21; 26) '{ t }': T 1588 [21; 26) '{ t }': T
1610 [23; 24) 't': T 1589 [23; 24) 't': T
@@ -1652,7 +1631,6 @@ fn test() -> i128 {
1652} 1631}
1653"#), 1632"#),
1654 @r###" 1633 @r###"
1655
1656 [74; 78) 'self': A<X, Y> 1634 [74; 78) 'self': A<X, Y>
1657 [85; 107) '{ ... }': X 1635 [85; 107) '{ ... }': X
1658 [95; 99) 'self': A<X, Y> 1636 [95; 99) 'self': A<X, Y>
@@ -1706,7 +1684,6 @@ fn test(o: Option<u32>) {
1706} 1684}
1707"#), 1685"#),
1708 @r###" 1686 @r###"
1709
1710 [78; 82) 'self': &Option<T> 1687 [78; 82) 'self': &Option<T>
1711 [98; 100) '{}': () 1688 [98; 100) '{}': ()
1712 [111; 112) 'o': Option<u32> 1689 [111; 112) 'o': Option<u32>
@@ -1744,7 +1721,6 @@ fn test() -> i128 {
1744} 1721}
1745"#), 1722"#),
1746 @r###" 1723 @r###"
1747
1748 [53; 57) 'self': A<T2> 1724 [53; 57) 'self': A<T2>
1749 [65; 87) '{ ... }': T2 1725 [65; 87) '{ ... }': T2
1750 [75; 79) 'self': A<T2> 1726 [75; 79) 'self': A<T2>
@@ -1921,7 +1897,6 @@ fn test() {
1921} 1897}
1922"#), 1898"#),
1923 @r###" 1899 @r###"
1924
1925 [56; 64) '{ A {} }': A 1900 [56; 64) '{ A {} }': A
1926 [58; 62) 'A {}': A 1901 [58; 62) 'A {}': A
1927 [126; 132) '{ 99 }': u32 1902 [126; 132) '{ 99 }': u32
@@ -1961,7 +1936,6 @@ fn test() {
1961} 1936}
1962"#), 1937"#),
1963 @r###" 1938 @r###"
1964
1965 [64; 67) 'val': T 1939 [64; 67) 'val': T
1966 [82; 109) '{ ... }': Gen<T> 1940 [82; 109) '{ ... }': Gen<T>
1967 [92; 103) 'Gen { val }': Gen<T> 1941 [92; 103) 'Gen { val }': Gen<T>
@@ -2129,7 +2103,6 @@ fn test(x: X) {
2129} 2103}
2130"#), 2104"#),
2131 @r###" 2105 @r###"
2132
2133 [20; 21) 'x': X 2106 [20; 21) 'x': X
2134 [26; 47) '{ ...eld; }': () 2107 [26; 47) '{ ...eld; }': ()
2135 [32; 33) 'x': X 2108 [32; 33) 'x': X
@@ -2151,7 +2124,6 @@ fn test() {
2151} 2124}
2152"#), 2125"#),
2153 @r###" 2126 @r###"
2154
2155 [11; 89) '{ ... } }': () 2127 [11; 89) '{ ... } }': ()
2156 [17; 21) 'X {}': {unknown} 2128 [17; 21) 'X {}': {unknown}
2157 [27; 87) 'match ... }': () 2129 [27; 87) 'match ... }': ()
@@ -2174,7 +2146,6 @@ fn quux() {
2174} 2146}
2175"#), 2147"#),
2176 @r###" 2148 @r###"
2177
2178 [11; 41) '{ ...+ y; }': () 2149 [11; 41) '{ ...+ y; }': ()
2179 [21; 22) 'y': i32 2150 [21; 22) 'y': i32
2180 [25; 27) '92': i32 2151 [25; 27) '92': i32
@@ -2300,7 +2271,6 @@ fn write() {
2300} 2271}
2301"#), 2272"#),
2302 @r###" 2273 @r###"
2303
2304 [54; 139) '{ ... } }': () 2274 [54; 139) '{ ... } }': ()
2305 [60; 137) 'match ... }': () 2275 [60; 137) 'match ... }': ()
2306 [66; 83) 'someth...nknown': Maybe<{unknown}> 2276 [66; 83) 'someth...nknown': Maybe<{unknown}>
@@ -2322,7 +2292,6 @@ fn test_line_buffer() {
2322} 2292}
2323"#), 2293"#),
2324 @r###" 2294 @r###"
2325
2326 [23; 53) '{ ...n']; }': () 2295 [23; 53) '{ ...n']; }': ()
2327 [29; 50) '&[0, b...b'\n']': &[u8;_] 2296 [29; 50) '&[0, b...b'\n']': &[u8;_]
2328 [30; 50) '[0, b'...b'\n']': [u8;_] 2297 [30; 50) '[0, b'...b'\n']': [u8;_]
@@ -2446,7 +2415,6 @@ fn test<R>(query_response: Canonical<QueryResponse<R>>) {
2446} 2415}
2447"#), 2416"#),
2448 @r###" 2417 @r###"
2449
2450 [92; 106) 'query_response': Canonical<QueryResponse<R>> 2418 [92; 106) 'query_response': Canonical<QueryResponse<R>>
2451 [137; 167) '{ ...lue; }': () 2419 [137; 167) '{ ...lue; }': ()
2452 [143; 164) '&query....value': &QueryResponse<R> 2420 [143; 164) '&query....value': &QueryResponse<R>
@@ -2472,7 +2440,6 @@ pub fn main_loop() {
2472} 2440}
2473"#), 2441"#),
2474 @r###" 2442 @r###"
2475
2476 [144; 146) '{}': () 2443 [144; 146) '{}': ()
2477 [169; 198) '{ ...t(); }': () 2444 [169; 198) '{ ...t(); }': ()
2478 [175; 193) 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<T, H> 2445 [175; 193) 'FxHash...efault': fn default<{unknown}, FxHasher>() -> HashSet<T, H>
@@ -2518,7 +2485,6 @@ fn test() {
2518} 2485}
2519"#), 2486"#),
2520 @r###" 2487 @r###"
2521
2522 [49; 50) '0': u32 2488 [49; 50) '0': u32
2523 [80; 83) '101': u32 2489 [80; 83) '101': u32
2524 [95; 213) '{ ...NST; }': () 2490 [95; 213) '{ ...NST; }': ()
@@ -2549,7 +2515,6 @@ fn test() {
2549} 2515}
2550"#), 2516"#),
2551 @r###" 2517 @r###"
2552
2553 [29; 32) '101': u32 2518 [29; 32) '101': u32
2554 [70; 73) '101': u32 2519 [70; 73) '101': u32
2555 [85; 280) '{ ...MUT; }': () 2520 [85; 280) '{ ...MUT; }': ()
@@ -2588,7 +2553,6 @@ fn test() {
2588} 2553}
2589"#), 2554"#),
2590 @r###" 2555 @r###"
2591
2592 [31; 35) 'self': &Self 2556 [31; 35) 'self': &Self
2593 [110; 114) 'self': &Self 2557 [110; 114) 'self': &Self
2594 [170; 228) '{ ...i128 }': () 2558 [170; 228) '{ ...i128 }': ()
@@ -2636,7 +2600,6 @@ mod bar_test {
2636} 2600}
2637"#), 2601"#),
2638 @r###" 2602 @r###"
2639
2640 [63; 67) 'self': &Self 2603 [63; 67) 'self': &Self
2641 [169; 173) 'self': &Self 2604 [169; 173) 'self': &Self
2642 [300; 337) '{ ... }': () 2605 [300; 337) '{ ... }': ()
@@ -2664,7 +2627,6 @@ fn test() {
2664} 2627}
2665"#), 2628"#),
2666 @r###" 2629 @r###"
2667
2668 [33; 37) 'self': &Self 2630 [33; 37) 'self': &Self
2669 [92; 111) '{ ...d(); }': () 2631 [92; 111) '{ ...d(); }': ()
2670 [98; 99) 'S': S 2632 [98; 99) 'S': S
@@ -2694,7 +2656,6 @@ fn test() {
2694} 2656}
2695"#), 2657"#),
2696 @r###" 2658 @r###"
2697
2698 [43; 47) 'self': &Self 2659 [43; 47) 'self': &Self
2699 [82; 86) 'self': &Self 2660 [82; 86) 'self': &Self
2700 [210; 361) '{ ..., i8 }': () 2661 [210; 361) '{ ..., i8 }': ()
@@ -2725,7 +2686,6 @@ fn test() {
2725} 2686}
2726"#), 2687"#),
2727 @r###" 2688 @r###"
2728
2729 [33; 37) 'self': &Self 2689 [33; 37) 'self': &Self
2730 [102; 127) '{ ...d(); }': () 2690 [102; 127) '{ ...d(); }': ()
2731 [108; 109) 'S': S<u32>(T) -> S<T> 2691 [108; 109) 'S': S<u32>(T) -> S<T>
@@ -3130,7 +3090,6 @@ fn test<T: Iterable<Item=u32>>() {
3130} 3090}
3131"#), 3091"#),
3132 @r###" 3092 @r###"
3133
3134 [67; 100) '{ ...own; }': () 3093 [67; 100) '{ ...own; }': ()
3135 [77; 78) 'y': {unknown} 3094 [77; 78) 'y': {unknown}
3136 [90; 97) 'unknown': {unknown} 3095 [90; 97) 'unknown': {unknown}
@@ -3146,7 +3105,6 @@ const A: u32 = 1 + 1;
3146static B: u64 = { let x = 1; x }; 3105static B: u64 = { let x = 1; x };
3147"#), 3106"#),
3148 @r###" 3107 @r###"
3149
3150 [16; 17) '1': u32 3108 [16; 17) '1': u32
3151 [16; 21) '1 + 1': u32 3109 [16; 21) '1 + 1': u32
3152 [20; 21) '1': u32 3110 [20; 21) '1': u32
@@ -3170,7 +3128,6 @@ fn test() -> u64 {
3170} 3128}
3171"#), 3129"#),
3172 @r###" 3130 @r###"
3173
3174 [38; 87) '{ ... a.1 }': u64 3131 [38; 87) '{ ... a.1 }': u64
3175 [48; 49) 'a': S 3132 [48; 49) 'a': S
3176 [52; 53) 'S': S(i32, u64) -> S 3133 [52; 53) 'S': S(i32, u64) -> S
@@ -3225,7 +3182,6 @@ fn indexing_arrays() {
3225 assert_snapshot!( 3182 assert_snapshot!(
3226 infer("fn main() { &mut [9][2]; }"), 3183 infer("fn main() { &mut [9][2]; }"),
3227 @r###" 3184 @r###"
3228
3229 [10; 26) '{ &mut...[2]; }': () 3185 [10; 26) '{ &mut...[2]; }': ()
3230 [12; 23) '&mut [9][2]': &mut {unknown} 3186 [12; 23) '&mut [9][2]': &mut {unknown}
3231 [17; 20) '[9]': [i32;_] 3187 [17; 20) '[9]': [i32;_]
@@ -4822,9 +4778,9 @@ fn main() {
4822} 4778}
4823"#), 4779"#),
4824 @r###" 4780 @r###"
4825 ![0; 1) '6': i32 4781 ![0; 1) '6': i32
4826 [64; 88) '{ ...!(); }': () 4782 [64; 88) '{ ...!(); }': ()
4827 [74; 75) 'x': i32 4783 [74; 75) 'x': i32
4828 "### 4784 "###
4829 ); 4785 );
4830} 4786}