mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 13:25:09 +00:00
Fix handling of const patterns
E.g. in `match x { None => ... }`, `None` is a path pattern (resolving to the option variant), not a binding. To determine this, we need to try to resolve the name during lowering. This isn't too hard since we already need to resolve names for macro expansion anyway (though maybe a bit hacky). Fixes #1618.
This commit is contained in:
parent
e3037c2631
commit
f1f45f9191
5 changed files with 85 additions and 6 deletions
|
@ -189,7 +189,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
|||
};
|
||||
// use a new type variable if we got Ty::Unknown here
|
||||
let ty = self.insert_type_vars_shallow(ty);
|
||||
self.unify(&ty, expected);
|
||||
if !self.unify(&ty, expected) {
|
||||
// FIXME record mismatch, we need to change the type of self.type_mismatches for that
|
||||
}
|
||||
let ty = self.resolve_ty_as_possible(ty);
|
||||
self.write_pat_ty(pat, ty.clone());
|
||||
ty
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use super::infer;
|
||||
use super::{infer, infer_with_mismatches};
|
||||
use insta::assert_snapshot;
|
||||
use test_utils::covers;
|
||||
|
||||
|
@ -236,3 +236,47 @@ fn test(a1: A<u32>, o: Option<u64>) {
|
|||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_const_pattern() {
|
||||
assert_snapshot!(
|
||||
infer_with_mismatches(r#"
|
||||
enum Option<T> { None }
|
||||
use Option::None;
|
||||
struct Foo;
|
||||
const Bar: usize = 1;
|
||||
|
||||
fn test() {
|
||||
let a: Option<u32> = None;
|
||||
let b: Option<i64> = match a {
|
||||
None => None,
|
||||
};
|
||||
let _: () = match () { Foo => Foo }; // Expected mismatch
|
||||
let _: () = match () { Bar => Bar }; // Expected mismatch
|
||||
}
|
||||
"#, true),
|
||||
@r###"
|
||||
[74; 75) '1': usize
|
||||
[88; 310) '{ ...atch }': ()
|
||||
[98; 99) 'a': Option<u32>
|
||||
[115; 119) 'None': Option<u32>
|
||||
[129; 130) 'b': Option<i64>
|
||||
[146; 183) 'match ... }': Option<i64>
|
||||
[152; 153) 'a': Option<u32>
|
||||
[164; 168) 'None': Option<u32>
|
||||
[172; 176) 'None': Option<i64>
|
||||
[193; 194) '_': ()
|
||||
[201; 224) 'match ... Foo }': Foo
|
||||
[207; 209) '()': ()
|
||||
[212; 215) 'Foo': Foo
|
||||
[219; 222) 'Foo': Foo
|
||||
[255; 256) '_': ()
|
||||
[263; 286) 'match ... Bar }': usize
|
||||
[269; 271) '()': ()
|
||||
[274; 277) 'Bar': usize
|
||||
[281; 284) 'Bar': usize
|
||||
[201; 224): expected (), got Foo
|
||||
[263; 286): expected (), got usize
|
||||
"###
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue