Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions crates/ra_hir_ty/src/infer/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use hir_def::{
use hir_expand::name::Name;
use test_utils::tested_by;

use super::{BindingMode, InferenceContext};
use super::{BindingMode, Expectation, InferenceContext};
use crate::{utils::variant_data, Substs, Ty, TypeCtor};

impl<'a> InferenceContext<'a> {
Expand Down Expand Up @@ -198,7 +198,14 @@ impl<'a> InferenceContext<'a> {

Ty::apply_one(container_ty, elem_ty)
}
_ => Ty::Unknown,
Pat::Wild => expected.clone(),
Pat::Range { start, end } => {
let start_ty = self.infer_expr(*start, &Expectation::has_type(expected.clone()));
let end_ty = self.infer_expr(*end, &Expectation::has_type(start_ty));
end_ty
}
Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
Pat::Missing => Ty::Unknown,
};
// use a new type variable if we got Ty::Unknown here
let ty = self.insert_type_vars_shallow(ty);
Expand Down
6 changes: 6 additions & 0 deletions crates/ra_hir_ty/src/tests/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,12 +275,14 @@ fn test(i: i32) {
[70; 147) 'match ... }': &[i32]
[76; 77) 'i': i32
[88; 89) '2': i32
[88; 89) '2': i32
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the duplicates?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One is the pattern (which was previously inferred 'backwards' in this case), one is the expression inside the pattern.

[93; 96) 'foo': fn foo<i32>(&[i32]) -> &[i32]
[93; 102) 'foo(&[2])': &[i32]
[97; 101) '&[2]': &[i32; _]
[98; 101) '[2]': [i32; _]
[99; 100) '2': i32
[112; 113) '1': i32
[112; 113) '1': i32
[117; 121) '&[1]': &[i32; _]
[118; 121) '[1]': [i32; _]
[119; 120) '1': i32
Expand Down Expand Up @@ -316,10 +318,12 @@ fn test(i: i32) {
[70; 147) 'match ... }': &[i32]
[76; 77) 'i': i32
[88; 89) '1': i32
[88; 89) '1': i32
[93; 97) '&[1]': &[i32; _]
[94; 97) '[1]': [i32; _]
[95; 96) '1': i32
[107; 108) '2': i32
[107; 108) '2': i32
[112; 115) 'foo': fn foo<i32>(&[i32]) -> &[i32]
[112; 121) 'foo(&[2])': &[i32]
[116; 120) '&[2]': &[i32; _]
Expand Down Expand Up @@ -357,9 +361,11 @@ fn test() {
[45; 142) 'match ... }': *const i32
[51; 52) '1': i32
[63; 64) '1': i32
[63; 64) '1': i32
[68; 69) 't': &mut i32
[68; 81) 't as *mut i32': *mut i32
[91; 92) '2': i32
[91; 92) '2': i32
[96; 97) 't': &mut i32
[96; 105) 't as &i32': &i32
[115; 116) '_': i32
Expand Down
85 changes: 85 additions & 0 deletions crates/ra_hir_ty/src/tests/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,90 @@ fn test(x: &i32) {
);
}

#[test]
fn infer_literal_pattern() {
assert_snapshot!(
infer_with_mismatches(r#"
fn any<T>() -> T { loop {} }
fn test(x: &i32) {
if let "foo" = any() {}
if let 1 = any() {}
if let 1u32 = any() {}
if let 1f32 = any() {}
if let 1.0 = any() {}
if let true = any() {}
}
"#, true),
@r###"
[18; 29) '{ loop {} }': T
[20; 27) 'loop {}': !
[25; 27) '{}': ()
[38; 39) 'x': &i32
[47; 209) '{ ...) {} }': ()
[53; 76) 'if let...y() {}': ()
[60; 65) '"foo"': &str
[60; 65) '"foo"': &str
[68; 71) 'any': fn any<&str>() -> &str
[68; 73) 'any()': &str
[74; 76) '{}': ()
[81; 100) 'if let...y() {}': ()
[88; 89) '1': i32
[88; 89) '1': i32
[92; 95) 'any': fn any<i32>() -> i32
[92; 97) 'any()': i32
[98; 100) '{}': ()
[105; 127) 'if let...y() {}': ()
[112; 116) '1u32': u32
[112; 116) '1u32': u32
[119; 122) 'any': fn any<u32>() -> u32
[119; 124) 'any()': u32
[125; 127) '{}': ()
[132; 154) 'if let...y() {}': ()
[139; 143) '1f32': f32
[139; 143) '1f32': f32
[146; 149) 'any': fn any<f32>() -> f32
[146; 151) 'any()': f32
[152; 154) '{}': ()
[159; 180) 'if let...y() {}': ()
[166; 169) '1.0': f64
[166; 169) '1.0': f64
[172; 175) 'any': fn any<f64>() -> f64
[172; 177) 'any()': f64
[178; 180) '{}': ()
[185; 207) 'if let...y() {}': ()
[192; 196) 'true': bool
[192; 196) 'true': bool
[199; 202) 'any': fn any<bool>() -> bool
[199; 204) 'any()': bool
[205; 207) '{}': ()
"###
);
}

#[test]
fn infer_range_pattern() {
assert_snapshot!(
infer_with_mismatches(r#"
fn test(x: &i32) {
if let 1..76 = 2u32 {}
if let 1..=76 = 2u32 {}
}
"#, true),
@r###"
[9; 10) 'x': &i32
[18; 76) '{ ...2 {} }': ()
[24; 46) 'if let...u32 {}': ()
[31; 36) '1..76': u32
[39; 43) '2u32': u32
[44; 46) '{}': ()
[51; 74) 'if let...u32 {}': ()
[58; 64) '1..=76': u32
[67; 71) '2u32': u32
[72; 74) '{}': ()
"###
);
}

#[test]
fn infer_pattern_match_ergonomics() {
assert_snapshot!(
Expand Down Expand Up @@ -212,6 +296,7 @@ fn test() {
[59; 62) 'arr': [f64; _]
[73; 81) '[1.0, a]': [f64; _]
[74; 77) '1.0': f64
[74; 77) '1.0': f64
[79; 80) 'a': f64
[85; 111) '{ ... }': ()
[99; 100) 'a': f64
Expand Down
3 changes: 2 additions & 1 deletion crates/ra_hir_ty/src/tests/regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,8 @@ pub fn compute() {
[24; 106) 'match ... }': ()
[30; 37) 'nope!()': {unknown}
[48; 94) 'SizeSk...tail }': {unknown}
[82; 86) 'true': {unknown}
[82; 86) 'true': bool
[82; 86) 'true': bool
[88; 92) 'tail': {unknown}
[98; 100) '{}': ()
"###
Expand Down
2 changes: 2 additions & 0 deletions crates/ra_hir_ty/src/tests/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,7 @@ fn foo() {
[165; 247) 'match ... }': i32
[171; 175) 'true': bool
[186; 190) 'true': bool
[186; 190) 'true': bool
[194; 195) '3': i32
[205; 206) '_': bool
[210; 241) '{ ... }': !
Expand All @@ -956,6 +957,7 @@ fn foo() {
[263; 320) 'match ... }': i32
[269; 273) 'true': bool
[284; 288) 'true': bool
[284; 288) 'true': bool
[292; 293) '4': i32
[303; 304) '_': bool
[308; 314) 'return': !
Expand Down