diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 34 | ||||
-rw-r--r-- | crates/ra_hir/src/expr.rs | 23 | ||||
-rw-r--r-- | crates/ra_hir/src/marks.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 125 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_1.snap | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_2.snap | 14 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_3.snap | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_4.snap | 16 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_5.snap | 30 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 89 |
10 files changed, 326 insertions, 32 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index cafc5279d..19f103855 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::sync::Arc; | 1 | use std::sync::Arc; |
2 | 2 | ||
3 | use relative_path::RelativePathBuf; | 3 | use relative_path::RelativePathBuf; |
4 | use ra_db::{CrateId, FileId}; | 4 | use ra_db::{CrateId, FileId, SourceRootId}; |
5 | use ra_syntax::{ast::self, TreeArc, SyntaxNode}; | 5 | use ra_syntax::{ast::self, TreeArc, SyntaxNode}; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
@@ -16,7 +16,7 @@ use crate::{ | |||
16 | docs::{Documentation, Docs, docs_from_ast}, | 16 | docs::{Documentation, Docs, docs_from_ast}, |
17 | module_tree::ModuleId, | 17 | module_tree::ModuleId, |
18 | ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId}, | 18 | ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId}, |
19 | impl_block::ImplId, | 19 | impl_block::{ImplId, ImplBlock}, |
20 | resolve::Resolver, | 20 | resolve::Resolver, |
21 | }; | 21 | }; |
22 | 22 | ||
@@ -44,6 +44,15 @@ impl Crate { | |||
44 | pub fn root_module(&self, db: &impl PersistentHirDatabase) -> Option<Module> { | 44 | pub fn root_module(&self, db: &impl PersistentHirDatabase) -> Option<Module> { |
45 | self.root_module_impl(db) | 45 | self.root_module_impl(db) |
46 | } | 46 | } |
47 | |||
48 | // TODO: should this be in source_binder? | ||
49 | pub fn source_root_crates( | ||
50 | db: &impl PersistentHirDatabase, | ||
51 | source_root: SourceRootId, | ||
52 | ) -> Vec<Crate> { | ||
53 | let crate_ids = db.source_root_crates(source_root); | ||
54 | crate_ids.iter().map(|&crate_id| Crate { crate_id }).collect() | ||
55 | } | ||
47 | } | 56 | } |
48 | 57 | ||
49 | #[derive(Debug)] | 58 | #[derive(Debug)] |
@@ -168,6 +177,27 @@ impl Module { | |||
168 | let item_map = db.item_map(self.krate); | 177 | let item_map = db.item_map(self.krate); |
169 | Resolver::default().push_module_scope(item_map, *self) | 178 | Resolver::default().push_module_scope(item_map, *self) |
170 | } | 179 | } |
180 | |||
181 | pub fn declarations(self, db: &impl HirDatabase) -> Vec<ModuleDef> { | ||
182 | let (lowered_module, _) = db.lower_module(self); | ||
183 | lowered_module | ||
184 | .declarations | ||
185 | .values() | ||
186 | .cloned() | ||
187 | .flat_map(|per_ns| { | ||
188 | per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) | ||
189 | }) | ||
190 | .collect() | ||
191 | } | ||
192 | |||
193 | pub fn impl_blocks(self, db: &impl HirDatabase) -> Vec<ImplBlock> { | ||
194 | let module_impl_blocks = db.impls_in_module(self); | ||
195 | module_impl_blocks | ||
196 | .impls | ||
197 | .iter() | ||
198 | .map(|(impl_id, _)| ImplBlock::from_id(module_impl_blocks.clone(), impl_id)) | ||
199 | .collect() | ||
200 | } | ||
171 | } | 201 | } |
172 | 202 | ||
173 | impl Docs for Module { | 203 | impl Docs for Module { |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 4e61d87ff..4e73590d0 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -70,6 +70,14 @@ impl Body { | |||
70 | self.owner | 70 | self.owner |
71 | } | 71 | } |
72 | 72 | ||
73 | pub fn exprs(&self) -> impl Iterator<Item = (ExprId, &Expr)> { | ||
74 | self.exprs.iter() | ||
75 | } | ||
76 | |||
77 | pub fn pats(&self) -> impl Iterator<Item = (PatId, &Pat)> { | ||
78 | self.pats.iter() | ||
79 | } | ||
80 | |||
73 | pub fn syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySyntaxMapping> { | 81 | pub fn syntax_mapping(&self, db: &impl HirDatabase) -> Arc<BodySyntaxMapping> { |
74 | db.body_syntax_mapping(self.owner) | 82 | db.body_syntax_mapping(self.owner) |
75 | } | 83 | } |
@@ -831,18 +839,18 @@ impl ExprCollector { | |||
831 | p.field_pat_list().expect("every struct should have a field list"); | 839 | p.field_pat_list().expect("every struct should have a field list"); |
832 | let mut fields: Vec<_> = field_pat_list | 840 | let mut fields: Vec<_> = field_pat_list |
833 | .bind_pats() | 841 | .bind_pats() |
834 | .map(|bind_pat| { | 842 | .filter_map(|bind_pat| { |
835 | let ast_pat = ast::Pat::cast(bind_pat.syntax()).expect("bind pat is a pat"); | 843 | let ast_pat = ast::Pat::cast(bind_pat.syntax()).expect("bind pat is a pat"); |
836 | let pat = self.collect_pat(ast_pat); | 844 | let pat = self.collect_pat(ast_pat); |
837 | let name = bind_pat.name().expect("bind pat has a name").as_name(); | 845 | let name = bind_pat.name()?.as_name(); |
838 | FieldPat { name, pat } | 846 | Some(FieldPat { name, pat }) |
839 | }) | 847 | }) |
840 | .collect(); | 848 | .collect(); |
841 | let iter = field_pat_list.field_pats().map(|f| { | 849 | let iter = field_pat_list.field_pats().filter_map(|f| { |
842 | let ast_pat = f.pat().expect("field pat always contains a pattern"); | 850 | let ast_pat = f.pat()?; |
843 | let pat = self.collect_pat(ast_pat); | 851 | let pat = self.collect_pat(ast_pat); |
844 | let name = f.name().expect("field pats always have a name").as_name(); | 852 | let name = f.name()?.as_name(); |
845 | FieldPat { name, pat } | 853 | Some(FieldPat { name, pat }) |
846 | }); | 854 | }); |
847 | fields.extend(iter); | 855 | fields.extend(iter); |
848 | 856 | ||
@@ -850,6 +858,7 @@ impl ExprCollector { | |||
850 | } | 858 | } |
851 | 859 | ||
852 | // TODO: implement | 860 | // TODO: implement |
861 | ast::PatKind::LiteralPat(_) => Pat::Missing, | ||
853 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, | 862 | ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, |
854 | }; | 863 | }; |
855 | let syntax_ptr = SyntaxNodePtr::new(pat.syntax()); | 864 | let syntax_ptr = SyntaxNodePtr::new(pat.syntax()); |
diff --git a/crates/ra_hir/src/marks.rs b/crates/ra_hir/src/marks.rs index d704c3adb..aba0c9968 100644 --- a/crates/ra_hir/src/marks.rs +++ b/crates/ra_hir/src/marks.rs | |||
@@ -3,4 +3,5 @@ test_utils::marks!( | |||
3 | item_map_enum_importing | 3 | item_map_enum_importing |
4 | type_var_cycles_resolve_completely | 4 | type_var_cycles_resolve_completely |
5 | type_var_cycles_resolve_as_possible | 5 | type_var_cycles_resolve_as_possible |
6 | type_var_resolves_to_int_var | ||
6 | ); | 7 | ); |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 453520bbe..2dc1de41a 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -449,6 +449,49 @@ impl Ty { | |||
449 | Ty::Tuple(Arc::new([])) | 449 | Ty::Tuple(Arc::new([])) |
450 | } | 450 | } |
451 | 451 | ||
452 | pub fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
453 | f(self); | ||
454 | match self { | ||
455 | Ty::Slice(t) | Ty::Array(t) => t.walk(f), | ||
456 | Ty::RawPtr(t, _) => t.walk(f), | ||
457 | Ty::Ref(t, _) => t.walk(f), | ||
458 | Ty::Tuple(ts) => { | ||
459 | for t in ts.iter() { | ||
460 | t.walk(f); | ||
461 | } | ||
462 | } | ||
463 | Ty::FnPtr(sig) => { | ||
464 | for input in &sig.input { | ||
465 | input.walk(f); | ||
466 | } | ||
467 | sig.output.walk(f); | ||
468 | } | ||
469 | Ty::FnDef { substs, sig, .. } => { | ||
470 | for input in &sig.input { | ||
471 | input.walk(f); | ||
472 | } | ||
473 | sig.output.walk(f); | ||
474 | for t in substs.0.iter() { | ||
475 | t.walk(f); | ||
476 | } | ||
477 | } | ||
478 | Ty::Adt { substs, .. } => { | ||
479 | for t in substs.0.iter() { | ||
480 | t.walk(f); | ||
481 | } | ||
482 | } | ||
483 | Ty::Bool | ||
484 | | Ty::Char | ||
485 | | Ty::Int(_) | ||
486 | | Ty::Float(_) | ||
487 | | Ty::Str | ||
488 | | Ty::Never | ||
489 | | Ty::Param { .. } | ||
490 | | Ty::Infer(_) | ||
491 | | Ty::Unknown => {} | ||
492 | } | ||
493 | } | ||
494 | |||
452 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { | 495 | fn walk_mut(&mut self, f: &mut impl FnMut(&mut Ty)) { |
453 | f(self); | 496 | f(self); |
454 | match self { | 497 | match self { |
@@ -491,7 +534,15 @@ impl Ty { | |||
491 | } | 534 | } |
492 | substs.0 = v.into(); | 535 | substs.0 = v.into(); |
493 | } | 536 | } |
494 | _ => {} | 537 | Ty::Bool |
538 | | Ty::Char | ||
539 | | Ty::Int(_) | ||
540 | | Ty::Float(_) | ||
541 | | Ty::Str | ||
542 | | Ty::Never | ||
543 | | Ty::Param { .. } | ||
544 | | Ty::Infer(_) | ||
545 | | Ty::Unknown => {} | ||
495 | } | 546 | } |
496 | } | 547 | } |
497 | 548 | ||
@@ -879,11 +930,22 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
879 | ty | 930 | ty |
880 | } | 931 | } |
881 | 932 | ||
882 | fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs) -> bool { | 933 | fn unify_substs(&mut self, substs1: &Substs, substs2: &Substs, depth: usize) -> bool { |
883 | substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify(t1, t2)) | 934 | substs1.0.iter().zip(substs2.0.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth)) |
884 | } | 935 | } |
885 | 936 | ||
886 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { | 937 | fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool { |
938 | self.unify_inner(ty1, ty2, 0) | ||
939 | } | ||
940 | |||
941 | fn unify_inner(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { | ||
942 | if depth > 1000 { | ||
943 | // prevent stackoverflows | ||
944 | panic!("infinite recursion in unification"); | ||
945 | } | ||
946 | if ty1 == ty2 { | ||
947 | return true; | ||
948 | } | ||
887 | // try to resolve type vars first | 949 | // try to resolve type vars first |
888 | let ty1 = self.resolve_ty_shallow(ty1); | 950 | let ty1 = self.resolve_ty_shallow(ty1); |
889 | let ty2 = self.resolve_ty_shallow(ty2); | 951 | let ty2 = self.resolve_ty_shallow(ty2); |
@@ -904,13 +966,15 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
904 | ( | 966 | ( |
905 | Ty::Adt { def_id: def_id1, substs: substs1, .. }, | 967 | Ty::Adt { def_id: def_id1, substs: substs1, .. }, |
906 | Ty::Adt { def_id: def_id2, substs: substs2, .. }, | 968 | Ty::Adt { def_id: def_id2, substs: substs2, .. }, |
907 | ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2), | 969 | ) if def_id1 == def_id2 => self.unify_substs(substs1, substs2, depth + 1), |
908 | (Ty::Slice(t1), Ty::Slice(t2)) => self.unify(t1, t2), | 970 | (Ty::Slice(t1), Ty::Slice(t2)) => self.unify_inner(t1, t2, depth + 1), |
909 | (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => self.unify(t1, t2), | 971 | (Ty::RawPtr(t1, m1), Ty::RawPtr(t2, m2)) if m1 == m2 => { |
910 | (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify(t1, t2), | 972 | self.unify_inner(t1, t2, depth + 1) |
973 | } | ||
974 | (Ty::Ref(t1, m1), Ty::Ref(t2, m2)) if m1 == m2 => self.unify_inner(t1, t2, depth + 1), | ||
911 | (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true, | 975 | (Ty::FnPtr(sig1), Ty::FnPtr(sig2)) if sig1 == sig2 => true, |
912 | (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => { | 976 | (Ty::Tuple(ts1), Ty::Tuple(ts2)) if ts1.len() == ts2.len() => { |
913 | ts1.iter().zip(ts2.iter()).all(|(t1, t2)| self.unify(t1, t2)) | 977 | ts1.iter().zip(ts2.iter()).all(|(t1, t2)| self.unify_inner(t1, t2, depth + 1)) |
914 | } | 978 | } |
915 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) | 979 | (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) |
916 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) | 980 | | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) |
@@ -989,19 +1053,30 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
989 | /// If `ty` is a type variable with known type, returns that type; | 1053 | /// If `ty` is a type variable with known type, returns that type; |
990 | /// otherwise, return ty. | 1054 | /// otherwise, return ty. |
991 | fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { | 1055 | fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { |
992 | match ty { | 1056 | let mut ty = Cow::Borrowed(ty); |
993 | Ty::Infer(tv) => { | 1057 | // The type variable could resolve to a int/float variable. Hence try |
994 | let inner = tv.to_inner(); | 1058 | // resolving up to three times; each type of variable shouldn't occur |
995 | match self.var_unification_table.probe_value(inner).known() { | 1059 | // more than once |
996 | Some(known_ty) => { | 1060 | for i in 0..3 { |
997 | // The known_ty can't be a type var itself | 1061 | if i > 0 { |
998 | Cow::Owned(known_ty.clone()) | 1062 | tested_by!(type_var_resolves_to_int_var); |
1063 | } | ||
1064 | match &*ty { | ||
1065 | Ty::Infer(tv) => { | ||
1066 | let inner = tv.to_inner(); | ||
1067 | match self.var_unification_table.probe_value(inner).known() { | ||
1068 | Some(known_ty) => { | ||
1069 | // The known_ty can't be a type var itself | ||
1070 | ty = Cow::Owned(known_ty.clone()); | ||
1071 | } | ||
1072 | _ => return ty, | ||
999 | } | 1073 | } |
1000 | _ => Cow::Borrowed(ty), | ||
1001 | } | 1074 | } |
1075 | _ => return ty, | ||
1002 | } | 1076 | } |
1003 | _ => Cow::Borrowed(ty), | ||
1004 | } | 1077 | } |
1078 | log::error!("Inference variable still not resolved: {:?}", ty); | ||
1079 | ty | ||
1005 | } | 1080 | } |
1006 | 1081 | ||
1007 | /// Resolves the type completely; type variables without known type are | 1082 | /// Resolves the type completely; type variables without known type are |
@@ -1185,17 +1260,21 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1185 | self.infer_path_expr(&resolver, &path).unwrap_or(Ty::Unknown) | 1260 | self.infer_path_expr(&resolver, &path).unwrap_or(Ty::Unknown) |
1186 | } | 1261 | } |
1187 | Pat::Bind { mode, name: _name, subpat } => { | 1262 | Pat::Bind { mode, name: _name, subpat } => { |
1188 | let subty = if let Some(subpat) = subpat { | 1263 | let inner_ty = if let Some(subpat) = subpat { |
1189 | self.infer_pat(*subpat, expected) | 1264 | self.infer_pat(*subpat, expected) |
1190 | } else { | 1265 | } else { |
1191 | expected.clone() | 1266 | expected.clone() |
1192 | }; | 1267 | }; |
1268 | let inner_ty = self.insert_type_vars_shallow(inner_ty); | ||
1193 | 1269 | ||
1194 | match mode { | 1270 | let bound_ty = match mode { |
1195 | BindingAnnotation::Ref => Ty::Ref(subty.into(), Mutability::Shared), | 1271 | BindingAnnotation::Ref => Ty::Ref(inner_ty.clone().into(), Mutability::Shared), |
1196 | BindingAnnotation::RefMut => Ty::Ref(subty.into(), Mutability::Mut), | 1272 | BindingAnnotation::RefMut => Ty::Ref(inner_ty.clone().into(), Mutability::Mut), |
1197 | BindingAnnotation::Mutable | BindingAnnotation::Unannotated => subty, | 1273 | BindingAnnotation::Mutable | BindingAnnotation::Unannotated => inner_ty.clone(), |
1198 | } | 1274 | }; |
1275 | let bound_ty = self.resolve_ty_as_possible(&mut vec![], bound_ty); | ||
1276 | self.write_pat_ty(pat, bound_ty); | ||
1277 | return inner_ty; | ||
1199 | } | 1278 | } |
1200 | _ => Ty::Unknown, | 1279 | _ => Ty::Unknown, |
1201 | }; | 1280 | }; |
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_1.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_1.snap new file mode 100644 index 000000000..4b99788e4 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_1.snap | |||
@@ -0,0 +1,13 @@ | |||
1 | --- | ||
2 | created: "2019-02-09T16:56:24.803326529Z" | ||
3 | creator: [email protected] | ||
4 | source: crates/ra_hir/src/ty/tests.rs | ||
5 | expression: "&result" | ||
6 | --- | ||
7 | [54; 139) '{ ... } }': () | ||
8 | [60; 137) 'match ... }': () | ||
9 | [66; 83) 'someth...nknown': Maybe<[unknown]> | ||
10 | [94; 124) 'Maybe:...thing)': Maybe<[unknown]> | ||
11 | [106; 123) 'ref mu...ething': &mut [unknown] | ||
12 | [128; 130) '()': () | ||
13 | |||
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_2.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_2.snap new file mode 100644 index 000000000..fd0b39b7d --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_2.snap | |||
@@ -0,0 +1,14 @@ | |||
1 | --- | ||
2 | created: "2019-02-09T17:03:11.974225590Z" | ||
3 | creator: [email protected] | ||
4 | source: crates/ra_hir/src/ty/tests.rs | ||
5 | expression: "&result" | ||
6 | --- | ||
7 | [23; 53) '{ ...n']; }': () | ||
8 | [29; 50) '&[0, b...b'\n']': &[u8] | ||
9 | [30; 50) '[0, b'...b'\n']': [u8] | ||
10 | [31; 32) '0': u8 | ||
11 | [34; 39) 'b'\n'': u8 | ||
12 | [41; 42) '1': u8 | ||
13 | [44; 49) 'b'\n'': u8 | ||
14 | |||
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_3.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_3.snap new file mode 100644 index 000000000..d15b77e17 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_3.snap | |||
@@ -0,0 +1,13 @@ | |||
1 | --- | ||
2 | created: "2019-02-09T18:02:37.377591660Z" | ||
3 | creator: [email protected] | ||
4 | source: crates/ra_hir/src/ty/tests.rs | ||
5 | expression: "&result" | ||
6 | --- | ||
7 | [18; 102) '{ ... } }': () | ||
8 | [24; 100) 'match ... }': () | ||
9 | [42; 88) 'SizeSk...tail }': [unknown] | ||
10 | [76; 80) 'true': [unknown] | ||
11 | [82; 86) 'tail': [unknown] | ||
12 | [92; 94) '{}': () | ||
13 | |||
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_4.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_4.snap new file mode 100644 index 000000000..fb31883ce --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_4.snap | |||
@@ -0,0 +1,16 @@ | |||
1 | --- | ||
2 | created: "2019-02-09T19:55:39.712470520Z" | ||
3 | creator: [email protected] | ||
4 | source: crates/ra_hir/src/ty/tests.rs | ||
5 | expression: "&result" | ||
6 | --- | ||
7 | [25; 110) '{ ... } }': () | ||
8 | [31; 108) 'match ... }': () | ||
9 | [37; 42) '*self': [unknown] | ||
10 | [38; 42) 'self': [unknown] | ||
11 | [53; 95) 'Borrow...), ..}': [unknown] | ||
12 | [74; 77) 'box': [unknown] | ||
13 | [78; 87) 'Primitive': [unknown] | ||
14 | [88; 89) 'p': [unknown] | ||
15 | [99; 101) '{}': () | ||
16 | |||
diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_5.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_5.snap new file mode 100644 index 000000000..6bbf59fb6 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_5.snap | |||
@@ -0,0 +1,30 @@ | |||
1 | --- | ||
2 | created: "2019-02-09T20:28:37.294693728Z" | ||
3 | creator: [email protected] | ||
4 | source: crates/ra_hir/src/ty/tests.rs | ||
5 | expression: "&result" | ||
6 | --- | ||
7 | [27; 323) '{ ... } }': () | ||
8 | [33; 321) 'for co... }': () | ||
9 | [37; 44) 'content': &[unknown] | ||
10 | [48; 61) 'doesnt_matter': [unknown] | ||
11 | [62; 321) '{ ... }': () | ||
12 | [76; 80) 'name': &&[unknown] | ||
13 | [83; 167) 'if doe... }': &&[unknown] | ||
14 | [86; 99) 'doesnt_matter': bool | ||
15 | [100; 129) '{ ... }': &&[unknown] | ||
16 | [114; 119) 'first': &&[unknown] | ||
17 | [135; 167) '{ ... }': &&[unknown] | ||
18 | [149; 157) '&content': &&[unknown] | ||
19 | [150; 157) 'content': &[unknown] | ||
20 | [182; 189) 'content': &&[unknown] | ||
21 | [192; 314) 'if ICE... }': &&[unknown] | ||
22 | [195; 232) 'ICE_RE..._VALUE': [unknown] | ||
23 | [195; 248) 'ICE_RE...&name)': bool | ||
24 | [242; 247) '&name': &&&[unknown] | ||
25 | [243; 247) 'name': &&[unknown] | ||
26 | [249; 277) '{ ... }': &&[unknown] | ||
27 | [263; 267) 'name': &&[unknown] | ||
28 | [283; 314) '{ ... }': &[unknown] | ||
29 | [297; 304) 'content': &[unknown] | ||
30 | |||
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 2621d1b55..e64fd2749 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -630,6 +630,95 @@ fn test() { | |||
630 | ); | 630 | ); |
631 | } | 631 | } |
632 | 632 | ||
633 | #[test] | ||
634 | fn infer_std_crash_1() { | ||
635 | // caused stack overflow, taken from std | ||
636 | check_inference( | ||
637 | "infer_std_crash_1", | ||
638 | r#" | ||
639 | enum Maybe<T> { | ||
640 | Real(T), | ||
641 | Fake, | ||
642 | } | ||
643 | |||
644 | fn write() { | ||
645 | match something_unknown { | ||
646 | Maybe::Real(ref mut something) => (), | ||
647 | } | ||
648 | } | ||
649 | "#, | ||
650 | ); | ||
651 | } | ||
652 | |||
653 | #[test] | ||
654 | fn infer_std_crash_2() { | ||
655 | covers!(type_var_resolves_to_int_var); | ||
656 | // caused "equating two type variables, ...", taken from std | ||
657 | check_inference( | ||
658 | "infer_std_crash_2", | ||
659 | r#" | ||
660 | fn test_line_buffer() { | ||
661 | &[0, b'\n', 1, b'\n']; | ||
662 | } | ||
663 | "#, | ||
664 | ); | ||
665 | } | ||
666 | |||
667 | #[test] | ||
668 | fn infer_std_crash_3() { | ||
669 | // taken from rustc | ||
670 | check_inference( | ||
671 | "infer_std_crash_3", | ||
672 | r#" | ||
673 | pub fn compute() { | ||
674 | match _ { | ||
675 | SizeSkeleton::Pointer { non_zero: true, tail } => {} | ||
676 | } | ||
677 | } | ||
678 | "#, | ||
679 | ); | ||
680 | } | ||
681 | |||
682 | #[test] | ||
683 | fn infer_std_crash_4() { | ||
684 | // taken from rustc | ||
685 | check_inference( | ||
686 | "infer_std_crash_4", | ||
687 | r#" | ||
688 | pub fn primitive_type() { | ||
689 | match *self { | ||
690 | BorrowedRef { type_: box Primitive(p), ..} => {}, | ||
691 | } | ||
692 | } | ||
693 | "#, | ||
694 | ); | ||
695 | } | ||
696 | |||
697 | #[test] | ||
698 | fn infer_std_crash_5() { | ||
699 | // taken from rustc | ||
700 | check_inference( | ||
701 | "infer_std_crash_5", | ||
702 | r#" | ||
703 | fn extra_compiler_flags() { | ||
704 | for content in doesnt_matter { | ||
705 | let name = if doesnt_matter { | ||
706 | first | ||
707 | } else { | ||
708 | &content | ||
709 | }; | ||
710 | |||
711 | let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) { | ||
712 | name | ||
713 | } else { | ||
714 | content | ||
715 | }; | ||
716 | } | ||
717 | } | ||
718 | "#, | ||
719 | ); | ||
720 | } | ||
721 | |||
633 | fn infer(content: &str) -> String { | 722 | fn infer(content: &str) -> String { |
634 | let (db, _, file_id) = MockDatabase::with_single_file(content); | 723 | let (db, _, file_id) = MockDatabase::with_single_file(content); |
635 | let source_file = db.parse(file_id); | 724 | let source_file = db.parse(file_id); |