From f1f45f9191d60c52dbedec717aee0de4a0580bcc Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 21 Feb 2020 16:56:34 +0100 Subject: 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. --- crates/ra_hir_ty/src/infer/pat.rs | 4 ++- crates/ra_hir_ty/src/tests/patterns.rs | 46 +++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_ty') diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs index a495ecbfe..bf8ea192b 100644 --- a/crates/ra_hir_ty/src/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs @@ -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 diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs index e25d6dbc4..81d00c2af 100644 --- a/crates/ra_hir_ty/src/tests/patterns.rs +++ b/crates/ra_hir_ty/src/tests/patterns.rs @@ -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, o: Option) { "### ); } + +#[test] +fn infer_const_pattern() { + assert_snapshot!( + infer_with_mismatches(r#" +enum Option { None } +use Option::None; +struct Foo; +const Bar: usize = 1; + +fn test() { + let a: Option = None; + let b: Option = 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 + [115; 119) 'None': Option + [129; 130) 'b': Option + [146; 183) 'match ... }': Option + [152; 153) 'a': Option + [164; 168) 'None': Option + [172; 176) 'None': Option + [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 + "### + ); +} -- cgit v1.2.3