Skip to content

Commit b2a6245

Browse files
authored
Merge pull request #21113 from ChayimFriedman2/byte-range
fix: Infer range patterns correctly
2 parents 813c7d4 + ba27d77 commit b2a6245

File tree

2 files changed

+29
-55
lines changed

2 files changed

+29
-55
lines changed

crates/hir-ty/src/infer/pat.rs

Lines changed: 9 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use hir_expand::name::Name;
1111
use rustc_ast_ir::Mutability;
1212
use rustc_type_ir::inherent::{GenericArg as _, GenericArgs as _, IntoKind, SliceLike, Ty as _};
1313
use stdx::TupleExt;
14-
use syntax::ast::RangeOp;
1514

1615
use crate::{
1716
DeclContext, DeclOrigin, InferenceDiagnostic,
@@ -350,51 +349,16 @@ impl<'db> InferenceContext<'_, 'db> {
350349
self.infer_slice_pat(expected, prefix, *slice, suffix, default_bm, decl)
351350
}
352351
Pat::Wild => expected,
353-
Pat::Range { start, end, range_type } => {
354-
// FIXME: Expectation
355-
let lhs_expectation = Expectation::none();
356-
let lhs_ty =
357-
start.map(|start| self.infer_expr(start, &lhs_expectation, ExprIsRead::Yes));
358-
let rhs_expectation = lhs_ty.map_or_else(Expectation::none, Expectation::HasType);
359-
let rhs_ty = end.map(|end| self.infer_expr(end, &rhs_expectation, ExprIsRead::Yes));
360-
let single_arg_adt = |adt, ty: Ty<'db>| {
361-
Ty::new_adt(
362-
self.interner(),
363-
adt,
364-
GenericArgs::new_from_iter(self.interner(), [ty.into()]),
365-
)
366-
};
367-
match (range_type, lhs_ty, rhs_ty) {
368-
(RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
369-
Some(adt) => Ty::new_adt(self.interner(), adt, self.types.empty_args),
370-
None => self.err_ty(),
371-
},
372-
(RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
373-
Some(adt) => single_arg_adt(adt, ty),
374-
None => self.err_ty(),
375-
},
376-
(RangeOp::Inclusive, None, Some(ty)) => {
377-
match self.resolve_range_to_inclusive() {
378-
Some(adt) => single_arg_adt(adt, ty),
379-
None => self.err_ty(),
380-
}
381-
}
382-
(RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
383-
Some(adt) => single_arg_adt(adt, ty),
384-
None => self.err_ty(),
385-
},
386-
(RangeOp::Inclusive, Some(_), Some(ty)) => {
387-
match self.resolve_range_inclusive() {
388-
Some(adt) => single_arg_adt(adt, ty),
389-
None => self.err_ty(),
390-
}
391-
}
392-
(RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
393-
Some(adt) => single_arg_adt(adt, ty),
394-
None => self.err_ty(),
395-
},
396-
(RangeOp::Inclusive, _, None) => self.err_ty(),
352+
Pat::Range { start, end, range_type: _ } => {
353+
if let Some(start) = *start {
354+
let start_ty = self.infer_expr(start, &Expectation::None, ExprIsRead::Yes);
355+
_ = self.demand_eqtype(start.into(), expected, start_ty);
356+
}
357+
if let Some(end) = *end {
358+
let end_ty = self.infer_expr(end, &Expectation::None, ExprIsRead::Yes);
359+
_ = self.demand_eqtype(end.into(), expected, end_ty);
397360
}
361+
expected
398362
}
399363
&Pat::Lit(expr) => {
400364
// Don't emit type mismatches again, the expression lowering already did that.

crates/hir-ty/src/tests/patterns.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -196,28 +196,38 @@ fn test(x..y: &core::ops::Range<u32>) {
196196
}
197197
"#,
198198
expect![[r#"
199-
8..9 'x': u32
199+
8..9 'x': Range<u32>
200200
8..12 'x..y': Range<u32>
201-
11..12 'y': u32
201+
11..12 'y': Range<u32>
202202
38..96 '{ ...2 {} }': ()
203203
44..66 'if let...u32 {}': ()
204204
47..63 'let 1....= 2u32': bool
205-
51..52 '1': i32
206-
51..56 '1..76': Range<i32>
207-
54..56 '76': i32
205+
51..52 '1': u32
206+
51..56 '1..76': u32
207+
54..56 '76': u32
208208
59..63 '2u32': u32
209209
64..66 '{}': ()
210210
71..94 'if let...u32 {}': ()
211211
74..91 'let 1....= 2u32': bool
212-
78..79 '1': i32
213-
78..84 '1..=76': RangeInclusive<i32>
214-
82..84 '76': i32
212+
78..79 '1': u32
213+
78..84 '1..=76': u32
214+
82..84 '76': u32
215215
87..91 '2u32': u32
216216
92..94 '{}': ()
217-
51..56: expected u32, got Range<i32>
218-
78..84: expected u32, got RangeInclusive<i32>
219217
"#]],
220218
);
219+
check_no_mismatches(
220+
r#"
221+
//- minicore: range
222+
fn main() {
223+
let byte: u8 = 0u8;
224+
let b = match byte {
225+
b'0'..=b'9' => true,
226+
_ => false,
227+
};
228+
}
229+
"#,
230+
);
221231
}
222232

223233
#[test]

0 commit comments

Comments
 (0)