aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
authorMarcus Klaas de Vries <[email protected]>2019-01-16 16:47:59 +0000
committerAleksey Kladov <[email protected]>2019-01-19 12:37:25 +0000
commit9c2d83a4c809b0b11ca389bb454e197859e5116c (patch)
tree36fd28ab25e05276559d5a1086e63cb58aae8673 /crates/ra_hir/src/ty.rs
parent3b0de53904e560f85ccfdc38e66e6d6c9e997b7a (diff)
Add crude implementation of tuplestruct pattern inference
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs81
1 files changed, 55 insertions, 26 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index a13356714..cdecbd064 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -877,7 +877,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
877 fn infer_pat(&mut self, pat: PatId, expected: &Expectation) -> Ty { 877 fn infer_pat(&mut self, pat: PatId, expected: &Expectation) -> Ty {
878 let body = Arc::clone(&self.body); // avoid borrow checker problem 878 let body = Arc::clone(&self.body); // avoid borrow checker problem
879 879
880 match (&body[pat], &expected.ty) { 880 let ty = match (&body[pat], &expected.ty) {
881 (Pat::Tuple(ref args), &Ty::Tuple(ref tuple_args)) 881 (Pat::Tuple(ref args), &Ty::Tuple(ref tuple_args))
882 if args.len() == tuple_args.len() => 882 if args.len() == tuple_args.len() =>
883 { 883 {
@@ -885,42 +885,71 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
885 // FIXME: can we do w/o cloning? 885 // FIXME: can we do w/o cloning?
886 self.infer_pat(pat, &Expectation::has_type(ty.clone())); 886 self.infer_pat(pat, &Expectation::has_type(ty.clone()));
887 } 887 }
888 expected.ty.clone()
888 } 889 }
889 (&Pat::Ref { pat, mutability }, &Ty::Ref(ref sub_ty, ty_mut)) 890 (&Pat::Ref { pat, mutability }, &Ty::Ref(ref sub_ty, ty_mut))
890 if mutability == ty_mut => 891 if mutability == ty_mut =>
891 { 892 {
892 self.infer_pat(pat, &Expectation::has_type((&**sub_ty).clone())); 893 self.infer_pat(pat, &Expectation::has_type((&**sub_ty).clone()));
894 expected.ty.clone()
893 } 895 }
894 (pattern, &Ty::Adt { def_id, .. }) => { 896 (
895 let adt_def = def_id.resolve(self.db); 897 &Pat::TupleStruct {
896 match (pattern, adt_def) { 898 path: ref p,
897 (&Pat::Struct, Def::Struct(s)) => {} 899 args: ref sub_pats,
898 ( 900 },
899 &Pat::TupleStruct { 901 _expected,
900 path: ref p, 902 ) => {
901 args: ref sub_pats, 903 let def = p
902 }, 904 .as_ref()
903 Def::Enum(ref e), 905 .and_then(|path| self.module.resolve_path(self.db, &path).take_types())
904 ) => { 906 .map(|def_id| def_id.resolve(self.db));
905 // TODO: resolve enum 907
906 } 908 if let Some(def) = def {
907 ( 909 let (ty, fields) = match def {
908 &Pat::TupleStruct { 910 Def::Struct(s) => {
909 path: ref p, 911 let fields: Vec<_> = self
910 args: ref sub_pats, 912 .db
911 }, 913 .struct_data(s.def_id())
912 Def::EnumVariant(ref e), 914 .variant_data
913 ) => { 915 .fields()
914 let variant_data = self.db.enum_variant_data(e.def_id); 916 .iter()
917 .cloned()
918 .collect();
919 (type_for_struct(self.db, s), fields)
920 }
921 Def::EnumVariant(ev) => {
922 let fields: Vec<_> =
923 ev.variant_data(self.db).fields().iter().cloned().collect();
924 (type_for_enum_variant(self.db, ev), fields)
925 }
926 _ => unreachable!(),
927 };
928 // walk subpats
929 if fields.len() == sub_pats.len() {
930 for (&sub_pat, field) in sub_pats.iter().zip(fields.iter()) {
931 let sub_ty = Ty::from_hir(
932 self.db,
933 &self.module,
934 self.impl_block.as_ref(),
935 &field.type_ref,
936 );
937
938 self.infer_pat(sub_pat, &Expectation::has_type(sub_ty));
939 }
940
941 ty
942 } else {
943 expected.ty.clone()
915 } 944 }
916 _ => {} 945 } else {
946 expected.ty.clone()
917 } 947 }
918 } 948 }
919 // TODO: implement more 949 (_, ref _expected_ty) => expected.ty.clone(),
920 (_, ref _expected_ty) => {}
921 }; 950 };
922 // use a new type variable if we got Ty::Unknown here 951 // use a new type variable if we got Ty::Unknown here
923 let ty = self.insert_type_vars_shallow(expected.ty.clone()); 952 let ty = self.insert_type_vars_shallow(ty);
924 self.unify(&ty, &expected.ty); 953 self.unify(&ty, &expected.ty);
925 let ty = self.resolve_ty_as_possible(ty); 954 let ty = self.resolve_ty_as_possible(ty);
926 self.write_pat_ty(pat, ty.clone()); 955 self.write_pat_ty(pat, ty.clone());