diff options
author | Lukas Wirth <[email protected]> | 2020-11-24 12:41:21 +0000 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2020-11-24 12:56:20 +0000 |
commit | 35dd62e915905b6a93e2069a6d155cdf00cd254a (patch) | |
tree | ebaf611da8e52f8df0c2d308b18bb9b6368fe3ef /crates/hir_ty/src/infer | |
parent | 6294286fee6e53c29e8ad563f476721ad85ef266 (diff) |
Properly infer tuple patterns when encountering ellipsis
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index cde2ab82b..b3fd74eab 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -111,20 +111,29 @@ impl<'a> InferenceContext<'a> { | |||
111 | let expected = expected; | 111 | let expected = expected; |
112 | 112 | ||
113 | let ty = match &body[pat] { | 113 | let ty = match &body[pat] { |
114 | Pat::Tuple { ref args, .. } => { | 114 | Pat::Tuple { ref args, ellipsis } => { |
115 | let expectations = match expected.as_tuple() { | 115 | let expectations = match expected.as_tuple() { |
116 | Some(parameters) => &*parameters.0, | 116 | Some(parameters) => &*parameters.0, |
117 | _ => &[], | 117 | _ => &[], |
118 | }; | 118 | }; |
119 | let expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); | ||
120 | 119 | ||
121 | let inner_tys = args | 120 | let (pre, post) = match ellipsis { |
122 | .iter() | 121 | &Some(idx) => args.split_at(idx), |
123 | .zip(expectations_iter) | 122 | None => (&args[..], &[][..]), |
124 | .map(|(&pat, ty)| self.infer_pat(pat, ty, default_bm)) | 123 | }; |
125 | .collect(); | 124 | let uncovered_range = pre.len()..expectations.len().saturating_sub(post.len()); |
125 | let mut expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); | ||
126 | let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm); | ||
127 | |||
128 | let mut inner_tys = Vec::with_capacity(expectations.len()); | ||
129 | inner_tys.extend(pre.iter().zip(expectations_iter.by_ref()).map(&mut infer_pat)); | ||
130 | inner_tys.extend(expectations_iter.by_ref().take(uncovered_range.len()).cloned()); | ||
131 | inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); | ||
126 | 132 | ||
127 | Ty::apply(TypeCtor::Tuple { cardinality: args.len() as u16 }, Substs(inner_tys)) | 133 | Ty::apply( |
134 | TypeCtor::Tuple { cardinality: inner_tys.len() as u16 }, | ||
135 | Substs(inner_tys.into()), | ||
136 | ) | ||
128 | } | 137 | } |
129 | Pat::Or(ref pats) => { | 138 | Pat::Or(ref pats) => { |
130 | if let Some((first_pat, rest)) = pats.split_first() { | 139 | if let Some((first_pat, rest)) = pats.split_first() { |